> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-docs-zh.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 HanaSparqlQAAgent 进行问答

> 使用 LangChain JavaScript 与 HanaSparqlQAAgent 类型集成。

## 设置与安装

要使用此功能，请安装 `@sap/hana-langchain` 包及其依赖项：

```bash theme={null}
npm install @sap/hana-langchain @langchain/core@latest @langchain/classic@latest langchain@latest
```

`HanaSparqlQAAgent` 是一种基于智能体的方法，用于回答存储在 SAP HANA Cloud 中的 RDF 数据库中的问题。与基于链的方法不同，智能体可以：

1. **动态检索本体** 使用专用工具
2. **生成并执行 SPARQL 查询** 迭代
3. **自我纠正** 如果查询失败或返回意外结果
4. **逐步推理** 关于复杂问题

## 初始化

您需要：

* 一个 **LLM** 为智能体的推理提供支持
* 一个 **`HanaRdfGraph`**（具有连接、`graphUri` 和本体）

请按照此处 [HanaRdfGraph](https://langchain-docs-zh.mintlify.site/langchain/oss/python/integrations/graphs/sap_hana_rdf_graph.md) 的步骤了解更多关于创建 `HanaRdfGraph` 实例的信息。

导入 `HanaSparqlQAAgent`

```typescript theme={null}
import { HanaSparqlQAAgent, HanaSparqlQAAgentOptions } from "@sap/hana-langchain";
const agentConfig : HanaSparqlQAAgentOptions = {
  graph: graph
};
const agent = HanaSparqlQAAgent.createAgent(llm, agentConfig);
```

## 智能体概述

智能体使用工具迭代执行以下操作：

1. 首先检索本体以理解数据结构
2. 根据模式生成适当的 SPARQL 查询
3. 执行查询并解释结果
4. 制定自然语言答案

### 默认设置

* **工具**:
  * `retrieveOntology` - 从图中以 Turtle 格式检索 RDF 本体/模式
  * `executeSparql` - 对 HANA RDF 图执行 SPARQL 查询
* **系统提示词**：提供默认系统提示词，包含 SPARQL 生成和工具使用的说明。
* **中间件**：`ModelRetryMiddleware({maxRetries:3})` 和 `ToolRetryMiddleWare({maxRetries:2})` 默认添加以防止无限循环

### 自定义您的智能体

您可以通过向 `createAgent` 提供附加参数来自定义智能体的行为：

```typescript theme={null}
const agentConfig : HanaSparqlQAAgentOptions = {
  graph: graph,  // Required: HanaRdfGraph instance
  systemPrompt: yourCustomPrompt,  // Custom system prompt (string or SystemMessage)
  tools: [yourCustomTools],  // Additional tools to include
  middleware: [yourCustomMiddlewares],  // Additional middleware to include
  includeDefaultTools: true,  // include default tools (default: True)
  includeDefaultMiddleware: true,  // include default middleware (default: True)
};
const agent = HanaSparqlQAAgent.createAgent(
    model, // Required LLM to power the agent
    agentConfig
)
```

## 示例：在“电影”知识图谱上进行问答

**前提条件**：
您必须有一个启用了 **三元组存储** 功能的 SAP HANA Cloud 实例。
有关详细说明，请参阅：[启用三元组存储](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-knowledge-graph-guide/enable-triple-store/)\

加载 `kgdocu_movies` 示例数据。参见 [知识图谱示例](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-knowledge-graph-guide/knowledge-graph-example)。

以下示例：

1. 实例化 `HanaRdfGraph` 指向电影数据图
2. 创建一个由 LLM 驱动的 `HanaSparqlQAAgent`
3. 提出自然语言问题，并让智能体通过推理得出答案

这展示了智能体如何动态检索本体、生成 SPARQL 查询并返回人类可读的答案。

```typescript theme={null}
import * as dotenv from 'dotenv';
// Load environment variables if needed
dotenv.config();

import hanaClient from "@sap/hana-client";

const connectionParams = {
  host: process.env.HANA_DB_ADDRESS,
  port: process.env.HANA_DB_PORT,
  user: process.env.HANA_DB_USER,
  password: process.env.HANA_DB_PASSWORD,
};
const client = hanaClient.createConnection(connectionParams);

// connect to hanaDB
await new Promise<void>((resolve, reject) => {
  client.connect((err: Error) => {
    // Use arrow function here
    if (err) {
      reject(err);
    } else {
      console.log("Connected to SAP HANA successfully.");
      resolve();
    }
  });
});
```

然后，设置知识图谱实例

```typescript theme={null}
import { HanaRdfGraph, HanaRdfGraphOptions } from "@sap/hana-langchain";

const graphOptions: HanaRdfGraphOptions = {
  connection: client,
  graphUri: "kgdocu_movies",
  autoExtractOntology: true,
};

// create a Graph instance from a source URI
const graph = new HanaRdfGraph(graphOptions);

// need to initialize once an instance is created.
await graph.initialize(graphOptions);
```

```typescript theme={null}
// Serialise the graph schema (optional)
// Internally, the schema is stored as an N3 Store instance,
// We use the N3 Writer to serialise it to Turtle format for display.
const schemaStore = graph.getSchema();
const writer = new Writer({
  prefixes: {
    rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    rdfs: "http://www.w3.org/2000/01/rdf-schema#",
    owl: "http://www.w3.org/2002/07/owl#",
    xsd: "http://www.w3.org/2001/XMLSchema#",
  },
});
schemaStore.forEach((quad) => {
  writer.addQuad(quad);
});
writer.end((error, result) => {
  if (error) {
    console.error("Error serialising schema:", error);
  } else {
    console.log("Graph Schema in Turtle format:\n", result);
  }
});
```

```text theme={null}
Graph Schema in Turtle format:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

<http://kg.demo.sap.com/Place> a owl:Class;
    rdfs:label "Place".
rdfs:label a owl:DatatypeProperty;
    rdfs:label "label";
    rdfs:domain <http://kg.demo.sap.com/Place>, <http://kg.demo.sap.com/Actor>, <http://kg.demo.sap.com/Director>, <http://kg.demo.sap.com/Genre>;
    rdfs:range xsd:string.
<http://kg.demo.sap.com/Actor> a owl:Class;
    rdfs:label "Actor".
<http://kg.demo.sap.com/Film> a owl:Class;
    rdfs:label "Film".
<http://kg.demo.sap.com/Director> a owl:Class;
    rdfs:label "Director".
<http://kg.demo.sap.com/Genre> a owl:Class;
    rdfs:label "Genre".
<http://kg.demo.sap.com/dateOfBirth> a owl:DatatypeProperty;
    rdfs:label "dateOfBirth";
    rdfs:domain <http://kg.demo.sap.com/Actor>;
    rdfs:range xsd:dateTime.
<http://kg.demo.sap.com/placeOfBirth> a owl:ObjectProperty;
    rdfs:label "placeOfBirth";
    rdfs:domain <http://kg.demo.sap.com/Actor>;
    rdfs:range <http://kg.demo.sap.com/Place>.
<http://kg.demo.sap.com/title> a owl:DatatypeProperty;
    rdfs:label "title";
    rdfs:domain <http://kg.demo.sap.com/Film>;
    rdfs:range xsd:string.
<http://kg.demo.sap.com/directed> a owl:ObjectProperty;
    rdfs:label "directed";
    rdfs:domain <http://kg.demo.sap.com/Director>;
    rdfs:range <http://kg.demo.sap.com/Film>.
<http://kg.demo.sap.com/acted_in> a owl:ObjectProperty;
    rdfs:label "acted_in";
    rdfs:domain <http://kg.demo.sap.com/Actor>;
    rdfs:range <http://kg.demo.sap.com/Film>.
<http://kg.demo.sap.com/genre> a owl:ObjectProperty;
    rdfs:label "genre";
    rdfs:domain <http://kg.demo.sap.com/Film>;
    rdfs:range <http://kg.demo.sap.com/Genre>.
```

接下来，初始化 LLM。

```typescript theme={null}
import { ChatOpenAI } from "@langchain/openai"; // or your chosen LLM
// import { AzureOpenAiChatClient } from "@sap-ai-sdk/langchain";

const llm = new ChatOpenAI({ model: "gpt-4o" });
// const llm = new AzureOpenAiChatClient({ modelName: "gpt-4o" });
```

然后，创建 SPARQL 问答智能体。

```typescript theme={null}
const agentConfig: HanaSparqlQAAgentOptions = {
  graph: graph,
};

// Initialize the QA agent
const agent = HanaSparqlQAAgent.createAgent(llm, agentConfig);
```

```typescript theme={null}
const query = "which actors acted in Blade Runner?";
// const query = "Which movies are in the data?"
// const query = "In which movies did Keanu Reeves and Carrie-Anne Moss play in together"
// const query = "which movie genres are in the data?"
// const query = "which are the two most assigned movie genres?"
// const query = "where were the actors of 'Blade Runner' born?"
// const query = "which actors acted together in a movie and were born in the same city?"

console.log("\n--- Streamed (messages: token-by-token) ---");
for await (const [chunk, _metadata] of await agent.stream(
  { messages: [{ role: "user", content: query }] },
  { streamMode: "messages" }
)) {
  if (chunk.content) {
    process.stdout.write(chunk.text);
  }
}
console.log();
```

```output theme={null}
--- Streamed (messages: token-by-token) ---
Ontology Information:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

<http://kg.demo.sap.com/Actor> a owl:Class;
    rdfs:label "Actor".
rdfs:label a owl:DatatypeProperty;
    rdfs:label "label";
    rdfs:domain <http://kg.demo.sap.com/Actor>, <http://kg.demo.sap.com/Place>, <http://kg.demo.sap.com/Genre>, <http://kg.demo.sap.com/Director>;
    rdfs:range xsd:string.
<http://kg.demo.sap.com/Film> a owl:Class;
    rdfs:label "Film".
<http://kg.demo.sap.com/Place> a owl:Class;
    rdfs:label "Place".
<http://kg.demo.sap.com/Genre> a owl:Class;
    rdfs:label "Genre".
<http://kg.demo.sap.com/Director> a owl:Class;
    rdfs:label "Director".
<http://kg.demo.sap.com/dateOfBirth> a owl:DatatypeProperty;
    rdfs:label "dateOfBirth";
    rdfs:domain <http://kg.demo.sap.com/Actor>;
    rdfs:range xsd:dateTime.
<http://kg.demo.sap.com/placeOfBirth> a owl:ObjectProperty;
    rdfs:label "placeOfBirth";
    rdfs:domain <http://kg.demo.sap.com/Actor>;
    rdfs:range <http://kg.demo.sap.com/Place>.
<http://kg.demo.sap.com/title> a owl:DatatypeProperty;
    rdfs:label "title";
    rdfs:domain <http://kg.demo.sap.com/Film>;
    rdfs:range xsd:string.
<http://kg.demo.sap.com/acted_in> a owl:ObjectProperty;
    rdfs:label "acted_in";
    rdfs:domain <http://kg.demo.sap.com/Actor>;
    rdfs:range <http://kg.demo.sap.com/Film>.
<http://kg.demo.sap.com/directed> a owl:ObjectProperty;
    rdfs:label "directed";
    rdfs:domain <http://kg.demo.sap.com/Director>;
    rdfs:range <http://kg.demo.sap.com/Film>.
<http://kg.demo.sap.com/genre> a owl:ObjectProperty;
    rdfs:label "genre";
    rdfs:domain <http://kg.demo.sap.com/Film>;
    rdfs:range <http://kg.demo.sap.com/Genre>.
SPARQL Query Result:
actorLabel
William Sanderson
Morgan Paull
James Hong
Daryl Hannah
M. Emmet Walsh
Brion James
Q81328
Rutger Hauer
Joanna Cassidy
Hy Pyke
Sean Young
Edward James Olmos
Joe Turkel
In the movie "Blade Runner," the following actors were part of the cast:

- William Sanderson
- Morgan Paull
- James Hong
- Daryl Hannah
- M. Emmet Walsh
- Brion James
- Rutger Hauer
- Joanna Cassidy
- Hy Pyke
- Sean Young
- Edward James Olmos
- Joe Turkel
```

### 底层工作原理是什么？

1. **本体检索**
   智能体首先使用 `retrieveOntology` 工具以 Turtle 格式获取 RDF 模式。这使其了解可用的类、属性和关系。

2. **SPARQL 生成**
   根据本体和用户的问题，智能体推理要查询哪些实体和属性，然后生成一个有效的 `SELECT` 查询。

3. **查询执行**
   智能体调用 `executeSparql` 工具在 HANA RDF 图上运行生成的查询。如果查询失败或返回意外结果，智能体可以自我纠正并重试。

4. **答案制定**
   智能体解释查询结果，并严格基于检索到的数据制定简洁、人类可读的答案。

***

> 官方原文：[src/oss/javascript/integrations/agents/sap\_hana\_sparql\_qa\_agent.mdx](https://github.com/langchain-ai/docs/blob/main/src/oss/javascript/integrations/agents/sap_hana_sparql_qa_agent.mdx) · 非官方翻译，译文由 AI 生成，以英文原文为准。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.