第 5 讲:无幻觉的 RAG——WikiChat 深入

Agentic AI · Lecture 05。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应: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 学完本讲,你应该能够

  1. 说出 BlenderBot-3 和 Atlas 的评估为什么”看起来很好”,以及知识型对话机器人需要哪些指标。
  2. 解释 LLM 带来的 NLP 研究方法的”范式转变”,并能按”LLM 工程”的四步去开发自己的系统。
  3. 比较稀疏检索、稠密检索、晚交互(ColBERT)、融合与重排序,说出各自擅长和害怕的情况。
  4. 说清楚 WikiChat 在”读资料”这一步处理的三个细节:时间上下文、逐段过滤、“我不知道”。
  5. 解释为什么事实核查要先把回复拆成原子的、自足的声明,并能读懂”两条流水线都需要”的设计分析。
  6. 设计一个评估:模拟用户、按头部 / 长尾 / 新近分档、声明级的事实核查、LLM 评委加人工兜底。
  7. 说明语料库内部的矛盾从哪里来、怎样检测、怎样在回答里处理。

0.2 先修知识

知识点用在哪里最低要求
第 1 讲全讲WikiChat 的 7 个阶段和 5+n+c5+n+c 次调用;头部 / 长尾 / 新近;“核查比生成可靠”
第 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 讲用记忆曲线 m/(m+κ)m/(m+\kappa) 解释过前两条:出现次数少的事实记不住,训练截止之后的事实根本没见过。第三条更直接:医院的病历、公司的内部文档,从来没有进过预训练语料。所以任何需要这三类知识的应用都必须检索。

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 站在谁的肩膀上:

年份里程碑意义
1952Uniterm关键词检索
1961BASEBALL最早的问答系统之一
1972TF-IDF把信息编码成向量
1990ATIS对话式问答
1998Google 搜索把检索做到网页规模
2004TREC 2004从维基百科检索答案
2015Memory Network信息编码为可学习的稠密向量
2017DrQA“先检索、再阅读”的流水线
2018Wizard of Wikipedia、BERT先检索、再生成的知识型对话
2019DenSPI第一个实时的稠密向量检索
2020ColBERT、GPT-3晚交互检索;大语言模型
2022BlenderBot-3、Atlas检索 + 语言模型的对话系统
2023Bing Chat、WikiChat、GPT-4
2024M3、多语言 WikiChat;ChatGPT / Copilot / Gemini / Perplexity 的检索

这条线上有两条支流:检索(从关键词到向量再到晚交互)和问答 / 对话(从规则到”检索 + 阅读”再到”检索 + 生成”)。WikiChat 把两者结合起来,并且在两者之间加上了”核查”。

1.4 本讲的目标

幻灯片列了三个目标,也是这一讲的三条线索:

  1. 无幻觉 RAG 的内部故事:每个阶段的细节和原因;
  2. NLP 研究的范式转变:数据集、训练、测试的老路为什么走不通了;
  3. 一般意义上的 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 讲的三个系统重现了这个现象:

系统头部长尾新近众包式分布分层分布
闭卷 LLM96.2%39.0%10.0%90.5%48.4%
朴素 RAG98.8%83.0%73.3%97.2%85.0%
WikiChat98.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.196100.0%100.0%100.0%
照抄文章开头两句0.32514.3%100.0%100.0%
“我不知道”0.0000.0%0.0%—
闭卷 LLM 的一句话0.181100.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 工程”的四步:

  1. 设计指标:先想清楚什么叫”好”(第 2 节)。
  2. 从最一般的指令开始:不要一开始就写一大堆规则和例子。
  3. 调试,直到你弄不坏它:
    • 用”关键”例子测试(最难的、最容易出错的情况);
    • 对 LLM 的错误做根因分析;
    • 增加或改进步骤(把任务进一步分解);
    • 在提示词里写上理由;把关键例子作为辅助加进去。
  4. 评估:
    • 测试必须覆盖最难的情况;
    • 用 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 的上下文编码)。打分时,查询里的每个词去段落里找”最像自己的那个词”,把这些最大相似度加起来:

score(q,d)=∑i∈qmax⁡j∈d  qi⋅dj\text{score}(q, d) = \sum_{i \in q} \max_{j \in d} \; \mathbf{q}_i \cdot \mathbf{d}_j

这叫 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):

RRF(d)=∑检索器 r1k+rankr(d),k=60\text{RRF}(d) = \sum_{\text{检索器 } r} \frac{1}{k + \text{rank}_r(d)}, \quad k = 60

只看名次、不看分数,所以可以合并分数尺度完全不同的检索器(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(答案所在的段落出现在前 kk 名里的比例,各 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):

方法头部·直接长尾·直接新近·直接头部·换说法长尾·换说法新近·换说法
BM25100.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 成本”的旋钮:

名单长度135102050
换说法 R@170.0%92.6%92.9%93.3%94.0%94.0%
每题调用重排序器135102050

名单里没有正确的段落,重排序器也无能为力,所以效果受第一阶段召回率的限制;名单越长,调用次数成正比地增加。


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”取前 kk 段(稠密检索对长尾名字模糊,会把名字相似的病检索进来),比较两种读法(60 种病各一次,统计交给起草者的事实):

kk做法正确事实/轮错误事实/轮准确率调用/轮别的病的段落/轮
5一次读全部5.270.1098.1%11.4
5逐段过滤5.180.0798.7%51.4
10一次读全部5.880.3294.9%15.9
10逐段过滤5.820.2096.7%105.9
20一次读全部6.030.7888.5%115.7
20逐段过滤6.070.4593.1%2015.7

(“一次读全部”时,别的病的一条事实被安错的概率设为 0.03+0.4×0.03 + 0.4 \times 名字相似度;“逐段过滤”时,把一段别的病的资料误判为相关的概率设为 2%。)

  • kk 越大,混进来的别的病的段落越多,错误事实随之增加。
  • 逐段过滤每次只回答一个简单的问题——“这段讲的是不是这种病?“——错误事实少了三到四成,代价是调用次数从 1 次变成 kk 次。这就是 WikiChat 调用次数里那个 nn 的来源。
  • 逐段过滤的错误也随 kk 增加:过滤器自己偶尔误判,别的病的段落越多,被误放进来的就越多。
  • kk 小时正确的事实也少(检索没找全)。召回和噪声之间要权衡:逐段过滤降低了把 kk 调大的代价,但不能消除它。

5.3 “我不知道”

幻灯片说:“对 LLM 来说最难说出口的一句话:‘我不知道’。它喜欢幻觉。“当一个话题经过过滤和核查之后什么信息都没剩下时,WikiChat 的起草提示要求它说”抱歉,我不知道”。

代码 02 演示 4 让用户问 40 种语料里根本没有的”病”。注意:检索永远会返回 kk 段,哪怕语料里根本没有这种病——“检索到了东西”不等于”知道答案”。

做法编了一段介绍的次数
A:交给起草的 LLM,提示里要求”资料里没有就说不知道”(违反指令的概率 15%)9/40
B:程序先检查”过滤和核查之后还剩不剩东西”,什么都不剩就直接回答”我不知道”3/40

做法 B 把这个判断从 LLM 手里拿出来,交给一行确定的代码——能用程序保证的事情,就不要交给 LLM,这和第 4 讲”让求解器做决策”是同一个思想。剩下的 3 次来自过滤器把别的病的段落误判为相关:做法 B 的前提是过滤这一步可靠。


6. 生成与核查

6.1 为什么要让 LLM 自己说?

第 1 讲讲过第 3 步的反直觉之处:明知 LLM 会幻觉,还要让它说。原因是检索只查了 nn 段,LLM 的记忆里有很多正确的东西(尤其是头部话题),可以作为线索。但 LLM 说的每一句都必须经过核查(第 4、5 步)。

6.2 为什么事实核查很难?

幻灯片举了一个关于某项赛事的回答:它说前三名晋级,还提到了一场三四名决赛。只有一部分是错的:实际上只有前两名晋级,但确实有一场三四名决赛。整句判”对”,错的那部分就混过去了;整句判”错”,对的那部分也被扔掉了。

新闻记者天天核查政客的讲话,做法是:找出每一条声明,给每一条打分。WikiChat 借用了这个做法,并用两个假设把核查简化:

  1. 事实性只有相对于一个”真相来源”才有意义——这里是维基百科(就像报社信任自己以前发表的报道)。
  2. 如果声明是原子的,每条声明非对即错。

于是:事实准确率=核查通过的声明数声明总数\text{事实准确率} = \dfrac{\text{核查通过的声明数}}{\text{声明总数}}。核查一段回复的流程是:找出其中的声明;对每条声明,在真相来源里检索相关的文档,判断这条声明是否被支持。

幻灯片对每一步的评价:

  • 声明识别:用 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 个提示词,调用 5+n+c5 + n + c 次(第 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%)+ 人工兜底兜底次数
闭卷 LLM50.8%53.3%50.0%50.0%1/240
朴素 RAG85.8%75.4%84.2%84.2%0/240
WikiChat98.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-494.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%
Atlas90.6%86.5%89.4%88.8%

对话性(满分 5 分;数字读自幻灯片上的柱状图):

系统切题有信息量自然不重复时间上正确
GPT-45.04.85.05.04.9
WikiChat(GPT-4)4.94.64.95.05.0
WikiChat(GPT-3.5)4.84.64.94.84.8
WikiChat(LLaMA)4.74.34.84.94.7
Atlas3.62.83.84.54.6

两张表放在一起看:Atlas 的事实准确率不低(它大量照抄原文),但对话性很差,尤其是信息量(2.8);GPT-4 很会聊天,但在长尾和新近话题上事实准确率只有一半左右;WikiChat 在对话性上和 GPT-4 相差无几,事实准确率远高于所有基线。

7.5 真实用户评估

幻灯片的小测验:“分析到这里,我们做完了吗?“——还没有。在 LLM 之前,很少有人做真实用户评估,因为系统的准确率太差。但它是最重要的指标。用户研究的设置:用户读一篇新的维基百科页面的第一句话,然后和系统聊这个话题。

系统用户评分(满分 5)事实准确率
GPT-43.442.9%
WikiChat(GPT-4)3.897.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%13540
C 检索 + LLM 比较(CLAIRE 的思路)58.3%80.8%36420
  • A:最彻底,但调用次数随事实数的平方增长——维基百科有上亿条事实,根本做不到。
  • B:很便宜,但只认识事先定义好的说法,换了说法的矛盾全都漏掉了;抽取时读错一个值,又会制造假矛盾。真实的维基百科没有固定的模式,“先定好表结构再抽取”做不到(第 9 讲的 SLIDERS 会讨论怎样自动建立模式)。
  • C:让检索把”可能相关的说法”找到一起,再让 LLM 逐对比较。只比较”讲同一件事”的两句话,所以调用次数和事实数成正比;换了说法也看得懂,所以召回率高得多。但精确率只有六成左右:LLM 每次比较只有 5% 的概率判错,可比较的次数多,假报警就积累起来了。
  • 无论哪种方法,结果都应该交给人审核:程序找候选,人做决定(往往还要判断哪一边是对的)。

8.3 矛盾对 RAG 的影响

代码 05 演示 3:每种病 4 种关系各问一次(BM25 取前 5 段):

问题做法题数答对说明分歧答错
无矛盾朴素 RAG214100.0%0.0%0.0%
无矛盾知道有分歧的 RAG214100.0%0.0%0.0%
有矛盾朴素 RAG2692.3%0.0%7.7%
有矛盾知道有分歧的 RAG2615.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 个提示、5+n+c5+n+c 次调用,又慢又贵。幻灯片的两个办法:

  • 蒸馏:把整个流水线(用大模型运行)的输入和输出收集起来,训练一个小模型(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. 本讲小结

  1. 指标先行:众包评估偏向热门话题(BlenderBot-3 的 2.1% 错误率);词重叠指标偏爱照抄(Atlas)。知识型对话需要事实准确率 + 五个对话性指标(切题、有信息量、自然、不重复、时间上正确),并且按头部 / 长尾 / 新近分档报告。
  2. LLM 工程:设计指标 → 从最一般的指令开始 → 用关键例子调试直到弄不坏 → 系统地评估。关键是看错误。
  3. 检索:稀疏检索精确但不懂同义;稠密检索懂同义但对罕见名字模糊(检索器也有长尾问题);晚交互(ColBERT)两者兼顾但存储更大;融合求稳;重排序在短名单上精排,受第一阶段召回和自身准确率的限制。
  4. 读资料:每个提示都写上当前时间,段落带上日期;逐段过滤减少实体混淆;什么都不剩时说”我不知道”,最好由程序判断。
  5. 核查:把回复拆成原子的、自足的声明,每条单独检索、单独核查。两条流水线都需要:LLM 生成补充了检索漏掉的信息(论文 27%),核查挡住了随话题变冷门而急剧增加的错误(论文 20% / 45% / 56%)。
  6. 评估:模拟用户解决对话分叉;声明识别 + 证据检索 + 人工判断;检索失败时人工兜底;最后是真实用户评估(97.9% vs 42.9%)。
  7. 语料库也会矛盾(维基百科至少 3.3%):检索 + LLM 比较可以高召回地找出候选,再交给人审核;回答时把分歧说出来。

11. 与项目的关系

  • 如果你的项目基于自由文本(论文、病历、法规、网页),WikiChat 的几个细节几乎都用得上:时间上下文、逐段过滤、原子且自足的声明、“我不知道”。
  • 项目的评估要回答:话题分布是什么(你的”长尾”在哪里)?指标是什么(事实性之外,还需要哪些)?谁来判断(LLM 评委是否和人工一致,抽样检查过吗)?多轮对话要用模拟用户,不能用静态的数据集。
  • 你的语料库内部一致吗?如果语料来自多个来源(不同年份的指南、不同医院的记录),矛盾几乎是必然的。

12. 练习

练习 1(RRF 手算)。段落 X 在 BM25 里排第 1、在稠密检索里排第 3;段落 Y 在两种检索里都排第 2。取 k=60k = 60,RRF 融合后谁排在前面?如果 k=1k = 1 呢?

参考答案

k=60k=60:X 得 1/61+1/63≈0.016393+0.015873=0.0322661/61 + 1/63 \approx 0.016393 + 0.015873 = 0.032266;Y 得 2/62≈0.0322582/62 \approx 0.032258。X 以极小的差距领先。 k=1k=1:X 得 1/2+1/4=0.751/2 + 1/4 = 0.75;Y 得 2/3≈0.6672/3 \approx 0.667。X 领先得更明显。 kk 越小,排名靠前的位置权重越大(“某一种检索器排第 1”更有分量);kk 越大,越看重”各种检索器都排得不错”。k=60k = 60 是原始论文的经验值。

练习 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”一次读全部”的那几行。错误事实还剩多少?

参考答案

实测(一次读全部,错误事实/轮):k=5,10,20k = 5, 10, 20 时从 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% 新近”这种话题分布下的事实准确率。你的项目的”真实用户”会问什么样的话题分布?

参考答案

0.5×96.2%+0.5×39.0%=67.6%0.5 \times 96.2\% + 0.5 \times 39.0\% = 67.6\%。真实用户的话题分布取决于应用:通用聊天以头部话题为主;而罕见病诊断、专业研究、企业内部问答这类应用,几乎全是”长尾”(对 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 做铺垫。
← 返回课程目录