<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Precision-Recall on 云喵盒子</title><link>https://zyfsir.github.io/tags/precision-recall/</link><description>Recent content in Precision-Recall on 云喵盒子</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 01 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://zyfsir.github.io/tags/precision-recall/index.xml" rel="self" type="application/rss+xml"/><item><title>生产环境 RAG 的七步流水线：PR 矛盾没被解决，只是被管理了</title><link>https://zyfsir.github.io/post/rag-seven-step-pipeline/</link><pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate><guid>https://zyfsir.github.io/post/rag-seven-step-pipeline/</guid><description>&lt;p&gt;在上一篇（《SOAR 的记忆蓝图》）里，我拆解了检索式记忆系统的 Precision-Recall 矛盾：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;提高召回率&lt;/strong&gt; → 必然引入噪声 → LLM 被无关信息干扰&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提高精度&lt;/strong&gt; → 降低召回率 → 遗漏相关信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;加 Reranker/CRAG&lt;/strong&gt; → 延迟和复杂度上升 → 本身也会失败&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这不是&amp;quot;优化几个参数就能解决&amp;quot;的工程问题，这是高维空间的几何学、Transformer 的注意力机制、以及 LLM 的噪声敏感性共同决定的&lt;strong&gt;结构性约束&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;但有一个问题还没回答：如果这个矛盾没法解决，那在实际干活的人是怎么做的？&lt;/p&gt;
&lt;p&gt;答案是：&lt;strong&gt;他们不解决矛盾，他们管理矛盾。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;经过 2023-2026 年的快速迭代，工业界已经收敛到一个标准的&amp;quot;七步流水线&amp;quot;。每一步都在做不同的权衡，每一步都承认矛盾没有被消除。但这个管道叠加起来，把 PR 矛盾压到了一个可接受的范围。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一步查询变换query-transformation"&gt;&lt;a href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e6%9f%a5%e8%af%a2%e5%8f%98%e6%8d%a2query-transformation" class="header-anchor"&gt;&lt;/a&gt;第一步：查询变换（Query Transformation）
&lt;/h2&gt;&lt;p&gt;原始的用户查询很少适合直接检索。&lt;/p&gt;
&lt;p&gt;用户说&amp;quot;帮我看看那个张三上次提到的项目进度&amp;quot;，直接拿去向量检索，八成找不到对应的文档。需要先把查询转换成更适合检索的形式。&lt;/p&gt;
&lt;h3 id="常用方案"&gt;&lt;a href="#%e5%b8%b8%e7%94%a8%e6%96%b9%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;常用方案
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;方法&lt;/th&gt;
 &lt;th style="text-align: left"&gt;做法&lt;/th&gt;
 &lt;th style="text-align: left"&gt;效果&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;strong&gt;Multi-Query&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;用 LLM 把一个问题改写为 3-5 个不同角度的检索词&lt;/td&gt;
 &lt;td style="text-align: left"&gt;增加召回率，减少遗漏&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;strong&gt;HyDE&lt;/strong&gt; (Gao, 2022)&lt;/td&gt;
 &lt;td style="text-align: left"&gt;先生成一个&amp;quot;假设的理想文档&amp;quot;，用它的嵌入去检索&lt;/td&gt;
 &lt;td style="text-align: left"&gt;对需要精确匹配的场景效果好&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;strong&gt;Step-back Prompting&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;先生成一个更抽象的宽泛问题，从宽到窄检索&lt;/td&gt;
 &lt;td style="text-align: left"&gt;适合需要先理解上下文再找细节的场景&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;strong&gt;查询分解&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;把复杂问题拆成多个子问题，分别检索&lt;/td&gt;
 &lt;td style="text-align: left"&gt;适合多跳问题&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="这一步的权衡"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;查询变换提高了召回率（覆盖了查询的不同侧面），但代价是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;可能偏离原始意图&lt;/strong&gt;——改写后的查询抓住了相关的 false positive，漏掉了真正的目标&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 调用成本&lt;/strong&gt;——每次查询变换都多了一次 LLM 调用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;延迟增加&lt;/strong&gt;——Multi-Query 让一次检索变成 3-5 次&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第一层应对：用算力换召回率。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第二步元数据预过滤metadata-pre-filtering"&gt;&lt;a href="#%e7%ac%ac%e4%ba%8c%e6%ad%a5%e5%85%83%e6%95%b0%e6%8d%ae%e9%a2%84%e8%bf%87%e6%bb%a4metadata-pre-filtering" class="header-anchor"&gt;&lt;/a&gt;第二步：元数据预过滤（Metadata Pre-filtering）
