[控场AI]
· 7 分钟阅读· 3,741 字

MCP检索服务输出引用为何丢失:CSR基准深度解析

MCP检索服务输出引用为何丢失:CSR基准深度解析

MCP 边界后引用格式漂移被误判为引用丢失,默认 API 是主因,短来源 ID 可修复。

文章研究通过 MCP 向外部 Agent 暴露 RAG 检索能力后,「引用在边界后是否存活」的新问题。作者以 FastAPI 文档构建 127 道题的评测集,定义 CSR(Citation Survival Rate)指标,同时检查引用是否被检索内容支撑、URL 是否真出现在工具调用日志中。首轮结果显示 OpenAI Agents SDK 的 CSR 仅 0.323,但逐条阅读发现多数「未引用」其实是 Markdown 链接等格式差异,修正评分后升至 0.470。控制实验表明 Agent 循环、温度和传输层都不是元凶,真正变量是 SDK 默认使用的 Responses API;切到 Chat Completions 后格式错误从 41 降到 9。服务端短来源 ID 方案进一步把格式错误从约 50 降到约 5,CSR 提升 0.10–0.13。

当一家公司把文档变成 MCP 搜索工具,交给 Claude、ChatGPT 或任意 Agent 使用时,检索端能保证把正确的来源送进去,却完全看不到最终答案里引用了什么。这种「引用在边界后是否存活」的问题,正在成为 RAG 与 Agent 结合后的新盲区。

MCP检索边界引用问题示意

问题定义:引用在 MCP 边界后是否存活

典型的 RAG 是「检索一次、回答一次」,检索服务和生成模型在同一个系统里,链路可控。但一旦通过 MCP 把检索能力暴露给外部 Agent,控制权就分家了:检索服务器返回带 source_url 的文档块,Agent 自己决定读哪些、怎么组织答案、要不要标引用。

对文档助手来说,这带来两个层次的失败。答案是正确但没有引用,用户无法点开查看边界情况;答案引用了错误页面,看起来经过了验证,实则更具误导性。作者做了 250 道题的人工筛选,保留 127 道,其中 82 道单页可答、29 道需要跨页、16 道文档未覆盖,用来捕捉编造行为。语料是 FastAPI 文档,153 页切成 2085 个标题感知的块。

这个实验设计的关键在于:它复刻的是一个真实托管 MCP 检索产品的契约,连工具命名风格都对齐,而不是一个玩具环境。

Citation Survival Rate:不只看有没有 URL

衡量「有没有引用」比想象中麻烦。答案可能满是 URL 却归属错误,也可能编造一个看起来很合理的 FastAPI 链接——模型本来就知道这类 URL 长什么样。

因此作者定义了 CSR(Citation Survival Rate),要求每个引用通过两道检查:支持性检查用 FActScore 式原子断言拆分加 ALCE 式蕴含模型,验证被引块是否真的支撑该断言;溯源检查则依赖工具调用日志,确认该 URL 确实出现在 Agent 检索到的内容里。

CSR 的分母有一个重要限定:只统计 Agent 实际检索到的正确来源。如果 Agent 根本没找到正确页面,那是检索失败,不计入 CSR。它只衡量正确来源跨越边界之后发生了什么。

FActScore 式原子断言拆分:FActScore 是一种细粒度事实性评估方法,将一段长文本拆解为若干独立的原子事实(atomic facts),每条只包含一个可验证的命题,再逐条核对是否有来源支撑。本文借用这一思路,把 Agent 生成的答案拆成最小断言单元,从而判断每个被引块究竟支撑哪一条断言,避免「整段答案看似有引用、实则引用不支撑具体结论」的漏检。

ALCE 式蕴含模型:ALCE(Attributed Language Model Evaluation)在评估引用时,不只匹配 URL,还用自然语言推理(NLI)或蕴含模型判断「被检索到的文档块」是否在语义上蕴含「答案中的断言」。本文用这种蕴含检查做支持性验证:即使 URL 确实来自检索结果,若块内容与断言无关,也不算引用存活。

首轮结果与那个差点发布的错误

首轮数据显示,LangGraph Agent 与单次 RAG 几乎持平(0.614 对 0.618),而 OpenAI Agents SDK 构建的 Agent 只有 0.323,看起来腰斩。127 条回答中有 66 条没有使用要求的 [url] 格式。

