跳到主要内容

检索不准时的两个杠杆 — 改写问题,换掉被嵌入的对象

这一章讲三件事: 向量检索为什么会「该找到的找不到」; 问题侧的修法(step-back 改写)和文档侧的修法(parent-document 策略)各自怎么转; 两招叠装后的完整流水线怎么走。拿不准的生词全部当场解释。

1. 先看病灶:两边说的不是一种话

第 03 章的爱因斯坦走查里,检索是成功的。但书里开章先讲失败时的机理: 用户问题的嵌入,和藏着答案的文档的嵌入,经常对不上—— 用词不同、粒度不同、上下文不同。结果是对回答问题至关重要的高相关文档, 在向量空间(所有这些数串共同组成的一张假想大图)里离问题很远,被漏掉了1

用户的问法 ──嵌入──→ ● ○ —— 藏着答案的文档的嵌入
两者离得远 → 检索漏掉

图说:嵌入只度量「字面上像不像」,不度量「能不能回答」。距离就是在这断的。

修法有四个杠杆,书里点名了两个细讲,另两个只归档2:

杠杆动哪一侧本书处理
查询改写(step-back、HyDE)问题侧本章细讲
换嵌入对象(parent-document、假设问题)文档侧本章细讲
微调嵌入模型 / 二次精排 / 按附带信息过滤两侧只点名,见下

书里只点名、不展开的另两个杠杆,各值一句解释:重排——先用便宜的办法粗查一批,再用更重的模型精排一遍。

元数据——资料的作者、日期、标签这类附带信息;按它先过滤,能缩小检索范围。

2. 杠杆一:step-back 改写——把问题抬高一档

解决什么问题

用户的问题常常过于具体:带了时间段、带了限定词。 而文档写的是一般性事实。越具体,嵌入越难对上。

怎么做

step-back prompting(退一步提示)出自 2023 年的论文(Zheng 等)3: 让 LLM 把具体问题改写成更概括的「退一步问题」。 书里引论文原例:「Thierry Audel 在 2007 到 2008 年效力哪支球队?」 退一步变成「Thierry Audel 职业生涯效力过哪些球队?」—— 概括版的嵌入更容易和讲他生平的文档对上4

改写用一个带示例的系统提示(system prompt,给模型定规矩的开场指令)驱动。

提示工程(琢磨怎么给模型下指令的活儿)里,这种「在指令后附两三个输入输出示例」的写法叫 few-shot。

少样本:给两三个示例;一个示例都不给、纯靠指令的叫 zero-shot——零样本:全靠模型自己。 示例能锚住输出格式与改写力度,书里明确说作者们选了 few-shot5

为什么有效

概括化等于撒一张更大的网:退一步问题的嵌入覆盖面宽, 命中的文档池变大,原问题的答案大概率在池子里。 代价也在这里——池子大了,不相关的也进来了,所以它几乎总是和下面的 parent-document 策略配套使用,由后者负责收口。

3. 杠杆二:parent-document 策略——小块匹配,大块喂模型

解决什么问题

第 03 章说过:块切小了匹配准,但块太小,交给 LLM 时上下文不够, 答案可能正好被切在两块之间。匹配要小块,喂模型要大块——两个需求打架。

怎么做

把文档分两层存进图:父文档(大块)和子块(小块), 子块通过 HAS_CHILD 关系挂在父文档下面;嵌入只算子块的6。 检索时三步:

① 向量检索在子块里找最像的
② 沿 HAS_CHILD 关系上卷到它们各自的父文档,去重
③ 把父文档(不是子块!)交给 LLM[^7]

这就是它的全名「parent document retriever(父文档检索器)」的含义: 按子块匹配、按父文档交付。上一层再往上是 PDF 节点(HAS_PARENT 关系), 整份文档从根到叶是一棵三层树7

为什么有效

它同时吃到两个世界的好处:子块嵌入聚焦、匹配准; 父文档完整、上下文够。而且去重有个讲究——书里的实现一次取 k×4 个子块, 而不是 k 个:因为同一个父文档下的好几个子块可能同时命中, 取少了,去重后剩下的父文档可能凑不够 k 份;k×4 是个安全缓冲8

同一思路还有个变体:假设问题策略——不嵌入文档本身, 而是先用 LLM 生成「这份文档能回答哪些问题」,把这些问题的嵌入存起来 (挂 HAS_QUESTION 关系)。用户问题来了,和「问题」比和「文档」比, 措辞上天然更对得齐9。书里把它归档为思路介绍,实战做的是 parent-document。

4. 主走查:两招叠装,爱因斯坦的衬衫专利

