人人都会AI编程

引用标注与来源追溯实现

更新时间:2026-07-12

让回答“有据可查”是 RAG 区别于纯生成模型的核心能力之一。但“有依据”的前提是,系统知道每句回答的依据来自哪里,并能以清晰、可验证的方式呈现给用户。这一节具体说明引用标注的实现方式,以及如何打通“从答案到原文”的追溯链路。

1. 整体思路:让来源信息跟随片段流动

RAG 从检索到生成的整个流程中,每个文档片段在入库时就携带了来源元数据(文件名、章节、页码、版本等)。关键的设计原则是:在切片、检索和生成三个阶段,始终保留并传递这些元数据,直到最终回答中呈现给用户。

具体而言:

  • 入库时:每个切片除了文本内容和向量,还必须存储对应的来源字段(source)。
  • 检索时:向量数据库返回的 top-k 结果不仅要包含文本,还要包含完整的元数据。
  • 生成时:将片段文本和它的来源信息一起填入提示词,要求模型在回答中注明出处,或通过程序后处理将出处添加到回答末尾。

2. 在提示词中要求模型标注引用

这是最直接、成本最低的方式。在构造提示词时,给每个检索到的片段分配一个临时编号,并在指令中明确要求模型引用。

提示词模板示例

你是一位基于资料回答的助手。请根据以下【参考资料】回答用户问题。回答时,若使用了某段资料,请在对应句末标注资料编号,如[1]、[2]。

【参考资料】
[1] (来源:员工手册_2025版.pdf,第3章)内容是:年假天数为15天,工作满5年后增加至20天。
[2] (来源:假期管理补充规定.pdf,第2条)内容是:未休年假可延至次年3月底,过期作废。

【用户问题】
我的年假有多少天?能延期吗?

模型会生成类似这样的回答:

您目前每年享有15天年假;工作满五年后将增加至20天[1]。未休完的年假可以延期至次年3月底,超出部分自动作废[2]。

这样,用户和审核人员都能快速建立“这句话对应哪份资料”的映射。

3. 程序化追加来源列表(双重保障)

有时模型可能漏掉标注,或标注不够稳定,因此更稳健的做法是在最终回复中由程序统一追加“参考来源”区块。

实现步骤:

  1. 在调用 LLM 后,从返回结果中提取仍然可用的检索结果元数据(通常在请求过程中同时保存)。
  2. 按片段去重,组装成可读的来源列表,如:
   参考来源:
   1. 《员工手册(2025版)》第3章 – 年假天数
   2. 《假期管理补充规定》第2条 – 延期规则
   
  1. 将这个列表附加到模型生成的回答末尾。

这种方式不依赖模型是否严格遵循引用指令,极大增强了稳定性。即便模型在某处忘了标注,用户也能在下方统一查看所有被检索到的依据。

4. 支持可点击链接与原文跳转

在真实系统中,来源不应只是静态文字,而是可以操作的入口。更进一步,可以为每条来源生成跳转链接,点击后直接打开原始文档并定位到相应章节。

常见的做法:

  • 如果文档是内部网页(如 Confluence),元数据里存储的是页面 URL + 锚点,前端直接渲染为超链接。
  • 如果是 PDF 等文件,可以在向量化时记录页码,并在内部搭建文档查看器,将页码作为参数传递给查看接口。例如:https://doc.example.com/viewer?doc=staff_handbook&page=12

在回答末尾,用户看到的是带下划线的来源名称,点击即可跳到对应页面,实现“从答案一键查阅原文”。

5. 处理重叠来源与多文档引用

实际检索中,同一事实可能被多个片段覆盖。例如年假政策既出现在《员工手册》也出现在《福利摘要》里。需要做一些去重和优先级处理:

  • 按相关度分数排序,只呈现分数最高的前 2~3 个来源,避免堆砌过多链接干扰阅读。
  • 如果两个来源实质内容一致但属于不同文档,可以标注为主来源 + 辅助来源,例如:“依据《员工手册》第 3 章(同时可参考《福利摘要》第 1 条)”。

6. 面向审计的完整追溯日志

除了前端展示,系统还应在后端记录每一次问答的完整链,用于事后核查。日志应至少包含:

  • 用户问题原文
  • 检索到的 top-k 片段及元数据
  • 实际拼接后发给 LLM 的完整提示词
  • LLM 返回的原始回答
  • 最终展示给用户的回答(含来源标注)

当出现争议时,运维人员可以通过日志快速定位:检索漏掉了关键文档?提示词不够明确?还是模型错误理解了资料?这种透明度为系统的持续优化和合规审查奠定了数据基础。

通过上述层层递进的手段,RAG 系统才能真正做到“每一句回答都经得起追问”,把可溯源性从一个宣传概念落地为可操作、可验证的工程实践。