跳至主要内容

如何使用向量存储检索数据

先决条件

本指南假定您熟悉以下概念

向量存储可以使用 .asRetriever() 方法转换为检索器,这使您能够更轻松地将它们组合在链中。

下面,我们展示了一个检索增强生成 (RAG) 链,它使用以下步骤对文档执行问答:

  1. 初始化向量存储
  2. 从该向量存储创建检索器
  3. 组合问答链
  4. 提问!

每个步骤都有多个子步骤和潜在配置,但我们将介绍一个常见的流程。首先,安装所需的依赖项

npm install @langchain/openai

您可以 此处 下载 state_of_the_union.txt 文件。

import * as fs from "node:fs";

import { OpenAIEmbeddings, ChatOpenAI } from "@langchain/openai";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import {
RunnablePassthrough,
RunnableSequence,
} from "@langchain/core/runnables";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import type { Document } from "@langchain/core/documents";

const formatDocumentsAsString = (documents: Document[]) => {
return documents.map((document) => document.pageContent).join("\n\n");
};

// Initialize the LLM to use to answer the question.
const model = new ChatOpenAI({
model: "gpt-4o",
});
const text = fs.readFileSync("state_of_the_union.txt", "utf8");
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
const docs = await textSplitter.createDocuments([text]);
// Create a vector store from the documents.
const vectorStore = await MemoryVectorStore.fromDocuments(
docs,
new OpenAIEmbeddings()
);

// Initialize a retriever wrapper around the vector store
const vectorStoreRetriever = vectorStore.asRetriever();

// Create a system & human prompt for the chat model
const SYSTEM_TEMPLATE = `Use the following pieces of context to answer the question at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
----------------
{context}`;

const prompt = ChatPromptTemplate.fromMessages([
["system", SYSTEM_TEMPLATE],
["human", "{question}"],
]);

const chain = RunnableSequence.from([
{
context: vectorStoreRetriever.pipe(formatDocumentsAsString),
question: new RunnablePassthrough(),
},
prompt,
model,
new StringOutputParser(),
]);

const answer = await chain.invoke(
"What did the president say about Justice Breyer?"
);

console.log({ answer });

/*
{
answer: 'The president honored Justice Stephen Breyer by recognizing his dedication to serving the country as an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. He thanked Justice Breyer for his service.'
}
*/

API 参考

让我们逐步介绍这里发生了什么。

  1. 我们首先加载一段长文本,并使用文本分割器将其拆分为较小的文档。然后,我们将这些文档(也使用传递的 OpenAIEmbeddings 实例嵌入文档)加载到 HNSWLib(我们的向量存储)中,从而创建索引。

  2. 虽然我们可以直接查询向量存储,但我们将向量存储转换为检索器,以便以问答链所需的正确格式返回检索到的文档。

  3. 我们初始化一个检索链,我们将在步骤 4 中调用它。

  4. 我们提问!

下一步

您现在已经了解了如何将向量存储转换为检索器。

有关特定检索器的更深入探讨,请参阅各个部分,有关 RAG 的更广泛教程,请参阅 有关 RAG 的更广泛教程,或参阅本节以了解如何 在任何数据源上创建自己的自定义检索器


此页面是否有帮助?


您也可以在 GitHub 上留下详细的反馈 在 GitHub 上.