跳到主要内容

找得「像」不等于找得「对」 — 三种翻车与三种补救

这一章讲三件事: 「意思相近」会怎么骗你(三种方式); 书里给的三种补救各自治的是哪一种; 以及它们的共同点——全都在入库时做,不是在用户提问时做。 位置:入库线的最后一步。如果你已经搭了一个 RAG 系统、只是觉得它老答非所问,直接读这一章。

1. 先看现象:搜回来的东西「看着都挺相关」,可就是没用

你搭好了系统。用户提问,系统搜回来五块内容,模型照着写了个答案。

答案读起来很顺,但它是错的,或者答非所问。 你去看搜回来的那五块:

  • 每一块读起来确实跟问题有关;
  • 可其中三块根本不该被搬出来

问题不在模型,在检索。 而检索没做错任何事—— 它忠实地找出了「意思最相近」的五块。

问题在于:「意思相近」不等于「对这个问题有用」。

书里那句话说得最准:

不是每一块跟用户问题语义相似度高的文本,都真的相关。1

2. 顶层全景:三种骗法,三种解法

骗法一:意思确实像,但对这个用户没用
└─ 解法:给每块贴标签,搜之前先把不该考虑的踢掉 ← 元数据过滤

骗法二:块脱离前后文,自己看不懂自己
└─ 解法:入库前把缩写、代词、模糊指代都补成全称 ← 让块自解释

骗法三:用户提的是问句,资料是表格/代码/聊天记录,形状对不上
└─ 解法:事先给每块编几个「用户可能会这么问」的问题 ← 假设性问题

图说:三种骗法互不重叠,三种解法也可以同时用。它们全都发生在入库那一侧。

这个「全都在入库时做」的共性,是这一章最值得记住的一件事—— 第 6 节会展开讲它为什么重要。

这一章的主走查从第 3 节起立起来:一份招聘知识库里的一块。 三节各让它走一步,第 6 节把五步并起来再看一遍。

3. 骗法一:意思很像,但对这个用户没用

先立这一章的主走查:一份招聘知识库

从这一节开始,三招都拿同一份资料走,一直走到第 6 节。 输入是一家公司的招聘知识库:里面有简历、有面试记录, 还混进了一批从供应链部门抄送过来的采购文档。我们全程盯住其中一块:

块 c-64(现在原样躺在库里的样子):
「PO 已核准,候选人 c-64 进入终面。」

图说:一句十几个字的话。它一次踩中三种骗法 —— 下面三节各拆一种,第 6 节并起来看。

先声明:这份招聘知识库、上面这块的字串、以及后面出现的块数、距离、编出来的问题, 全部是为演示编的,不是真实数值。 书里在这一整章里只给了这么几样真东西:抗氧化剂那个对照例子、 「简历按岗位打标签」这个做法、LSTM 那张缩写表、以及「每块编 5 个问题」这个数。 其余是我们为了让每一步看得见而编的,不许引用

骗法一在这块上长什么样

一个只管软件开发招聘的用户问:「PO 进展如何?」 系统搬回来的前五块里,有三块来自供应链部门的采购文档—— 那边的「PO」指的是采购单。这三块跟「PO」这两个字母确实高度相关, 可没有一块跟他要办的事有关。

书里给的旁证:抗氧化剂

书里用另一个例子说同一件事,而且更极端。同一个词「抗氧化剂」,两段内容都跟它高度相关:

  • 一段讲抗氧化剂对人体的好处;
  • 一段讲抗氧化剂如何改善原材料的性能

书里的判据:

如果你是医生,你关心的是前者。 如果你是工程师,你关心的是后者。 用户几乎不会问另一边的那些场景2

书里紧接着给出的结论,值得一字不落地记:

乍一看又正确又相关的信息,一旦我们知道用户问题背后的完整背景, 可能就变得不相关、甚至是错的。3

作者还补了一句:这个例子很极端,但这类问题在真实的 RAG 应用里很常见—— 经常是两份文档乍看有关,细看之下有一个事实让它们完全不相干4

解法:先缩小范围,再比相似度

做法:给每一块贴上标签(也就是第 02 章说的元数据), 搜之前先按标签把不该考虑的整片踢掉。

书里的说法:元数据能帮我们在做向量搜索之前先收窄搜索空间—— 「搜索空间」就是「这一次搜索,允许哪些块参赛」;收窄它, 既加快搜索,也把不相干的东西滤掉1

