对应:Stanford CS224V Fall 2026 Lecture 6(10/12 How to RAG without hallucination;系统 WikiChat)。 关于材料来源:2026 年这次课的幻灯片尚未公开。本讲依据:2025 年同主题的幻灯片(Lam & Semnani,Minimizing Hallucination in Retrieval-Augmented Generation);WikiChat 论文(Semnani 等,Findings of EMNLP 2023);语料库不一致检测的论文(Semnani 等,EMNLP 2025);课程阅读清单”Question-Answering on Free Text”部分。 配套代码:
code/lecture05/(只用 Python 标准库;06 号文件可选,需要anthropic包和 API 密钥) 预计阅读时间:3~4 小时(含运行代码)
0. 本讲导航
0.1 学完本讲,你应该能够
- 说出 BlenderBot-3 和 Atlas 的评估为什么”看起来很好”,以及知识型对话机器人需要哪些指标。
- 解释 LLM 带来的 NLP 研究方法的”范式转变”,并能按”LLM 工程”的四步去开发自己的系统。
- 比较稀疏检索、稠密检索、晚交互(ColBERT)、融合与重排序,说出各自擅长和害怕的情况。
- 说清楚 WikiChat 在”读资料”这一步处理的三个细节:时间上下文、逐段过滤、“我不知道”。
- 解释为什么事实核查要先把回复拆成原子的、自足的声明,并能读懂”两条流水线都需要”的设计分析。
- 设计一个评估:模拟用户、按头部 / 长尾 / 新近分档、声明级的事实核查、LLM 评委加人工兜底。
- 说明语料库内部的矛盾从哪里来、怎样检测、怎样在回答里处理。
0.2 先修知识
| 知识点 | 用在哪里 | 最低要求 |
|---|---|---|
| 第 1 讲 | 全讲 | WikiChat 的 7 个阶段和 次调用;头部 / 长尾 / 新近;“核查比生成可靠” |
| 第 1 讲的 BM25 | 第 4 节 | 知道 BM25 按”共同的词”打分(代码 retriever.py) |
| 向量与余弦相似度 | 第 4 节 | 两个长度为 1 的向量的点积 = 夹角的余弦(讲义里会解释) |
| 第 4 讲 | 第 5、7 节 | “把假设写出来”;“能用程序保证的事情,就不要交给 LLM” |
0.3 本讲地图
第 1 讲已经讲过 WikiChat 的整体流程、主要结果和两个消融实验。这一讲把它拆开来看:
第1节 背景:为什么一定要 RAG?商业 RAG 的问题
第2节 指标:BlenderBot-3 和 Atlas 的教训;对话需要的五个指标 ← 代码 04(演示 1、2)
第3节 方法论的范式转变:LLM 工程
第4节 检索:稀疏、稠密、晚交互、融合、重排序 ← 代码 01
第5节 读资料:时间上下文、逐段过滤、"我不知道" ← 代码 02
第6节 生成与核查:原子的、自足的声明;两条流水线都需要吗? ← 代码 03
第7节 评估:模拟用户、声明级核查、评委与人工兜底;实验结果 ← 代码 04(演示 3、4)
第8节 语料库自己不一致怎么办? ← 代码 05
第9节 补充:速度与蒸馏、多语言、说服型机器人
第10–14节 小结、与项目的关系、练习、延伸阅读、下一讲预告
0.4 本讲的玩具世界
继续使用第 1 讲的虚构罕见病百科(60 种疾病,按在预训练语料里出现的次数分为头部 20 种、长尾 25 种、新近 15 种;每种病一篇 5 段的文章;每种病 7 种关系可以提问,有”直接问法”和”换说法”两种问法)。在此基础上,各个代码文件加了一些东西:
- 01 号:一个手工模拟的”神经网络词向量”(同义词词典 + 罕见词的模糊表示),用来比较几种检索器;
- 02 号:每种病一条带日期的”治疗进展”时间线(2023 年的预测、2025 年的获批、2026 年的更新);
- 03 号:把闭卷 LLM 的回答写成口语化的样子(两件事连成一句、后面的句子用 “It” 指代);
- 05 号:别的文章里”顺带提到”的事实,其中约一成和主文章矛盾,一半换了说法。
关于本讲的数字:论文和幻灯片里的真实数字会注明出处;模拟实验的数字都来自 01~05 号代码的实际输出(固定随机种子,每个脚本几秒钟)。模拟的 LLM、检索器、评委会犯哪些错误、概率多大,都是设定的参数——它们展示的是机制和趋势。06 号代码需要 API 密钥,编写讲义时没有用真实的 API 运行过。
1. 背景:为什么一定要 RAG?
1.1 2022~2023 年的争论
幻灯片用一段对话概括了当时的争论:
- “我们直接问 LLM 不行吗?”——“不行,你得用 RAG。”
- “你只在你知道的东西上测过!LLM 当然知道你知道的东西。”
- “好吧,它现在会幻觉,但我们不能训练一个更大的模型、用更多数据吗?”——“LLM 不知道长尾、不知道新的实时信息、不知道私有信息!”
第 1 讲用记忆曲线 解释过前两条:出现次数少的事实记不住,训练截止之后的事实根本没见过。第三条更直接:医院的病历、公司的内部文档,从来没有进过预训练语料。所以任何需要这三类知识的应用都必须检索。
1.2 商业 RAG 并没有解决问题
到 2024 年,ChatGPT、Copilot、Gemini、Perplexity 都加上了检索。但 BBC 在 2025 年 1 月发布的调查(Representation of BBC News content in AI Assistants)发现:
- 51% 的 AI 新闻回答有严重问题;
- 引用了 BBC 内容的回答里,19% 引入了事实错误;
- 13% 的”BBC 原文引语”被改动过,或者原文里根本没有。
也就是说,“加了检索”不等于”不幻觉”。第 1 讲分析过两个原因(检索没找到、LLM 用记忆补上)。这一讲要看的是:一个几乎不幻觉的 RAG 系统,在每一个细节上做了什么。
1.3 知识型助手的简史
幻灯片画了一条时间线,可以帮助理解 WikiChat 站在谁的肩膀上:
| 年份 | 里程碑 | 意义 |
|---|---|---|
| 1952 | Uniterm | 关键词检索 |
| 1961 | BASEBALL | 最早的问答系统之一 |
| 1972 | TF-IDF | 把信息编码成向量 |
| 1990 | ATIS | 对话式问答 |
| 1998 | Google 搜索 | 把检索做到网页规模 |
| 2004 | TREC 2004 | 从维基百科检索答案 |
| 2015 | Memory Network | 信息编码为可学习的稠密向量 |
| 2017 | DrQA | “先检索、再阅读”的流水线 |
| 2018 | Wizard of Wikipedia、BERT | 先检索、再生成的知识型对话 |
| 2019 | DenSPI | 第一个实时的稠密向量检索 |
| 2020 | ColBERT、GPT-3 | 晚交互检索;大语言模型 |
| 2022 | BlenderBot-3、Atlas | 检索 + 语言模型的对话系统 |
| 2023 | Bing Chat、WikiChat、GPT-4 | |
| 2024 | M3、多语言 WikiChat;ChatGPT / Copilot / Gemini / Perplexity 的检索 |
这条线上有两条支流:检索(从关键词到向量再到晚交互)和问答 / 对话(从规则到”检索 + 阅读”再到”检索 + 生成”)。WikiChat 把两者结合起来,并且在两者之间加上了”核查”。
1.4 本讲的目标
幻灯片列了三个目标,也是这一讲的三条线索:
- 无幻觉 RAG 的内部故事:每个阶段的细节和原因;
- NLP 研究的范式转变:数据集、训练、测试的老路为什么走不通了;
- 一般意义上的 LLM 工程:对你们的项目同样有用。
2. 指标:BlenderBot-3 和 Atlas 的教训
2.1 BlenderBot-3:众包评估说它很好
BlenderBot-3(Meta,2022)用 1750 亿参数的 OPT 模型,在 20 个学术数据集的组合上微调,能访问搜索引擎,并且公开部署了。在 100 段众包对话上:只有 2.1% 的事实错误;连不检索的较小的第 1 版也只有 5.1%;人工评分 4.45/5。
可研究组自己一试,准确率很差。幻灯片上的例子:问”2023 年澳网男单冠军是谁?“,它说是梅德韦杰夫直落三盘击败德约科维奇(实际是德约科维奇夺冠,第 10 个澳网冠军、第 22 个大满贯);问”村上春树的哪些电影?“,它说最喜欢《After Dark》——那是一本书。
幻灯片的小测验:“为什么众包评估这么高?“答案是:众包工人问的都是热门话题。
代码 04 演示 1 用第 1 讲的三个系统重现了这个现象:
| 系统 | 头部 | 长尾 | 新近 | 众包式分布 | 分层分布 |
|---|---|---|---|---|---|
| 闭卷 LLM | 96.2% | 39.0% | 10.0% | 90.5% | 48.4% |
| 朴素 RAG | 98.8% | 83.0% | 73.3% | 97.2% | 85.0% |
| WikiChat | 98.3% | 98.5% | 98.6% | 98.3% | 98.5% |
(“众包式” = 90% 头部、10% 长尾、0% 新近;“分层” = 三档各三分之一;表中是加权的事实准确率。)在众包式的话题分布上,闭卷 LLM 看起来相当可靠;按档次分层,它的问题才暴露出来。评估集的话题分布本身就是一个设计决定:你想知道系统在哪里会出错,就必须去那里测。
2.2 Atlas:指标偏爱照抄
Atlas(Izacard 等,2022)是 30 亿参数的检索增强模型,在很多知识密集型任务上是当时最好的,包括 Wizard of Wikipedia 对话数据集。它在对话任务上用的指标是:模型回复和话题维基百科页面前 10 句话的词重叠 F1。
幻灯片指出这个指标”偏爱泛泛的、无关的、照抄原文的回复”,并给了一段 Atlas 的真实对话:用户想聊演员兼编剧 Amelia Gething 的作品,三番五次追问,Atlas 的回答是”她 1999 年出生在伦敦""她有一个 YouTube 频道""我没看过……她有一个 YouTube 频道”。
代码 04 演示 2 在 420 道”问具体方面”的题上比较四种回复:
| 回复 | 词重叠 F1 | 切题 | 有信息量 | 声明全部正确 |
|---|---|---|---|---|
| 正确、切题的一句话 | 0.196 | 100.0% | 100.0% | 100.0% |
| 照抄文章开头两句 | 0.325 | 14.3% | 100.0% | 100.0% |
| “我不知道” | 0.000 | 0.0% | 0.0% | — |
| 闭卷 LLM 的一句话 | 0.181 | 100.0% | 100.0% | 50.7% |
两个教训:
- 照抄文章开头的回复 F1 最高,但它和问题无关;
- 错误的回答和正确的回答只差一两个词,F1 几乎一样——词重叠分不出对错。
2.3 事实性够不够?
幻灯片接着问:“只要事实正确就够了吗?“显然不够:照抄的回复全是正确的事实,“我不知道”一句错话也没有,但它们都不是好的回答。WikiChat 为知识型对话定义了五个对话性指标:
| 指标 | 含义 |
|---|---|
| 切题(relevant) | 回答了用户问的东西 |
| 有信息量(informational) | 提供了有用的信息。说”我不知道”会在这一项被扣分 |
| 自然(natural) | 像人说话,而不是照搬百科 |
| 不重复(non-repetitive) | 不要反复说同样的话(Atlas 的”YouTube 频道”) |
| 时间上正确(temporally correct) | 提供最新的信息,用正确的时态 |
再加上事实准确率(被语料支持的声明所占的比例)。这些指标一起,把”不幻觉”和”有用”之间的张力摆到了桌面上:一个永远说”我不知道”的系统事实准确率是 100%,但信息量是 0。
3. 方法论的范式转变:LLM 工程
3.1 老路为什么走不通
经典的 NLP 研究方法是:建一个数据集(训练集、验证集、测试集)→ 训练 → 在测试集上报告数字。LLM 让这条路的每一步都出了问题。幻灯片引用了几句研究者常说的话:
- “现有 NLP 数据集里的标注错误百出!LLM 生成的结果更好!“(第 6 讲会看到 Text-to-SQL 数据集里的例子)
- “根本没有唯一的标准答案。我们怎么比较?“(对话尤其如此:同一个问题有无数种好的回答)
- “在特定问题的数据集上微调,可能让 LLM 变差(而且非常贵)。”
3.2 LLM 工程的四步
WikiChat 的工程花了 3 名学生 4 个月;评估又花了 2~3 个月。幻灯片把这段经验总结成”LLM 工程”的四步:
- 设计指标:先想清楚什么叫”好”(第 2 节)。
- 从最一般的指令开始:不要一开始就写一大堆规则和例子。
- 调试,直到你弄不坏它:
- 用”关键”例子测试(最难的、最容易出错的情况);
- 对 LLM 的错误做根因分析;
- 增加或改进步骤(把任务进一步分解);
- 在提示词里写上理由;把关键例子作为辅助加进去。
- 评估:
- 测试必须覆盖最难的情况;
- 用 LLM 模拟的、性格各异的”难缠用户”来测试;
- 用 LLM 评估;如果 LLM 和人的判断不一致,就用人工评估;
- 用真实用户测试。
总的原则是”系统地建立经过充分测试的、一步一步的算法”——也就是第 1 讲说的计算思维。幻灯片说,好消息是用关键例子调试就能让 WikiChat 达到很高的质量。关键是:看错误!
这一讲剩下的部分,基本上都是在展示”看错误”之后发现的问题,以及每一步是怎么改的。
4. 检索
4.1 为什么检索是第一道关
WikiChat 选择英文维基百科作为知识来源:规模大(6.7M 篇文章、4.3B 个词)、开放领域(什么都能聊)、有大量的前人工作可以比较、公开可复现。幻灯片的说法是:“如果能处理好维基百科,就能处理其他大规模的开放领域语料。”
对着一篇文档回答问题,效果取决于文档的长度,而文档长度有上限(GPT-4 是 128K token,大约 9.6 万个英文单词)。所以必须先从语料里检索出少量相关的段落。幻灯片强调:“检索必须返回正确的文档,回答才可能准确。”
4.2 几种检索方法
稀疏检索(第 1 讲的 BM25):查询和段落都表示成”词 → 权重”,只有字面相同的词才算匹配。优点是精确匹配名字、代号很强,不需要训练;缺点是换个说法就找不到(“genetic cause”对不上”caused by mutations in the … gene”)。
稠密检索(dense retrieval):用一个神经网络(通常是在”问题—段落”对上微调过的 BERT)把整段话压成一个向量,比较查询向量和段落向量的夹角(余弦相似度)。训练让意思相近的话向量也相近,所以它认得同义词。但一个向量要装下整段话的意思,细节会丢——尤其是训练时很少见到的罕见名字,它们的表示是模糊的。文献里有专门的研究(Sciavolino 等,2021)发现,稠密检索器在”关于罕见实体的简单问题”上明显不如 BM25。
晚交互(late interaction,ColBERT,Khattab & Zaharia 2020,本讲的必读论文):段落里每个词各有一个向量(经过 BERT 的上下文编码)。打分时,查询里的每个词去段落里找”最像自己的那个词”,把这些最大相似度加起来:
这叫 MaxSim。“晚”的意思是:查询和段落各自编码(段落的向量可以离线算好存起来),到最后打分时才逐词交互。它既能像稠密检索那样认出同义词,又能像 BM25 那样精确匹配罕见的名字。代价是要存的向量多得多(每个词一个),ColBERTv2 用压缩技术把存储降了下来。WikiChat v1 用的就是 ColBERTv2:查询延迟约 100 毫秒,在 MS MARCO(2016 年发布的段落排序数据集)上训练。
M3-Embedding(Chen 等,2024):在 XLM-R 上用 17 个多语言段落排序数据集(加上一些合成数据)微调,支持 100 多种语言;“多功能”——同一个模型同时输出稠密、多向量和稀疏三种表示;“多粒度”——从短句到长文档都能处理。WikiChat 后来换成了 M3,从而支持多语言。
融合(hybrid):把几种检索器的结果合起来。最常用的是倒数排名融合(Reciprocal Rank Fusion,RRF):
只看名次、不看分数,所以可以合并分数尺度完全不同的检索器(BM25 的分数可以是 030,余弦相似度在 01 之间)。
重排序(reranking):先用便宜的检索取一个短名单(比如前 20 名),再用一个”读得懂”的模型把查询和每个候选段落放在一起读,重新打分。这个模型可以是交叉编码器(cross-encoder),也可以像 RankGPT(Sun 等,2023)那样直接让 LLM 给候选排序。它准,但贵:每个”查询—段落”对都要算一次,只能用在短名单上。
4.3 模拟实验
代码 01 用一个手工的”同义词词典”和”罕见词的模糊表示”模拟神经网络学到的东西(这一点在代码开头有详细说明),在第 1 讲的 300 段语料上比较。
两个例子(演示 1,长尾疾病 Salotos syndrome):
- “How is Salotos syndrome passed down in families?”:BM25 只匹配上了病名,而病名在第 0 段里出现了两次,于是第 0 段排第 1;稠密检索认出了 passed、families ≈ inheritance,但长尾的名字在它眼里很模糊,把另一种病(Velordela syndrome)的同类段落排到了第 1;晚交互答对了。
- “How rare is Salotos syndrome?”:BM25、稠密、晚交互都排错了。第 0 段 “Salotos syndrome is a rare genetic disorder” 里有一个字面相同的 “rare”,对晚交互来说,字面相同胜过同义(“affects … people”)。这是一个字面陷阱。重排序器把问题和段落一起读,知道 “How rare” 问的是患病率,把正确的段落提到了第 1。
Recall@k(答案所在的段落出现在前 名里的比例,各 420 道题,演示 2):
| 方法 | 直接 R@1 | 直接 R@3 | 换说法 R@1 | 换说法 R@3 | 换说法·病对了 |
|---|---|---|---|---|---|
| BM25(稀疏) | 100.0% | 100.0% | 14.3% | 71.4% | 100.0% |
| 稠密(单向量) | 82.9% | 92.9% | 71.0% | 87.9% | 85.2% |
| 晚交互(ColBERT) | 100.0% | 100.0% | 71.4% | 100.0% | 100.0% |
| 融合(BM25 + 稠密) | 96.4% | 97.4% | 70.0% | 96.4% | 100.0% |
| 融合 + 重排序前 20 名 | 97.9% | 99.5% | 94.0% | 95.5% | 97.1% |
(“换说法·病对了”:第 1 名至少是关于这种病的段落。)
- 没有一种第一阶段的方法在两种问法上都最好。
- 融合没有在哪一列单独拿第一,但它的 Recall@3 在两种问法上都很高。它的价值是稳:两种方法的弱点不重合。
- 重排序把换说法的 Recall@1 从 70.0% 提到了 94.0%。但重排序器自己也会出错(设为每读一对 5%),所以它的 Recall@3 和”病对了”反而比融合略低。精排模型的准确率,是这一步的天花板。
长尾问题(演示 3,Recall@1):
| 方法 | 头部·直接 | 长尾·直接 | 新近·直接 | 头部·换说法 | 长尾·换说法 | 新近·换说法 |
|---|---|---|---|---|---|---|
| BM25 | 100.0% | 100.0% | 100.0% | 14.3% | 14.3% | 14.3% |
| 稠密 | 88.6% | 77.7% | 83.8% | 84.3% | 62.9% | 66.7% |
| 晚交互 | 100.0% | 100.0% | 100.0% | 71.4% | 71.4% | 71.4% |
第 1 讲说 LLM 的记忆有长尾问题;这里看到,稠密检索器的表示也有长尾问题:模型”见过”头部疾病的名字,对长尾的名字只有模糊的印象。BM25 和晚交互对名字做精确匹配,没有这个问题——这是混合检索(或者 M3 这种同时输出几种表示的模型)在实践中很受欢迎的原因之一。
代价(演示 4):BM25 存 2928 条倒排记录;稠密检索存 300 个向量(每段一个);晚交互存 3496 个向量(每个词一个),每次查询也最慢(这个玩具实现里大约是稠密检索的二十多倍)。重排序的名单长度是一个”准确率 vs 成本”的旋钮:
| 名单长度 | 1 | 3 | 5 | 10 | 20 | 50 |
|---|---|---|---|---|---|---|
| 换说法 R@1 | 70.0% | 92.6% | 92.9% | 93.3% | 94.0% | 94.0% |
| 每题调用重排序器 | 1 | 3 | 5 | 10 | 20 | 50 |
名单里没有正确的段落,重排序器也无能为力,所以效果受第一阶段召回率的限制;名单越长,调用次数成正比地增加。
5. 读资料:时间、混淆与”我不知道”
检索到了正确的段落,事情还没完:LLM 还得读对。
5.1 时间上下文
幻灯片的小测验:“这段对话哪里不对?“对话发生在 2023 年 3 月,检索到两段资料:一段是 2023 年 1 月的”《龙之家族》获得金球奖最佳剧集”,一段是 2022 年 12 月的”《龙之家族》获两项金球奖提名”。聊天机器人先说它赢了金球奖(对),接着又说”2023 年 1 月,这部剧预计将赢得金球奖最佳剧集”——把一条旧的预测当成了现在时。
原因是:LLM 是用所有过去的知识一次性训练出来的,没有”时间流逝”的模型。检索到的段落写于不同的时间,LLM 分不清哪句是旧的;它也不知道”现在”是什么时候(往往以为现在是它的训练截止年份)。WikiChat 的解决办法很简单:每一个提示词里都写上当前的时间(和地点),检索到的段落也带上日期。
代码 02 给每种病生成了一条”治疗进展”时间线,例如:
(2023) Dorivir is expected to be approved for Galadela syndrome in 2025.
(2025) In 2025, Dorivir was approved for Galadela syndrome.
(2026) In 2026, Zelovir replaced Dorivir as the first-line treatment for Galadela syndrome.
站在 2026 年 10 月 12 日问三类问题,三种提示设置下的准确率(演示 2,60 种病):
| 设置 | 现在的一线治疗 | 获批了吗 | 今年的新药 |
|---|---|---|---|
| 段落不带日期,提示里没有当前时间 | 85.0% | 75.0% | 65.0% |
| 段落带日期,提示里没有当前时间 | 100.0% | 75.0% | 65.0% |
| 段落带日期 + 每个提示都写上当前时间(WikiChat) | 100.0% | 100.0% | 100.0% |
- 没有日期:几段话在 LLM 眼里是同时成立的几种说法,回答取决于碰巧先读哪句。上面这个病例里,旧的”已获批”覆盖了新的”已被取代”,回答成了 Dorivir。
- 有日期、没有当前时间:新旧分得清了,但模型以为现在是 2024 年。“今年有新药吗”被理解成 2024 年,回答”没有”。对只有一段 2023 年预测的病,它把”预计 2025 年获批”当成将来的事说出来——时态错了,而且漏掉了一个重要的信号:“预计的事情已经到期,却没有任何消息”。
- 这些错误不会因为模型更大、更聪明而消失:模型无从知道今天是几号。这是信息问题,不是能力问题,所以解决办法是把信息给它。
5.2 逐段摘要与过滤
BBC 的调查里,19% 的回答引入了事实错误,13% 的引语被改动或根本不存在。一次把很多段落塞给 LLM,它可能把一段里关于另一个实体的事实,安到用户问的实体头上。WikiChat 的第 2 步是每一段单独过滤:每次只给 LLM 一段资料和用户的问题,让它摘出相关的内容;不相关的段落整段丢掉。
代码 02 演示 3 用稠密检索为”Tell me about X”取前 段(稠密检索对长尾名字模糊,会把名字相似的病检索进来),比较两种读法(60 种病各一次,统计交给起草者的事实):
| 做法 | 正确事实/轮 | 错误事实/轮 | 准确率 | 调用/轮 | 别的病的段落/轮 | |
|---|---|---|---|---|---|---|
| 5 | 一次读全部 | 5.27 | 0.10 | 98.1% | 1 | 1.4 |
| 5 | 逐段过滤 | 5.18 | 0.07 | 98.7% | 5 | 1.4 |
| 10 | 一次读全部 | 5.88 | 0.32 | 94.9% | 1 | 5.9 |
| 10 | 逐段过滤 | 5.82 | 0.20 | 96.7% | 10 | 5.9 |
| 20 | 一次读全部 | 6.03 | 0.78 | 88.5% | 1 | 15.7 |
| 20 | 逐段过滤 | 6.07 | 0.45 | 93.1% | 20 | 15.7 |
(“一次读全部”时,别的病的一条事实被安错的概率设为 名字相似度;“逐段过滤”时,把一段别的病的资料误判为相关的概率设为 2%。)
- 越大,混进来的别的病的段落越多,错误事实随之增加。
- 逐段过滤每次只回答一个简单的问题——“这段讲的是不是这种病?“——错误事实少了三到四成,代价是调用次数从 1 次变成 次。这就是 WikiChat 调用次数里那个 的来源。
- 逐段过滤的错误也随 增加:过滤器自己偶尔误判,别的病的段落越多,被误放进来的就越多。
- 小时正确的事实也少(检索没找全)。召回和噪声之间要权衡:逐段过滤降低了把 调大的代价,但不能消除它。
5.3 “我不知道”
幻灯片说:“对 LLM 来说最难说出口的一句话:‘我不知道’。它喜欢幻觉。“当一个话题经过过滤和核查之后什么信息都没剩下时,WikiChat 的起草提示要求它说”抱歉,我不知道”。
代码 02 演示 4 让用户问 40 种语料里根本没有的”病”。注意:检索永远会返回 段,哪怕语料里根本没有这种病——“检索到了东西”不等于”知道答案”。
| 做法 | 编了一段介绍的次数 |
|---|---|
| A:交给起草的 LLM,提示里要求”资料里没有就说不知道”(违反指令的概率 15%) | 9/40 |
| B:程序先检查”过滤和核查之后还剩不剩东西”,什么都不剩就直接回答”我不知道” | 3/40 |
做法 B 把这个判断从 LLM 手里拿出来,交给一行确定的代码——能用程序保证的事情,就不要交给 LLM,这和第 4 讲”让求解器做决策”是同一个思想。剩下的 3 次来自过滤器把别的病的段落误判为相关:做法 B 的前提是过滤这一步可靠。
6. 生成与核查
6.1 为什么要让 LLM 自己说?
第 1 讲讲过第 3 步的反直觉之处:明知 LLM 会幻觉,还要让它说。原因是检索只查了 段,LLM 的记忆里有很多正确的东西(尤其是头部话题),可以作为线索。但 LLM 说的每一句都必须经过核查(第 4、5 步)。
6.2 为什么事实核查很难?
幻灯片举了一个关于某项赛事的回答:它说前三名晋级,还提到了一场三四名决赛。只有一部分是错的:实际上只有前两名晋级,但确实有一场三四名决赛。整句判”对”,错的那部分就混过去了;整句判”错”,对的那部分也被扔掉了。
新闻记者天天核查政客的讲话,做法是:找出每一条声明,给每一条打分。WikiChat 借用了这个做法,并用两个假设把核查简化:
- 事实性只有相对于一个”真相来源”才有意义——这里是维基百科(就像报社信任自己以前发表的报道)。
- 如果声明是原子的,每条声明非对即错。
于是:。核查一段回复的流程是:找出其中的声明;对每条声明,在真相来源里检索相关的文档,判断这条声明是否被支持。
幻灯片对每一步的评价:
- 声明识别:用 GPT-4 可以做好,但必须保证声明是自足的(self-contained);
- 检索:用最先进的检索器可以做好;
- “一句话 vs 一段证据”的判断:自动方法最好的结果是约 67% F1(微调的 LLaMA)或 83.2% F1(少样本的 ChatGPT)——“不够好!必须人工评估。”
6.3 原子的、自足的声明
“自足”也叫去语境化(decontextualization):把”它是 1987 年首次描述的”改写成”Velmora 综合征是 1987 年首次描述的”。一条声明要单独拿出去检索、单独给核查者看,就必须自己说清楚是关于谁的。
代码 03 把闭卷 LLM 对 60 种疾病的回答(各 4 条事实,共 240 条,其中 122 条对、118 条错)写成口语化的样子:两件事用 ”, and” 连成一句,后面的句子用代词。例如(演示 1):
The hallmark feature of Galophy syndrome is early-onset obesity, and its first cases were reported by Rhea Keleau, MD. Its symptoms usually begin in adolescence, and it affects about 1 in 100,000 people.
四条事实里,标志性症状和起病年龄是错的,另外两条是对的——两句话都是”一对一错”。四种处理方法:
| 做法 | 这个例子 | 60 种病:正确事实保住 | 错误事实漏过 | 保留的事实里正确的比例 |
|---|---|---|---|---|
| 整句核查:每部分都被支持才保留 | 两句都删,0 条 | 47.5% | 10.2% | 82.9% |
| 整句核查:有一部分被支持就保留 | 两句都留,4 条里 2 条错 | 94.3% | 60.2% | 61.8% |
| 拆成原子声明(代词不改) | 留 3 条,1 条错 | 95.9% | 55.9% | 63.9% |
| 拆成原子声明 + 去语境化(WikiChat) | 留 2 条,全对 | 99.2% | 4.2% | 96.0% |
- 整句核查只能在”保住正确的”和”挡住错误的”之间二选一。
- 只拆不去语境化,错误漏过的比例仍然很高。例子里的 “Its symptoms usually begin in adolescence.” 单独拿去检索,查询里没有病名,找回来的是别的病的段落;核查者不知道 “its” 指谁,看到某种别的病也是青春期起病,就判了”支持”。
- 去语境化把代词换回病名,检索找得到正确的段落,核查者也知道该比较哪种病。
编写这段代码时还踩了一个很有代表性的坑:第 1 讲的声明解析器会把 “It follows X inheritance.” 里的 “It” 当成一种叫 “It” 的病(模板 “{病名} follows {值} inheritance.” 恰好匹配)。结果所有代词声明都被当成”关于 It 这种病”的声明,核查全部失败,正确事实保住的比例只有 54%。这正是 LLM 工程第 3 步说的:看错误,做根因分析。
6.4 两条流水线都需要吗?
幻灯片在”设计分析”里回答了两个问题:
- 需要两条流水线(检索 + LLM 生成)吗?需要:最终回复里 27% 的事实来自 LLM 的生成——检索那条流水线没有提供它们。幻灯片上的例子是和 WikiChat 聊歌手 Sting(他的音乐为什么独特、出生地纽卡斯尔对他的影响),并用颜色标出了回答里哪些内容来自检索、哪些来自 LLM 的生成——两者交织在同一段回答里。
- 需要核查 LLM 的输出吗?需要:LLM 生成的声明里,核查不通过的比例在头部、长尾、新近话题上分别是 20%、45%、56%。
代码 03 演示 3 用第 1 讲的迷你 WikiChat 做了同样的分析(60 种疾病各一轮):
- 最终回复里只来自 LLM 生成(第 2 步没有提供)的事实:30/318(9.4%);
- LLM 生成的声明核查不通过的比例:头部 5/75(6.7%)、长尾 63/97(64.9%)、新近 52/60(86.7%)。
趋势和论文一致:第 3 步带来了检索漏掉的信息,第 5 步挡住的错误随话题变冷门、变新而急剧增加。具体数字取决于模拟 LLM 的记忆参数,不能和论文直接比较。
6.5 起草与润色
第 6 步根据第 2 步过滤出的资料和第 5 步核查通过的声明起草回复;第 7 步润色:切题、自然、不重复、时态正确。整个流程 7 个提示词,调用 次(第 1 讲)。幻灯片把这些步骤分成两类:传统的部分(检索、过滤、核查,负责事实性)和 LLM 的部分(生成、起草、润色,同时负责对话性和事实性)。
7. 评估
7.1 旧的数据集不管用
幻灯片列出了旧的评估方法的问题。总的困难是:没有一个简单的数字基准可以反复迭代。
- 以前的评估对话是众包的:让众包工人互相聊一个熟悉的话题。这有盲区:长尾话题、专业话题。
- 评估对话是静态的:很快就过时;Wizard of Wikipedia 的话题已经在 GPT-3 的预训练数据里了;新的基准将来也会被拿去预训练。
而且有几个新的难题:
- 怎么评估长尾问题?人也不知道长尾话题!
- 怎么评估 LLM 的对话?两个系统的对话在第一轮之后就分叉了,怎么比较?
- 怎么把人工的工作量、成本和可能的错误降到最低?
幻灯片的回答:“LLM 来救场。”
7.2 为什么必须模拟用户
代码 04 演示 3 说明了”分叉”的问题。假设数据集里录下的是用户和闭卷 LLM 的对话,第二轮用户追问了第一轮里的某句话,例如:
录下的第一轮(闭卷 LLM):…… Salotos syndrome follows mitochondrial inheritance. 录下的第二轮(用户):You said that Salotos syndrome follows mitochondrial inheritance. Could you tell me more about that? WikiChat 的第一轮:…… Salotos syndrome follows autosomal dominant inheritance. ……
用同样的用户发言去评估 WikiChat,用户追问的是一句 WikiChat 根本没说过的话(而且是闭卷 LLM 编的错话)。这种”对不上”的比例:头部 3/20(15%)、长尾 15/25(60%)、新近 12/15(80%)。
所以 WikiChat 用 LLM 模拟用户:给它一个话题(头部、长尾或新近)和一种性格,让它根据被评估系统实际说的话继续聊下去。每个系统聊同样多的轮次,再对每一轮评分。
7.3 评估流水线
幻灯片上的评估流水线:
模拟用户(头部/长尾/新近话题)──对话──► 被评估的聊天机器人
│
┌─────────────────────────────┴─────────────┐
声明识别(LLM)→ 证据检索 → 众包工人判断:事实准确率 对话性评分(LLM 评委)
当声明核查失败时(检索没有找到相关的文章),手动检索、核对——“贵,但很少”。
代码 04 演示 4 比较了不同的”评委”(三个系统的全部声明):
| 系统 | 真实 | 自动评委(LLM,出错 15%) | 众包工人看证据(出错 3%) | + 人工兜底 | 兜底次数 |
|---|---|---|---|---|---|
| 闭卷 LLM | 50.8% | 53.3% | 50.0% | 50.0% | 1/240 |
| 朴素 RAG | 85.8% | 75.4% | 84.2% | 84.2% | 0/240 |
| WikiChat | 98.4% | 83.0% | 95.9% | 95.9% | 0/318 |
自动评委把三个系统的分数往中间”挤”:真实准确率高的被低估,低的被高估。排名没变,但”WikiChat 比闭卷 LLM 好多少”这个结论被削弱了。在这个玩具世界里,检索几乎总能找到证据,所以兜底的次数很少——这正是”贵,但很少”。评估本身也是一个需要设计、需要验证的系统。
7.4 实验设置与结果
WikiChat v1 的实现:检索用 ColBERTv2;维基百科语料取自 2023 年 4 月 28 日;所有提示用 text-davinci-003 或 GPT-4。基线:微调的 Atlas(30 亿参数);被提示扮演聊天机器人的 text-davinci-003 或 GPT-4。每个系统评估 600 轮对话。
事实准确率(第 1 讲已列出,这里补上 Atlas):
| 系统 | 头部 | 长尾 | 新近 | 全部 |
|---|---|---|---|---|
| GPT-4 | 94.9% | 56.0% | 47.5% | 66.1% |
| WikiChat(GPT-4) | 98.8% | 94.6% | 98.5% | 97.3% |
| WikiChat(GPT-3.5) | 97.1% | 82.2% | 88.2% | 89.2% |
| WikiChat(LLaMA,蒸馏) | 95.2% | 87.1% | 90.9% | 91.1% |
| Atlas | 90.6% | 86.5% | 89.4% | 88.8% |
对话性(满分 5 分;数字读自幻灯片上的柱状图):
| 系统 | 切题 | 有信息量 | 自然 | 不重复 | 时间上正确 |
|---|---|---|---|---|---|
| GPT-4 | 5.0 | 4.8 | 5.0 | 5.0 | 4.9 |
| WikiChat(GPT-4) | 4.9 | 4.6 | 4.9 | 5.0 | 5.0 |
| WikiChat(GPT-3.5) | 4.8 | 4.6 | 4.9 | 4.8 | 4.8 |
| WikiChat(LLaMA) | 4.7 | 4.3 | 4.8 | 4.9 | 4.7 |
| Atlas | 3.6 | 2.8 | 3.8 | 4.5 | 4.6 |
两张表放在一起看:Atlas 的事实准确率不低(它大量照抄原文),但对话性很差,尤其是信息量(2.8);GPT-4 很会聊天,但在长尾和新近话题上事实准确率只有一半左右;WikiChat 在对话性上和 GPT-4 相差无几,事实准确率远高于所有基线。
7.5 真实用户评估
幻灯片的小测验:“分析到这里,我们做完了吗?“——还没有。在 LLM 之前,很少有人做真实用户评估,因为系统的准确率太差。但它是最重要的指标。用户研究的设置:用户读一篇新的维基百科页面的第一句话,然后和系统聊这个话题。
| 系统 | 用户评分(满分 5) | 事实准确率 |
|---|---|---|
| GPT-4 | 3.4 | 42.9% |
| WikiChat(GPT-4) | 3.8 | 97.9% |
幻灯片的评语:用 GPT-4 时,用户甚至没有察觉到一半以上的陈述是错的(第 1 讲第 2.3 节)。
8. 语料库自己不一致怎么办?
8.1 问题
WikiChat 假设维基百科是”真相的来源”。但维基百科自己也会前后矛盾:同一件事在不同的文章里各写一遍,改了一处、忘了另一处。Semnani 等(Detecting Corpus-Level Knowledge Inconsistencies in Wikipedia with Large Language Models,EMNLP 2025)的发现:
- 英文维基百科里至少 3.3% 的事实和另一条事实矛盾;
- 这些矛盾传到了建立在维基百科上的数据集里:FEVEROUS 的 7.3%、AmbigQA 的 4.0% 的样例受到影响;
- 最好的全自动系统 AUROC 只有 75.1%——这是一个真正困难的问题;
- 他们的系统 CLAIRE 是一个”检索 + LLM 推理”的智能体:为每条事实找出可能矛盾的说法,连同上下文证据一起交给人类审核;他们还建立了第一个真实维基百科矛盾的基准 WikiCollide;
- 用户研究:有经验的维基百科编辑里,87.5% 表示用了 CLAIRE 更有信心,同样时间内多找出了 64.7% 的不一致。
8.2 三种检测方法
代码 05 在第 1 讲的百科上加了 240 段”别的文章里顺带提到的事实”(基因页、人物传记、按年代和按起病年龄的列表页),其中 26 处(10.8%)和主文章矛盾,一半的句子换了说法(“was identified in” 而不是 “was first described in”)。例如:
[Braebrin syndrome] Braebrin syndrome was first described in 1943.
[Rare diseases described in the 1940s] Braebrin syndrome was identified in 1941.
语料里一共 660 条事实(演示 2):
| 方法 | 精确率 | 召回率 | 报警数 | LLM 调用 |
|---|---|---|---|---|
| A 两两全比 | — | — | — | 217,470 |
| B 按固定模式抽取,再分组比较 | 84.6% | 42.3% | 13 | 540 |
| C 检索 + LLM 比较(CLAIRE 的思路) | 58.3% | 80.8% | 36 | 420 |
- A:最彻底,但调用次数随事实数的平方增长——维基百科有上亿条事实,根本做不到。
- B:很便宜,但只认识事先定义好的说法,换了说法的矛盾全都漏掉了;抽取时读错一个值,又会制造假矛盾。真实的维基百科没有固定的模式,“先定好表结构再抽取”做不到(第 9 讲的 SLIDERS 会讨论怎样自动建立模式)。
- C:让检索把”可能相关的说法”找到一起,再让 LLM 逐对比较。只比较”讲同一件事”的两句话,所以调用次数和事实数成正比;换了说法也看得懂,所以召回率高得多。但精确率只有六成左右:LLM 每次比较只有 5% 的概率判错,可比较的次数多,假报警就积累起来了。
- 无论哪种方法,结果都应该交给人审核:程序找候选,人做决定(往往还要判断哪一边是对的)。
8.3 矛盾对 RAG 的影响
代码 05 演示 3:每种病 4 种关系各问一次(BM25 取前 5 段):
| 问题 | 做法 | 题数 | 答对 | 说明分歧 | 答错 |
|---|---|---|---|---|---|
| 无矛盾 | 朴素 RAG | 214 | 100.0% | 0.0% | 0.0% |
| 无矛盾 | 知道有分歧的 RAG | 214 | 100.0% | 0.0% | 0.0% |
| 有矛盾 | 朴素 RAG | 26 | 92.3% | 0.0% | 7.7% |
| 有矛盾 | 知道有分歧的 RAG | 26 | 15.4% | 84.6% | 0.0% |
朴素 RAG 悄悄地选了排名最前的说法:这里主文章通常排在前面,所以大多答对了,但用户完全不知道还有另一种说法。真实世界里,排在前面的那一段未必是对的那一段。把分歧说出来,例如:
Sources disagree: the article ‘Disorders with onset in infancy’ says infancy, while the article ‘Fenovane disease’ says early childhood.
这比悄悄选一个更诚实,也给了用户核实的线索——和第 4 讲”把假设写出来”是同一个精神。
9. 补充:速度、多语言、说服型机器人
9.1 速度与蒸馏
7 个提示、 次调用,又慢又贵。幻灯片的两个办法:
- 蒸馏:把整个流水线(用大模型运行)的输入和输出收集起来,训练一个小模型(LLaMA)完成同样的步骤。第 7.4 节的表里,蒸馏后的 WikiChat(LLaMA)事实准确率 91.1%,仍远高于 GPT-4 的 66.1%。第 14 讲会讲蒸馏。
- 更新的推理模型(幻灯片提到 OpenAI 的 o1-mini)已经快到不需要微调就够用了。
9.2 多语言
WikiChat 的演示网站(wikichat.genie.stanford.edu)已经收到了 3.5 万多个问题,涉及 10 多种语言。支持多语言需要两样东西:
- 多语言检索:用 M3 这样的多语言嵌入,可以用中文的问题检索英文的段落;
- 多语言实体消解:例如 “Hsiang-Tsung Kung” 和 “孔祥重” 是同一个人。这可以借助 Wikidata:同一个实体在不同语言的维基百科里有同一个编号(第 8 讲会讲 Wikidata)。
9.3 说服型机器人
WikiChat 的方法能用在说服型的对话任务上吗?幻灯片介绍了 Furumai 等(Findings of EMNLP 2024)的经验:
- 适用吗?适用:不检索的话,LLM 会编造成功故事——“有一个叫 Maria 的女孩……”。
- 够了吗?不够:核查会把所有编造的故事都删掉,结果一点都不打动人。解决办法:按编造故事的意图去检索,例如搜索”讲一个关于某个人的真实影响故事”,用真实的故事替换编造的故事。
- 对话性评估还能用 LLM 吗?不能:LLM 对”有多有说服力”的评分和人的评分不相关,只能人工评估。
这个例子提醒我们:方法要根据任务调整,评估方法也要。第 3 节 LLM 工程的第 4 步说”如果 LLM 和人的判断不一致,就用人工评估”,这里就是一个实例。
10. 本讲小结
- 指标先行:众包评估偏向热门话题(BlenderBot-3 的 2.1% 错误率);词重叠指标偏爱照抄(Atlas)。知识型对话需要事实准确率 + 五个对话性指标(切题、有信息量、自然、不重复、时间上正确),并且按头部 / 长尾 / 新近分档报告。
- LLM 工程:设计指标 → 从最一般的指令开始 → 用关键例子调试直到弄不坏 → 系统地评估。关键是看错误。
- 检索:稀疏检索精确但不懂同义;稠密检索懂同义但对罕见名字模糊(检索器也有长尾问题);晚交互(ColBERT)两者兼顾但存储更大;融合求稳;重排序在短名单上精排,受第一阶段召回和自身准确率的限制。
- 读资料:每个提示都写上当前时间,段落带上日期;逐段过滤减少实体混淆;什么都不剩时说”我不知道”,最好由程序判断。
- 核查:把回复拆成原子的、自足的声明,每条单独检索、单独核查。两条流水线都需要:LLM 生成补充了检索漏掉的信息(论文 27%),核查挡住了随话题变冷门而急剧增加的错误(论文 20% / 45% / 56%)。
- 评估:模拟用户解决对话分叉;声明识别 + 证据检索 + 人工判断;检索失败时人工兜底;最后是真实用户评估(97.9% vs 42.9%)。
- 语料库也会矛盾(维基百科至少 3.3%):检索 + LLM 比较可以高召回地找出候选,再交给人审核;回答时把分歧说出来。
11. 与项目的关系
- 如果你的项目基于自由文本(论文、病历、法规、网页),WikiChat 的几个细节几乎都用得上:时间上下文、逐段过滤、原子且自足的声明、“我不知道”。
- 项目的评估要回答:话题分布是什么(你的”长尾”在哪里)?指标是什么(事实性之外,还需要哪些)?谁来判断(LLM 评委是否和人工一致,抽样检查过吗)?多轮对话要用模拟用户,不能用静态的数据集。
- 你的语料库内部一致吗?如果语料来自多个来源(不同年份的指南、不同医院的记录),矛盾几乎是必然的。
12. 练习
练习 1(RRF 手算)。段落 X 在 BM25 里排第 1、在稠密检索里排第 3;段落 Y 在两种检索里都排第 2。取 ,RRF 融合后谁排在前面?如果 呢?
参考答案
:X 得 ;Y 得 。X 以极小的差距领先。 :X 得 ;Y 得 。X 领先得更明显。 越小,排名靠前的位置权重越大(“某一种检索器排第 1”更有分量); 越大,越看重”各种检索器都排得不错”。 是原始论文的经验值。
练习 2(动手改代码:稠密检索的容量)。在 01_retrieval.py 里,把 Encoder 的 blur_dims 从 16 改成 64,重新计算稠密检索按档次的 Recall@1。长尾问题怎样变化?这对应真实世界里的什么?
参考答案
实测(Recall@1,头部 / 长尾 / 新近):直接问法从 88.6% / 77.7% / 83.8% 变成 97.1% / 96.0% / 96.2%;换说法从 84.3% / 62.9% / 66.7% 变成 85.7% / 84.0% / 85.7%。维度多了,不同的罕见名字撞在一起的机会少了,长尾的差距基本消失。真实世界里对应更大、训练得更好的嵌入模型(例如在包含大量实体的数据上训练)。但罕见实体永远比模型的容量多,而且新的实体不断出现(新近话题),所以混合检索仍然有价值。
练习 3(动手改代码:混淆从哪里来)。在 02_time_and_filtering.py 里,把 PassageReader 的 sim_mix 改成 0(名字相似度不再影响混淆),重新运行演示 3”一次读全部”的那几行。错误事实还剩多少?
参考答案
实测(一次读全部,错误事实/轮): 时从 0.10、0.32、0.78 降到 0.02、0.13、0.45。名字相似的实体是混淆的主要来源之一(真实世界里,同名的人、名字相近的药和病、同一系列的产品都是重灾区),但即使名字完全不像,上下文里的无关段落越多,混淆仍然越多。
练习 4(动手改代码:去语境化的质量)。在 03_claims_and_verification.py 里,把 check_response 的 decontext_error(去语境化时漏改代词的概率)从 0.03 改成 0.3 和 1.0,“错误事实漏过”的比例怎样变化?
参考答案
实测:0.03 时正确事实保住 99.2%、错误事实漏过 4.2%;0.3 时 99.2%、21.2%;1.0 时 99.2%、51.7%(接近”只拆不去语境化”的 55.9%,差别来自每段回复的第一条声明本来就带着病名)。去语境化这一个小步骤的质量,直接决定了核查能挡住多少错误——分解之后,每个小任务都必须可靠(第 1 讲)。
练习 5(评估的话题分布)。用演示 1 的表,计算闭卷 LLM 在”50% 头部、50% 长尾、0% 新近”这种话题分布下的事实准确率。你的项目的”真实用户”会问什么样的话题分布?
参考答案
。真实用户的话题分布取决于应用:通用聊天以头部话题为主;而罕见病诊断、专业研究、企业内部问答这类应用,几乎全是”长尾”(对 LLM 而言)。评估的话题分布应该尽量接近部署时的真实分布,并且单独报告最难的那一档。
练习 6(动手改代码:固定模式的抽取)。在 05_corpus_inconsistency.py 里,调用 build_corpus(world, p_alt=0.0)(所有”顺带提到”的句子都用标准说法),方法 B 和方法 C 的精确率、召回率怎样变化?这说明了什么?
参考答案
实测:方法 B 的召回率从 42.3% 升到 100.0%,精确率 81.2%(读错值造成的假矛盾);方法 C 精确率 65.7%、召回率 88.5%。当所有说法都符合固定的模式时,“抽取 + 分组”又便宜又全;它的弱点完全在于真实语料的说法千变万化。这也是为什么第 9 讲的 SLIDERS 要自动建立模式、做数据对账,而不是手工定义表结构。
练习 7(思考:时间)。一个基于公司内部文档的问答机器人,被问到”我们现在的报销上限是多少?“。检索到三份文档:2023 年的政策、2025 年的修订、一封 2026 年的邮件说”新政策下个月生效”。列出系统需要哪些时间信息才能正确回答,以及回答里应该包含什么。
参考思路
需要:当前日期;每份文档的发布日期;邮件里”下个月”指的是哪个月(相对时间要换算成绝对时间,用的是邮件的发布日期,不是今天);新政策是否已经生效(比较生效日期和今天)。回答应该给出当前有效的上限,注明依据的文档和日期;如果新政策即将生效或刚刚生效,也要说明,并指出生效日期。如果检索不到 2025 年以后的文档,应该说明”依据的是 2023 年的政策,可能已经过时”——这是第 5.1 节”预计的事情已经到期却没有消息”的同类信号。
练习 8(思考:评估说服型机器人)。为什么 LLM 对”有多有说服力”的评分和人不相关,而对”切题""自然”的评分和人比较一致?设计一个说服型机器人的评估方案。
参考思路
“切题""自然”这类判断相对客观,读一遍回复就能判断;“说服力”取决于听者是谁、原来的立场、情绪反应,LLM 评委没有这些,而且 LLM 往往偏爱长的、条理清楚的论证,这未必能打动真实的人。评估方案:以真实的行为结果为主要指标(例如对话后的捐款意愿、实际捐款),由真实用户参与;辅以人工评分(说服力、可信度、是否感到被操纵);事实性仍然逐条核查(编造的成功故事要计为错误);按用户的初始立场分层报告。
13. 延伸阅读
本讲的核心论文
- Semnani, Yao, Zhang, Lam. WikiChat: Stopping the Hallucination of Large Language Model Chatbots by Few-Shot Grounding on Wikipedia. Findings of EMNLP 2023.(维基媒体基金会 2024 年度研究奖)
- Semnani, Burapacheep, Khatua, Atchariyachanvanit, Wang, Lam. Detecting Corpus-Level Knowledge Inconsistencies in Wikipedia with Large Language Models. EMNLP 2025. arXiv 2509.23233.
检索(课程阅读清单)
- Khattab & Zaharia. ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT. SIGIR 2020.(必读)
- Santhanam 等. ColBERTv2: Effective and Efficient Retrieval via Lightweight Late Interaction. NAACL 2022.
- Chen 等. M3-Embedding: Multi-Linguality, Multi-Functionality, Multi-Granularity Text Embeddings Through Self-Knowledge Distillation. Findings of ACL 2024.
- Sun 等. Is ChatGPT Good at Search? Investigating Large Language Models as Re-Ranking Agents(RankGPT). EMNLP 2023.
- Sciavolino, Zhong, Lee, Chen. Simple Entity-Centric Questions Challenge Dense Retrievers. EMNLP 2021.
检索 + 生成(课程阅读清单)
- Gao 等. Enabling Large Language Models to Generate Text with Citations. EMNLP 2023.
- Jiang 等. Active Retrieval Augmented Generation. EMNLP 2023.
评估与基线
- Min 等. FActScore: Fine-grained Atomic Evaluation of Factual Precision in Long Form Text Generation. EMNLP 2023.
- Yue 等. Automatic Evaluation of Attribution by Large Language Models. Findings of EMNLP 2023.
- Shuster 等. BlenderBot 3: a deployed conversational agent that continually learns to responsibly engage. arXiv 2022.
- Izacard 等. Atlas: Few-shot Learning with Retrieval Augmented Language Models. arXiv 2022.
- BBC. Representation of BBC News content in AI Assistants. 2025.
说服型机器人
- Furumai 等. Zero-shot Persuasive Chatbots with LLM-Generated Strategies and Information Retrieval. Findings of EMNLP 2024.
14. 下一讲预告
WikiChat 基于自由文本。可是很多知识存放在数据库里:餐厅的菜系、价格、评分;医院的化验结果;公司的订单。对这样的数据,“检索几段文字再读”既不准确也不完整——“人均 30 美元以下、评分 4.5 以上的意大利餐厅有几家?“需要的是一个查询,而不是几段文字。
第 6 讲进入结构化数据:
- 语义解析:把自然语言翻译成可执行的查询(SQL)。为什么”查出来的”比”记住的”可靠?
- 数据库查询的表达能力:过滤、连接、聚合、排序——关系代数能回答哪些问题?
- 小表结构上的少样本提示;枚举类型(菜系、价格档)的对齐;
- 评估的陷阱:数据集里的标注错误、问题的歧义、执行准确率 vs 字面匹配;
- 当问题同时涉及表格和文字时(“评价里说适合带孩子的意大利餐厅”),以往的几种做法为什么都不够——这为第 7 讲的 SUQL 做铺垫。