如何进行每用户检索
本指南假设您熟悉以下内容
在构建检索应用时,您通常需要考虑多个用户。这意味着您可能不仅为一个用户存储数据,而是为许多不同的用户存储数据,并且他们不应该能够看到彼此的数据。这意味着您需要能够配置检索链以仅检索特定信息。这通常涉及两个步骤。
步骤 1:确保您使用的检索器支持多个用户
目前,LangChain 中没有统一的标志或过滤器用于此。相反,每个向量存储和检索器可能都有自己的标志或过滤器,并且可能被称为不同的名称(命名空间、多租户等)。对于向量存储,这通常以在similaritySearch
期间传入的关键字参数的形式公开。通过阅读文档或源代码,找出您使用的检索器是否支持多个用户,如果是,如何使用它。
步骤 2:将该参数添加为链的可配置字段
LangChain config
对象会传递给每个可运行对象。在这里,您可以向configurable
对象添加任何您想要的字段。稍后,在链中,我们可以提取这些字段。
步骤 3:使用该可配置字段调用链
现在,在运行时,您可以使用可配置字段调用此链。
代码示例
让我们看一个代码中如何实现的具体示例。我们将使用 Pinecone 作为示例。
设置
安装依赖项
请参阅 此部分了解有关安装集成包的常规说明。
- npm
- yarn
- pnpm
npm i @langchain/pinecone @langchain/openai @langchain/core @pinecone-database/pinecone
yarn add @langchain/pinecone @langchain/openai @langchain/core @pinecone-database/pinecone
pnpm add @langchain/pinecone @langchain/openai @langchain/core @pinecone-database/pinecone
设置环境变量
我们将在此示例中使用 OpenAI 和 Pinecone
OPENAI_API_KEY=your-api-key
PINECONE_API_KEY=your-api-key
PINECONE_INDEX=your-index-name
# Optional, use LangSmith for best-in-class observability
LANGSMITH_API_KEY=your-api-key
LANGCHAIN_TRACING_V2=true
# Reduce tracing latency if you are not in a serverless environment
# LANGCHAIN_CALLBACKS_BACKGROUND=true
import { OpenAIEmbeddings } from "@langchain/openai";
import { PineconeStore } from "@langchain/pinecone";
import { Pinecone } from "@pinecone-database/pinecone";
import { Document } from "@langchain/core/documents";
const embeddings = new OpenAIEmbeddings();
const pinecone = new Pinecone();
const pineconeIndex = pinecone.Index(process.env.PINECONE_INDEX);
/**
* Pinecone allows you to partition the records in an index into namespaces.
* Queries and other operations are then limited to one namespace,
* so different requests can search different subsets of your index.
* Read more about namespaces here: https://docs.pinecone.io/guides/indexes/use-namespaces
*
* NOTE: If you have namespace enabled in your Pinecone index, you must provide the namespace when creating the PineconeStore.
*/
const namespace = "pinecone";
const vectorStore = await PineconeStore.fromExistingIndex(
new OpenAIEmbeddings(),
{ pineconeIndex, namespace }
);
await vectorStore.addDocuments(
[new Document({ pageContent: "i worked at kensho" })],
{ namespace: "harrison" }
);
await vectorStore.addDocuments(
[new Document({ pageContent: "i worked at facebook" })],
{ namespace: "ankush" }
);
[ "77b8f174-9d89-4c6c-b2ab-607fe3913b2d" ]
Pinecone 的 kwarg namespace
可以用于分离文档
// This will only get documents for Ankush
const ankushRetriever = vectorStore.asRetriever({
filter: {
namespace: "ankush",
},
});
await ankushRetriever.invoke("where did i work?");
[ Document { pageContent: "i worked at facebook", metadata: {} } ]
// This will only get documents for Harrison
const harrisonRetriever = vectorStore.asRetriever({
filter: {
namespace: "harrison",
},
});
await harrisonRetriever.invoke("where did i work?");
[ Document { pageContent: "i worked at kensho", metadata: {} } ]
我们现在可以创建用于执行问答的链。
import { StringOutputParser } from "@langchain/core/output_parsers";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import {
RunnableBinding,
RunnableLambda,
RunnablePassthrough,
} from "@langchain/core/runnables";
import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";
const template = `Answer the question based only on the following context:
{context}
Question: {question}`;
const prompt = ChatPromptTemplate.fromTemplate(template);
const model = new ChatOpenAI({
model: "gpt-3.5-turbo-0125",
temperature: 0,
});
我们现在可以使用我们的可配置检索器创建链。它是可配置的,因为我们可以定义任何将传递给链的对象。从那里,我们提取可配置对象并将其传递给向量存储。
import {
RunnablePassthrough,
RunnableSequence,
} from "@langchain/core/runnables";
const chain = RunnableSequence.from([
RunnablePassthrough.assign({
context: async (input: { question: string }, config) => {
if (!config || !("configurable" in config)) {
throw new Error("No config");
}
const { configurable } = config;
const documents = await vectorStore
.asRetriever(configurable)
.invoke(input.question, config);
return documents.map((doc) => doc.pageContent).join("\n\n");
},
}),
prompt,
model,
new StringOutputParser(),
]);
我们现在可以使用可配置选项调用链。search_kwargs
是可配置字段的 ID。该值是用于 Pinecone 的搜索 kwarg
await chain.invoke(
{ question: "where did the user work?" },
{ configurable: { filter: { namespace: "harrison" } } }
);
"The user worked at Kensho."
await chain.invoke(
{ question: "where did the user work?" },
{ configurable: { filter: { namespace: "ankush" } } }
);
"The user worked at Facebook."
有关可以支持多个用户的更多向量存储实现,请参阅特定页面,例如 Milvus。
下一步
您现在已经了解了一种使用来自多个用户的数据支持检索的方法。
接下来,查看一些关于 RAG 的其他操作指南,例如 返回来源。