不过滤:一万块,全部参与比相似度 → 前五名里混进三块供应链采购文档

先过滤:标签「岗位 = 软件开发」→ 只剩两千块参与比 → 前五名全是招聘相关的块
└─ 被踢掉的那八千块,不是「排名低」,是「根本没资格进入比较」
└─ 块 c-64 身上贴的正是这张标签,所以它留在场上

图说:这跟第 02 章「先找章标题再往下找」是同一个动作,只是过滤条件从「章名」换成了任意标签。
(一万块、两千块、八千块这三个数是为演示编的,不是真实数值;书里没有给任何数。)

书里给的其他可用标签:文档发表的时间段、作者名、正文里有没有提到某些人、 合同里含不含某些条款——具体用什么,完全取决于你的场景5

元数据从哪儿来:三步,一步比一步费劲

书里把攒元数据拆成三步6:

做什么举例
把文档自带的元数据抽出来PDF 里存着作者、创建时间、最后修改时间、标题、主题,还有生成它的软件7
自己补一些文件层面的信息页数、文件大小、文件名、文件路径、抽出来的文字有多长8
让模型读正文,把缺的挖出来PDF 自带的「作者」那一栏经常是空的,但作者名往往就写在正文第一页上9

第三步才是这一节真正的技巧。

书里的例子很实在:一个招聘用的 RAG 系统里, 简历的 PDF 元数据里没有「这是什么岗位的简历」这一项——可这正是最该用来过滤的标签。

所以让模型读一遍正文,判断这份简历属于软件开发、平面设计还是市场营销。 这样用户问「软件开发的简历里常提到哪些技能」时,系统就能把非开发岗的简历全滤掉10

让模型把结果吐成固定格式:结构化输出

第三步有个实际问题:模型是写文章的,它吐出来的是一段话,不是一张能直接入库的表。

书里用的办法叫结构化输出:事先声明「我要哪几栏、每一栏装什么样的东西」, 让模型只能按这个格式回答11。(这一栏一栏的东西,程序里叫字段。)

书里用一个叫 Pydantic 的工具来声明格式 (Pydantic 是 Python 里最常用的一个「数据格式校验」工具—— 你先写一张表格样板,列明「要姓名、要公司、要邮箱,姓名必须是一段文字」, 它负责把模型交上来的东西对着这张样板核一遍,不合规就打回)。

还要给模型一段指令,告诉它该干什么。 这段放在最前面的指令,书里叫「系统消息」12—— 它和用户的问题分开放,作用是设定模型的角色和任务。

4. 骗法二:块自己看不懂自己

问题的根子

书里给了一句定义式的话:

文本块是从一段更长的文字里切下来的片段, 孤零零地看的时候,可能很难理解。13

注意这句话跟第 05 章的关系: 第 05 章解决的是「在哪儿下刀」, 这一节解决的是「刀下完之后,这块自己站不站得住」。两件事,不能互相替代。

三个例子,一看就懂

块里写的问题
「PO 已核准」供应链文档里指采购单;换个场景可能指产品负责人,也可能指邮局14
「MJ 拿下了六冠」体育文档里指迈克尔·乔丹;不熟悉篮球的人根本不知道 MJ 是谁14
「点击「设置」按钮」教程类文档里的这句话,配图不在块里,你不知道那个按钮长什么样、在哪儿15

前两个是同一类:缩写脱离了行业背景就没有意义。 第三个是另一类:文字在指一个不在文字里的东西。

解法一(最朴素):入库前把缩写换成全称

做法就是准备一张缩写对照表,入库前做一次替换。 替换的写法有讲究:不是把缩写删掉换成全称,而是写成「全称(缩写)」。

书里的例子是一篇讲 Transformer(今天几乎所有大模型底层都在用的那套网络结构)的博客,里面全是缩写: LSTM 变成 Long Short-Term Memory (LSTM)16

为什么要两个都留? 书里给了理由,而且是这一节最实用的一句:

这样一来,不管用户用缩写问还是用全称问,系统都懂: 「什么是 LSTM?」和「什么是 Long Short-Term Memory?」17

只留全称:用户问「LSTM 是什么」 → 块里没有 LSTM 三个字母 → 相似度掉下来
只留缩写:用户问全称 → 同上,反过来
两个都留:两种问法都对得上 ← 这才是目的

图说:替换的目的不是让块「更通顺」,是让块能被两种问法同时命中。

