当前位置: 首页 > news >正文

Claude Citations API 实战:让模型自动标注引用来源,RAG 准确率提升 15%

Claude Citations API 实战:让模型自动标注引用来源,RAG 准确率提升 15%

做 RAG(检索增强生成)的工程师都遇到过这种灵魂提问:

“你这个回答到底是从哪段文档里得出来的?”

这个问题之所以致命,是因为模型会自信地引用一段根本不存在的原文。在法律、医疗、金融、合规审计这些场景,引用错了不只是难看,可能直接出事故。

过去大家的解法是在 prompt 里写"请用方括号标注你引用了哪段文字",然后正则解析。这种方式至少有三个问题:

  1. 模型会编造看似真实但实际不存在的引用编号
  2. 直接输出原文片段,output token 飙升导致成本翻倍
  3. 解析逻辑脆弱,模型偶尔不按格式输出就全崩

Anthropic 在 2025 年初推出、2026 年正式 GA 的Citations API给出了官方答案——模型直接返回结构化的引用对象,包含字符级偏移、文档索引、原文片段,全部由 API 层保证。

本文给出 Citations 的完整接入方案、三种文档喂入方式、与传统 prompt 引用的对比、以及一个真实可跑的法律 RAG 例子。


一、Citations 到底是什么

Citations 是 Anthropic 在messagesAPI 上的一个文档块开关。你把文档作为documentcontent block 传给 Claude,并打开citations.enabled = true,模型回答时就会自动在每个论点后附带一个citation 对象,结构如下:

{"type":"char_location","cited_text":"...被引用的原文片段...","document_index":0,"document_title":"annual-report-2025.pdf","start_char_index":1024,"end_char_index":1180}

四个关键属性:

字段含义
cited_text被引用的原文片段,不计入 output token
document_index第几个文档(0-indexed)
start_char_index/end_char_index在该文档中的字符偏移
type引用粒度类型(见下表)

三种引用粒度

粒度适用场景类型字段
char_location纯文本文档(最精确)char_location
page_locationPDF 文档(页级)page_location
content_block_location自定义文档块(最灵活)content_block_location

为什么比 prompt 工程更靠谱

Anthropic 自家的对比评测里,Citations 内置版相比 prompt-engineered 版本在召回准确率上提升最高 15%。原因有三个:

  1. 引用指向是 API 强制保证的——start_char_index/end_char_index由系统计算,不是模型生成的字符串
  2. cited_text不计入 output token——你不再需要为了让模型"输出原文"而支付额外的 token 费用
  3. 模型不会再编造——所有 citation 都映射到你提供文档的真实位置

二、三种文档喂入方式

方式 1:Plain Text(字符精确引用)

最适合:你已经把文档解析为纯文本,需要字符级精确定位。

importanthropic client=anthropic.Anthropic(api_key="sk-你的密钥",base_url="https://gw.claudeapi.com")doc_text=open("contract.txt","r",encoding="utf-8").read()response=client.messages.create(model="claude-opus-4-7",max_tokens=1024,messages=[{"role":"user","content":[{"type":"document","source":{"type":"text","media_type":"text/plain","data":doc_text,},"title":"甲方乙方合作协议-2026.txt","citations":{"enabled":True}},{"type":"text","text":"这份合同的违约金条款是怎么规定的?"}]}])

返回结构(精简版):

forblockinresponse.content:ifblock.type=="text":print(block.text)forcitinblock.citationsor[]:print(f" └─ 引自{cit.document_title}")print(f" 字符 [{cit.start_char_index}:{cit.end_char_index}]")print(f" 原文:{cit.cited_text[:80]}...")

输出示例:

违约方需向守约方支付合同总金额 20% 的违约金,并在 30 日内一次性支付。 └─ 引自 甲方乙方合作协议-2026.txt 字符 [4128:4280] 原文:第十二条 违约责任:违约方应当向守约方支付合同总金额百分之二十的违约金...

方式 2:PDF(页级引用)

最适合:扫描件、含图表的财报、合同原件。模型会自动 OCR + 视觉理解,引用粒度精确到 PDF 的页号。