&lt;/h2&gt;&lt;p&gt;纯向量检索在生产环境中已经没人用了。&lt;/p&gt;
&lt;p&gt;你的知识库有各种属性——时间范围、文档来源、领域、权限级别。如果不在向量检索之前用这些属性做预过滤，你的向量搜索就会在一个巨大的、大部分不相关的空间里找相似度。&lt;/p&gt;
&lt;p&gt;Pinecone、Weaviate、Qdrant 的生产指南里有一条共识：&lt;strong&gt;先过元数据，再过向量。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="典型实现"&gt;&lt;a href="#%e5%85%b8%e5%9e%8b%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;典型实现
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;查询: &amp;#34;2026年Q1的项目报告&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;过滤: date &amp;gt;= 2026-01-01 AND date &amp;lt;= 2026-03-31
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; AND type = &amp;#34;project_report&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;向量检索: 在过滤后的子集里做 top-k
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="这一步的权衡-1"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1-1" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;预过滤大幅提高精度（把搜索空间缩小到真正相关的子集），但代价是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;如果过滤条件太激进，召回率会骤降&lt;/strong&gt;——你过滤掉了你以为是无关、但实际上相关的内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;预过滤 vs 后过滤的永恒争议&lt;/strong&gt;：先过滤再向量搜索（丢失潜在匹配）vs 先向量搜索再过滤（浪费算力在不相关的结果上）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;两个过滤器之间的&lt;/strong&gt;：元数据过滤掉的文档，向量搜索不会看到&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第二层应对：用先验知识减少搜索空间。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第三步混合检索--rrfhybrid-search--reciprocal-rank-fusion"&gt;&lt;a href="#%e7%ac%ac%e4%b8%89%e6%ad%a5%e6%b7%b7%e5%90%88%e6%a3%80%e7%b4%a2--rrfhybrid-search--reciprocal-rank-fusion" class="header-anchor"&gt;&lt;/a&gt;第三步：混合检索 + RRF（Hybrid Search + Reciprocal Rank Fusion）
&lt;/h2&gt;&lt;p&gt;纯稠密检索（Dense Retrieval）和纯稀疏检索（BM25）各有缺陷：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;检索方式&lt;/th&gt;
 &lt;th style="text-align: left"&gt;强项&lt;/th&gt;
 &lt;th style="text-align: left"&gt;弱项&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;稠密检索（Embedding）&lt;/td&gt;
 &lt;td style="text-align: left"&gt;语义匹配&lt;/td&gt;
 &lt;td style="text-align: left"&gt;丢失精确关键词匹配，受嵌入质量影响&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;稀疏检索（BM25）&lt;/td&gt;
 &lt;td style="text-align: left"&gt;精确关键词匹配&lt;/td&gt;
 &lt;td style="text-align: left"&gt;无法处理同义、近义表达&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;工业界的答案是：&lt;strong&gt;两个都做，然后把结果融合。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="reciprocal-rank-fusionrrf"&gt;&lt;a href="#reciprocal-rank-fusionrrf" class="header-anchor"&gt;&lt;/a&gt;Reciprocal Rank Fusion（RRF）
