跳至主要内容

如何处理多个查询

先决条件

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

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

设置

安装依赖项

yarn add @langchain/community @langchain/openai @langchain/core 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 上留下详细的反馈 GitHub.