作者没有立刻下结论,而是逐条读了这 66 条答案。结果发现大部分其实引用了来源:51 条把 URL 以 Markdown 链接 [source](https://...) 形式放在断言后面,7 条用了其他括号格式,只有 8 条完全没给 URL——而作为对照的单次 RAG 有 19 条如此。

评分器只认 [url] 格式,把 Markdown 链接全部记成了缺失引用。修正定义后重新评分,SDK Agent 从 0.323 升至 0.470。三组重复实验后,较小幅度的损失稳定存在:原始评分器下为 −0.12,gpt-4o 评判下为 −0.09,而在只认指定格式时约为 −0.30。也就是说,这个差距约六成来自格式,四成是真实的引用损失。温度设为 0 时检测不到损失。

更稳定的发现是:OpenAI Agents SDK 在默认 API 下,127 条回答中有 51 条(40%)忽略了要求的引用格式,两次重复实验分别为 53 和 46;单次 RAG 为 0 次,LangGraph 为 8 次。任何按固定格式解析引用的下游系统——文档小部件、来源面板、护栏、评测——都会看到一片空白。

原因排查:Agent 循环与传输都不是元凶

作者做了五组控制实验,每次只改一个变量。

LangGraph 同样在循环,却保住了格式,而且各 Agent 的循环次数很低,每题约 1.2 到 1.3 次检索。温度也不是主因:SDK 管线从未设置温度,与 LangGraph 的 0 对齐后,格式漂移仅从 60 降到 54。传输层同样清白:转储显示每个块抵达模型时 source_url 完好,118 个 Markdown 链接中 98 个指向 Agent 检索过的页面。

真正的变量是 API。OpenAI Agents SDK 默认调用 Responses API,而 LangGraph 的 OpenAI 集成走 Chat Completions。把同一个 SDK Agent 切到 Chat Completions,格式错误回答从 41 降到 9;换上一份公开的接地系统提示词则降到 20。两者在三轮实验中均成立,但对「是否引用」本身没有显著影响——它们修的是格式。

由于这两项都位于检索提供方无法控制的 Agent 侧,作者又测试了一个服务端可做的修复:给每个块打上短来源 ID(如 [S3fa21c]),要求以 [ID] 引用,答案生成后再把 ID 映射回 URL。在自托管镜像上,格式错误回答从每轮约 50 降到约 5,SDK Agent 的 CSR 提升 0.10 到 0.13,与单次 RAG 的差距消失。作者也注明,这些引用尚未经过人工审核。

Responses API 与 Chat Completions 的差异:这是 OpenAI 提供的两套生成接口。Chat Completions 是长期存在的经典接口,输入输出以消息列表为中心;Responses API 是较新的接口,原生围绕工具调用、多轮状态与结构化输出设计,OpenAI Agents SDK 默认走这条路径。两者在系统提示词注入、工具结果呈现、输出格式约束等层面存在实现差异,因此同一个模型、同一份提示词在两条管线下可能表现出不同的格式遵循度。本文的对照实验正是利用这一差异定位到 API 默认值是格式漂移的主因。

可信度与边界

评测的可信度取决于评分器。作者用 115 条自己的盲判来校准检查器,gpt-4o 评判与本人一致度最高(κ 0.86)。在 30 个盲测案例上,CSR 判定与人工判断一致 25 到 27 个。每个 gpt-4o-mini 配置跑了三轮,并预先写下鲁棒性规则:每轮符号一致,合并区间排除零。

发布前作者以敌对评审的视角审查流水线,发现五个 bug,其中四个原本会上线。格式问题算第六个,也是最令作者难堪的一个:在发现之前,被夸大的数字已经发给了别人。

局限也写得很坦白:单一语料、两种模型、gpt-4o-mini 配置跑三轮而 Claude 只跑一轮、人工检查样本小,且使用的是自托管的 MCP 服务器镜像,而非任何人的生产系统。

对构建者的启示

如果通过 MCP 提供 RAG,准确率保证止步于边界。检索可控,写答案的 Agent 不可控,引用若对产品重要,就必须测量边界另一侧发生了什么。

框架默认值也是系统的一部分。同一个模型、同一个提示词,两个 Agent 的引用格式表现迥异,原因是一个开发者可能永远不会看的默认设置。

把格式和存在性分开测量。「我解析的格式里没有引用」与「没有引用」是两种不同失败,对应不同修复。更重要的是读输出,而不只看指标:一个「未引用回答」的计数掩盖了多数回答其实包含来源的事实。只跑一次不够,剩余差距的单次结果可能落在 −0.05 到 −0.16 之间。

最后,检索侧其实能修格式:给 Agent 一个短来源 ID 去复制,而不是一个长 URL 去重新格式化,再自己映射回来。

MCP(Model Context Protocol):一种开放协议,用于把外部工具、数据源和检索服务以标准化方式暴露给 AI 应用与 Agent。检索方实现一个 MCP 服务器,Agent 侧通过 MCP 客户端调用工具并拿到结构化结果。协议本身只规定「如何传」,不规定「拿到之后怎么用」,因此引用是否被保留完全发生在 Agent 一侧——这正是本文所说「准确率保证止步于边界」的由来。

#MCP#RAG引用#Citation Survival Rate#OpenAI Agents SDK#LangGraph#Responses API#检索引用丢失
分享:

相关推荐