RAG还在用基础版?句子滑动窗口·自动合并·索引·融合·CRAG·Self-RAG全讲透(附代码)

发布时间:2026/7/24 12:22:36
RAG还在用基础版?句子滑动窗口·自动合并·索引·融合·CRAG·Self-RAG全讲透(附代码) 本文是「108张AI知识卡片·大模型通关手册」系列第 7 篇。上一篇把 RAG 的 6 个调优旋钮相似度/意图识别/召回/ReRank/排序/混合检索拧了一遍效果确实提了——但调来调去还是检索→生成一条路走到黑。这篇讲的是更根本的升级让检索结果不再被 Chunk 边界截断、让多路结果更聪明地合并、让系统自己判断检索结果靠不靠谱、甚至自己决定要不要检索——从调优到自省RAG 才算真正进阶。目录TL;DR 太长不看一、句子滑动窗口检索Chunk边界截断语义滑动一下就解决二、自动合并检索小粒度检索大粒度回溯三、索引亿级数据的检索速度全靠它四、融合多路检索结果怎么合并才聪明五、CRAG检索不靠谱自动纠正拒绝垃圾上下文六、Self-RAG让大模型自己决定要不要检索七、一张图串起RAG进阶链路八、代码CRAG Self-RAG 实战写到最后系列导航 持续更新TL;DR 太长不看⚡30 秒版先记这 7 条细节往下翻。句子滑动窗口Chunk 边界把一句话切成两半滑动窗口让检索片段前后延伸上下文不断裂。自动合并检索小 Chunk 检索精准大 Chunk 上下文完整——自动合并两者优势按需回溯。索引HNSW 图索引快但费内存、IVF 分桶省内存但精度略降、PQ 压缩向量省空间——选错索引亿级数据直接卡死。融合多路召回结果怎么合并RRF 看排名、互信息融合看分数——量纲不同时用 RRF同量纲时用加权融合。CRAG检索结果不靠谱用 LLM 评估相关性不相关的纠正或重检索拒绝垃圾上下文污染生成。Self-RAG让大模型自己决定要不要检索、检索结果要不要用、要不要重检索——自省式 RAG。进阶口诀滑动窗口保上下文 → 自动合并选粒度 → 索引撑速度 → 融合合多路 → CRAG 纠错 → Self-RAG 自省。一、句子滑动窗口检索Chunk边界截断语义滑动一下就解决你把一篇文档切成 512 字的 Chunk有一条关键信息恰好跨在第 3 段末尾和第 4 段开头——被一刀切成两半检索时哪段都搜不到完整语义。这不是模型的问题是切分的锅。句子滑动窗口检索解决的核心问题固定 Chunk 边界会截断语义。滑动窗口让每个检索片段都带上前后文的余量不再因为切分位置不对而丢失关键信息。它到底在干嘛机制层传统 Chunk 是硬切——按固定 token 数切分切完就完。句子滑动窗口的做法是以句子为最小切分单位不会把一句话切成两半同时设置一个窗口大小如 3 句和滑动步长如 1 句。每次取连续 3 句作为一个检索片段然后向前滑动 1 句取下一段 3 句——相邻片段有 2 句重叠。这样即使关键信息跨越两个传统 Chunk 的边界在滑动窗口中它也会完整出现在某个片段里。你能感受到什么体感层假设文档有 5 句话 A-B-C-D-E窗口3句步长1句检索片段是ABC、BCD、CDE。关键信息在 B 和 C 之间ABC 和 BCD 都完整包含它。传统硬切AB | CDE呢B 和 C 被分到两个 Chunk哪个都不完整。重叠的代价是存储量增加——5 句话生成了 3 个片段而非 2 个但换来的是不漏语义。固定 Chunk句子滑动窗口切分单位Token 数句子语义完整性可能截断句内不断重叠无相邻片段重叠存储开销低中重叠部分重复存储检索精度中高️ 动手感受硬切 vs 滑动窗口操作同一篇文档分别用固定 512 token 切分 vs 句子滑动窗口窗口3句步长1句搜一个跨 Chunk 边界的问题。你会看到硬切关键信息被分到两个 Chunk检索时哪个 Chunk 的相似度都不够高排不进 Top-K。滑动窗口关键信息完整出现在某个重叠片段中相似度直接拉满。变化说明了什么不是模型不行是切分位置不对——滑动窗口用重叠换完整代价可控、收益明显。 想一想重叠越多存储越大——窗口5句、步长1句的重叠率远高于窗口3句、步长2句。你的业务能容忍多少存储膨胀如果文档库有 1000 万篇重叠带来的存储增量可不是小数目。 顺着他想滑动窗口解决了边界截断但检索回来的片段还是固定粒度的——有时你需要更粗的粒度一整段有时需要更细的粒度一句话。能不能检索时用小粒度回溯时自动合并成大粒度这就是自动合并检索做的事。二、自动合并检索小粒度检索大粒度回溯滑动窗口解决了边界截断但粒度问题还在——小 Chunk 检索精准但上下文不够大 Chunk 上下文完整但检索噪声多。能不能两全其美自动合并检索解决的核心问题检索精度和上下文完整性之间的矛盾。它用小粒度 Chunk 做检索精准命中后自动回溯到包含该 Chunk 的大粒度文档完整上下文两者优势兼得。它到底在干嘛机制层自动合并检索的核心是层级索引——同一篇文档被切成多个粒度叶子节点小 Chunk如 128 token、中间节点段落级如 512 token、根节点全文或章节级。检索时只在叶子节点小 Chunk上做相似度匹配——小粒度精准噪声少。命中某个叶子节点后系统自动向上回溯如果同一父节点下的多个叶子节点都被命中说明这一整段都相关直接返回父节点大粒度如果只有零星叶子节点命中就只返回那些叶子节点小粒度。这就是自动合并——系统根据命中密度自动决定返回的粒度。你能感受到什么体感层问退货政策和退货流程有什么区别——小 Chunk 检索命中了退货政策和退货流程两个叶子节点它们恰好属于同一个段落节点系统自动合并返回整个段落上下文完整。如果只问退货政策只命中一个叶子节点系统就只返回那个小 Chunk不浪费上下文窗口。“按需给量”——问题涉及的范围大返回大粒度问题聚焦返回小粒度。️ 动手感受固定大 Chunk vs 自动合并操作同一批文档分别用固定 512 token Chunk 检索 vs 自动合并检索叶子128 token 段落512 token对比两种问题的结果。你会看到固定大 Chunk宽泛问题命中完整段落✅但精准问题也返回整个段落混入大量无关内容❌。自动合并宽泛问题自动合并返回大段落✅精准问题只返回小 Chunk✅。变化说明了什么自动合并不是更聪明的切分是按需决定返回粒度——同一个索引不同问题自动适配不同粒度。 想一想自动合并的前提是构建层级索引——同一篇文档要切多个粒度索引构建成本和存储都增加。如果你的文档库更新频繁如新闻每次更新都要重建层级索引这个成本你愿意承担吗 顺着他想层级索引建好了检索速度靠什么保证亿级文档、多层级索引暴力扫描肯定不行——这就引出了索引结构的话题HNSW、IVF、PQ选错索引亿级数据直接卡死。三、索引亿级数据的检索速度全靠它100 万条向量做暴力搜索每次查询要算 100 万次相似度——延迟从毫秒变秒级。1 亿条呢分钟级。索引结构就是让检索从全量扫描变成近似查找的关键。索引解决的核心问题向量数量大到暴力搜索不可接受时怎么快速找到近邻索引结构通过空间换时间或精度换速度让亿级数据的检索延迟保持在毫秒级。它到底在干嘛机制层三大主流索引结构各有取舍。HNSW分层可导航小世界图把每个向量连成一张多层图检索时从顶层入口开始逐层向下贪心搜索——跳过大量不相关区域直达近邻。速度快log 级、精度高但内存占用大要存图结构。IVF倒排文件索引先把向量空间用 K-Means 分成 N 个簇桶检索时只搜索离查询最近的几个簇——把全量搜索变成局部搜索。省内存、速度快但精度取决于簇的划分质量。PQ乘积量化把高维向量切成 M 个子空间每个子空间用码本量化成短编码——向量从 1024 维 float 压缩成几十字节的编码。存储暴降 10-50 倍但精度有损。实战组合IVF PQ 是最经典的搭配——IVF 先缩小搜索范围PQ 再压缩向量加速距离计算亿级数据毫秒级检索。索引速度精度内存适用规模暴力搜索慢100%低10万HNSW极快高高1000万IVF快中高中千万级IVFPQ快中低亿级你能感受到什么体感层10 万条向量暴力搜索和 HNSW 差别不大——都很快。但到 1000 万条暴力搜索延迟飙到秒级HNSW 仍在毫秒级。到 1 亿条HNSW 内存可能撑不住换成 IVFPQ牺牲 5% 精度换回毫秒级延迟——这个交换在生产环境里几乎总是值得的。️ 动手感受不同索引的延迟对比操作同一批 100 万条向量分别建 HNSW / IVF / IVFPQ 索引测查询延迟和召回率。你会看到HNSW延迟 2ms召回率 98%——快且准但内存占用 4GB。IVF延迟 5ms召回率 95%——稍慢稍低精度但内存只要 2GB。IVFPQ延迟 3ms召回率 92%——精度有损但存储暴降内存只要 500MB。变化说明了什么没有最好的索引只有最适合你场景的索引——数据量、内存预算、精度要求三个维度决定选择。 想一想PQ 量化有损损失的那 5-8% 精度到底影响什么如果你的业务是法律条文检索5% 的精度损失可能意味着漏掉关键法条——不可接受。如果是商品推荐5% 的损失用户根本感知不到。精度换速度值不值取决于业务对漏答案的容忍度。 顺着他想索引解决了单路检索的速度问题但上一篇讲的混合检索是两路——向量路和关键词路各出 Top-K合并后统一排序。合并策略怎么选RRF 和互信息融合有什么区别这就是融合要讲的事。四、融合多路检索结果怎么合并才聪明向量路召回 Top-20关键词路召回 Top-20两路合并 40 条——但两路的分数量纲不同余弦相似度 0-1BM25 分数 0-∞怎么排谁前谁后融合解决的核心问题多路检索结果的分数不可比怎么合并成一个统一排序融合策略不看绝对分数看相对排名——或者把分数归一化后再加权。它到底在干嘛机制层两种主流融合策略。RRFReciprocal Rank Fusion不看分数只看排名。每条文档的 RRF 分数 Σ 1/(krank_i)k 通常取 60。两路都排得靠前的文档天然得高分——两路共识比单路高分更可靠。RRF 的优点是量纲无关余弦和 BM25 的分数不需要归一化缺点是丢了分数信息排名第 1 和第 2 的差距可能巨大但 RRF 只看排名差 1。互信息融合Score Fusion先对每路的分数做归一化Min-Max 或 Z-Score统一到同一量纲再按权重加权final_score α×norm(向量分) β×norm(BM25分)。优点是保留了分数信息缺点是归一化方法选择影响结果、极端分数会扭曲归一化。RRFScore Fusion依赖排名分数量纲问题无量纲无关需归一化分数信息丢失保留极端值鲁棒性强弱极端分数扭曲归一化实现复杂度低中你能感受到什么体感层向量路第 1 名相似度 0.95第 2 名 0.52——差距巨大关键词路第 1 名 BM25 分 28.3第 2 名 27.1——差距微小。RRF 不管这些差距只看谁排前面Score Fusion 会把向量路第 1 名的巨大优势体现出来。如果你的场景里第 1 名远超其他是常态如精确匹配场景Score Fusion 更合适如果分数分布比较均匀RRF 更稳定。️ 动手感受RRF vs Score Fusion操作同一批双路召回结果分别用 RRF 和 Score FusionMin-Max归一化 等权合并看 Top-5 差异。你会看到RRF两路都排得靠前的文档排前面“共识优先”。Score Fusion某路分数特别高的文档排前面“高分优先”。变化说明了什么RRF 更稳定不受极端分数影响Score Fusion 更灵敏能捕捉远超其他的信号——选哪个取决于你的数据分布。 想一想RRF 的 k 值怎么选k60 是经验值k 越大排名差异的影响越小更平滑k 越小排名靠前的优势越大更陡峭。k10 和 k100 的结果可能差很多——这个参数没有万能值要靠你的数据调。 顺着他想融合做完多路结果合并成了一个统一排序——但这个排序就一定靠谱吗如果某一路的召回结果全是垃圾呢融合只会让垃圾的排名稍微低一点不会把它踢出去。那检索结果靠不靠谱谁来评估这就是 CRAG 要解决的问题。五、CRAG检索不靠谱自动纠正拒绝垃圾上下文检索回来 5 条文档3 条是垃圾——但模型不知道照单全收生成出来的答案一半是幻觉。问题不在模型在检索结果没过质检。CRAGCorrective RAG解决的核心问题检索结果可能不靠谱但基础 RAG 无条件使用所有检索结果。CRAG 加了一道质检——用轻量评估器判断检索结果的相关性靠谱的用不靠谱的纠正或重检索拒绝垃圾上下文污染生成。它到底在干嘛机制层CRAG 的流程在检索和生成之间加了一个评估-决策-纠正循环。检索结果回来后先用轻量评估器小模型或 LLM给每条文档打相关性分。然后根据分数做决策**高分靠谱**→直接送进生成**中分半靠谱**→纠正对文档做精炼提取关键句、去噪再送进生成**低分垃圾**→丢弃触发重检索换关键词/换检索策略再搜一次。整个流程是检索→评估→决策→{直接用/纠正/重检索}→生成。你能感受到什么体感层问2024 年退税新政策检索回来 3 条1 条 2024 年新政策高分直接用、1 条 2020 年旧政策中分纠正提取2020 年标记为过时信息、1 条完全不相关的退税诈骗新闻低分丢弃重检索。CRAG 让模型只吃经过质检的食材而不是检索到什么就吃什么。基础 RAGCRAG检索结果无条件使用先评估再决策垃圾文档照单全收丢弃重检索半相关文档原样送入精炼后再送入额外开销无评估器推理成本幻觉率高低️ 动手感受开/关 CRAG 对比操作故意构造一个检索结果大部分不靠谱的场景如问冷门问题开/关 CRAG看生成质量差异。你会看到关 CRAG模型把垃圾文档也当知识用生成出包含错误信息的答案。开 CRAG评估器识别出垃圾文档丢弃后重检索或直接用模型自身知识生成答案更准确。变化说明了什么CRAG 不是让检索更准是让不准的检索结果不污染生成——质检这道关拦住的是幻觉的源头。 想一想CRAG 的评估器本身也有误判风险——把靠谱的文档判为垃圾丢弃比保留垃圾更糟丢了正确答案。评估器的精度怎么保证用大模型做评估器精度高但延迟大用小模型快但精度低——这个评估器的评估是 CRAG 的隐藏成本。 顺着他想CRAG 是检索后评估但有些问题根本不需要检索——“11等于几你检索什么如果模型能自己判断这个问题要不要检索”不检索的直接生成需要检索的才走 RAG 流程效率会高得多。这就是 Self-RAG 的思路。六、Self-RAG让大模型自己决定要不要检索每次提问都检索问11等于几也去搜一遍文档库——浪费延迟还可能引入噪音。问2024年退税新政策却不检索——模型只能靠训练数据猜大概率过时。能不能让模型自己判断Self-RAG 解决的核心问题不是所有问题都需要检索也不是所有检索结果都该用。Self-RAG 让大模型在生成过程中自己插入反思标记决定是否检索、检索结果是否相关、是否需要重检索——自省式 RAG。它到底在干嘛机制层Self-RAG 在生成流程中插入了 3 种反思标记Reflection Tokens。① 检索标记[Retrieve]模型生成前先判断这个问题需要检索吗——事实性问题“2024年退税政策”→需要检索常识/推理问题“11等于几”→不需要直接生成。② 相关性标记[ISREL]检索结果回来后模型判断这条文档和问题相关吗→相关则使用不相关则丢弃。③ 支持性标记[ISSUP]生成答案后模型判断这个答案有检索文档支持吗→有支持则输出无支持则重检索或修正。整个流程问题→[Retrieve?]→{检索/不检索}→[ISREL?]→{使用/丢弃}→生成→[ISSUP?]→{输出/重检索}。你能感受到什么体感层问Python 的 list 怎么排序——模型判断这是常识不需要检索直接生成list.sort()省了检索延迟。问LangChain 0.3 的最新 API——模型判断这是时效性问题需要检索走 RAG 流程拿到最新文档。问量子计算的未来——模型判断这是开放性问题不需要精确检索直接用自身知识生成。Self-RAG 让每个问题走最合适的路而不是一刀切全检索或一刀切全不检索。基础 RAGCRAGSelf-RAG检索决策总是检索总是检索模型自判结果评估无评估器评估模型自评答案校验无无模型自检延迟中高评估器可变按需检索复杂度低中高️ 动手感受Self-RAG 的三种决策路径操作分别输入三类问题——常识问题、时效性问题、开放性问题观察 Self-RAG 的决策路径。你会看到常识问题11等于几→[Retrieve: No]→直接生成→快且准。时效性问题2024年退税新政策→[Retrieve: Yes]→检索→[ISREL: Yes]→生成→[ISSUP: Yes]→输出。开放问题AI的未来→[Retrieve: No]→直接生成→省检索延迟。变化说明了什么Self-RAG 不是更准的 RAG是更聪明的 RAG——它让系统自己决定走哪条路而不是人写规则。 想一想Self-RAG 的反思标记需要模型学会什么时候该插入——这需要专门训练或微调。如果你的模型没经过 Self-RAG 训练它不会自发地输出[Retrieve]标记。用通用模型模拟Self-RAG通过 Prompt 引导模型判断是否需要检索可行吗精度够吗延迟呢 顺着他想Self-RAG 让模型自己决定要不要检索但检索策略本身向量检索还是关键词检索、K 设多少、要不要混合检索还是人定的。如果模型连用什么策略检索也能自己决定呢那就是更远的前沿——自适应检索策略目前还在研究阶段。七、一张图串起RAG进阶链路6 个高阶旋钮串成一条从切分到自省的完整链路文档入库 │ ① 句子滑动窗口切分 ← 以句子为单位重叠保语义不断裂 │ ② 层级索引构建 ← 叶子/段落/章节多粒度支撑自动合并 │ ③ 索引结构选择 ← HNSW(快准贵)/IVF(中)/IVFPQ(省量大) │ 用户提问 │ ④ 多路召回融合 ← 向量路关键词路RRF/Score Fusion合并 │ ⑤ CRAG评估-纠正 ← 检索结果过质检靠谱用/半靠谱纠正/垃圾丢弃重检索 │ ⑥ Self-RAG自省 ← 模型自判要不要检索结果相关吗答案有支撑吗 │ Top-N → 拼进 Prompt → 大模型生成进阶口诀滑动窗口保上下文——Chunk 边界不再截断语义。自动合并选粒度——小粒度检索精准大粒度回溯完整。索引撑速度——亿级数据毫秒级选错索引直接卡死。融合合多路——RRF 量纲无关看排名Score Fusion 保留分数信息。CRAG纠错——检索结果过质检垃圾不进生成。Self-RAG自省——模型自己决定要不要检索按需走最合适的路。八、代码CRAG Self-RAG 实战上一篇跑了混合检索 RRF 融合这篇加两个高阶升级CRAG 评估-纠正和Self-RAG 自省决策。fromopenaiimportOpenAIimportnumpyasnp clientOpenAI(api_key你的KEY,base_urlhttps://api.openai.com/v1)docs[2024年退税新政策个税起征点不变专项附加扣除标准提高,2020年退税政策个税起征点5000元,退税诈骗案例某市民被骗10万元,Python的list排序用list.sort()方法]defembed(text):rclient.embeddings.create(inputtext,modeltext-embedding-3-small)returnnp.array(r.data[0].embedding)vecs[embed(d)fordindocs]# ① Self-RAG: 模型自判是否需要检索q2024年退税新政策是什么need_retrievalclient.chat.completions.create(modelgpt-4o-mini,messages[{role:system,content:判断问题是否需要检索外部知识。事实性/时效性问题回答YES常识/推理问题回答NO。只输出YES或NO。},{role:user,content:q}]).choices[0].message.content.strip()ifneed_retrievalYES:# ② 向量检索qvembed(q)cos_sims[qv v/(np.linalg.norm(qv)*np.linalg.norm(v))forvinvecs]top_indicesnp.argsort(cos_sims)[::-1][:3]retrieved[docs[i]foriintop_indices]# ③ CRAG: 评估检索结果相关性eval_prompt给以下(问题,文档)对的相关性打1-10分只输出数字。\nfordinretrieved:eval_promptf问题{q}| 文档{d}\nscoresclient.chat.completions.create(modelgpt-4o-mini,messages[{role:user,content:eval_prompt}]).choices[0].message.content# ④ 只用高分文档生成context\n.join(retrieved[:2])# 简化取前2条ansclient.chat.completions.create(modelgpt-4o-mini,messages[{role:system,content:只根据参考资料回答资料不足就说不确定},{role:user,content:f参考资料{context}\n问题{q}}]).choices[0].message.contentprint(f[检索]{ans})else:# ⑤ 不检索直接生成ansclient.chat.completions.create(modelgpt-4o-mini,messages[{role:user,content:q}]).choices[0].message.contentprint(f[直接生成]{ans})这段代码实现了 Self-RAG 的核心逻辑先让模型判断是否需要检索需要则走 CRAG 流程检索→评估→过滤→生成不需要则直接生成。生产环境要做的升级评估器换成真正的 Cross-Encoder、加上重检索逻辑、支持多轮自省循环。写到最后三篇 RAG 文章从入门核心链路到进阶6 个调优旋钮到高阶自省式决策终于把 RAG 的完整图景画完了。基础 RAG 是检索→生成进阶 RAG 是检索→重排→生成高阶 RAG 是检索→评估→纠正→自省→生成——每一步升级都是让系统从被动执行变成主动决策。写这三篇的时候我一直在想RAG 的天花板到底在哪CRAG 和 Self-RAG 已经让系统会反思了但反思的精度取决于评估器的精度评估器的精度又取决于训练数据——这个循环能走多远也许真正的突破不在于让 RAG 更聪明而在于让模型本身更懂什么时候该用 RAG。这个话题后续系列如果有机会再展开。如果你读下来觉得真有用点个赞让我知道 RAG 三部曲这种从入门到高阶一条线的写法值得继续⭐收藏起来这篇的高阶概念CRAG/Self-RAG是 RAG 天花板级别的方案回来翻的概率很高关注一下下一篇开启新话题Agent 实战——从 ChatBot 到数字员工AI 才真正从问答变成行动。–PC学习效果更好哦系列导航 持续更新系列第 7 篇上一篇RAG效果不好怎么调6张图讲透相似度·意图识别·召回排序·ReRank·混合检索 下一篇预告2025最火方向——6张图搞懂AI Agent如果这篇对你有帮助点个收藏RAG 高阶方案是天花板级别的知识回来翻的概率很高。有问题欢迎在评论区交流我会逐条回复。