AI回答为什么可信Open Glean行内引用系统的设计与实现原理解析【免费下载链接】open-gleanAn open-source AI platform for knowledge work. Connect your apps, find answers, and get work done.项目地址: https://gitcode.com/gh_mirrors/op/open-gleanOpen Glean 是一款开源 AI 知识工作台它的核心能力是行内引用系统inline citations每当你向它提问答案里出现的每个[1]、[2]标记都能点击直接跳转到对应的来源卡片——AI 说了什么就一定有出处可以核对。这篇文章带你从零看懂这套引用系统背后的设计与实现原理。什么是行内引用为什么 AI 回答需要出处很多 AI 助手回答问题时只说结论、不给证据你很难判断它是真的基于你的资料还是在大脑中编造的也就是常说的幻觉。Open Glean 的 Ask 功能采取了一个简单但有效的策略先检索把你的问题发给 Hydra 数据库召回相关文档片段chunks再作答大模型只能基于这些召回的片段写答案必须引用提示词明确要求模型在行文中用[1]、[2]这样的编号标注依据这个流程的入口在 useQa它串起了检索 → 组提示词 → 流式生成答案三个步骤。 提示词中的原话是Context entries are numbered — cite them inline with [1], [2], …见 buildLlmMessages。核心设计一套编号两处渲染这套系统最精妙的一点写在 lib/citations.ts 文件头部的注释里The prompt and the panel both render from this index. A change to the grouping rule therefore moves both together, and the number the model cites always matches the card the user sees.意思是给模型的上下文编号和给用户看的来源卡片编号来自同一个索引。模型引用[7]用户就一定能看到第 7 张卡片——两边永远不会对不上。按文档编号而不是按片段编号检索返回的结果是片段chunk一份文档可能召回好几个片段。如果按片段编号模型会拿到 10 个编号而用户界面上只有 4 张来源卡片模型引用[7]时用户根本找不到第 7 张卡。所以 buildCitationIndex 的分组规则是按来源去重步骤说明1同一个source_id的所有片段合并成一张卡片、一个编号2Hydra 来源按首次出现的顺序排号[1] [2] …3网页搜索的引用接着排号共用同一个编号空间4网页结果按 URL 去重避免同一页面占两个编号编号确定后renderContext 会把全部片段渲染成带编号的文本块塞进提示词——模型看得见所有原文却只能引用有卡片的编号。答案里的 [1] 如何变成可点击的引用模型流式吐出的答案里[1]只是普通文本。要把它变成可点击的引用需要一段标记转链接的处理实现见 linkCitations。这里有两个容易被忽略的边界情况设计超范围编号保持原样如果只有 4 个来源模型却引用了[7]它就渲染为普通文本而不是一个点了没反应的死链接。代码里不生效codearray[1]/code中的[1]是数组下标不是引用。实现会把 HTML 按标签切分只在文本节点中替换并跳过code、pre、a、button标签内部的内容。⚠️ 这段代码运行在dangerouslySetInnerHTML的渲染管线上所以安全性是承重墙函数唯一插入输出的值是它自己解析出来的已校验整数攻击者控制的文本无法进入 HTML 属性。相关回归测试见 citationMarkup.test.ts。流式场景下的引用同步哨兵协议启用联网搜索时还有一个更棘手的工程问题模型的答案是一段一段流出来的而网页来源清单URL 标题往往在答案结束后才一起给出。怎么在纯文本流里把答案和引用 JSON分开Open Glean 的方案是哨兵行sentinel服务端在答案末尾追加一行固定标记---OPEN-GLEAN-CITATIONS---后面跟引用 JSON见 CITATIONS_SENTINEL客户端扫描到这个独占一行的标记后切换到引用解析模式见 parseCitations客户端还会扣住尾部几个字符再显示防止哨兵被网络分包切成两半而泄漏进正文流结束时还会校验完成标记---OPEN-GLEAN-DONE---如果中途断线前端会明确报错答案没有写完而不是把半截内容当成完整答案见 splitTerminator有意思的是哨兵行必须独占一行这条规则来自一个真实事故早期用普通子串匹配一旦答案里恰好提到这个标记后面的正文就会被当成引用 JSON 吞掉。这个修复的验收测试保存在 citationsStream.test.ts。点击引用后你会看到什么用户点击答案里的[3]界面会联动右侧的来源面板SourcesPanel滚动定位自动展开并闪烁对应编号的来源卡片原文预览弹窗先立刻显示被引用的那段原文再异步去取整份文档供对照打开原件如果来源有外链或预签名 URL可以一键跳到原文仅放行http/https拒绝javascript:等危险协议也就是说验证链路是闭环的答案里的编号 → 来源卡片 → 被引用的原文段落 → 原始文档。总结可信不是口号是三层约束回顾 Open Glean 的行内引用系统可信来自三层层层收紧的设计提示词层答案只能基于编号上下文且被明确要求引用编号编号层模型与界面共用一套按文档去重的编号模型引用不存在的编号时宁缺毋滥渲染层引用标记的转换经过整数校验与标签隔离既防幻觉死链也防 XSS这些设计大多不长却都对应着一次真实踩坑——项目的验收测试 c1-acceptance.test.ts 把编号一致、超范围不渲染、按文档分组这三条核心不变量固化了下来是理解这套系统的好入口。如果你也想拥有每个答案都能溯源的 AI 知识工作台可以克隆仓库本地体验git clone https://gitcode.com/gh_mirrors/op/open-glean【免费下载链接】open-gleanAn open-source AI platform for knowledge work. Connect your apps, find answers, and get work done.项目地址: https://gitcode.com/gh_mirrors/op/open-glean创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考