书里的实战把两个杠杆串成一条流水线,还是用那篇爱因斯坦论文。 先看建库:全文先按章节结构切(正则匹配编号标题行)得到 9 节; 数一下各节的 token(语言模型计量文字的单位,约等于半个到一个词): 154、254、4186、570、2703、1441、194、600——第三节超 4000, 必须再切;于是每节再按 2000 字符切成父文档,父文档再按 500 字符/重叠 20 切成子块,子块算嵌入入库10

然后是查询侧。测试问题11:

第 1 步 用户问:"When was Einstein granted the patent for his
blouse design?"(爱因斯坦的衬衫设计专利是何时授予的?)
——一个带具体宾语的细问题

第 2 步 step-back 改写,LLM 返回:
"What are some notable achievements in Einstein's life?"
(爱因斯坦一生有哪些值得一提的成就?)——问题被抬高一档

第 3 步 用改写后的问题算嵌入,向量检索取 4×4=16 个子块,
沿 HAS_CHILD 上卷去重,返回前 4 份父文档[^13]

第 4 步 注意:生成答案时用的是【原始问题】+ 这 4 份父文档
——检索用概括版(撒网),作答用原始版(对准)[^14]

第 5 步 LLM 输出:"Einstein was granted the patent for his blouse
design on October 27, 1936."[^15]

第 4 步是整章最容易被读漏的机制:改写后的问题只用于检索; 如果连作答也用概括版问题,答案就会偏成「成就列表」而不是「衬衫专利的日期」。

5. 作者的判断与证据

  • 改写和换嵌入对象是正交的——书里的实战把两者叠在一条流水线, 隐含判断是「问题侧的网撒得再大,文档侧交付的上下文不够照样答不好」;
  • 书里把假设问题策略和 parent-document 并列为「换嵌入对象」的两条路9, 但只给后者写了实现,前者停在思路层面;
  • step-back 的效果证据来自它引用的原论文(Zheng 等,2023)3, 本书自己没有做消融实验(去掉 step-back 对比效果是书里的练习题,不是书里给的数据)12

判断(我们的,不是书里的): 这一章的两个杠杆本质上都在调「网眼大小」: step-back 把网撒大,parent-document 把交付收拢。凡是「召回不够」的检索系统, 先看网眼——问题侧太窄就改写,文档侧太碎就上卷;反过来「杂质太多」, 就收紧 step-back 或加第 03 章的混合检索硬过滤。先调这对旋钮, 再考虑换嵌入模型这种重活。 如果错,会错在: 如果失败根因是嵌入模型本身不懂这个领域(专业材料), 调网眼收益有限,该走书里归档的「微调嵌入模型」那条重路。

6. 边界与局限

  • step-back 不是万能药:有些问题概括化之后语义漂移(「2007-2008 效力哪队」 概括成「职业生涯效力过哪些队」会捞回太多生涯材料), 书里没有给「什么时候不该退一步」的判据;
  • k×4 是经验值,不是理论推导;换一类数据可能要调;
  • 父文档交付换来的代价是 prompt 变长:每个父文档 2000 字符,取 4 份就是 约 8000 字符进上下文——成本与上下文窗口(模型一次能读进来的字数上限)压力书里没有讨论;
  • 微调嵌入模型、重排、元数据过滤三个杠杆书里明确不展开2, 想深入要另找材料(补充(不在书里,来自通用知识): 重排在生产 RAG 里几乎必配,先粗查一批、再用更重的模型精排一遍);
  • Cypher(图数据库的查询语言,本章建图与检索的载体)在本书首次出场, 它的来龙去脉与写法规则在第 12 章专讲。

7. 可带走的

  1. 检索漏,先怀疑问题嵌入与文档嵌入措辞错位,不是模型坏了;
  2. step-back = 把具体问题概括化去检索,few-shot 示例锚住改写力度;
  3. parent-document = 子块匹配、父文档交付,两层各取所长;
  4. 上卷去重要留缓冲(k×4),否则同名父文档互相挤占名额;
  5. 检索用改写后的问题,作答用原始问题——两头各用各的,别混;
  6. 建库先按文档自身结构切(章节/条款),再按字数切,顺序别反;
  7. 「召回不够」和「杂质太多」是两对相反的故障,对应两个相反的调法。

8. 原文地图