主走查走到这一步: 块 c-64 在入库之前被改写了一次,原样存进去的不再是 「PO 已核准,候选人 c-64 进入终面。」,而是:

「**采购单(PO)**已核准,候选人 c-64 进入终面。」

注意这一改带来了什么: 用户拿「采购单」问,能命中;拿「PO」问,也能命中; 而上一节那个只管软件开发招聘的用户,再也不会因为「PO」两个字母 把供应链的采购文档整片搬回来——因为那些块也被改写过了, 它们现在明白写着「采购单」,而他要的是候选人。

解法二:内容太复杂就交给模型改写

对付充满专业术语、光看数字看不懂的内容(书里的例子是一张财务幻灯片), 朴素的词典替换不够,那就直接让模型来18

书里那段提示词里有一句要求很妙,值得学:

要写得足够浅显,浅显到一个十岁的小学生也能看懂。19

书里给的四条写作建议

作者列了四条,本质是同一件事——把块里所有「要靠别处才能理解」的东西补齐20:

别写要写
「它把效率提升了 40%。」新换的那套搜索做法把搜索效率提升了 40%。」
「它是去年上线的。」客户反馈系统是去年上线的。」
「谷歌 2019 年发布了它。」「谷歌 2019 年发布了 BERT(一个语言模型的名字)。」
「系统现在更好用了。」「系统的响应时间从 500 毫秒改善到 200 毫秒。」

四条的共同点:把代词、模糊指代、含糊的形容词,全都换成具体的东西。

一个更根本的坦白

书里在讨论里承认了一件事,而且这件事很少有人写出来。用我们自己的话复述: 理想情况下每一块自己就能读懂,可现实是大多数文档都默认读者带着一点背景知识—— 就像读一本进阶的 Python 书,默认你已经懂基础的 Python;不懂的地方,人可以自己去翻一本入门书补上。 而钉住这一整章的是下面这一句:

在基础的 RAG 系统里,模型只看得到向量搜索捞回来的那点东西。21

这是这一整章的元问题: 人有「去别处补课」的能力,而 RAG 里的模型没有。 所有的补救,本质上都是在入库时替它把课补好。

这本书之后出现的更强做法

书里的替换是词一级的(把 LSTM 换成全称)。 2024 年 9 月 Anthropic 公布了一个块一级的做法,叫上下文检索: 入库前,先让模型给每一块生成一段专属的说明性上下文,拼在这一块前面再算嵌入22

它举的例子正好对上这一节:一块只写着「本季度公司营收环比增长 3%」, 补完上下文之后会变成「(某公司某季度财报中的一段)……上一季度营收是多少……本季度增长 3%」。

它给了这本书完全没有的东西——数字: 单用这一招, 检索失败率从 5.7% 降到 3.7%(下降 35%); 配合关键词检索降到 2.9%;再加上一次重新排序降到 1.9%(总共下降 67%)22

判断(我们的,不是书里的): 这条外部结果值得单独记住,不是因为它更新, 而是因为它是这一章唯一一组可引用的数字。 书里的三招全都没有效果数据,而这一招给了对照:同样的文档、同样的评测,四种配置各自的失败率。 更要紧的是那组数字的形状——单靠一招下降 35%,三招叠起来下降 67%。 说明这类改进是可叠加的,但没有任何一招能单独解决问题。 如果错,会错在: 那组数字来自公布方自己的实验、自己挑的那些文档, 换成你自己的文档未必复现。它能证明的是「方向有效」,不是「你也会降 67%」。

5. 骗法三:问题和资料长得不像

问题:形状不匹配

书里描述得很准。基础的做法是直接拿用户的问题去跟文本块比。 麻烦在于:文本块的形态千差万别——可能是代码片段、可能是段落、也可能是表格一个「问句」和一张「表格」之间天生就不一样, 所以即便底层信息高度吻合,两者的嵌入也可能对不齐23

书里管这个现象叫语义对齐——「对齐」就是「对得上」: 说的是同一回事,算出来的两串数却对不到一块儿去。书里的原话写作「语义对齐问题」23

注意措辞: 书里用的是「通常被称为」,但没有给出处。 我们查不到一个被广泛引用的同名标准术语。 当成一个描述性的说法用,别当成公认名词引。

解法:反过来,让文档先把问题编好

书里的做法很妙,原话是我们把这个过程反过来: 之前是让模型给内容写摘要,这次是把最终的文本块给模型看, 让它生成一些「可以用这块内容回答的用户问题」24

