你让模型给一个带引用的研究摘要。回答很流畅,末尾是 Smith et al. (2019). Effects of microbreaks on cognitive performance. Journal of Occupational Psychology, 42(3), 287-301.,看起来很真。你去搜期刊,没这篇。DOI 是假的。更糟的是,URL 域名是真的、但路径一点就 404。这是最伤的幻觉模式之一,因为”错但看似合理”的回答读起来跟正确的没区别,直到有人真去验证才露馅。
最快的修复:如果模型既没有文档库、也没有实时检索工具,就不要让它给引用。一个裸模型,你让它 “cite sources”,它就会编出引用样式的字符串,没有例外。要么用检索到的文本给回答打地基(RAG),要么接一个真实的 search/fetch 工具,然后把输出约束在这些来源(用 ID),并拒掉任何 URL 或 DOI 解析不了的 response。本页剩下的部分就是这几件事怎么做。
引用幻觉是结构性的、不是随机的。训练语料里声明后面不断跟着引用,模型学到的模式就是”声明后面要跟一个引用样式的串”。当它没有真引用时,它照样生成一个引用样式的串。这个本能靠 prompt 压不住,你得把”模型被逼着编”的情景拆掉。
这不是边角问题。一项被 Lancet 报道的研究发现:2023 年大约每 2,828 篇学术论文里有 1 篇含伪造引用,随着 AI 辅助写作普及,到 2026 年初已升到约每 277 篇里有 1 篇。在 2026 年一项覆盖多家商业模型的基准里,引用幻觉率从约 14% 到超过 90% 不等(取决于模型和领域),对抗性 prompt 还能把一些模型推到 90% 以上。
你属于哪一类
动 prompt 之前先跑两个检查,它们告诉你该用哪个修复。
| 症状 | 可能原因 | 去看 |
|---|---|---|
| 没检索、没工具,引用基本是假的 | 裸模型按训练模式硬编 | 第 1 步、第 5 步 |
RAG 返回 [],模型还是给了引用 | 检索失败、模型照样答 | 第 2 步 |
| 检索到的 chunks 里没引用,模型自己加了 | 模型为显得严谨而硬塞 | 第 2 步、第 4 步 |
| URL 域名真,路径 404 | 格式套出来的 URL 幻觉 | 第 3 步 |
| DOI 看着合法,但解析不到 | DOI 伪造或 chimera reference | 第 3 步 |
| 作者是真的,论文错的或不存在 | 作者与论文张冠李戴 | 第 4 步、第 7 步 |
chimera reference(嵌合引用)值得单独点名:模型把一个真实的 DOI 或真实的作者,跟错误的标题、年份或期刊拼在一起。每个零件都存在,组合不存在。这种引用能骗过”DOI 能不能解析”这种简单检查,只有当你把解析出来的元数据跟模型声称的对比时才会露馅。
常见原因
1. 没检索的裸模型被要求引用
“Summarize the research on X and cite sources.”模型没接数据库。它按训练分布生成像样的引用。大部分会是部分或全部假的。
怎么判断:把模型给的 5 个引用扔到 Google Scholar 或 CrossRef 搜。0-1 个真实就是这个 bug。
2. RAG 没检索到内容,但模型照样答
检索层返回空(empty result,或所有 chunk 都低于相似度阈值)。模型没拿到 context 仍然自信回答,还编了引用来支撑这份自信。
怎么判断:log 检索到的 chunks。RAG 返回 [] 但模型仍带引用,就是它编的。
3. 检索到的 chunks 里没引用,模型还硬塞
RAG 拿回 3 段关于 microbreaks 的文本,里面一个引用都没有。模型在答案末尾仍写 (Smith, 2019) 来显得严谨。
怎么判断:在 retrieved chunks 里搜引用字符串。找不到 = 模型造的。
4. 真作者套到了错论文上
John Smith 是真作者,2017 年写过别的主题。模型把一个 2019 年关于近似主题的论文按到了他头上。作者真,论文假。
怎么判断:搜作者名 Scholar 有结果,但搜引用里的论文标题没结果。
5. URL 幻觉来自高自信的模式匹配
Source: https://stackoverflow.com/questions/1234567/how-to-foo——域名真实、slug 格式对,但 question 不存在。模型按格式生成了 URL。
怎么判断:点开 URL,404 或 “no results” = 假。
6. DOI 伪造
模型输出 https://doi.org/10.1234/jop.2019.42.3.287——格式合法、registrant 前缀可能甚至是真的,但 DOI 解析不到。
怎么判断:粘到 doi.org,“DOI not found” = 假。截至 2026 年 CrossRef 已索引约 1.8 亿篇学术成果,真 DOI 几乎一定能在那里解析到。
7. 引用作者名落在通用模式上
模型默认常见英语姓:Smith、Jones、Brown、Williams。某个专业领域或非英语领域真实研究的作者姓往往分布很不一样。
怎么判断:非英语领域的 bibliography 一堆通用英语姓——可疑。
最短修复路径
第 1 步:不要让裸模型给引用
这是单点收益最大的修复。模型没文档库还让它引用,伪造率会非常高。
BAD: "Summarize research on X. Include 5 academic citations."
GOOD: "Summarize the topic of X based on your general knowledge.
Do NOT include citations, DOIs, or URLs. Mark anything
specific as 'based on general knowledge, please verify.'"
第 2 步:用 RAG,并把输出约束在检索到的源里
You will receive 3 document excerpts below.
Answer the user's question using ONLY these excerpts.
For every claim, cite which excerpt it came from: [1], [2], [3].
If the excerpts do not cover something, say "Not in provided sources."
Never invent a citation. Never reference a source not in the excerpts.
负面约束很关键。用检索到的文本给回答打地基,在 2026 年的多项研究里能把幻觉降 30-70%,做摘要任务时可以降到 2% 以下,但 RAG 仍会在大约 5-15% 的情况下编内容,多数发生在检索悄悄返回空、或返回了跑题的 chunk 时。所以你还需要第 2 步的空结果护栏和第 4 步的 ID 校验。
在代码里、而不是在 prompt 里加一个显式的”检索为空”分支:
if not retrieved:
return "No sources found for this query." # 不要调用模型
第 3 步:程序化校验每个 URL 和 DOI
import re
import requests
def validate_citations(text):
urls = re.findall(r'https?://[^\s)]+', text)
dois = re.findall(r'10\.\d+/[^\s)]+', text)
bad = []
for url in urls:
try:
r = requests.head(url, timeout=5, allow_redirects=True)
if r.status_code >= 400:
bad.append(url)
except Exception:
bad.append(url)
for doi in dois:
r = requests.head(f"https://doi.org/{doi}", timeout=5, allow_redirects=True)
if r.status_code >= 400:
bad.append(doi)
return bad
包含失效引用的 response 直接拒。要同时抓到 chimera reference(DOI 能解析、但指向错论文),用 CrossRef REST API 查 https://api.crossref.org/works/{doi},把返回的 title 和 author 跟模型声称的对比。DOI 能解析是必要条件,不是充分条件。
第 4 步:RAG 场景下,校验引用 token 在检索库里
allowed_sources = set(chunk['id'] for chunk in retrieved)
cited = extract_citation_ids(model_output)
fake = cited - allowed_sources
if fake:
raise ValueError(f"Model cited sources not in corpus: {fake}")
第 5 步:用”原生引用”特性,而不是自由文本引用
截至 2026 年 6 月,几家主流厂商都提供了把引用绑定到真实来源文本的特性,让模型没法指向一个从没提供过的东西。
- Anthropic Citations API:在每个
document内容块上设citations: {enabled: true}。response 会把文本块和引用对象交错返回,引用对象里带cited_text、document_index以及start_char_index/end_char_index(PDF 则是页码)。这些是指向你所提供文档的、保证有效的指针,而且cited_text不计入 output tokens。注意:Citations 与 Structured Outputs 不兼容,两个一起开会返回 400。 - OpenAI Responses API 配 web search:开启
web_search工具,并传include: ["web_search_call.action.sources"]。最终回答里会带内联的url_citation标注,附上每个真正抓取过的页面的标题和 URL。 - Google Gemini grounding:开启 Google Search grounding,Gemini 3.1 Pro 会为每条经过 grounding 的声明返回 grounding 元数据(支撑用的 snippet 和来源 URI)。
三家的原理是一样的:模型只能引用工具真正返回的内容。没有工具结果,就没有引用。
tools = [{"name": "search_papers", ...}, {"name": "fetch_url", ...}]
# 模型只能引用工具返回的内容。
第 6 步:让”编引用”比”不编”代价更高
IMPORTANT: If you cannot find a real source, write
"No source found" instead of inventing one. A fabricated
citation is treated as a failure; "No source found" is not.
说明后果能让对齐过的模型降低伪造率,但永远不要单靠它,要跟第 2 步 + 第 4 步组合。instruction 只是引导行为,代码才能保证结果。
第 7 步:UI 里把引用做成可验证的独立 claim
引用别只显示纯文本。每个引用应该是可点击链接、点开就是来源,链接 404 时显示一个红色 badge。RAG 场景下,把引用到的 snippet 显示在声明旁边,让读者能确认来源是不是真这么说。把可验证性推到 UI 层是最后一道防线,也是唯一能抓住”人会轻易相信”的 chimera reference 的那道防线。
怎么确认修好了
- 取 20 个引用最密集的输出,逐个跑
validate_citations()。坏 URL/DOI 的拒绝率应该是 0。 - RAG 场景下,确认第 4 步的 ID 校验在留出测试集上从不抛错,即每个被引用的 ID 都在语料里。
- 抽 10 个输出,每个 DOI 都过一遍 CrossRef,对比 title 和 author。零个 chimera reference。
- 按模型、按 prompt 模板长期记录伪造率。模型或 prompt 一改就涨的话,你会在用户之前先看到。
哪些情况不是你操作错了
裸 LLM 的训练语料含数百万引用,把”声明要跟引用”内化成了模式。即使指令很强,顶级模型没检索时仍会幻觉相当比例的引用,更小的 open-weight 模型伪造得多得多。对任何需要准确来源的产品,检索都是必选项、不是 nice-to-have。这是模型训练方式的属性,不是你 prompt 写得差的信号。
容易误判的情况
误判成”模型知识缺口”——“它就是不知道最近的论文。“它知道有论文,它没办法 ground 到具体某一篇。知识没问题,可验证性才是问题。修复方案从来不是单换一个更大或更新的模型。
预防建议
- 没检索的裸模型永远不要直接让它引用。
- 输出始终约束在检索语料、用显式 ID。
- post-processing 校验每个 URL 和 DOI,失败的整个 response 拒;能解析的 DOI 再跟 CrossRef 元数据交叉核对。
- 真正需要论文级输出时,用原生引用特性(Anthropic Citations API、OpenAI web search sources,或 Gemini grounding)。
- UI 里引用显示为可点击链接,让假引用在点击时暴露。
- 按模型、按 prompt 模板记录伪造率,长期跟踪。
FAQ
- 在 prompt 里加 “only cite real sources” 能修吗? 不能。模型以为自己编出来的就是真的,所以”只引用真的”这条指令改变不大。单靠 instruction 在这里效果很低,你需要检索加一道代码侧的校验。
- 有的模型比其他模型差吗? 是。更小的 open-weight 模型引用伪造率高很多,2026 年一项跨厂商基准的范围从约 14% 到超过 90%(取决于模型和领域)。但顶级模型没检索时也会伪造,所以换更好的模型不能替代 grounding。
- DOI 能解析,那引用就是真的吧? 不一定。chimera reference 会把一个真 DOI 跟错误的标题、年份或作者拼在一起。信它之前,先把解析出来的 CrossRef 元数据跟模型声称的对比。
- 我的 RAG 流水线偶尔还是幻觉,为什么? RAG 仍会在大约 5-15% 的情况下编内容,几乎都发生在检索悄悄返回空、或返回了跑题的 chunk 时。加上显式的空结果分支(第 2 步)和语料 ID 校验(第 4 步),检索为空时绝不让模型跑。
- 能让模型上网拿真引用吗? 能,但要用会返回来源元数据的原生特性(OpenAI
web_searchsources、Gemini grounding,或一个fetch_url工具),而不是自由文本 URL,并且仍要校验每个返回的 URL 能不能解析。
相关阅读
- AI 编造事实
- AI 幻觉出不存在的文件路径
- Prompt 缺少来源层级
- Prompt 缺少 context 层级
- 模型自己补足缺失细节
- AI 回答太空泛
- 没定义成功标准
- 评估标准含糊
- AI 编造错误的 API 签名
- 输出很漂亮但没法执行
标签: #Prompt 工程 #排查 #llm-output #幻觉 #引用 #rag