跳至主要内容

如何处理多个查询

先决条件

本指南假设您熟悉以下内容

有时,查询分析技术可能允许生成多个查询。在这些情况下,我们需要记住运行所有查询,然后合并结果。我们将展示一个简单的示例(使用模拟数据)来说明如何做到这一点。

设置

安装依赖项

yarn add @langchain/community @langchain/openai zod chromadb

设置环境变量

OPENAI_API_KEY=your-api-key

# 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 { Chroma } from "@langchain/community/vectorstores/chroma";
import { OpenAIEmbeddings } from "@langchain/openai";
import "chromadb";

const texts = ["Harrison worked at Kensho", "Ankush worked at Facebook"];
const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });
const vectorstore = await Chroma.fromTexts(texts, {}, embeddings, {
collectionName: "multi_query",
});
const retriever = vectorstore.asRetriever(1);

查询分析

我们将使用函数调用来构建输出。我们将让它返回多个查询。

import { z } from "zod";

const searchSchema = z
.object({
queries: z.array(z.string()).describe("Distinct queries to search for"),
})
.describe("Search over a database of job records.");

选择您的聊天模型

安装依赖项

yarn add @langchain/openai 

添加环境变量

OPENAI_API_KEY=your-api-key

实例化模型

import { ChatOpenAI } from "@langchain/openai";

const llm = new ChatOpenAI({
model: "gpt-4o-mini",
temperature: 0
});
import { ChatPromptTemplate } from "@langchain/core/prompts";
import {
RunnableSequence,
RunnablePassthrough,
} from "@langchain/core/runnables";

const system = `You have the ability to issue search queries to get information to help answer user information.

If you need to look up two distinct pieces of information, you are allowed to do that!`;

const prompt = ChatPromptTemplate.fromMessages([
["system", system],
["human", "{question}"],
]);
const llmWithTools = llm.withStructuredOutput(searchSchema, {
name: "Search",
});
const queryAnalyzer = RunnableSequence.from([
{
question: new RunnablePassthrough(),
},
prompt,
llmWithTools,
]);

我们可以看到这允许创建多个查询

await queryAnalyzer.invoke("where did Harrison Work");
{ queries: [ "Harrison" ] }
await queryAnalyzer.invoke("where did Harrison and ankush Work");
{ queries: [ "Harrison work", "Ankush work" ] }

使用查询分析检索

那么如何将其包含在链中呢?如果我们异步调用我们的检索器,这将使事情变得更容易 - 这将让我们循环遍历查询,而不会被响应时间阻塞。

import { RunnableConfig, RunnableLambda } from "@langchain/core/runnables";

const chain = async (question: string, config?: RunnableConfig) => {
const response = await queryAnalyzer.invoke(question, config);
const docs = [];
for (const query of response.queries) {
const newDocs = await retriever.invoke(query, config);
docs.push(...newDocs);
}
// You probably want to think about reranking or deduplicating documents here
// But that is a separate topic
return docs;
};

const customChain = new RunnableLambda({ func: chain });
await customChain.invoke("where did Harrison Work");
[ Document { pageContent: "Harrison worked at Kensho", metadata: {} } ]
await customChain.invoke("where did Harrison and ankush Work");
[
Document { pageContent: "Harrison worked at Kensho", metadata: {} },
Document { pageContent: "Ankush worked at Facebook", metadata: {} }
]

下一步

您现在已经学习了一些在查询分析系统中处理多个查询的技术。

接下来,查看本部分中的一些其他查询分析指南,例如 如何处理没有生成查询的情况.


此页面对您有帮助吗?


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