基于LangChain JS的vectorstore.asRetriever()实现特定文档语义搜索
基于元数据过滤的特定文档语义搜索实现方案(LangChain + Pinecone)
一、vectorstore.asRetriever() 运作逻辑
asRetriever() 是LangChain中VectorStore类的核心方法,作用是将向量存储实例转换为检索器(Retriever),使其能被QA链等上层组件调用。
- 参数
k:设置检索时返回的最相似文档数量 - 参数
filter:传入元数据过滤规则,检索时会先筛选出符合规则的文档,再在这个子集内执行语义相似度匹配 - 内部实现:直接创建
VectorStoreRetriever实例,将向量存储本身、k值、过滤规则传入,后续检索流程会自动应用过滤逻辑
二、基于唯一code字段的特定文档语义搜索实现
你的需求是通过唯一ID类的code字段精准定位单份文档,再对其执行语义搜索,只需修改元数据过滤规则即可实现:
修改后的完整代码
export const makeChain = (vectorstore: PineconeStore) => { const model = new OpenAI({ temperature: 0, modelName: 'gpt-3.5', }); // 替换为目标文档的唯一code值,例如"DOC-00001" const metadataFilter = { code: "DOC-00001" }; // 因code唯一,将k设为1即可确保只返回匹配的单份文档 const chain = ConversationalRetrievalQAChain.fromLLM( model, vectorstore.asRetriever(1, metadataFilter), { qaTemplate: QA_PROMPT, questionGeneratorTemplate: CONDENSE_PROMPT, returnSourceDocuments: true, }, ); return chain; };
关键说明
- Pinecone支持精准匹配的元数据过滤,当
code为唯一值时,过滤后只会得到对应的单份文档 - 将
k设为1可避免冗余,后续语义搜索会直接在这份文档的向量数据中进行
三、替代方案
方案1:直接调用Pinecone API查询指定文档
若无需LangChain检索器的链路封装,可直接调用Pinecone API根据code获取文档,再手动传入QA链:
// 示例:通过Pinecone API获取指定code的文档内容 const getDocumentByCode = async (pineconeIndex, targetCode) => { const queryResult = await pineconeIndex.query({ filter: { code: { $eq: targetCode } }, topK: 1, includeMetadata: true, // 传入与嵌入模型维度匹配的空向量即可,因过滤条件已精准定位 vector: new Array(1536).fill(0) // 适配text-embedding-ada-002的1536维度 }); return queryResult.matches[0]?.metadata?.text; }; // 获取文档后,可手动将内容注入QA Prompt使用
方案2:自定义检索器类
若需要更灵活的业务逻辑,可自定义Retriever类,先过滤指定文档再执行语义匹配:
import { BaseRetriever, Document } from "langchain/schema"; class CodeFilteredRetriever extends BaseRetriever { constructor(private vectorStore: PineconeStore, private targetCode: string) { super(); } async getRelevantDocuments(query: string): Promise<Document[]> { // 先通过code过滤文档,再执行语义搜索 return this.vectorStore.similaritySearch(query, 1, { code: this.targetCode }); } } // 使用时替换原asRetriever生成的检索器 const retriever = new CodeFilteredRetriever(vectorstore, "DOC-00001"); const chain = ConversationalRetrievalQAChain.fromLLM(model, retriever, { qaTemplate: QA_PROMPT, questionGeneratorTemplate: CONDENSE_PROMPT, returnSourceDocuments: true, });
内容的提问来源于stack exchange,提问作者vetheve
相关产品推荐
相关产品推荐

