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

如何在Stuff链型ConversationalRetrievalChain中获取源文档、分数及元数据?

解决方案

要在使用Stuff链的ConversationalRetrievalChain中获取source_documents、匹配分数及向量数据库原始元数据,无需依赖大模型返回,可通过以下步骤实现:

1. 开启链的源文档返回参数

ConversationalRetrievalChain默认仅返回问答内容,通过设置return_source_documents=True,可让链在返回结果中包含检索到的源文档数据。同时配置检索器(Retriever)以返回匹配分数:

from langchain.chains import ConversationalRetrievalChain
from langchain.chat_models import ChatOpenAI

# 初始化LLM和检索器
llm = ChatOpenAI(temperature=0)
# 配置检索器返回匹配分数(以FAISS为例)
retriever = your_vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={"k": 3, "score_threshold": 0.7}  # 控制返回数量和分数阈值
)

# 创建Chain时开启源文档返回
qa_chain = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=retriever,
    return_source_documents=True,  # 关键参数:启用源文档返回
    return_generated_question=False  # 可选:关闭自动生成问题功能
)

2. 提取并处理源文档、分数与元数据

调用链后,返回结果会包含answer和source_documents字段。source_documents是Document对象列表,每个对象包含:

  • page_content:文档内容片段
  • metadata:向量数据库存储的原始元数据(含匹配分数score,需检索器配置支持)

在Chainlit中处理结果时,可直接提取这些数据用于展示或导出:

import chainlit as cl

@cl.on_message
async def handle_message(message: cl.Message):
    # 调用链获取结果
    chat_history = cl.user_session.get("chat_history", [])
    result = await cl.make_async(qa_chain)(
        {"question": message.content, "chat_history": chat_history}
    )

    # 提取源文档信息
    source_docs = result["source_documents"]
    formatted_source_info = []
    for idx, doc in enumerate(source_docs):
        # 获取匹配分数(检索器配置后会存在于metadata中)
        match_score = doc.metadata.get("score", "未获取")
        # 获取原始元数据(如文档路径、页码等)
        raw_metadata = {k: v for k, v in doc.metadata.items() if k != "score"}
        # 格式化展示内容
        formatted_source_info.append(
            f"### 参考文档 {idx+1}\n"
            f"- 匹配分数: {match_score:.4f}\n"
            f"- 原始元数据: {raw_metadata}\n"
            f"- 内容片段: {doc.page_content[:250]}..."
        )

    # 构建回复消息,合并问答内容与源文档信息
    response = cl.Message(content=f"{result['answer']}\n\n" + "\n\n".join(formatted_source_info))
    await response.send()

    # (可选)实现导出功能:将源数据转为JSON
    # import json
    # export_data = json.dumps([
    #     {"page_content": doc.page_content, "metadata": doc.metadata} 
    #     for doc in source_docs
    # ], indent=2)
    # 可通过Chainlit的`cl.File`组件提供下载

3. 避免大模型幻觉的优化思路

无需在提示词中要求大模型返回源文档信息,直接通过链的return_source_documents参数获取原始数据,由代码自行处理展示。这种方式既保证了源数据的准确性,又避免了大模型幻觉问题,同时保留Stuff链的使用。

内容的提问来源于stack exchange,提问作者Guilherme Giuliano Nicolau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:55:33