You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让LangChain的ConversationalRetrievalChain仅基于单文档嵌入对话

解决思路:让检索器只锁定目标文档

核心是给单个上传的文档做专属标记,然后让检索器只拉取带这个标记的内容,下面是两种可行方案:

方案一:用文档唯一标识过滤(推荐)

  1. 上传时给文档加专属标记:把当前会话的唯一ID(或自定义文档ID)塞进文档的metadata里,确保这个标记在整个索引里唯一。示例上传代码:
from langchain.schema import Document

# content为读取的文档内容,session_id是当前会话的唯一标识(比如前端传入的会话ID)
target_doc = Document(
    page_content=content,
    metadata={
        "unique_doc_id": f"session_{session_id}_single_doc",
        "source": "用户上传的文件名.pdf"
    }
)
self.vector_store.add_documents([target_doc])
  1. 检索时过滤目标文档:修改retriever初始化逻辑,用Azure搜索的OData过滤语法,只返回带专属标记的文档。替换原代码中的retriever部分:
# 生成和上传时一致的唯一标识
target_doc_id = f"session_{session_id}_single_doc"
# 创建带过滤条件的检索器
retriever = self.vector_store.as_retriever(
    search_kwargs={
        "filter": f"unique_doc_id eq '{target_doc_id}'"
    }
)

# 后续链的初始化保持原有逻辑,传入这个带过滤的检索器即可
chain = ConversationalRetrievalChain(
    retriever=retriever,
    question_generator=question_generator,
    combine_docs_chain=doc_chain,
    return_source_documents=True
)

方案二:用临时向量存储(适合单次会话用完即弃的场景)

如果不想和全局索引里的其他文档混在一起,每次上传文档时单独创建一个只包含该文档的向量存储实例:

# 新建临时Azure搜索索引(索引名用会话ID保证唯一)
temp_vector_store = AzureCognitiveSearch(
    azure_search_endpoint="你的Azure搜索端点",
    azure_search_key="你的搜索密钥",
    index_name=f"temp_session_{session_id}_index"
)
# 将单个上传文档添加到临时存储
temp_vector_store.add_documents([target_doc])

# 用临时存储创建检索器
retriever = temp_vector_store.as_retriever()
# 后续链的初始化保持原有逻辑,传入这个临时检索器即可

注意:这种方式每次会话会生成新索引,用完记得删除临时索引,避免资源浪费。

内容的提问来源于stack exchange,提问作者Gaurav Mahapatro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:12:42