ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RAG 深度解析:从原理到工程实践(一)

RAG 深度解析:从原理到工程实践(一) 目录前言1、基础原理先建立正确认知1.1 RAG 的本质检索 生成1.2 RAG 解决的核心问题1.3 RAG 与微调的区别1.4 RAG 的边界1.4.1 三种典型失败场景1.5 常见架构模式1.5.1 Naive RAG一切的起点1.5.2 Advanced RAG检索前 检索后双重优化1.5.3 Modular RAG按需组装1.5.4 Agentic RAG自主决策2、数据处理RAG 最容易被低估的环节2.1 文档解析比想象中复杂得多2.1.1 常见文档类型及解析难点2.1.2 关键难点表格、图片、公式2.1.3 容易被忽略的细节2.2 文本清洗脏数据进脏答案出2.2.1 五项必做清洗2.3 元数据抽取被忽视的检索利器2.3.1 为什么要抽取元数据2.3.2 必抽取的元数据字段2.4 分块策略影响全局的关键参数2.4.1 几种常见的分块策略2.4.2 关键参数调优2.5 父子文档小检索大返回2.5.1 核心思想2.5.2 为什么有效2.5.3 实现要点写在最后前言过去一年几乎每个做 AI 应用的团队都绕不开一个词RAG。但真正把它做好的人并不多。很多团队以为接个向量数据库、调个 Embedding 接口就算落地了 RAG结果上线后发现检索不准、回答跑偏、效果时好时坏。问题出在哪出在对基本原理的理解不够深对数据处理的重视不够多。这篇文章试图把 RAG 最核心的两件事讲透第一建立正确的认知框架第二把最容易踩坑的数据处理环节拆开来讲。1、基础原理先建立正确认知这部分不是背概念而是要能回答三个问题为什么用 RAG、RAG 适合什么场景、不适合什么场景。如果你连这三个问题都答不上来就急着搭系统大概率会在后期踩坑。核心理念RAG 不是一个检索生成的简单拼接而是用外部知识约束 LLM 生成的完整工程体系。它的核心价值在于让模型在生成答案之前先看到正确的事实从而大幅降低幻觉同时保留 LLM 的语言理解和推理能力。1.1 RAG 的本质检索 生成RAG 的全称是 Retrieval-Augmented Generation很多人把 RAG 理解为检索 生成这没错但太浅了。名字本身就揭示了它的两阶段结构先从外部知识源检索相关内容再把这些内容作为上下文喂给大语言模型生成回答。很多人把 RAG 想得很复杂但它的核心思想其实非常朴素——让模型在回答之前先翻翻书。大语言模型本身只有训练数据里学到的知识这些知识有截止日期也不包含你的私有数据。RAG 做的事情就是在推理阶段给它补充实时、私有的上下文信息让它的生成有据可依。传统 LLM 的工作方式是用户提问 → 模型从参数化的知识中回忆答案 → 输出。这些知识是训练时固化在模型权重里的无法更新也无法验证。RAG 改变了这个链路用户提问 →先从外部知识库检索相关文档→ 将检索到的文档拼入 prompt → 模型基于这些文档生成答案。模型不再是凭记忆回答而是开卷考试。图 1传统 LLM vs RAG 的工作流程对比用一个类比来说大语言模型是一个很聪明但闭卷考试的学生RAG 就是允许他在答题前先查阅参考资料。他依然用自己的理解力来组织答案但答案的内容有了事实依据。核心认知RAG 并没有改变模型本身的能力它改变的是模型能看到的信息。这个区分非常重要——它意味着 RAG 的效果上限很大程度上不取决于你用了多好的模型而取决于你给模型提供了多好的检索内容。1.2 RAG 解决的核心问题RAG 不是万能的它精准地解决了 LLM 的四类痛点01、知识截止LLM 的训练数据有截止日期无法回答训练之后发生的事。RAG 通过检索最新文档让模型看到最新的信息。02、幻觉问题LLM 在不确定时会编造看似合理但实际错误的内容。RAG 提供事实依据让模型有据可依大幅降低幻觉率。03、私有知识企业内部文档、制度、产品手册——这些永远不会出现在公域训练数据中。RAG 是让 LLM 接入私有知识的最实用方案。04、时效性产品文档更新了、政策改了、价格调了——RAG 只需更新知识库无需重新训练模型知识可以做到准实时更新。实战洞察在我经手的项目中80% 的企业 AI 问答需求本质上都是 RAG 需求。原因很简单企业要的不是模型的创造力而是准确性和可溯源。RAG 恰好在这两点上有结构性优势。1.3 RAG 与微调的区别这是面试和项目评审中最高频的问题也是工程选型中最容易混淆的决策点。一句话总结RAG 改变的是模型的输入微调改变的是模型本身。维度RAG微调Fine-tuning解决的核心问题知识获取让模型知道它原本不知道的事行为调整让模型以特定方式做事知识更新成本低更新知识库即可准实时高需要重新训练 / 继续训练适合场景知识更新快、需要溯源、权限控制风格统一、格式固定、任务行为调整不适合场景需要深度推理链、多跳逻辑推理频繁更新知识、小批量快速迭代幻觉控制强——有明确的事实来源可约束弱——知识融入权重无法溯源权限控制天然支持——按用户角色过滤检索结果不支持——知识融入权重无法按人隔离延迟开销多一步检索增加 100-500ms无额外开销推理速度不变实施难度中等——主要在数据处理和检索质量较高——需要标注数据、训练调优选型误区最常见的错误是用微调来注入知识。我见过不少团队花几万块钱标注数据、跑 LoRA 微调结果知识更新一次就得重来一轮。微调不适合频繁更新知识这是结构性限制不是工程能力问题。如果你的需求是让模型知道公司最新的产品文档答案几乎永远是 RAG。当然RAG 和微调不是非此即彼。在实际项目中RAG 轻量微调 的组合很常见用微调让模型学会特定的回答风格和输出格式用 RAG 提供事实知识。两者互补不矛盾。RAG 像是在考试时给考生一本参考书考生还是那个考生但他能查资料了。微调像是考前给考生做了一轮集训他的知识结构和思维方式都变了但考完就定型了下次知识更新还得重新集训。在实际选型中我的经验法则是这样的如果你的需求是让模型知道某些知识优先用 RAG如果你的需求是让模型以某种方式说话或做事考虑微调。两者并不互斥很多生产系统会同时使用——用微调来调整模型的行为风格用 RAG 来注入实时知识。但如果预算有限只能选一个绝大多数场景下 RAG 的性价比更高。1.4 RAG 的边界这是我在一线项目中最想强调的部分。RAG 不是万能的它有明确的失败边界。如果你不知道边界在哪就无法判断这个问题该不该用 RAG。1.4.1 三种典型失败场景检索不到用户问了一个知识库里确实有答案的问题但检索系统没有把相关文档片段找出来。原因可能是 Embedding 模型的语义理解不够好分块策略把关键信息切碎了或者向量化时丢失了重要的上下文知识库里根本没有相关文档。模型只能基于不相关的上下文硬编结果比不用 RAG 还差。这是最常见的失败——不是 RAG 不行是知识库不全。检索错了检索系统返回了相关内容但混入了大量不相关的片段。模型的注意力被噪声分散反而生成了更差的答案。这就像给考生一本参考书但书里夹了很多无关的页面考生翻来翻去反而更混乱了。模型看到错的文档自然给出错的答案。上下文塞不下检索到了正确的内容但内容太多超出了模型的上下文窗口。或者虽然窗口够大但关键信息被淹没在大量文本中——模型的中间迷失Lost in the Middle问题已经被多篇论文证实它们倾向于更关注上下文开头和结尾的内容。一个反直觉的事实给模型更多上下文并不总是更好。当上下文从 1K tokens 增加到 8K tokens 时如果新增的内容中噪声比例上升模型的准确率可能反而下降。RAG 不是塞得越多越好而是塞得越准越好。不是所有问答都适合 RAG以下场景 RAG 效果会很差·多跳推理——A 的上级的上级负责哪些项目需要跨文档链式推理·聚合统计——上季度所有合同总额需要遍历大量文档做计算·隐式知识——从未被显式记录的经验、惯例、潜规则这些场景要么需要 Agentic RAG多轮检索推理要么需要结合 NL2SQL 等其他技术方案。推理失败Reasoning Failure。检索到了正确的内容上下文也塞得下但模型在推理过程中出了错。比如需要跨多个文档做综合推理或者需要精确的数值计算模型可能力不从心。这不是 RAG 的问题而是 LLM 本身的能力边界。所以不是所有问答都适合用 RAG。如果你的任务是闲聊、创意写作、通用知识问答直接用模型就好。RAG 的价值在于当模型自身的知识不够用、不够新、不够准确时提供外部知识支撑。1.5 常见架构模式RAG 不是一成不变的架构它经历了从简单到复杂的演进。理解每种模式的特点和适用场景才能在选型时做出正确判断。架构核心特征优点缺点适用场景Naive RAG直接检索 → 拼上下文 → 生成简单快速易于实现检索质量不稳定无优化环节概念验证、简单 FAQAdvanced RAG检索前优化 检索后重排检索精度高答案质量好链路更长延迟增加生产环境、企业问答系统Modular RAG模块化路由按需调度灵活可扩展可按场景定制架构复杂维护成本高多数据源、多场景企业系统Agentic RAGAgent 自主决策检索策略多跳推理、复杂问题处理延迟高、成本高、不确定性强复杂分析、研究报告生成1.5.1 Naive RAG一切的起点最朴素的形式是最基础的实现用户提问 → Embedding 检索 → 把 Top-K 结果塞进 Prompt → 模型生成回答。这个流程简单粗暴但问题也很多检索质量完全依赖 Embedding 模型和分块策略没有查询改写没有重排序没有后处理。很多团队的 RAG 系统停留在这一阶段然后发现效果不行。图 2Naive RAG 流程——最基础的检索增强生成链路Naive RAG 的问题在于检索阶段没有任何优化。如果用户问题写得模糊或者知识库里文档质量参差不齐检索效果就会很差。于是有了 Advanced RAG。1.5.2 Advanced RAG检索前 检索后双重优化Advanced RAG 的核心改进是在检索前后各加了一道工序检索前Pre-retrieval查询改写、查询扩展、HyDE假设性文档嵌入、多查询生成——把用户的烂问题变成好问题。检索后Post-retrieval重排序Reranker、上下文压缩、去重、相关性过滤——从检索结果中挑出真正有用的部分。图 3Advanced RAG 流程——在检索前后各加一道优化工序1.5.3 Modular RAG按需组装Modular RAG 把整个链路拆成独立模块检索模块、路由模块、排序模块、生成模块、记忆模块……每个模块可以独立替换、升级。这种架构的好处是灵活性极高你可以根据不同场景选择不同的模块组合。比如对于简单问题走快速通道对于复杂问题走多轮检索 推理通道。比如简单 FAQ 走 Naive 链路技术文档查询走 Advanced 链路统计类问题路由到 NL2SQL 模块。这就是 路由Routing 的价值——不是所有问题都需要重链路。1.5.4 Agentic RAG自主决策Agentic RAG 是当前的前沿方向。它不再走固定的 检索→生成 链路而是让 Agent 自主决策要不要检索检索几次检索什么检索到了要不要再检索要不要调用工具它把 RAG 嵌入到 Agent 框架中让模型自主决定何时检索、检索什么、是否需要多轮检索、是否需要调用其他工具。模型不再是一个被动的检索-生成管道而是一个主动的决策者。它可能会先检索一次发现信息不够于是改写查询再检索一次或者发现需要查数据库而不是文档库或者判断当前信息已经足够直接生成答案而不需要检索。典型场景用户问分析一下我们竞品 Q3 的产品策略。Agent 可能需要先检索竞品列表 → 再检索每个竞品的 Q3 动态 → 调用搜索引擎补充公开信息 → 综合分析 → 生成报告。这是多轮检索 多工具调用的复杂流程。架构选型建议不要一上来就搞 Agentic RAG。先用 Naive RAG 跑通用真实数据验证检索质量再根据瓶颈决定升级到哪一层。我见过太多团队直接上 Modular/Agentic结果连基础检索质量都没做好架构再复杂也没用。四种 RAG 架构模式多维对比2、数据处理RAG 最容易被低估的环节我见过太多团队花大量时间调模型、调 Prompt、调向量数据库参数但数据处理环节就是随便写个脚本把 PDF 转成文本然后按 500 字切分。结果效果上不去。后来把数据处理重做了一遍效果立竿见影。数据处理不是 RAG 的前处理它就是 RAG 的核心。如果你问我RAG 项目效果不好最常见的根因是什么我的回答是不是模型不行不是算法不行是数据处理没做好。数据处理是 RAG 中最没有技术含量但最影响最终效果的环节。它不像模型选型那样有明确的 benchmark不像 prompt 工程那样能立刻看到效果变化但它决定了 RAG 的上限——垃圾进垃圾出Garbage In, Garbage Out。一线经验在我评审过的 RAG 项目中70% 的检索不准问题最终定位到数据处理环节要么文档解析丢了关键信息要么分块方式切断了上下文要么文本清洗引入了噪声。模型只占 30% 的问题。2.1 文档解析比想象中复杂得多文档解析是 RAG 数据处理的第一道关卡也是信息损失最大的环节。一个 PDF 解析不好表格变成乱码图片丢失公式碎裂——后面所有环节都白搭。企业环境中的数据源是极其多样的。PDF、Word、PPT、Excel、Markdown、HTML、网页、数据库、API……每种格式都有自己的坑。PDF 是公认的硬骨头。它的设计初衷是打印不是解析。一个 PDF 文件里的文字可能没有逻辑段落结构表格可能是用线条位置画出来的而不是用表格标签定义的图片可能是嵌入的光栅图也可能是矢量图。更头疼的是多栏排版、页眉页脚、脚注、参考文献——这些元素在视觉上很清楚但程序解析时很容易搞混。我见过一些团队直接用 PyPDF2 或者 pdfplumber 做转换出来的文本充满了断行错误、表格错乱、页眉页脚混入正文的问题。对于复杂的 PDF更好的选择是使用专业的文档解析工具比如基于深度学习的版面分析模型来识别标题、段落、表格、图片等区域然后分别处理。表格处理尤其值得关注。一个财务报表或者产品参数表如果简单地转成纯文本行列关系就全丢了。正确做法是把表格保留结构化格式比如 Markdown 表格或者 HTML或者把每一行转成一个独立的事实陈述例如产品 A 的价格是 100 元这样在检索时才能精确匹配。图片和公式也不能忽视。技术文档中大量的关键信息藏在图片里——架构图、流程图、截图。公式在 STEM 领域文档中更是核心内容。对于图片可以用多模态模型做描述生成对于公式可以用 LaTeX OCR 工具转成 LaTeX 表达式。这些额外步骤看起来增加了工作量但丢失了这些信息你的 RAG 系统就等同于对这些内容失明。经验之谈文档解析的质量直接决定了后续所有环节的上限。如果解析出来的文本本身就是错的、乱的、缺失的后面用再好的 Embedding 模型和检索策略也救不回来。在这个环节省时间后面会加倍还回来。2.1.1 常见文档类型及解析难点文档类型推荐工具主要难点PDFPyMuPDF / pdfplumber / Unstructured多栏布局、表格嵌套、扫描件 OCR、页眉页脚干扰、公式识别Wordpython-docx / Unstructured修订标记、嵌入对象、样式映射、目录结构PPTpython-pptx / Unstructured幻灯片间逻辑断裂、备注页遗漏、图文混排Excelopenpyxl / pandas多 Sheet、合并单元格、公式值、表头识别Markdown原生解析 / markitdown相对简单但需保留标题层级和代码块结构HTML / 网页BeautifulSoup / Trafilatura正文提取、广告/导航去噪、JavaScript 渲染数据库 / APISQL 查询 / API 调用结构化数据转文本、Schema 理解、实时性保证2.1.2 关键难点表格、图片、公式这三类内容是文档解析中信息损失最严重的部分表格PDF 中的表格经常被解析器拆成碎片化的文本行行列关系丢失。解决方案使用专门的表格解析工具如 Camelot、Table Transformer或对关键表格做人工标注。对于复杂表格可以考虑将其转为 Markdown 表格再嵌入。图片图片中的信息图表、流程图、截图如果不处理就直接丢弃会造成信息损失。方案用多模态模型如 GPT-4V做图片描述将描述文本与图片位置信息一起存储。公式数学公式在 PDF 中通常是特殊编码直接提取会变成乱码。方案使用 Nougat 等专门工具将公式转为 LaTeX再作为文本存储。2.1.3 容易被忽略的细节⌖ 页眉页脚页码、文档标题、公司 logo——这些在每页重复的内容如果不去掉会污染每个 chunk干扰检索。№ 脚注/尾注脚注常包含关键解释和引用解析时容易与正文脱离上下文。建议将脚注归入所在段落。§ 代码块代码块不应被随意截断。建议将完整代码块作为一个独立 chunk保留语言标识。¶ 段落结构标题层级是宝贵的结构信息。解析时保留 H1-H6 层级分块时以此为边界效果远好于盲目切分。2.2 文本清洗脏数据进脏答案出文档解析后拿到的原始文本通常是脏的——有重复内容、有噪声、有编码问题、有特殊字符。文本清洗的目标是让进入向量库的每一段文本都是干净、完整、无歧义的。即使文档解析做对了原始文本中仍然充斥着噪声。文本清洗的目标是让每一段进入向量库的文本都是干净的、有意义的、适合检索的。去重。企业文档中重复内容比你想象的要多——制度文件的前言部分经常大段雷同年报中不同章节会引用相同的数据段落同一份模板被不同部门填充后只有少量差异。如果不做去重重复的文本片段会在检索中占据更高的权重导致结果偏向那些被复制了多次的内容而不是最相关的内容。去噪。包括去除无意义的特殊字符比如 PDF 转换产生的乱码、多余的分页符、零宽字符去除过短的行可能是页码、页眉修复合并断行一个段落被硬回车切成了多行以及处理编码问题UTF-8 和 GBK 混用、全角半角混乱等。低质量内容过滤。不是所有文本都适合进入知识库。目录页、版权声明、法律免责声明、如有疑问请联系管理员之类的模板文本这些对检索没有价值反而会引入噪声。可以基于规则比如文本长度、特定关键词或者基于分类模型来过滤。2.2.1 五项必做清洗清洗项问题表现处理方案去重同一文档多次上传、跨文档内容复制粘贴导致检索结果冗余精确去重hash 匹配 近似去重MinHash / SimHash去噪OCR 错误字符、HTML 标签残留、水印文字、页码正则过滤 停用词表 结构化清洗管道编码统一GBK/UTF-16/ISO-8859 混杂乱码、全角半角混用统一转 UTF-8全角转半角Unicode 规范化NFKC特殊字符不可见字符零宽空格 U200B、控制字符、异常换行正则清除不可见字符统一换行符为 \n合并多余空格低质量过滤过短的片段10 字、无意义的目录页、空白页设最小长度阈值过滤无实质内容的 chunk实用技巧文本清洗最容易被忽视的是不可见字符。零宽空格U200B、软连字符U00AD、BOM 标记UFEFF这些字符人眼看不见但会严重干扰 embedding 模型和 LLM 的处理。用unicodedata.normalize(NFKC, text) 正则清理是低成本高收益的操作。2.3 元数据抽取被忽视的检索利器元数据是 RAG 中最容易被忽略但价值最高的数据之一。没有元数据的 chunk 是裸数据有元数据的 chunk 才是可管理的数据。大多数人做 RAG 时只关注文本内容本身忽略了元数据。但元数据在过滤、溯源和权限控制中起着关键作用。一个好的元数据体系至少应该包括来源哪个文件、哪个系统、作者谁写的、哪个部门、时间什么时候创建或更新的、标签属于什么主题、什么类型、权限级别公开、内部、机密、版本号。为什么元数据这么重要考虑这个场景用户问最新的退货政策是什么。如果没有时间元数据你无法确定哪个文档是最新的如果没有来源元数据你无法告诉用户答案来自哪个文件如果没有版本元数据你可能返回了已作废的旧版政策。更重要的是元数据可以大幅提升检索精度。一种常见的做法是元数据过滤 向量检索组合先用元数据缩小范围比如只看 2025 年以后的人力资源部文档再在这个子集里做向量相似度搜索。这比在整个知识库里盲目搜索要精准得多。2.3.1 为什么要抽取元数据元数据直接影响三个关键能力过滤用户问2024 年的产品规格时可以先按时间元数据过滤只在 2024 年的文档中检索大幅提升精度和速度。这就是 元数据预过滤Pre-filtering。溯源答案来自哪份文档的哪一页、哪个章节没有元数据就无法溯源无法建立用户信任。权限控制企业场景中不同部门、不同级别的用户能看到的文档不同。元数据中的权限标签是实现检索级权限控制的基础。2.3.2 必抽取的元数据字段元数据示例用途来源文件名、URL、数据源标识溯源、来源可信度排序作者张三 / 产品部权限控制、作者可信度时间创建时间、更新时间、生效日期时效性过滤、版本排序部门研发 / 市场 / 法务权限隔离、范围过滤标签产品规格 / 制度 / 技术文档分类路由、多级检索权限public / internal / confidential检索级权限控制版本号v2.1 / 2024-Q3-rev2版本去重、最新版优先实战经验在向量数据库如 Milvus、Pinecone、Weaviate中元数据作为标量字段与向量一起存储。检索时可以指定filter{department: product, date: {$gte: 2024-01-01}}进行预过滤。这种元数据过滤 向量检索的组合效果远好于纯向量检索尤其是在文档量大、场景明确的情况下。2.4 分块策略影响全局的关键参数分块Chunking是 RAG 数据处理中最核心的环节没有之一。分块决定了检索单元的粒度直接影响检索精度和最终答案质量。为什么要分块因为大语言模型的上下文窗口有限你不能把整个文档塞进去而且从检索精度来说一个 50 页的文档作为一个整体去计算相似度效果远不如把它切成语义连贯的小段。但切得太碎每段缺少上下文切得太大又不够精确。这就是分块要解决的核心矛盾。2.4.1 几种常见的分块策略固定长度分块是最简单的方式——按字符数或 token 数切分比如每 512 个 token 一块。优点是简单可预测缺点是可能在句子中间断开破坏语义完整性。递归字符分块是 LangChain 等框架的默认策略。它按一组分隔符先按双换行、再按单换行、再按空格、最后按字符递归地切分文本尽量在自然边界处断开。这比固定长度好很多但仍然不考虑语义。段落/句子分块以自然段落或句子为单位切分。这保证了每个 chunk 在语法上是完整的但段落长度差异很大——有的段落只有一句话有的段落长达一页导致 chunk 大小不均匀。语义分块是最智能的方式。它用 Embedding 模型计算相邻句子的语义相似度在相似度骤降的地方切分确保每个 chunk 内部语义连贯。缺点是计算成本高而且语义相似度的阈值需要根据具体场景调优。按文档结构分块利用文档本身的结构信息——标题层级、章节划分、HTML 标签——来切分。对于结构良好的文档比如 Markdown、有清晰标题层级的 Word 文档这通常是最好的策略因为它尊重了作者的原始组织逻辑。策略原理优点缺点适用场景固定长度分块按固定字符数如 512截断简单、均匀chunk 大小一致可能切断语义快速验证、格式统一的短文递归字符分块按分隔符层级递归切分\n\n → \n → 。→ 空格尽量保留语义边界灵活适配不考虑语义通用场景、技术文档段落/句子分块以段落或句子为最小单元语义完整天然边界长短不一需合并/拆分处理结构化文档、新闻文章语义分块用 embedding 计算相邻文本语义相似度在语义跳变处切分语义内聚性最高计算成本高需要 embedding 模型高质量要求、长文本父子分块小块检索返回父块大块上下文检索精准 上下文完整需要维护父子映射关系长文档、技术文档、制度文档按文档结构分块按标题层级H1/H2/H3切分保留文档结构上下文清晰依赖文档结构质量Markdown、结构化文档2.4.2 关键参数调优分块不是切了就行关键参数需要反复调优# 分块参数示例以 LangChain RecursiveCharacterTextSplitter 为例 splitter RecursiveCharacterTextSplitter( chunk_size512, # 每个 chunk 的最大字符数 chunk_overlap64, # 相邻 chunk 的重叠区域 separators[\n\n, \n, 。, ], # 分隔符优先级 length_functionlen, )关于两个关键参数chunk_size和chunk_overlap。chunk_size 的选择取决于你的场景。太小的 chunk比如 100 token语义信息不够检索到了也可能答不上来太大的 chunk比如 2000 token可能包含多个主题检索精度下降。根据我的经验对于中文文档200-500 个汉字大约 300-700 token是一个比较好的起点但具体值一定要根据你的实际数据和评测结果来调。chunk_overlap 的作用是防止关键信息恰好出现在切分边界上。一般设置为 chunk_size 的 10%-20%。比如 chunk_size 是 500 tokenoverlap 设 50-100 token 就足够了。overlap 太大会增加存储和计算成本太小则起不到保护作用。一个被反复验证的教训不要试图找到万能的分块参数。不同类型的文档技术文档 vs 合同 vs 聊天记录需要不同的策略和参数。最好的做法是针对你的实际数据做 A/B 测试用检索准确率和最终回答质量来评判哪种分块方案更好。2.5 父子文档小检索大返回这是我在实际项目中用得最多、效果最好的分块策略之一。它解决了一个核心矛盾检索要精准需要小块生成要完整需要大块。两者如何兼得2.5.1 核心思想父子文档策略将文档分成两个层级子块检索块小粒度切分如 200 字用于精准 embedding 检索。父块返回块大粒度切分如 1000 字或整个章节作为检索命中后实际返回给 LLM 的上下文。工作流程用子块做 embedding 检索 → 命中后找到其父块 → 返回父块而不是子块给 LLM 生成。图 4父子文档策略——用小块精准检索返回父块保证上下文完整2.5.2 为什么有效传统分块面临一个两难块太小语义不完整模型看到的是碎片块太大语义被稀释检索精度下降。父子文档策略把这个矛盾拆开了——检索阶段追求精准小块生成阶段追求完整大块各取所需。适用场景父子文档在以下场景效果尤为突出·长文档——产品手册、技术规格书、法律合同单块无法覆盖完整上下文·技术文档——API 文档中一个函数的说明分散在多个段落中·制度文档——某条规定的适用条件在上一段具体内容在下一段分开切分会丢失关联2.5.3 实现要点# 父子文档策略伪代码 # 1. 父块切分大粒度 parent_chunks split_by_sections(doc, max_size1000) # 2. 子块切分从每个父块中切出小粒度子块 child_chunks [] parent_map {} for parent_id, parent in enumerate(parent_chunks): children split_recursive(parent, max_size200) for child in children: child_id f{parent_id}-{len(child_chunks)} parent_map[child_id] parent_id child_chunks.append({id: child_id, text: child}) # 3. 只对子块做 embedding 和索引 embeddings embed([c[text] for c in child_chunks]) index.add(embeddings, metadatachild_chunks) # 4. 检索命中子块 → 返回父块 results index.search(query_embedding, top_k5) parent_ids [parent_map[r.id] for r in results] context [parent_chunks[pid] for pid in deduplicate(parent_ids)]关键细节子块做 embedding父块不做。父块只存储在映射表中检索命中子块后通过parent_map找到父块返回。这样既省了存储和计算又能保证返回的上下文完整。注意事项父子文档策略有一个隐藏成本维护父子映射关系。如果文档更新需要重新切分父块和子块更新映射表。在工程实现上建议将映射关系存储在数据库中而非内存以支持增量更新和故障恢复。写在最后RAG 看起来简单——检索加生成谁都能搭一个 demo。但从 demo 到生产中间隔着的是数据处理的各种脏活累活是对检索质量的持续优化是对失败模式的深入理解。它的门槛不在代码量而在工程细节的把控。基础原理决定了你能不能选对方向——知不知道为什么用 RAG、什么场景该用、什么场景不该用。数据处理决定了你的上限——检索质量的天花板不是模型能力而是数据质量。如果你正在做 RAG 项目我的建议是先花一周时间把数据处理管道打磨好再谈模型选型和 prompt 工程。文档解析是否完整文本清洗是否彻底元数据是否齐全分块策略是否匹配你的文档类型这些脏活累活做到位了后面的事情会顺很多。RAG 的本质是工程问题不是算法问题。把它当工程来做它就不会辜负你。RAG文章RAG 深度解析从原理到工程实践一RAG 检索深度指南从 Embedding 到 Query 处理二RAG 进阶双引擎重排序精准化与生成可控化的工程实践三RAG 进阶之路Agent 自主决策与评估体系四RAG 可观测性实战上线后必须能定位为什么答错五
返回列表