RAG 的引用溯源到原文页面高亮应如何实现?

考查重点:引用身份与原文坐标。片段保存文档版本、页码与坐标,生成引用绑定该片段 ID,点击引用时打开对应版本并高亮坐标区域

本题目录

参考答案

核心回答

把回答中的引用标记绑定到检索片段,再由片段找到原文版本、页码和坐标。 这条映射应在解析入库时建立,并经过检索、生成和接口返回一直保留;不能等用户点击引用时,再用回答文字去整篇文档里猜位置。

具体分三步:入库时给片段保存文档身份、版本和原文位置;生成时为本次提供给模型的片段编号,让回答引用这些编号,并校验引用是否存在;点击时打开对应版本,按页面坐标转换成预览器中的高亮区域,滚动到目标位置。

引用能打开,只说明来源定位链路可用。还要分别检查原文是否支持该结论,以及当前用户是否有权查看原文,不能把有编号、有高亮当成答案正确或访问已获授权。

入库时保留什么

片段除正文和向量外,还应保存文档 ID、可定位的原文版本、片段 ID,以及页码和一个或多个位置区域。文档 ID 用来标识业务文档;文件哈希、对象存储版本或独立版本号,用来确定当时实际解析的是哪份内容。重新上传或重新解析时,这两层身份不能混为一谈。

对 PDF,位置可以由“页码、矩形或多边形、坐标单位、页面尺寸”表示。同一片段跨多行或跨页时保留多个区域,避免用一个大框把中间无关内容一起覆盖。对扫描件,OCR 文本要保留到原图区域的映射;经过清洗、合并或切块后,也要让片段能回到原始区域。

对可重排版的文档,可以定位段落或字符范围,也可以基于固定的转换预览文件保存坐标。解析坐标与预览对象必须对应,不能拿旧版或另一份转换结果的坐标直接画在当前文档上。

引用怎样经过生成链路

把本次送入模型的证据整理为“引用编号到片段”的映射,提示模型在相关结论旁输出编号。接口同时返回答案、引用标记和对应片段的来源信息,前端通过映射查找,而不是让模型自行拼接文件地址或原文坐标。

引用编号应与本次回答绑定,不能当成全局文档 ID。模型产生不存在的编号时应识别为无效引用;全部召回片段也不能直接视为每句话的依据。若采用生成后的相似度补标,应把它理解为寻找相关片段,另行核对片段是否支持句子中的数字、条件和结论。

高亮怎样与页面对齐

先统一解析器与预览器的页码基准、坐标原点和单位,再按目标页的实际尺寸、缩放、旋转和裁剪信息做坐标变换。例如 PDF 原生坐标与浏览器画布的原点方向可能不同,不能只把后端的两个数字当成屏幕像素。

前端加载目标页面后,将引用区域转换为高亮层的矩形,覆盖在原文渲染层之上,并滚动到首个区域。多页文档要按各页尺寸处理,不能默认所有页与第一页一样大;缩放或旋转后也应保持标注对齐。

若原文已删除、版本不匹配或没有位置数据,应显示可用的引用片段及明确的原文状态,不能伪造一个看似精确的高亮。读取引用详情、预览和下载时仍要执行访问控制;引用 ID、文档 ID 或前端隐藏按钮本身都不是权限凭证。

RAGFlowPython

基于 RAGFlow

核心回答

RAGFlow 的这条链路依赖检索片段中的位置元数据,加上回答引用编号到片段列表的映射。Python 检索返回 chunk_id、doc_id 和 positions;聊天生成时使用片段编号组织引用,前端点击引用后带着文档和片段信息打开预览抽屉,由 PDF 预览器绘制高亮并滚动定位。

当前引用也可能由生成后的相似度匹配补上,所以它提供的是回看证据的入口,不是自动证明答案正确。另一个需要保留的区别是:doc_id 标识文档记录,不是不可变的文件版本;历史引用要长期准确,还需要把原文版本和解析结果对应起来。

片段如何带上原文位置

解析结果有位置时,add_positions() 将其保存为 position_int,每项按“页码、左、右、上、下”排列,并把输入页索引加一,转换为这里使用的页码。一个片段可以带多个位置;没有可用位置时,这一步不会凭空产生坐标。位置写入是后续定位的数据起点。