入库时:
每一块 ──→ 让模型编 5 个「用户可能会这么问」的问题

├─ 给这 5 个问题各算一个嵌入,存进库
└─ 每个问题都记着一个指针:我来自哪一块 ←── 关键

提问时:
用户的问题 ──→ 算嵌入 ──→ 跟【那些编出来的问题】比,不是跟块比

└─ 命中之后,顺着指针取回【原始文本块】,交给模型作答

图说:比对的双方从「问句 vs 表格」变成了「问句 vs 问句」——形状终于一样了。

书里的示例给每一块编 5 个问题25

主走查走到这一步: 把改写之后的块 c-64 交给模型,让它编 5 个问题。 原样写出其中两个——这一步最怕的就是只说「让模型编几个问题」而不给样子:

① 「c-64 号候选人走到哪一轮了?」 ② 「采购单核准之后,下一步是什么?

这两个问题都不是块里的原话,它们是模型照着这块内容编出来的。 每一个都单独算一串数存进库,每一串数上都拴着同一张便条:「我来自块 c-64」。

最后一步,用户开口: 他打的是「64 号进终面了吗」。 这句话算出嵌入之后,比对的对象是库里那些编出来的问题,不是块本身—— 它跟①号问题几乎重合(都是问某号候选人到了哪一轮),当场命中。 系统顺着①号问题那张便条,取回的是块 c-64 的原文 「采购单(PO)已核准,候选人 c-64 进入终面。」,交给模型作答。 交出去的从头到尾没有那句编出来的问题。

这里有一条必须做对的细节

书里写得很重,用了「至关重要」:

每个问题都要在元数据里链回原始文本块这一点至关重要,因为后面交给模型的是原始文本块,不是这些编出来的问题。 这些问题只用来改善检索这一步。26

这跟第 04 章那条补丁是同一条规则的又一次出现: 造出来的东西只负责「被搜到」,原件负责「被读懂」。

一个方向相反的近亲,书里没提

这一招是给文档编问题。学界还有一个反过来的做法叫 HyDE: 用户提问之后,先让模型凭空编一篇「如果有答案,它大概长这样」的假文档, 再拿这篇假文档去检索27

书里这一招HyDE
什么时候做入库时,一次性做完提问时,每次都做
造什么给每块造几个问题给每个问题造一篇假答案
比对的双方问句 vs 问句假答案 vs 真文档
代价入库贵一次,查询不加钱每次查询都多一次模型调用,查询变慢

判断(我们的,不是书里的): 这两招解决的是同一个「形状不匹配」问题, 但成本落在完全不同的地方,而这决定了该选哪个: 文档相对稳定、查询量大 → 选书里这一招(贵一次,省无数次); 文档天天变、查询量小 → 选 HyDE(不必每次把整个向量库重算一遍)。 如果错,会错在: 向量库里那份供检索用的清单,行话叫索引; 如果你的文档块数极多(百万级),给每块编 5 个问题就意味着索引膨胀六倍, 存储和检索成本都要重算——那时候即便查询量大,也可能算不过来。 判据是:块数 × 6 之后,你的向量库还扛不扛得住。

6. 三招的共同点:全都在入库时做

这一节是这一章的落点。

先把主走查的五步并起来看一遍

① 原始的一块 「PO 已核准,候选人 c-64 进入终面。」

② 骗法一 → 贴标签 给它贴上「岗位 = 软件开发」
└─ 供应链那八千块从此没资格跟招聘类问题参赛

③ 骗法二 → 改写 入库前改成「采购单(PO)已核准,候选人 c-64 进入终面。」
└─ 缩写和全称都留着,两种问法都命中

④ 骗法三 → 编问题 让模型给这块编 5 个问题,其中两个是
「c-64 号候选人走到哪一轮了?」
「采购单核准之后,下一步是什么?」
└─ 每个问题各存一串数,各拴一张写着「我来自块 c-64」的便条

⑤ 用户开口 「64 号进终面了吗」→ 命中④里的第一个问题
└─ 顺着便条取回的是③那句改写后的原文,不是那个问题

图说:①到④全部发生在没人等着的时候;⑤那一刻系统只做了一次比对和一次取回,
没有多花任何一次模型调用。这正是下面那张表要说的事。

三招各自的账,摊开看

做在哪一侧用户提问时额外花多少
元数据过滤入库时打标签几乎不花,过滤反而更快
缩写替换 / 让块自解释入库时改写不花
假设性问题入库时生成不花