importbase64withopen("annual-report.pdf","rb")asf:pdf_b64=base64.standard_b64encode(f.read()).decode("utf-8")response=client.messages.create(model="claude-opus-4-7",max_tokens=2048,messages=[{"role":"user","content":[{"type":"document","source":{"type":"base64","media_type":"application/pdf","data":pdf_b64,},"title":"财报-2025.pdf","citations":{"enabled":True}},{"type":"text","text":"现金流量表中经营性净现金流是多少?"}]}])

PDF 模式下 citation 会带start_page_number/end_page_number(1-indexed):

经营性净现金流为 28.5 亿元,同比增长 12%。 └─ 引自 财报-2025.pdf 第 32-32 页

如果文档已经上传到 Files API,可以用file_id引用,避免每次 base64 重传。

方式 3:Custom Content(最灵活,RAG 必选)

最适合:你自己分了块的 RAG 场景,想精确控制每个 chunk 的边界。

chunks=["第一条 本协议由甲方与乙方于 2026 年 1 月 1 日签订...","第十二条 违约责任:违约方应当向守约方支付合同总金额百分之二十的违约金...","第十五条 争议解决:因本协议产生的任何争议..."]response=client.messages.create(model="claude-opus-4-7",max_tokens=1024,messages=[{"role":"user","content":[{"type":"document","source":{"type":"content","content":[{"type":"text","text":chunk}forchunkinchunks]},"title":"合同条款-命中片段","citations":{"enabled":True}},{"type":"text","text":"违约金有多少?争议怎么解决?"}]}])

返回的 citation 会带start_block_index/end_block_index,告诉你引用的是数组里第几块。这种模式特别适合:

  • 向量检索后给 top-K 个 chunk:每个 chunk 是一个 block,模型回答时直接告诉你它引用了哪个 block
  • 多文档汇总:可以把不同来源的文档片段合并成一个 document,引用结构清晰

三、Node.js / cURL 等价实现

Node.js / TypeScript

importAnthropicfrom"@anthropic-ai/sdk";importfsfrom"fs";constclient=newAnthropic({apiKey:"sk-你的密钥",baseURL:"https://gw.claudeapi.com",});constdocText=fs.readFileSync("contract.txt","utf-8");constresponse=awaitclient.messages.create({model:"claude-opus-4-7",max_tokens:1024,messages:[{role:"user",content:[{type:"document",source:{type:"text",media_type:"text/plain",data:docText},title:"甲方乙方合作协议.txt",citations:{enabled:true},},{type:"text",text:"违约金条款是?"}]}]});for(constblockofresponse.content){if(block.type==="text"){console.log(block.text);for(constcitof(blockasany).citations||[]){console.log(`└─${cit.document_title}[${cit.start_char_index}:${cit.end_char_index}]`);}}}

cURL

curlhttps://gw.claudeapi.com/v1/messages\-H"x-api-key: sk-你的密钥"\-H"anthropic-version: 2023-06-01"\-H"content-type: application/json"\-d'{ "model": "claude-opus-4-7", "max_tokens": 1024, "messages": [{ "role": "user", "content": [ { "type": "document", "source": {"type": "text", "media_type": "text/plain", "data": "本协议自 2026 年 1 月 1 日生效..."}, "title": "合同.txt", "citations": {"enabled": true} }, {"type": "text", "text": "协议什么时候生效?"} ] }] }'

四、Citations vs Prompt 工程引用:六维对比

维度传统 Prompt 引用Citations API
引用可靠性模型可能编造API 保证位置真实
Output token 成本引用文本计入输出(昂贵)cited_text 不计费
字符级偏移需自己解析内置start_char_index
多文档支持需要复杂 prompt 描述自动document_index
实现复杂度自写正则解析SDK 直接拿对象
召回准确率基线+15%(Anthropic 内测数据)

对法律、医疗、金融、政府类客户,这六个维度里前两个就足够说服技术选型。


五、Web Search 自带 Citations(不需要开关)

