本页还没有译文
本页 27 段还没译成Español,下面显示的是英文原文。Question Answering with HanaSparqlQAAgent
还没翻译译自英文(docs.langchain.com)本页 27 段都还没译
Setup and Installation
To use this feature, install the @sap/hana-langchain package and its peer dependencies:
npm install @sap/hana-langchain @langchain/core@latest @langchain/classic@latest langchain@latestHanaSparqlQAAgent is an agent-based approach for answering questions over RDF data stored in SAP HANA Cloud. Unlike the chain-based approach, the agent can:
- Dynamically retrieve the ontology using a dedicated tool
- Generate and execute SPARQL queries iteratively
- Self-correct if a query fails or returns unexpected results
- Reason step-by-step about complex questions
Initialization
You need:
- An LLM to power the agent's reasoning
- A
HanaRdfGraph(with connection,graphUri, and ontology)
Follow the steps here HanaRdfGraph to know more about creating a HanaRdfGraph instance.
Import the HanaSparqlQAAgent
import { HanaSparqlQAAgent, HanaSparqlQAAgentOptions } from "@sap/hana-langchain";
const agentConfig : HanaSparqlQAAgentOptions = {
graph: graph
};
const agent = HanaSparqlQAAgent.createAgent(llm, agentConfig);Agent Overview
The agent uses tools iteratively to:
- First retrieve the ontology to understand the data structure
- Generate appropriate SPARQL queries based on the schema
- Execute queries and interpret results
- Formulate natural language answers
Defaults
- Tools:
retrieveOntology- Retrieves the RDF ontology/schema from the graph in Turtle formatexecuteSparql- Executes SPARQL queries against the HANA RDF graph
- System Prompt: A default system prompt is provided with instructions for SPARQL generation and tool usage.
- Middleware:
ModelRetryMiddleware({maxRetries:3})andToolRetryMiddleWare({maxRetries:2})is added by default to prevent infinite loops
Customizing Your Agent
You can customize the agent's behavior by providing additional parameters to createAgent:
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
)Example: Question answering over a "Movies" knowledge graph
Prerequisite:
You must have an SAP HANA Cloud instance with the triple store feature enabled.
For detailed instructions, refer to: Enable Triple Store
Load the kgdocu_movies example data. See Knowledge Graph Example.
The example below:
- Instantiates the
HanaRdfGraphpointing at the movies data graph - Creates a
HanaSparqlQAAgentpowered by an LLM - Asks natural-language questions and lets the agent reason through the answers
This demonstrates how the agent dynamically retrieves the ontology, generates SPARQL queries, and returns human-readable answers.
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();
}
});
});Then, set up the knowledge graph instance
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);// 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);
}
});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>.After that, initialise the LLM.
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" });Then, create the SPARQL QA Agent.
const agentConfig: HanaSparqlQAAgentOptions = {
graph: graph,
};
// Initialize the QA agent
const agent = HanaSparqlQAAgent.createAgent(llm, agentConfig);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();--- 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 TurkelWhat's happening under the hood?
-
Ontology Retrieval The agent first uses the
retrieveOntologytool to fetch the RDF schema in Turtle format. This gives it understanding of the available classes, properties, and relationships. -
SPARQL Generation Based on the ontology and the user's question, the agent reasons about which entities and properties to query, then generates a valid
SELECTquery. -
Query Execution The agent calls the
executeSparqltool to run the generated query against the HANA RDF graph. If the query fails or returns unexpected results, the agent can self-correct and try again. -
Answer Formulation The agent interprets the query results and formulates a concise, human-readable answer based strictly on the retrieved data.