判断(我们的,不是书里的): 这个共性不是巧合,它是这本书隐含的整个立场: RAG 的质量是在入库时决定的,不是在查询时补救的。 查询时能做的事很有限(用户在等),而入库时你有的是时间和一次性的成本。 这也解释了为什么全书前两章、十九个配方,几乎全在讲入库。 如果错,会错在: 如果查询时的技术(改写用户的问题、多路查询、再排一次序) 能拿到比入库侧更大的收益,那这个立场就偏了。 现实中两侧都要做——但入库侧的收益是一次性投入、长期生效,查询侧是每次都付。

7. 作者的判断与证据

说法属于哪一类
语义相似 ≠ 相关机制上必然;抗氧化剂那个例子是构造的,不是实测
「这类问题在真实应用里很常见」作者的经验,没有数据
缩写替换写成「全称(缩写)」两种问法都能命中机制上成立,不需要证据
四条写作建议作者的经验清单,没有依据
「语义对齐问题」这个名字书里写「通常被称为」,但没给出处——我们也没查到公认来源
假设性问题能改善检索作者的做法,书里没有给任何效果数据

这一章通篇没有一个效果数字。 三招都写成了「这样做会更好」, 没有一处告诉你好多少。 唯一能引用的数字来自第 4 节末尾那条外部来源。

8. 边界与局限

  1. 没有讲缩写表从哪儿来。 书里的示例是手写的一张七条的表。 真实场景里一家公司有几百个内部缩写,谁来维护这张表?书里没说;
  2. 没有讲替换会不会误伤。 简单的文字替换会把碰巧长得一样的普通词也换掉 (比如把英文里的 TF 一律替换成 Transformer),书里没有提这个风险;
  3. 没有讲标签体系怎么设计。 「按你的场景决定」是对的,但没有任何方法论;
  4. 假设性问题会让索引膨胀好几倍,书里没提成本;
  5. 三招之间怎么组合、有没有冲突,书里没有讨论;
  6. 依然没有评估手段。 这是第 05 章同一个缺口——你做完这三招, 怎么知道确实变好了?书里从头到尾没有回答。

9. 可带走的

  1. 检索没做错,是「意思相近」本身会骗人——它有三种骗法;
  2. 骗法一:意思像但对这个用户没用。 医生问抗氧化剂,搬来一篇材料工程文献——字字相关,完全没用;
  3. 解法是先过滤再比相似度:给每块贴标签,把不该考虑的整片踢掉; 被踢掉的不是「排名低」,是「没资格参赛」;
  4. 元数据三步走:文档自带的 → 自己补的文件信息 → 让模型读正文挖出来的; 第三步最有价值(简历属于哪个岗位,PDF 里没有,正文里有);
  5. 让模型吐固定格式要用「结构化输出」:事先声明要哪几个字段;
  6. 骗法二:块脱离前后文自己看不懂。 PO 是采购单还是邮局?MJ 是谁?
  7. 缩写要替换成「全称(缩写)」两个都留——目的不是通顺, 是让缩写问法和全称问法都能命中;
  8. 把代词、模糊指代、含糊形容词都换成具体的东西(四条写作建议);
  9. 这一章的元问题:人不懂可以去别处补课,而模型只看得到搜回来的那几块—— 所有补救都是在入库时替它把课补好;
  10. 骗法三:用户提的是问句,资料是表格/代码/聊天记录,形状对不上;
  11. 解法是事先给每块编几个「用户可能会这么问」的问题,拿问句去配问句; 编出来的问题必须链回原始块——交给模型的永远是原件;
  12. 它有个方向相反的近亲叫 HyDE(提问时编一篇假答案去检索); 文档稳定、查询量大选前者;文档常变、查询量小选后者;
  13. 三招全都发生在入库时,查询时不加钱—— RAG 的质量是在入库时决定的,不是在查询时补救的;
  14. 书里这三招一个效果数字都没给;唯一可引的对照数据来自外部 (单招失败率降 35%,三招叠加降 67%)。

10. 原文地图