&lt;/h3&gt;&lt;p&gt;RRF 的公式极其简单：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;score(d) = Σ 1 / (k + rank(d))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对每个文档，取它在两种检索方式中的排名，加起来算一个综合分数。k 是一个平滑常数，通常取 60。&lt;/p&gt;
&lt;h3 id="这一步的权衡-2"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1-2" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;混合检索在召回率上有明显的提升（5-15% 的 recall@10 改善），但代价是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;两个索引都要维护&lt;/strong&gt;——稠密索引 + 稀疏索引，存储翻倍&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RRF 权重难调&lt;/strong&gt;——k 值、稠密 vs 稀疏的权重比例，对不同的领域和查询类型有不同的最优值&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;两个引擎都可能出问题&lt;/strong&gt;——一个引擎的失败结果会通过 RRF 污染最终排名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第三层应对：用多个正交的检索信号互相补充。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第四步小-chunk-检索small-chunk-retrieval"&gt;&lt;a href="#%e7%ac%ac%e5%9b%9b%e6%ad%a5%e5%b0%8f-chunk-%e6%a3%80%e7%b4%a2small-chunk-retrieval" class="header-anchor"&gt;&lt;/a&gt;第四步：小 Chunk 检索（Small Chunk Retrieval）
&lt;/h2&gt;&lt;p&gt;这是整个流水线里最微妙的一步。&lt;/p&gt;
&lt;p&gt;你面临一个根本性的矛盾：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;Chunk 大小&lt;/th&gt;
 &lt;th style="text-align: left"&gt;嵌入精度&lt;/th&gt;
 &lt;th style="text-align: left"&gt;上下文完整性&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;小（~200 tokens）&lt;/td&gt;
 &lt;td style="text-align: left"&gt;高——每段聚焦一个主题，嵌入向量干净&lt;/td&gt;
 &lt;td style="text-align: left"&gt;低——切碎了语义边界&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;大（~1000 tokens）&lt;/td&gt;
 &lt;td style="text-align: left"&gt;低——一段包含多个主题，嵌入向量的平均化稀释了语义&lt;/td&gt;
 &lt;td style="text-align: left"&gt;高——保留了上下文&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Anyscale 在 2023 年做了一个有影响力的实验：把 chunk_size 从 100 逐步增加到 900，观察检索分数和生成质量的变化。&lt;/p&gt;
&lt;p&gt;结果是两条方向相反的曲线：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;检索分数单调递增&lt;/strong&gt;——更大的 chunk 更容易被命中（里面有更多关键词）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成质量先升后降&lt;/strong&gt;——在 300-500 tokens 达到峰值，之后更多的上下文开始引入噪声&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="工业界的共识"&gt;&lt;a href="#%e5%b7%a5%e4%b8%9a%e7%95%8c%e7%9a%84%e5%85%b1%e8%af%86" class="header-anchor"&gt;&lt;/a&gt;工业界的共识
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;小 chunk 用于检索，大 chunk 用于阅读。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;具体来说：嵌入和检索用 256-512 tokens 的小 chunk（保证精度），检索到之后把整个 parent document 或相邻 chunk 一起拉上来送给 LLM。&lt;/p&gt;
&lt;p&gt;这被称为 &lt;strong&gt;&amp;ldquo;small-to-retrieve, big-to-read&amp;rdquo;&lt;/strong&gt; 模式。&lt;/p&gt;
&lt;h3 id="这一步的权衡-3"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1-3" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;小 chunk 让检索精度大幅提升，但引入了一个新的复杂度：你需要额外维护 chunk ↔ parent 的映射关系，且 chunk 边界的切割永远会破坏一些语义边界。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第四层应对：把&amp;quot;检索&amp;quot;和&amp;quot;阅读&amp;quot;解耦，让它们用不同的粒度。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第五步上下文展开context-expansion"&gt;&lt;a href="#%e7%ac%ac%e4%ba%94%e6%ad%a5%e4%b8%8a%e4%b8%8b%e6%96%87%e5%b1%95%e5%bc%80context-expansion" class="header-anchor"&gt;&lt;/a&gt;第五步：上下文展开（Context Expansion）
&lt;/h2&gt;&lt;p&gt;第四步检索到的是小 chunk。但单独把小 chunk 扔给 LLM 是不够的——它只看到了切片，看不到上下文。&lt;/p&gt;
&lt;p&gt;上下文展开的做法是：&lt;strong&gt;拿到命中的小 chunk 后，把它的邻居 chunk 或 parent 文档一起带上来。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="实现方式"&gt;&lt;a href="#%e5%ae%9e%e7%8e%b0%e6%96%b9%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;实现方式
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SentenceWindowRetrieval&lt;/strong&gt;：命中一个句子，拉它前后 N 个句子作为上下文窗口&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ParentDocumentRetriever&lt;/strong&gt;：命中一个子 chunk，拉对应的父文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sliding Window&lt;/strong&gt;：把 chunk 边界滑动一下，重新拼接上下文&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="这一步的权衡-4"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1-4" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;展开把精度↔完整性的天平往回拉了拉——你放弃了部分精度，换回了上下文。但展开范围越大，你重新引入了多少噪声就越不可控：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chunk 精度: 高
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;展开后: 上下文完整了，但噪声回来了
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第五层应对：用&amp;quot;检索精度换阅读完整性&amp;quot;.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第六步重排序re-ranking"&gt;&lt;a href="#%e7%ac%ac%e5%85%ad%e6%ad%a5%e9%87%8d%e6%8e%92%e5%ba%8fre-ranking" class="header-anchor"&gt;&lt;/a&gt;第六步：重排序（Re-ranking）
&lt;/h2&gt;&lt;p&gt;前五步产出的结果是一堆&amp;quot;roughly 相关&amp;quot;的候选。它们之间的相关性差异很小，而向量相似度在这个阶段已经丧失了分辨力。&lt;/p&gt;
&lt;p&gt;Reranker（通常是一个交叉编码器）把 query 和每个候选文档配对，算一个精确的相关性分数。&lt;/p&gt;
&lt;h3 id="效果"&gt;&lt;a href="#%e6%95%88%e6%9e%9c" class="header-anchor"&gt;&lt;/a&gt;效果
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;方案&lt;/th&gt;
 &lt;th style="text-align: left"&gt;精度提升&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;不加 Reranker&lt;/td&gt;
 &lt;td style="text-align: left"&gt;基线&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;加 Cross-encoder Reranker&lt;/td&gt;
 &lt;td style="text-align: left"&gt;+5-15pp nDCG（在 BEIR 基准上）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Cohere Rerank、BGE-Reranker 是生产中最常用的选择。&lt;/p&gt;
