引用功能:让每一句结论都能指回原文
Anthropic 官方 Cookbook。与「让模型自己标出处」不同,这个功能在机制上保证引用只指向你实际提供的材料——不会指向不存在的位置。
- 原作者
- Anthropic
- 原文标题
- Citations
- 原发布平台
- Anthropic Claude Cookbooks
- 原发布日期
- 2026/08/05
译者说明:本文译自 Anthropic 官方 Claude Cookbooks。原文为 Jupyter Notebook,含可运行的 Python 代码;此处保留全部说明性内容与关键代码结构。
⚠️ 时效提示:原文中「哪些模型支持该功能」的具体说明是撰写时的状态,请以 官方文档为准。功能机制本身不受影响。
引用(Citations)
Claude API 提供引用支持,使 Claude 在回答关于文档的问题时能给出详细的引用。在许多基于大模型的应用中,引用是一项有价值的能力——它帮助用户追踪和核实回答中信息的来源。
引用功能是「基于提示词的引用技巧」的替代方案。使用这个功能有以下优势:
- 基于提示词的技巧通常要求 Claude 把它打算引用的原文完整输出出来,这会增加输出 token,因而增加成本。
- 引用功能不会返回指向未被提供为有效来源的文档或位置的引用。
- 在测试中我们发现,引用功能生成的引用,其召回率与精确率都高于基于提示词的技巧。
三种文档类型
引用支持三种不同的文档类型。输出的引用格式取决于被引用的文档类型:
| 文档类型 | 引用定位格式 |
|---|---|
| 纯文本文档 | 字符位置(char location) |
| PDF 文档 | 页码位置(page location) |
| 自定义内容文档 | 内容块位置(content block location) |
纯文本文档
使用纯文本文档引用时,你把文档作为原始文本提供给模型。可以提供一份或多份。这些文本会被自动切分成句子,模型会在适当的时候引用这些句子。
模型可以在一条引用里同时引用多个句子,但不会引用比一个句子更小的片段。
除了输出的文本之外,API 响应中还会包含所有引用的结构化数据。
文档的结构是这样的:
documents.append({
"type": "document",
"source": {
"type": "text",
"media_type": "text/plain",
"data": body,
},
"title": title,
"citations": {"enabled": True},
})
让引用可视化
利用引用数据,我们可以构建这样的界面:
- 向用户明确展示信息来自哪里
- 直接链接到源文档
- 在上下文中高亮被引用的文本
- 通过来源的透明化建立信任
原文给出了一个可视化函数,把 Claude 的结构化引用转换成类似学术论文的可读格式。函数接收响应对象,输出:
- 带编号引用标记的文本(例如「这个答案 [1] 包含了这个事实 [2]」)
- 一份编号的参考列表,显示每条被引用的文本及其来源文档
PDF 文档
处理 PDF 时,Claude 能够给出指向具体页码的引用,方便追踪信息来源。PDF 引用的工作方式:
- PDF 内容以 base64 编码提供
- 文本被自动切分成句子
- 引用中包含信息所在的页码(从 1 开始计数)
- 模型可以在一条引用里引用多个句子,但不会引用小于一句的片段
- 图像会被处理,但目前只有文本内容可以被引用
pdf_response = client.messages.create(
model="<模型名>",
temperature=0.0,
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": pdf_data,
},
"title": "文档标题",
"citations": {"enabled": True},
},
{"type": "text", "text": "你的问题"},
],
}],
)
自定义内容文档
纯文本文档会被自动按句子切分,而自定义内容文档让你完全控制引用的粒度。这种 API 形态允许你:
- 自行定义任意大小的分块
- 控制引用的最小单位
- 针对那些不适合按句子切分的文档做优化
原文的例子中,把每一篇文章当作一个整块,于是 cited_text 返回的是整篇文章,而不是其中的某一句。
documents.append({
"type": "document",
"source": {"type": "content", "content": [{"type": "text", "text": body}]},
"title": title,
"citations": {"enabled": True},
})
使用 context 字段
context 字段允许你提供关于某份文档的额外信息,Claude 在生成回答时可以使用这些信息,但它们不会被引用。这在以下场景有用:
- 提供文档的元数据(比如发布日期、作者)
- 上下文检索(contextual retrieval)
- 包含不应被直接引用的使用说明或背景
原文的例子中,在 context 字段里放了一条警告:
document = {
"type": "document",
"source": {"type": "text", "media_type": "text/plain", "data": "..."},
"title": "文档标题",
"context": "警告:本文已 12 个月未更新,内容可能过时。"
"在给出建议后,务必告知用户该内容可能不准确。",
"citations": {"enabled": True},
}
Claude 会依据 context 中的信息来组织回答,但 context 字段的内容本身不可被引用。
PDF 高亮
PDF 引用有一个限制:只返回页码。你可以用第三方库把返回的被引用文本与页面内容做匹配,从而在 PDF 上高亮出被引用的内容。原文演示了用 PyMuPDF 生成一份带批注的新 PDF。
译后附记:这对研究工作意味着什么
原文是面向开发者的 API 教程,但其中一条判断值得所有人知道:
引用功能不会返回指向未被提供为有效来源的文档或位置的引用。
这句话的分量在于——它是机制层面的保证,不是提示词层面的请求。
日常用对话框工作时,我们通常这样要求:「每条结论后面标出它来自哪份访谈」。这是基于提示词的做法,它依赖模型配合。模型多数时候会照做,但它也可能标错,甚至标一个看起来合理却不存在的出处——而你只有逐条回原文核对才能发现。
引用功能走的是另一条路:引用只能落在你实际提供的材料范围内,指向不存在的位置这件事在机制上就不成立。
对研究咨询工作,这个区别落在最要紧的地方:一份交给客户的报告,每个结论都要能追溯到具体的访谈、页码、原话。基于提示词的标注减少了核对工作量,而机制层面的引用改变了核对的性质——你核的是「引对了吗」,不再是「这个出处真的存在吗」。
如果你的团队有能力做 API 集成,把访谈稿库接上引用功能,是这个行业里投入产出比最高的一次工程投入之一。
如果只是在对话框里工作,退而求其次的做法是明确要求原话摘录而不只是编号:
每条结论后面必须附上支撑它的原话摘录(逐字,不要改写) 和访谈编号。 如果某条结论无法在材料中找到直接支撑的原话, 不要写这条结论,改为写「材料未提供充分依据」。
复制为纯文本,换行与缩进原样保留,可直接粘贴进对话框。
要求它贴原话,比要求它标编号更难作假——编造一个编号很容易,编造一段与上下文吻合的原话则会明显露出破绽。