主题原书章原文位置
元数据能收窄搜索范围、相似 ≠ 相关Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:138(搜「Metadata helps us narrow down the search space in our vector database」) · text/05-ch02-chapter-2-data-preparation.txt:138(搜「Not every text chunk that shows high semantic similarity to the user」)
抗氧化剂:医生与工程师Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:142(搜「If you are a doctor, you are interested in the benefits of antioxidants」) · text/05-ch02-chapter-2-data-preparation.txt:146(搜「can be irrelevant or even wrong when we know the full context」) · text/05-ch02-chapter-2-data-preparation.txt:150(搜「there is one fact that makes them completely irrelevant」)
其他可用的过滤条件Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:152(搜「Other filter criteria could be the period the documents were published」)
元数据三步Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:35(搜「We can extract and generate metadata in two ways」) · text/05-ch02-chapter-2-data-preparation.txt:41(搜「Generate new metadata: Use LLMs to find metadata in the document」) · text/05-ch02-chapter-2-data-preparation.txt:57(搜「Common metadata fields include the author, creation date」)
简历按岗位打标签Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:43(搜「PDFs store metadata in XML format」) · text/05-ch02-chapter-2-data-preparation.txt:43(搜「the system can filter out non-developer resumes」)
作者字段是空的、结构化输出、系统消息Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:86(搜「name fields are empty」) · text/05-ch02-chapter-2-data-preparation.txt:88(搜「we use OpenAI」) · text/05-ch02-chapter-2-data-preparation.txt:90(搜「These instructions, known as the system message」)
块孤立看很难懂、PO 与 MJChapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:162(搜「difficult to understand when viewed in isolation」) · text/05-ch02-chapter-2-data-preparation.txt:166(搜「purchase order」) · text/05-ch02-chapter-2-data-preparation.txt:168(搜「a tutorial might refer to a」)
缩写替换写成「全称(缩写)」Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:178(搜「LSTM becomes Long Short-Term Memory (LSTM)」) · text/05-ch02-chapter-2-data-preparation.txt:178(搜「What is LSTM? vs. What is Long Short-Term Memory?」)
让模型改写到十岁小孩能懂Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:224(搜「a 10 years old school kid could understand it」)
模型只看得到搜回来的东西Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:249(搜「In an ideal world, text chunks would be easy to understand on their own」) · text/05-ch02-chapter-2-data-preparation.txt:251(搜「most documents require some background knowledge」) · text/05-ch02-chapter-2-data-preparation.txt:253(搜「the LLM only sees the information retrieved from the vector search」)
四条写作建议Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:255(搜「Adding Contextual Sentences」) · text/05-ch02-chapter-2-data-preparation.txt:257(搜「Avoiding Pronouns and Implicit References」) · text/05-ch02-chapter-2-data-preparation.txt:261(搜「Avoiding Ambiguous Words」)
形状不匹配与「语义对齐问题」Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:358(搜「the vector embeddings may not align perfectly」) · text/05-ch02-chapter-2-data-preparation.txt:358(搜「semantic alignment problem」)
把过程反过来、每块编 5 个问题Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:273(搜「address the mismatch between user questions and document content in the embedding space」) · text/05-ch02-chapter-2-data-preparation.txt:279(搜「In this recipe, we reverse the process」) · text/05-ch02-chapter-2-data-preparation.txt:283(搜「we create five questions per chunk」)
必须链回原始块Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:287(搜「Each question links to the original text chunk in the metadata」) · text/05-ch02-chapter-2-data-preparation.txt:287(搜「The hypothetical questions are used solely to enhance the retrieval step」)
用编出来的问题去检索Chapter 2. Data Preparationtext/05-ch02-chapter-2-data-preparation.txt:295(搜「Retrieve a list of hypothetical questions that are semantically similar」) · text/05-ch02-chapter-2-data-preparation.txt:362(搜「we bridge the gap between user queries and document content」)