主题原书章原文位置
嵌入错位病灶3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:25(搜「might not always align」)
HyDE 与 step-back 出处3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:36(搜「hypothetical document retriever」)
Estella Leopold 例3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:63(搜「Estella Leopold」)
Thierry Audel 改写例3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:198(搜「Which team did Thierry」)
zero-shot / few-shot3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:245(搜「zero-shot prompting」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:249(搜「few-shot prompting」)
改写实测输出3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:276(搜「career history」)
假设问题策略3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:120(搜「embed the questions」)
长文档平均糊掉3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:139(搜「blur distinct ideas」)
其他策略归档3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:147(搜「Finetuning the text-embedding」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:154(搜「Reranking strategies」)
父/子文档图结构3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:301(搜「PDF node」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:326(搜「2,000-character」)
按章节结构切、9 节3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:334(搜「structural elements」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:363(搜「Number of sections」)
token 数与第三节超限3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:387(搜「154, 254」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:390(搜「over 4,000 tokens」)
k×4 与安全缓冲3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:512(搜「k * 4」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:519(搜「safety buffer」)
主走查(衬衫专利)3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:589(搜「blouse」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:590(搜「notable achievements」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:591(搜「October」)
检索用改写、作答用原始3 Advanced vector retrieval strategiestext/12-ch03-3-advanced-vector-retrieval-strategies.txt:578(搜「parent_retrieval(stepback_prompt)」) · text/12-ch03-3-advanced-vector-retrieval-strategies.txt:579(搜「generate_answer(question」)

Footnotes

  1. 出处:「3 Advanced vector retrieval strategies」第 25 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:25,搜「might not always align」)。原文:用户查询生成的嵌入可能因术语或上下文差异,与含关键信息的文档嵌入对不齐,导致高度相关的文档被忽略。

  2. 出处:「3 Advanced vector retrieval strategies」第 147 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:147,搜「Finetuning the text-embedding」)、第 154 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:154,搜「Reranking strategies」)与第 174 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:174,搜「beyond the scope」)。框注还列了元数据过滤与混合检索;书里声明除混合检索(第 03 章已讲)外,详细实现超出本书范围。 2

  3. 出处:「3 Advanced vector retrieval strategies」第 37 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:37,搜「Zheng et al」)。书末参考文献:《Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models》,arXiv:2310.06117(出处:「references」第 29 段,text/22-fm-references.txt:29,搜「Take a Step Back」)。 2

  4. 出处:「3 Advanced vector retrieval strategies」第 198 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:198,搜「Which team did Thierry」)。原文:具体问题「2007 到 2008 效力哪支球队」被拓宽成「职业生涯效力过哪些球队」,以提升向量检索精度。

  5. 出处:「3 Advanced vector retrieval strategies」第 245 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:245,搜「zero-shot prompting」)与第 249 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:249,搜「few-shot prompting」)。原文:zero-shot 只靠指令;few-shot 在提示里附少量示例(典型两到五个),用具体实例锚住任务,提升输出质量与稳定性。

  6. 出处:「3 Advanced vector retrieval strategies」第 328 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:328,搜「500-character chunk」)。原文:父文档节点链接子文档节点,每个子节点带 500 字符文本块与用于检索的嵌入向量;父文档 2000 字符上限见第 326 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:326,搜「2,000-character」)。

  7. 出处:「3 Advanced vector retrieval strategies」第 301 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:301,搜「PDF node」)。原文:PDF 节点在顶层,经 HAS_PARENT 连父文档节点,再经 HAS_CHILD 连子文档节点。

  8. 出处:「3 Advanced vector retrieval strategies」第 512 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:512,搜「k * 4」)与第 519 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:519,搜「safety buffer」)。原文:多个相似子块可能同属一个父文档,先取更大的 k×4 子块池,有效形成安全缓冲,最后再压回 k。

  9. 出处:「3 Advanced vector retrieval strategies」第 120 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:120,搜「embed the questions」)。原文:与其嵌入原始文档,不如嵌入「这份文档能回答的问题」;可用 LLM 生成,也可用聊天机器人的对话历史。 2

  10. 出处:「3 Advanced vector retrieval strategies」第 334 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:334,搜「structural elements」)、第 363 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:363,搜「Number of sections」)、第 387 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:387,搜「154, 254」)与第 390 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:390,搜「over 4,000 tokens」)。token 计数用 OpenAI 的 tiktoken 包;子块 500 字符/重叠 20 见第 442 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:442,搜「chunk_text(chunk, 500, 20)」)。

  11. 出处:「3 Advanced vector retrieval strategies」第 589 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:589,搜「blouse」)。

  12. 出处:「3 Advanced vector retrieval strategies」第 594 段(text/12-ch03-3-advanced-vector-retrieval-strategies.txt:594,搜「Evaluate how well」)。练习 3.3:让读者去掉 step-back 步骤对比效果——对比由读者自己做,书里没给数据。