检索的 retrieval() 在组织命中结果时保留 chunk_id、doc_id、正文和 positions,其中 positions 来自 position_int。供接口使用的 chunks_format() 可以进一步把字段归一化为 id、document_id、content 和 positions。前端需要保留这份来源信息,只有片段正文或文档名还不够完成区域高亮。

回答中的编号如何指向片段

kb_prompt() 按上下文预算选择片段,为它们添加 ID 和正文;引用提示词要求模型以 [ID:i] 标注来源。这里的 i 是本次片段列表的编号,不是原文页码,也不是文档主键。

启用引用且存在检索知识时,decorate_answer() 会解析回答中已有的引用标记。如果完全没有识别到引用标记,并且有可用的向量模型,则调用 insert_citations():将回答拆成句段,与检索片段做词法和向量相似度匹配,再插入标记。之后整理引用元数据并随答案返回。引用处理和相似度补标分别承担这两部分工作。

这种补标能找到与回答相关的材料,但没有逐项证明原文蕴含该句结论。例如两段都提到同一产品,却可能对应不同型号或年份;标上相关片段后,仍要核对这些条件。

点击后怎样在 PDF 中高亮

  1. 解析引用。 MarkdownContent 根据编号从 reference.chunks 取出片段,并通过文档信息找到文档 ID;点击支持原文定位的文件入口时,将文档 ID 与片段交给 useClickDrawer()。
  2. 打开预览。 PdfSheet 取得文档预览地址,并调用 useGetChunkHighlights() 处理片段位置;对 PDF,继续交给 PdfPreview。
  3. 转换位置。 buildChunkHighlights() 把每组位置转换为包含 pageNumber、boundingRect 和 rects 的高亮数据。PdfPreview 使用 react-pdf-highlighter 绘制区域,并通过滚动回调定位到首个高亮。高亮数据转换与PDF 预览连接了后端位置与页面展示。

当前预览实现读取第一页在 scale=1 时的宽高作为高亮尺寸参考。不同页面尺寸、旋转页面等情况需要专门核对,不能由这条代码路径直接推断所有 PDF 都能精确对齐;片段缺少位置时,高亮构造也会返回空列表。

长期溯源还要补齐什么

当前文档可以沿用同一 ID 重新解析,并清理旧片段;文档记录 ID 不承担不可变版本标识的职责。若要求旧回答始终能打开当时的原文,应记录文件版本或内容哈希、解析版本和引用片段快照,并让预览读取对应版本。这属于进一步设计,不能把现有 doc_id 直接解释为已经提供了版本锁定。

验收应分别检查编号是否映射正确、坐标是否落在对应页、原文是否支持答案,以及预览权限是否有效。可用跨页片段、同名新版文件、扫描件、混合页尺寸和无位置片段做对照;有引用标记、能打开文件和内容正确,需要各自的证据。

对应教程

  • 《RAG 检索增强生成》:参考文档切块、引用来源和检索生成链路的分工;本文进一步展开片段身份、原文位置和前端高亮的衔接。

参考资料

  • 国内:阿里云文档智能:文档智能解析:参考版面与单元格的文本、页码和坐标,以及页面尺寸与旋转信息,说明定位数据应在解析阶段保留。
  • 国内:阿里云百炼:工作流与旧版智能体应用 API:采用引用编号、文档 ID、文本片段和页码分别返回的结构,解释回答标记怎样与来源元数据配对。
  • 国内:腾讯云:知识库设置概览:参考原文链接、自定义链接和文档下载的独立配置,区分展示来源、打开原文与提供完整文档的不同动作。
  • 国内:腾讯云:对话接口参考来源事件:参考消息关联标识、片段级来源和文档预览页码的分工,说明同一文档可有多个引用片段;本文采用其来源结构示例。
  • 国外:Mozilla:PDF.js Examples:根据页面视口的缩放、旋转和坐标变换,解释解析坐标为何需要转换后才能叠加到浏览器预览。
  • 国外:PyMuPDF:Coordinates:核对页面、图像的原点与坐标系差异,说明坐标单位和转换约定为什么必须明确。

相关面经

2 篇

公司未注明

面经合集
查看原面经 →
如何实现答案溯源、引用位置与来源跳转?(3篇)

金蝶

Agent 开发工程师
校招一面
查看原面经 →
项目追问
详细说说这个引用溯源到页面高亮具体怎么实现的吗?

相关题目

4 题