&lt;h3 id="这一步的权衡-5"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1-5" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;Reranker 是目前最有效的精度提升手段，但它有一个你不能忽视的限制：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;它不能挽救没有被前面步骤命中到的文档。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Reranker 做的是&amp;quot;从候选里挑出最相关的&amp;quot;，候选名单在上一步就已经定了。如果前面六步都没有命中那个真正相关的文档，Reranker 也帮不了你。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Reranker 提高精度，召回率天花板由前序步骤设定。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;另外，交叉编码器比双编码器慢 2-5x。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第六层应对：用更多的算力（交叉编码）换取精度，但承认召回率的天花板已经定了。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第七步llm-生成"&gt;&lt;a href="#%e7%ac%ac%e4%b8%83%e6%ad%a5llm-%e7%94%9f%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;第七步：LLM 生成
&lt;/h2&gt;&lt;p&gt;最后一步，把前六步精挑细选出来的上下文送给 LLM，让它生成答案。&lt;/p&gt;
&lt;p&gt;这一步本身也能做一些事情来管理 PR 矛盾：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;系统提示约束&lt;/strong&gt;：明确告诉 LLM&amp;quot;如果检索到的内容不足以回答，请说不知道&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;引用锚定（Citation Anchoring）&lt;/strong&gt;：要求 LLM 在回答的每个关键事实后面注明来源 chunk&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;置信度声明&lt;/strong&gt;：如果模型的回答基于不充分的检索结果，要求它声明不确定性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="这一步的权衡-6"&gt;&lt;a href="#%e8%bf%99%e4%b8%80%e6%ad%a5%e7%9a%84%e6%9d%83%e8%a1%a1-6" class="header-anchor"&gt;&lt;/a&gt;这一步的权衡
&lt;/h3&gt;&lt;p&gt;这一步的约束越严格，精度越高（更少幻觉），但用户可能得到更多&amp;quot;我不知道&amp;quot;的回复——这是用&lt;strong&gt;用户满意度换精度&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是 PR 矛盾的第七层应对：用生成时的约束来兜底。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="全景七步的得失"&gt;&lt;a href="#%e5%85%a8%e6%99%af%e4%b8%83%e6%ad%a5%e7%9a%84%e5%be%97%e5%a4%b1" class="header-anchor"&gt;&lt;/a&gt;全景：七步的得失
&lt;/h2&gt;&lt;p&gt;把七步串起来，每一层的权衡一目了然：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;步骤&lt;/th&gt;
 &lt;th style="text-align: left"&gt;主要 tradeoff&lt;/th&gt;
 &lt;th style="text-align: left"&gt;状态&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;查询变换&lt;/td&gt;
 &lt;td style="text-align: left"&gt;召回率 ↑ / 意图偏离风险 ↑&lt;/td&gt;
 &lt;td style="text-align: left"&gt;生产标配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;元数据过滤&lt;/td&gt;
 &lt;td style="text-align: left"&gt;精度 ↑ / 过滤过头则召回率骤降&lt;/td&gt;
 &lt;td style="text-align: left"&gt;生产标配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;混合检索 + RRF&lt;/td&gt;
 &lt;td style="text-align: left"&gt;召回率 ↑ / 维护成本 ↑ / 权重难调&lt;/td&gt;
 &lt;td style="text-align: left"&gt;生产标配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;小 chunk 检索&lt;/td&gt;
 &lt;td style="text-align: left"&gt;精度 ↑ / 上下文完整性 ↓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;生产标配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;上下文展开&lt;/td&gt;
 &lt;td style="text-align: left"&gt;完整性 ↑ / 噪声回归&lt;/td&gt;
 &lt;td style="text-align: left"&gt;生产标配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;重排序&lt;/td&gt;
 &lt;td style="text-align: left"&gt;精度 ↑ / 延迟 ↑ / 召回率天花板已定&lt;/td&gt;
 &lt;td style="text-align: left"&gt;生产标配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;LLM 生成约束&lt;/td&gt;
 &lt;td style="text-align: left"&gt;精度 ↑ / 用户满意度 ↓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;按需采用&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;每一个步骤都引入了一个新的 tradeoff，下一个步骤又来部分弥补这个 tradeoff。整个流水线不是在解决问题，而是在不断转移问题。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="局限七步之后矛盾仍在"&gt;&lt;a href="#%e5%b1%80%e9%99%90%e4%b8%83%e6%ad%a5%e4%b9%8b%e5%90%8e%e7%9f%9b%e7%9b%be%e4%bb%8d%e5%9c%a8" class="header-anchor"&gt;&lt;/a&gt;局限：七步之后，矛盾仍在
