Skip to main content

如何处理多个查询

预备知识

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

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

安裝

安裝依賴項

:::提示 请参阅安装集成包的一般说明部分。 :::

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

設定環境變數

OPENAI_API_KEY=your-api-key

# 選用,使用 LangSmith 以獲得最佳的可觀測性
LANGSMITH_API_KEY=your-api-key
LANGSMITH_TRACING=true

# 如果你不在無伺服器環境中,可減少追蹤延遲
# 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.");

Pick your chat model:

Install dependencies

yarn add @langchain/groq 

Add environment variables

GROQ_API_KEY=your-api-key

Instantiate the model

import { ChatGroq } from "@langchain/groq";

const llm = new ChatGroq({
model: "llama-3.3-70b-versatile",
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: {} }
]

下一步

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

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


Was this page helpful?


You can also leave detailed feedback on GitHub.