有关 SAP HANA 向量存储的设置详情,请参阅指南 向量存储:SAP HANA.
我们在此使用相同的设置:
dotenv.config();
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();
}
});
});
为了能够以良好性能进行自查询,我们为向量存储表创建额外的元数据字段 用于 HANA 中的向量存储表:
await new Promise<void>((resolve, reject) => {
client.exec(
`DROP TABLE LANGCHAIN_DEMO_SELF_QUERY`,
(dropErr: Error) => {
// Ignore drop errors
client.exec(
`CREATE TABLE "LANGCHAIN_DEMO_SELF_QUERY" (
"name" NVARCHAR(100), "is_active" BOOLEAN, "id" INTEGER, "height" DOUBLE,
"VEC_TEXT" NCLOB,
"VEC_META" NCLOB,
"VEC_VECTOR" REAL_VECTOR
)`,
(createErr: Error) => {
if (createErr) {
reject(createErr);
} else {
resolve();
}
}
);
}
);
});
让我们添加一些文档。
const embeddings = new OpenAIEmbeddings();
const db = new HanaDB(embeddings, {
connection: client,
tableName: "LANGCHAIN_DEMO_SELF_QUERY",
specificMetadataColumns: ["name", "is_active", "id", "height"],
});
await db.initialize();
const docs = [
new Document({
pageContent: "First",
metadata: { name: "adam", is_active: true, id: 1, height: 10.0 },
}),
new Document({
pageContent: "Second",
metadata: { name: "bob", is_active: false, id: 2, height: 5.7 },
}),
new Document({
pageContent: "Third",
metadata: { name: "jane", is_active: true, id: 3, height: 2.4 },
}),
];
await db.delete({ filter: {} });
await db.addDocuments(docs);
自查询
现在进入主要部分:以下是如何为 HANA 向量存储构建 SelfQueryRetriever:
const llm = new ChatOpenAI({ model: "gpt-3.5-turbo" });
const metadataFieldInfo: AttributeInfo[] = [
{ name: "name", description: "The name of the person", type: "string" },
{ name: "is_active", description: "Whether the person is active", type: "boolean" },
{ name: "id", description: "The ID of the person", type: "integer" },
{ name: "height", description: "The height of the person", type: "float" },
];
const contentDescription = "A collection of persons";
const hanaTranslator = new HanaTranslator();
const retriever = await SelfQueryRetriever.fromLLM({
llm,
vectorStore: db,
documentContentDescription: contentDescription,
attributeInfo: metadataFieldInfo,
structuredQueryTranslator: hanaTranslator,
});
让我们使用此检索器来准备一个(自)查询:
const queryPrompt = "Which person is not active?"
const retrievedDocs = await retriever.invoke(queryPrompt);
for (const doc of retrievedDocs){
console.log("-".repeat(80));
console.log(doc.pageContent + " " + JSON.stringify(doc.metadata));
}
--------------------------------------------------------------------------------
Second {"name":"bob","is_active":false,"id":2,"height":5.7}