如果你用的是 Anthropic 原生web_search工具(web_search_20260209是 2026 年的最新版本,支持 dynamic filtering),citations 是默认强开的——你不需要在文档块里加citations.enabled,每个网页结果都会自带web_search_result_location类型的 citation。

response=client.messages.create(model="claude-opus-4-7",max_tokens=2048,tools=[{"type":"web_search_20260209","name":"web_search"}],messages=[{"role":"user","content":"2026 年 Anthropic 估值是多少?给出来源。"}])

Anthropic 的服务条款明确:直接把 API 输出展示给最终用户时,必须保留 citation 指向原始来源——这条对做搜索/问答类产品的团队尤其重要,别因为美观需求把 url 字段藏起来。

cited_text、title、url 字段同样不计入 token 计费


六、踩坑清单

坑 1:Citations 与 streaming 一起用要小心累积。流式返回时,每个 text delta 可能携带 citation_delta,需要在客户端按 block 累积,不能简单拼接字符串。SDK 已封装好,自写客户端要注意。

坑 2:document 必须有 title。实测不写 title 也能跑通,但所有 citation 的document_title字段会为空,前端展示会很难看。养成传 title 的习惯

坑 3:Custom content 模式下,block 太碎会影响召回。把一份合同拆成 200 个 8 字 block,模型反而会"看不清"。建议每个 block 保持 100-500 字的语义完整段落,太碎反而降低准确率。

坑 4:不是所有模型都返回引用粒度一致。Opus 4.7 / Sonnet 4.6 / Haiku 4.5 都支持 Citations,但 Haiku 在多文档复杂场景下偶尔会漏引用。重要场景请用 Opus 4.7 或 Sonnet 4.6。

坑 5:Citations 不等于"防幻觉"。模型仍然可能误读文档语义。Citations 只保证"引用位置真实存在",不保证"引用解读正确"。生产环境建议二次校验:把 cited_text 和模型回答做语义一致性检查。


七、一个完整的法律 RAG 端到端示例

把上面的 Custom Content 模式串起来,做一个最小可跑的法律咨询助手:

importanthropicfromtypingimportList client=anthropic.Anthropic(api_key="sk-你的密钥",base_url="https://gw.claudeapi.com")# 假设你有一个向量数据库 (Pinecone / Weaviate / Chroma)defretrieve_chunks(query:str,k:int=5)->List[dict]:"""返回 top-k 法条片段"""# ... 你的向量检索代码return[{"law":"民法典","article":"第585条","text":"当事人可以约定一方违约时..."},{"law":"合同法","article":"第114条","text":"约定的违约金低于造成的损失..."},# ...]defanswer_with_citations(question:str):chunks=retrieve_chunks(question)response=client.messages.create(model="claude-opus-4-7",max_tokens=2048,system="你是一个严谨的法律咨询助手。回答必须仅基于提供的法条片段,不允许引用未提供的法律。",messages=[{"role":"user","content":[{"type":"document","source":{"type":"content","content":[{"type":"text","text":f"【{c['law']}{c['article']}{c['text']}"}forcinchunks]},"title":"命中的法律条文","citations":{"enabled":True}},{"type":"text","text":question}]}])# 结构化输出,附带引用result={"answer":"","citations":[]}forblockinresponse.content:ifblock.type=="text":result["answer"]+=block.textforcitin(block.citationsor[]):idx=cit.start_block_index result["citations"].append({"law":chunks[idx]["law"],"article":chunks[idx]["article"],"cited_text":cit.cited_text,})returnresultprint(answer_with_citations("约定违约金过低能否调整?"))

输出结构示例:

{"answer":"根据法律规定,约定违约金低于造成损失的,可以请求法院或仲裁机构予以增加。","citations":[{"law":"合同法","article":"第114条","cited_text":"约定的违约金低于造成的损失的,当事人可以请求人民法院或者仲裁机构予以增加..."}]}

这样的输出可以直接喂给前端做"鼠标悬停展示原文"或者"导出审计报告",工程友好度远超 prompt 工程版本。


小结