&lt;/h2&gt;&lt;p&gt;必须坦诚地说：即使走了七步，PR 矛盾也没有被消灭。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Query 理解是根本瓶颈&lt;/strong&gt;——如果你的查询本身就是模糊的，整个管道的上限就定死了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chunk 边界永远在丢失信息&lt;/strong&gt;——无论切多小，信息的连续性都会在切割点中断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;递归检索没有好的停止条件&lt;/strong&gt;——搜了一次觉得不够，再搜一次，什么时候该停？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新鲜度检测没人做好&lt;/strong&gt;——系统无法可靠判断检索到的信息是否已经过时&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;工业界的七步流水线是一个&amp;quot;足够好&amp;quot;的方案，不是一个&amp;quot;解决了问题&amp;quot;的方案。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="结论管理矛盾而不是解决矛盾"&gt;&lt;a href="#%e7%bb%93%e8%ae%ba%e7%ae%a1%e7%90%86%e7%9f%9b%e7%9b%be%e8%80%8c%e4%b8%8d%e6%98%af%e8%a7%a3%e5%86%b3%e7%9f%9b%e7%9b%be" class="header-anchor"&gt;&lt;/a&gt;结论：管理矛盾，而不是解决矛盾
&lt;/h2&gt;&lt;p&gt;Precision-Recall 矛盾不是一个 bug，是一个 feature——它是检索式记忆系统在数学层面的固有属性。你不可能消除它，就像不可能消除重力。&lt;/p&gt;
&lt;p&gt;但你可以在重力存在的情况下建房子。七步流水线就是那个房子。&lt;/p&gt;
&lt;p&gt;每一步都在做权衡，每一步都在承认矛盾没有被消除。但这个管道叠加起来，把 PR 矛盾压到了一个工程上可接受的范围内，让生产系统能够稳定运行。&lt;/p&gt;
&lt;p&gt;如果你在做 RAG 或 Agent 记忆系统，我的建议是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;先走完前六步&lt;/strong&gt;，看看效果。大部分人走到第三步就觉得够了。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在每一步记录你的权衡。&lt;/strong&gt; 清楚你在哪里丢了精度、哪里丢了召回率。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接受&amp;rsquo;足够好&amp;rsquo;。&lt;/strong&gt; 追求完美的 PR 平衡会让你走进死胡同。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;回到上一篇的核心论点：记忆系统有用，但它有天花板。七步流水线就是工业界在天花板之下能找到的最佳实践。&lt;/p&gt;
&lt;p&gt;理解了这个框架，你就理解了为什么 Harness 工程（工具设计、反馈质量、状态控制）可能是比记忆系统更大的杠杆——&lt;strong&gt;因为你在七步之内能做的最大的改变，往往不在检索这一步。&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>