Footnotes

  1. 出处:「Chapter 2. Data Preparation」第 138 段(text/05-ch02-chapter-2-data-preparation.txt:138,搜「Not every text chunk that shows high semantic similarity to the user」)与同段(text/05-ch02-chapter-2-data-preparation.txt:138,搜「Metadata helps us narrow down the search space in our vector database」)。 2

  2. 出处:「Chapter 2. Data Preparation」第 142 段(text/05-ch02-chapter-2-data-preparation.txt:142,搜「If you are a doctor, you are interested in the benefits of antioxidants」)。原书把这个例子画成了一张图,正文只给了两句判据。

  3. 出处:「Chapter 2. Data Preparation」第 146 段(text/05-ch02-chapter-2-data-preparation.txt:146,搜「can be irrelevant or even wrong when we know the full context」)。

  4. 出处:「Chapter 2. Data Preparation」第 150 段(text/05-ch02-chapter-2-data-preparation.txt:150,搜「there is one fact that makes them completely irrelevant」)。

  5. 出处:「Chapter 2. Data Preparation」第 152 段(text/05-ch02-chapter-2-data-preparation.txt:152,搜「Other filter criteria could be the period the documents were published」)。

  6. 出处:「Chapter 2. Data Preparation」第 35 段(text/05-ch02-chapter-2-data-preparation.txt:35,搜「We can extract and generate metadata in two ways」)与第 41 段(text/05-ch02-chapter-2-data-preparation.txt:41,搜「Generate new metadata: Use LLMs to find metadata in the document」)。原文把「抽取现成的」和「用模型生成的」并列为两种来源,再拆成三个步骤。

  7. 出处:「Chapter 2. Data Preparation」第 57 段(text/05-ch02-chapter-2-data-preparation.txt:57,搜「Common metadata fields include the author, creation date」)。原文提醒:不是每份文档都有全部这些字段。

  8. 出处:「Chapter 2. Data Preparation」第 73 段(text/05-ch02-chapter-2-data-preparation.txt:73,搜「page count, file size, file name」)。示例里补的是页数、文件大小、文件名、文件路径和抽出文字的长度。

  9. 出处:「Chapter 2. Data Preparation」第 86 段(text/05-ch02-chapter-2-data-preparation.txt:86,搜「name fields are empty」)。原文说:跑完上一步你会发现作者名那几个字段是空的,而这些名字通常就写在文档正文里,科技论文尤其如此。

  10. 出处:「Chapter 2. Data Preparation」第 43 段(text/05-ch02-chapter-2-data-preparation.txt:43,搜「PDFs store metadata in XML format」)与同段(text/05-ch02-chapter-2-data-preparation.txt:43,搜「the system can filter out non-developer resumes」)。

  11. 出处:「Chapter 2. Data Preparation」第 88 段(text/05-ch02-chapter-2-data-preparation.txt:88,搜「we use OpenAI」)。原文用的是 OpenAI 的结构化输出功能,配一个 Pydantic 模型声明字段。补充(不在书里,来自通用知识):Pydantic 是 Python 生态里最常用的数据校验库,声明字段和类型之后由它负责检查数据合不合规。

  12. 出处:「Chapter 2. Data Preparation」第 90 段(text/05-ch02-chapter-2-data-preparation.txt:90,搜「These instructions, known as the system message」)。

  13. 出处:「Chapter 2. Data Preparation」第 162 段(text/05-ch02-chapter-2-data-preparation.txt:162,搜「difficult to understand when viewed in isolation」)。这一节的问题陈述见第 158 段(text/05-ch02-chapter-2-data-preparation.txt:158,搜「make text chunks more self-explanatory by replacing domain-specific abbreviations」)。

  14. 出处:「Chapter 2. Data Preparation」第 166 段(text/05-ch02-chapter-2-data-preparation.txt:166,搜「purchase order」)与同段(text/05-ch02-chapter-2-data-preparation.txt:166,搜「MJ」)。原文说 PO 在供应链文档里是采购单,换个上下文可能是产品负责人或邮局;MJ 指的是迈克尔·乔丹。 2

  15. 出处:「Chapter 2. Data Preparation」第 168 段(text/05-ch02-chapter-2-data-preparation.txt:168,搜「a tutorial might refer to a」)。原文的解法是用多模态模型处理这类带大量截图的文档。

  16. 出处:「Chapter 2. Data Preparation」第 178 段(text/05-ch02-chapter-2-data-preparation.txt:178,搜「LSTM becomes Long Short-Term Memory (LSTM)」)。书里那张对照表里有 NLP、RNN、LSTM、GRU、TF、MHA、FFN 七条。

  17. 出处:「Chapter 2. Data Preparation」第 178 段(text/05-ch02-chapter-2-data-preparation.txt:178,搜「What is LSTM? vs. What is Long Short-Term Memory?」)。

  18. 出处:「Chapter 2. Data Preparation」第 205 段(text/05-ch02-chapter-2-data-preparation.txt:205,搜「Without a finance background and the accompanying graphs」)。

  19. 出处:「Chapter 2. Data Preparation」第 224 段(text/05-ch02-chapter-2-data-preparation.txt:224,搜「a 10 years old school kid could understand it」)。这句话出现在示例提示词里,原文还有拼写小错(get's),是抢先版未编辑的痕迹。

  20. 出处:「Chapter 2. Data Preparation」第 255 段(text/05-ch02-chapter-2-data-preparation.txt:255,搜「Adding Contextual Sentences」)、第 257 段(text/05-ch02-chapter-2-data-preparation.txt:257,搜「Avoiding Pronouns and Implicit References」)、第 259 段(text/05-ch02-chapter-2-data-preparation.txt:259,搜「Preserving Full Names of Entities」)与第 261 段(text/05-ch02-chapter-2-data-preparation.txt:261,搜「Avoiding Ambiguous Words」)。

  21. 出处:「Chapter 2. Data Preparation」第 249 段(text/05-ch02-chapter-2-data-preparation.txt:249,搜「In an ideal world, text chunks would be easy to understand on their own」)、第 251 段(text/05-ch02-chapter-2-data-preparation.txt:251,搜「most documents require some background knowledge」)与第 253 段(text/05-ch02-chapter-2-data-preparation.txt:253,搜「the LLM only sees the information retrieved from the vector search」)。书里在这一节的「另见」里还提到,与其逐条处理这些毛病,不如用第 05 章那种让模型来切的办法一次解决,只是扫描、分析、处理每一份文档的代价可能相当高(text/05-ch02-chapter-2-data-preparation.txt:267,搜「it can become quite costly to scan, analyze, and process every single document」)。

  22. 补充(不在书里):这套做法叫 Contextual Retrieval,由 Anthropic 于 2024 年 9 月 19 日公布。做法是在切块之后、算嵌入之前,先用模型给每一块生成一段专属的解释性上下文并拼在块前面。公布的评测结果是:仅用上下文化嵌入,检索失败率从 5.7% 降到 3.7%(相对下降 35%);再叠加上下文化的关键词检索降到 2.9%(下降 49%);全部技术加上重新排序降到 1.9%(下降 67%)。来源:Anthropic「Introducing Contextual Retrieval」https://www.anthropic.com/news/contextual-retrieval(查阅于 2026-08-25)。 2

  23. 出处:「Chapter 2. Data Preparation」第 358 段(text/05-ch02-chapter-2-data-preparation.txt:358,搜「the vector embeddings may not align perfectly」)与同段(text/05-ch02-chapter-2-data-preparation.txt:358,搜「semantic alignment problem」)。原文的措辞是「这个问题通常被称为语义对齐问题」,但没有给出处;我们也没有查到与之对应的公认标准术语,所以在正文里做了提醒。 2

  24. 出处:「Chapter 2. Data Preparation」第 279 段(text/05-ch02-chapter-2-data-preparation.txt:279,搜「In this recipe, we reverse the process」)。这一节的问题陈述见第 273 段(text/05-ch02-chapter-2-data-preparation.txt:273,搜「address the mismatch between user questions and document content in the embedding space」)。

  25. 出处:「Chapter 2. Data Preparation」第 283 段(text/05-ch02-chapter-2-data-preparation.txt:283,搜「we create five questions per chunk」)。书里的示例语料是两个学生讨论制造业里 AI 用途的一段聊天记录(text/05-ch02-chapter-2-data-preparation.txt:303,搜「a sample chat history between two students」),生成时同样用了结构化输出来保证拿回一个字符串列表(text/05-ch02-chapter-2-data-preparation.txt:305,搜「we use the structured output functionality」)。

  26. 出处:「Chapter 2. Data Preparation」第 287 段(text/05-ch02-chapter-2-data-preparation.txt:287,搜「Each question links to the original text chunk in the metadata」)与同段(text/05-ch02-chapter-2-data-preparation.txt:287,搜「The hypothetical questions are used solely to enhance the retrieval step」)。检索时的两步见第 295 段(text/05-ch02-chapter-2-data-preparation.txt:295,搜「Retrieve a list of hypothetical questions that are semantically similar」)。

  27. 补充(不在书里):HyDE 出自 2022 年 12 月 20 日提交的论文,作者为 Luyu Gao、Xueguang Ma、Jimmy Lin、Jamie Callan。做法是先让一个会听指令的模型针对用户的问题「生成一篇假想文档」,再把这篇假文档变成一串数去检索。论文点出一件反直觉的事:假文档里编错的细节,在「变成一串数」这一步会被大量抹掉——因为那一步只留得下一个几百上千维的概括,装不下细枝末节。论文管这个筛掉细节的效果叫「稠密瓶颈」。来源:《Precise Zero-Shot Dense Retrieval without Relevance Labels》https://arxiv.org/abs/2212.10496(查阅于 2026-08-25)。