登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

Claude Messages API citations 怎么核对:document blocks、source 与引用位置

来源:17golang原创

时间:2026-08-21 12:00:59 295浏览 收藏

做 Claude 文档问答对接的时候,别看到输出里带一句「根据参考资料」就默认所有内容都能溯源了。稳妥的方案是把参考素材作为 document 内容块传给 Messages API,开启 citations.enabled 配置,之后逐一对返回的引用类型、位置区间、引用原文内容做核验,把「模型给出了回答」和「回答有明确证据支撑」拆成两个独立的校验维度。

要点速览

  • 引用开关写在每个 document block 的 citations.enabled 中。
  • PDF、纯文本和自定义内容块对应不同的引用位置字段。
  • PDF 页码从 1 开始计数,纯文本字符索引和自定义块索引从 0 开始计数。
  • 流式响应需要单独拼接 citations_delta,不能只收集文本增量。

先定义三个可验收指标

不要只拿单条自然语言回答做主观判断。准备一份包含明确标题、数值和版本号的短测试文档,提出三类不同的问题,对照记录结果:

指标判断方式失败表现
引用覆盖每个事实性回答是否关联对应 citation回答给出了明确结论但 citations 为空
位置有效页码或字符区间能否精准落回原文范围区间越界或者指向完全不相关的段落
内容一致cited_text 是否真的能支撑当前回答语句引用条目存在,但对应原文完全不支撑给出的断言

这三个指标比「回答看起来像有引用」更适合放到项目的回归测试流程里。模型是否主动选择引用仍有可能受提问表述方式影响,所以测试集要覆盖直接提问、对比提问和无法从文档得出答案的提问这三类场景。

在 document block 上打开 citations

请求的核心结构很清晰:文档块放在 user 消息体内,相邻位置再放用户的提问文本:

{
  "role": "user",
  "content": [
    {
      "type": "document",
      "source": {
        "type": "text",
        "media_type": "text/plain",
        "data": "Redis 8.0 于 2024 年发布。COMMAND DOCS 返回命令元数据。"
      },
      "title": "版本说明",
      "citations": {"enabled": true}
    },
    {"type": "text", "text": "Redis 8.0 的 COMMAND DOCS 用来做什么?请引用资料。"}
  ]
}

开启引用时,同一个请求内的所有文档块配置要保持一致:不要一份文档开启引用、另一份文档关闭引用,最后把返回结果当成同一套可信证据。官方相关说明也提到,提交的文档内容会先做自动切分,生成粒度足够细的可引用单元。

Claude document block 开启 citations 后返回回答与来源位置

按文档来源核对 citation 位置

PDF:核对 page_number

PDF 类型的引用通常会携带页码范围,页码从 1 开始计数。测试校验的时候不要拿 PDF 阅读器的内部对象编号做比对,要回到普通用户肉眼可见的显示页码做核对。扫描生成的 PDF 还要额外校验 OCR 提取的文字内容是否完整准确。

纯文本:核对 character_index

纯文本类型的引用用字符区间定位,索引从 0 开始,结束位置一般按排他边界规则理解。回归脚本可以直接截取这个区间对应的字符串,与 cited_text 或者原始文档片段做一致性比对。

自定义内容:核对 block_index

自定义文档的引用位置指向原始 content 列表里的块索引,同样从 0 开始计数。这个数组在送入 API 之前如果被排序或者过滤,索引对应的语义就会完全改变,所以一定要保存发送前的完整块序列用于后续校验。

Claude citations 按 PDF 页码、纯文本字符区间和自定义块索引核对来源

流式响应不要漏掉 citations_delta

非流式请求可以直接遍历 text 内容块里的 citations 字段完成核验。流式请求则需要同时处理文本增量和引用增量:citations_delta 代表要追加到当前 text block 下的一条引用。如果只拼接返回的文本内容、直接丢弃这类事件,最终前端展示的文本看起来完整,背后的证据链路已经丢失了。

text_delta        -> 追加回答文字
citation_delta    -> 追加当前 text block 的引用
message_stop      -> 校验引用数量和位置

建议把当前 content block 的序号、已收集文本总长度和 citations 累计数量一起写入调试日志。遇到请求断线重连的时候,不能把同一条引用重复追加,要靠事件顺序或者请求级唯一 ID 做去重处理。

把引用测试放进发布门禁

  • 固定一份小体积测试文档,里面包含三个可精确定位的事实点,再加一个文档里完全没有覆盖的事实点。
  • 分别测试 PDF、纯文本或自定义内容块中的任意一类,确认索引基准没有写反。
  • 断言回答里的事实句必须携带对应 citation,明确拒答或者提示资料不足的句子不能强行生成不存在的来源。
  • cited_text 做原文包含校验或者区间回查,避免出现引用内容漂移的问题。
  • 流式和非流式两种调用模式分别做验收,确认二者返回的引用数量和位置语义完全一致。

引用本身并不是内容可信度的自动证明。来源本身过期、多份文档内容冲突、问题超出素材覆盖范围时,正确的返回结果反而应该是提示现有资料不足以给出答案。测试门禁要保障的是「所有给出的引用都能回溯到对应证据」,而不是强迫模型每句话都附一个看似合规的无效引用。

常见问题

citations.enabled 应该写在哪里?

写在需要被引用的 document 内容块中,不能写在普通的 text 提问块上。

为什么 citation 的索引有 0 开始和 1 开始两种规则?

PDF 使用从 1 开始的可见页码;纯文本使用从 0 开始的字符索引;自定义文档使用从 0 开始的内容块索引。

流式调用为什么返回结果没有引用?

大概率是只处理了 text delta,遗漏了 citations_delta 事件;也有可能是没有在对应的 document block 上开启引用配置。

可以只让部分文档开启引用吗?

同一个请求内最好保持配置一致,官方文档说明当前引用功能要么对全部文档启用,要么全部关闭。

把 citations 当成一条可以逐节点回查的数据链来做验收:先确认配置开关正常生效,再确认不同文档类型对应的索引基准正确,最后同时校验非流式和流式的返回事件。只有引用的位置真的能回溯到原始文档内容,文档问答要求的「可追溯」才算真正落地。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>