Citations 是 Anthropic 官方对"防幻觉 + 可审计"需求的标准答案,比 prompt 工程引用更可靠、更省钱、更易工程化:

  • 三种粒度:char_location(纯文本)、page_location(PDF)、content_block_location(自定义 chunk)
  • 不计费的省钱细节:cited_text 不计入 output token
  • 生产建议:重要场景用 Opus 4.7 / Sonnet 4.6,document 一定要传 title,custom block 保持语义完整段落
  • 重要提醒:Citations 只保证引用位置真实,不保证语义解读正确

注意 Citations 是 Anthropic 原生能力,只在 messages API 路径上工作,OpenAI 兼容的 chat/completions 接口不支持。国内开发者如果直连api.anthropic.com不通,可以通过 claudeapi.com 把base_url改成https://gw.claudeapi.com,Citations 全部能力同步可用。


参考资料:Citations API 官方文档、Anthropic Citations 发布博客。

http://www.cnnetsun.cn/news/2497869.html

相关文章:

  • 【Prompt实战】角色扮演法:如何让AI分别扮演“小白用户”、“黑客”与“刁钻PM”?
  • 为你的开源项目配置 Taotoken 作为 Claude Code 的稳定后备方案
  • 思大电子丨M12 316L不锈钢防水连接器产品介绍
  • OpenBoardView终极指南:免费PCB分析工具与电路板查看器完全解析
  • 将Taotoken集成至自动化工作流实现内容批量生成
  • Buzz音频转录终极指南:3步掌握本地AI转录的完整技巧
  • Midjourney拟态风终极内参(2024.06最新版):含6类行业专属LORA融合权重表、11个失效规避checklist及3个已验证绕过--v 6.2限流机制的prompt结构
  • 老挝语TTS项目被拒3次?ElevenLabs合规性红线清单(含Lao语言政策备案要求、儿童语音禁用场景、宗教术语过滤规则)
  • 构建企业级 AI 编程助手(AI-OS)v1.0,集成 Matt Pocock 全套技能,实现零幻觉开发
  • 如何用Wannakey免费恢复WannaCry加密文件?3步内存密钥恢复指南
  • 从IO视角深度对比:BST、红黑树、B树、B+树
  • 2026年阿里云OpenClaw/Hermes Agent配置Token Plan集成保姆攻略
  • Java 常用类 - 比较两个 Integer 对象、Integer 转 Long、Long 转 Integer
  • Taotoken 的官方价折扣让高频使用者的成本更具优势
  • 一文了解魔芋AI:有前景的企业级大模型管理平台
  • 3步解锁百度文库纯净阅读:告别广告干扰的智能解决方案
  • YOLO26涨点改进| TGRS 2026 | 独家创新首发、注意力改进篇| 引入MCSA多尺度通道空间注意力,含二次创新多种改进点,助力小目标检测、图像分割、遥感目标检测、图像修复任务涨点
  • 湖南话TTS工业级部署手册:Nginx反向代理+边缘缓存+方言热切换的高并发架构(支撑日均500万次语音请求)
  • 5分钟激活Adobe全家桶:Adobe-GenP通用补丁终极使用指南
  • 终极Windows 11优化指南:用Win11Debloat轻松告别系统臃肿
  • PowerBI主题模板终极指南:35款专业模板快速美化数据报表
  • 在OpenClaw项目中集成Taotoken实现Agent工作流
  • 【2024方言AI语音权威报告】:基于1762条真实东北语料实测,ElevenLabs东北话MOS得分仅3.8?这4项定制化微调让评分跃升至4.6+
  • FlashAttention 训练时为什么会梯度爆炸?一次拆透反向传播的坑
  • 如何三步免费下载百度文库文档:智能清理与打印保存完整指南
  • 萌音播放器:如何打造纯净无广告的二次元音乐播放体验
  • 跨平台三星固件管理终极指南:Bifrost如何革新固件下载体验
  • 从vSphere Client到Linux命令行:一次完整的vCenter磁盘扩容实录与避坑总结
  • AM62x开发板LVDS显示接口配置与调试实战指南
  • 10分钟快速上手:用ElastiFlow搭建企业级网络流量监控系统