拆解腾讯开源知识库WeKnora学RAG:分片策略详解

拆解腾讯开源知识库WeKnora学RAG:分片策略详解
在RAG检索增强生成知识库系统开发中我们知道文档解析质量、分片策略、嵌入模型、召回策略、重排模型、查询优化等等这些影响了检索召回率和最终问答的质量。分片策略是承上启下的关键纽带它直接决定了文档如何被切转化为一个个 Chunk文本块。切分过大容易引入噪声切分过小则会导致语义碎片化破坏了原文的结构逻辑导致关键上下文在检索阶段被漏掉。文档解析如PDF质量是RAG系统后续环节的基石但本文不进行这方面的探讨很多开源项目如MinerU都在推进这方面的质量我们假设文档都能很好的被转为为Markdown。目前RAG系统中比较常用的分片策略有不代表所有固定大小切片把文本按照固定长度/字符暴力切分一般设置overlap重叠区域每个chunk都带点冗余。分隔符递归切片比如先按段落切分再按句子切分最后按单词切分。按文档结构切标题、章节、代码块算是方案2的增强版本比如标题、表格、代码块等就是天然的语义边界按语义相似度切基于向量嵌入或大模型核心思想是语义主题发生变化的时候才切但需要额外引入嵌入模型或推理模型计算成本高而且和模型能力也息息相关。父子块双层策略parent-child父块保留完整上下文子块负责向量语义匹配这个其实可以结合上面的任意策略来实现。当然分片策略也在不断演进还有一些新的切片模式这里不再展开我们只看WeKnora是如何做的这在RAG实践中很有指导意义甚至可以直接借鉴。关于WeKnora的项目介绍腾讯开源的企业级RAG(支持Wiki)知识库产品WeKnora1.8万Star 开箱即用它的分片策略更偏方案3、方案5细分分片策略为标题切分heading按Markdown标题切分适合标题结构明显的文档启发式切分heuristic按启发式标记切分分页符、编号章节、第X章等7类标记递归分隔符切分legacy兜底策略任何不命中的策略都会回到这层父子分片parent-child父块用来存上下文完整信息子块存入向量库用来检索召回的时候映射会父片。系统会通过分析文档结构依次选择合适的策略不合格就降级到下一种直到legacy模式兜底同时用正则保护表格、公式、代码块等结构元素不被切断。下面逐层拆解具体实现切分粒度结构保护公式、表格、代码块等保护单元的处理策略三层策略链递归分隔符切分legacy策略标题切分器启发式切分器父子块双层分片图片chunk分片后处理WeKnora的主要分片策略是先分析文档结构再选择最合适的切分策略最后用递归分隔符兜底。如果策略未设置或显式设为legacy/recursive则直接走递归分隔符切分。切分粒度chunk_size 512 chunk_overlap 80这个参数影响所有策略块太长或者太短都影响质量512也是常用的Chunk尺寸配置最多1024。这里chunk_size512更准确说是默认或者理想目标尺寸不是严格硬上限。可以把它理解成默认希望切在512左右而不是必须卡死在512以内。如果某个chunk最后切成720在当前实现里也是合法的其实系统隐形的上限是chunk_size * 2即1024。chunk_overlap是相邻chunk之间的重叠字符数也就是切分时新chunk会用上一个chunk的尾部80左右字符开始主要避免边界处的上下文被截断做一些冗余处理。overlap在不同策略下的生效范围不一样递归分隔符切分在所有chunk之间都应用启发式切分在边界段之间应用标题切分只在section内部做递归细分时才应用section与section之间不重叠。结构保护公式、表格、代码块等分片前会先扫一遍文档的结构特征通过两层机制识别需要保护的元素第一层正则表达式识别结构元素分片器内置了6类受保护的正则表达式在分片前扫描全文标记出所有需要保护的结构内容protected_regex [ r\$\$[\s\S]*?\$\$, # 数学公式LaTeX风格 r!\[.*?\]\(.*?\), # 图片Markdown语法 r\[.*?\]\(.*?\), # 链接Markdown语法 r[ ]*(?:\|[^|\n]*)\|[\r\n]\s*(?:\|\s*:?-{3,}:?\s*)\|[\r\n], # 表头 r[ ]*(?:\|[^|\n]*)\|[\r\n], # 表体 r(?:\w)[\r\n][^\r\n]*, # 代码块 ]第二层表头跟踪器HeaderTracker表头跟踪器通过配置类定义表头块的开始和结束模式headerTrackerHook{ startPattern: ^\s*(?:\|[^|\n]*)[\r\n]\s*(?:\|\s*:?-{3,}:?\s*)\|?[\r\n]$, endPattern: ^\s*$|^\s*[^|\s].*$, priority: 15, }Markdown表格由表头行、分隔行和表体行组成。跟踪器的作用不是阻止表格被切分而是记住当前表的表头当表格被切到多个chunk时每个chunk开头都会自动带上表头保证每个chunk都有列名上下文。注意这里的表头长度也计入chunk_size预算。这个机制发生在底层的SplitText递归分隔符逻辑里标题切分和启发式切分本身不直接做表头跟踪但在把超大章节/块下沉到SplitText分割时这个机制会生效。保护单元的处理策略数学公式、图片、链接、表格表头、表体、代码块这6类正则标记出的保护单元在装箱阶段作为不可分割的原子单元参与合并。注意: 表格的保护粒度是行级别: 正则把表头分隔行作为一个区间span、每行数据各作为一个区间保证行内部不被切断但整张表不是原子单元。普通文本按分隔符切分保护单元整体保留最终一起装进chunk入向量库。这意味着一个几千字符的代码块或大表格可能直接成为一个远超chunk_size目标的超大chunk。系统选择保护内容完整性优先于大小约束。保护单元的上限是7500字符超过这个长度的块比如很长的代码块会直接在换行或空格处强制切开不再当原子处理避免单个保护单元撑出过大的chunk。代价是几千字符的大chunk进向量库后嵌入embedding模型可能截断输入匹配精度也会下降。实际文档中这类超大保护单元不多真遇到了更多靠BM25关键词检索命中。三层策略链文档结构分片策略会先走一轮全文档结构分析profiling再根据分析结果组装策略链按优先级依次尝试。第一步结构扫描(和上面的表格、公式、图片分析不同)profiler对文档做一次单遍扫描收集所有结构信号Markdown标题数量、编号章节2.3 Methods、中/德/英文章节标记第一章、Chapter 3、Kapitel 5、全大写短行、视觉分隔线---、、换页符\f、页脚Page 3 of 10、连续空行以及文档语言取前4096字节采样CJK与Latin字符占比都达到15%判定为混合语言CJK占比超过30%判定为中文否则再额外检查德语特征最后回落到英文。第二步组装策略链根据扫描结果再决定哪些策略有资格进入候选链。策略有固定优先级heading最高heuristic次之legacy永远兜底。系统从高到低检查资格满足条件的才加入链不满足的直接跳过Tier 1: heading标题切分 ← 需满足3个条件优先级最高 Tier 2: heuristic启发式切分 ← 需满足1个条件次优先 Tier 3: legacy递归分隔符切分← 无条件永远在链尾兜底进入heading策略需要同时满足三个条件Markdown标题 3个标题行数占总行数的比例超过0.5%每200行至少1个标题存在可识别的标题层级作为文档骨架策略会优先选出3次的标题层级如H1出现了5次作为主切分骨架如果没有任何标题层级3次就用最深的标题层级这样小文档可能只有H1加几个H2也能走标题切分。进入heuristic策略只需满足一个条件启发式标记总数≥5存在换页符存在章节标记基于中/德/英文识别最终产出的策略链可能是[heading, heuristic, legacy]、[heading, legacy]、[heuristic, legacy]或者最坏情况直接是[legacy]。不管哪种组合legacy永远在最后兜底第三步逐级尝试、验证、降级满足条件的策略进入链后系统按优先级从高到低逐个执行。每个层级tier的输出都要过质量验证——验证通过就直接返回不再往下走验证失败才降级到下一个层级遍历 chain 中的每个 tier: → 执行该 tier 的切分逻辑 → 产出 chunks → 质量验证5项检查 ├─ 通过 → 返回结果流程结束 └─ 失败 → 记录拒绝原因降级到下一个 tier质量验证包含5项检查检查项条件拒绝原因空结果chunk数为0该策略没有产出任何chunk单chunk大文档只有1个chunk且文档超过2倍chunk_size切分完全没有生效碎片化超过25%的非末尾chunk不足50字符碎片太多语义信息被切碎过度碎片化所有chunk都不到chunk_size的1/4块太小没有完整语义单元超大chunk最大chunk超过2倍chunk_size块太大向量匹配精度下降验证器设计的比较宽松只拒绝明显有问题的输出接受合理变异这避免了在层级之间频繁振荡。这里也能看出512不是硬上限默认配置下策略验证真正拿来判断明显过大的线是2 * chunk_size 1024。也就是说向量chunk的设计目标是512左右而1024是过大警戒线一个720字符的chunk虽然偏大但仅凭长度这一项不会触发验证拒绝。legacy策略即使验证不通过也会返回结果它是策略链尾的最终兜底保证分片器永远不返回空。所以1024也不是系统绝对硬上限它更像是前面几个层级的质量警戒线。再往下legacy内部还有更靠后的安全兜底会继续强拆极端超大的块。递归分隔符切分legacy策略这是策略链的最后一层也是标题切分和启发式切分内部做细分时共用的底层逻辑。separators [\\n\\n, \\n, 。]这是最小分隔符集合实际使用时通常还会加上、、;、等标点。我记得LangChain的分片策略就是这套其设计偏英文环境。中文场景下\n不太能代表句子边界。这些标点全角符号的标点也是句子分隔。递归的含义是先用第一个分隔符\n\n把文档切成段落(或者说大块)检查每段是否超过chunk_size没超过的直接输出超过的用下一个分隔符\n继续切还超过的再用。切仍然超过的就按chunk_size硬切。每层切出来的chunk之间都带overlap。标题切分器和启发式切分器遇到超大章节/块时也会把超限部分交给这层逻辑做细分如果所有分隔符都切不动最终会按chunk_size硬切保证不超限。标题切分器确定主切分层级后标题切分器按这个层级的标题位置把文档切成章节——每个标题到下一个标题之间是一个章节。每个章节section在切分时会同步构建标题面包屑breadcrumb。系统维护一个6层栈记录标题层级遇到##时清空更深层级输出# Chapter 1\n## Section 2\n### Subsection格式的面包屑换行分隔保留原始#前缀。面包屑存为chunk的ContextHeader字段不占Content正文空间但判断章节能否放进单个chunk时面包屑长度算在chunk_size预算内。章节太大进入legacy策略细分时子chunk的大小预算不再扣面包屑。向量化时面包屑文本拼到文本前面向量检索因此能同时感知文本内容和文档位置。章节正文接近chunk_size时面包屑可能把它推过阈值导致本可以单chunk输出的章节被legacy重新切分。这是为了让chunk粒度贴近目标尺寸。FAQ、变更日志changelog这类标题多但内容短的文档相邻的小chunk会在共享面包屑下合并避免碎片化。面包屑不写入数据库但是拼接到chunk中存入向量库所以它可以影响能不能命中。启发式切分器如果文档标题数量不够或密度太低但文档里有分页符、第X章这类章节信息时策略会降级到启发式heuristic策略。其逻辑本质上和标题切分器一样是规则驱动没有语义理解或模型推理只是用正则表达式识别另一类结构线索非Markdown的视觉标记来找切分边界。进入这个策略只需满足一个条件启发式标记总数≥5或存在换页符、中/德/英文章节标记。备注前提是heading模式未触发。启发式标记共7类按优先级从高到低。同一份文档里多种标记可以共存系统会一次扫描全部收集同一位置出现多个标记时保留优先级最高的优先级类型匹配示例100换页符\fPDF转换后的分页标记90编号章节2.3 Methods、1.1.2 系统架构85中/德/英文章节第一章 概述、Chapter 3、Kapitel 570全大写标题INTRODUCTION、RELATED WORKS:60视觉分隔线---、、***50页脚Page 3 of 10、页码 3/1040连续空行3个以上换行符找到所有边界后先过滤掉落入保护区间的内容公式、图片、链接、表格、代码块不能被切断然后做贪心装箱从文档开头逐段累积内容累积到chunk_size就输出一个chunk两个边界之间的区域本身超过chunk_size时递归交给legacy切分器做内部细分flush后新chunk的起始位置会回退overlap个字符并对齐到最近的语义边界产出的chunk继续做质量验证碎片化太严重超25%的非末尾chunk不足50字符或超尺寸最大chunk超2倍chunk_size即1024都会被拒绝降级到legacy策略。其实整体流程和标题切分器一致 找边界→按边界切分→超大块交给legacy→产出chunks→过策略链验证。区别在于边界来源视觉标记vs标题层级和装箱策略贪心装箱overlap对齐vs按section直切小chunk合并。父子Chunk双层分片WeKnora的父子chunk双层分片parent-child策略默认未开启逻辑是把文档先切成比较大的父块再把父块切成更小的子块。parent_chunk_size 4096 child_chunk_size 384 child_overlap child_size / 5 ≈ 20%硬编码不可单独配置切分步骤先按4096切父块再对每个父块按384切子块两个值都是目标尺寸不是硬上限。父块和子块的切分都走策略链heading/heuristic/legacy逻辑不是固定只走legacy兜底但是按照配置子块大概率都会落入legacy策略处理。子块按父块粒度独立切分边界如果一个父块只切出一个子块且内容完全相同父块不存储子块退化为独立chunk。检索命中文本子块后通过映射关系找出父块内容在合并阶段使用父块内容并入上下文。图片chunk分片后处理文档中图片、图表等也是重要的信息。在文本分片完成后还会从文档中提取图片经过OCR和图片描述模型处理生成两种额外的chunk类型image_ocr图片中的文字和image_caption图片内容描述。这两种chunk是独立的chunk各自单独存储、单独向量化不会合并进text父块的正文里。它们通过ParentChunkID指向包含该图片引用的text父块召回时可以通过这条映射找回上下文。图片chunk的创建独立于文本分片策略不走上面说的三层策略链。无论文本用哪种策略切分图片都走统一的OCR描述流程。最后通过对WeKnora分片策略的拆解我们可以学习到它的核心是一条自适应策略链扫描文档结构按标题→启发式→递归分隔符的优先级逐级尝试 提取受保护元素公式、表格分表头和表体、代码块等结构元素保证这类元素不会被拆分 父子双层分片把检索粒度和上下文完整性拆开小块负责向量匹配然后映射到大块用来加入上下文不管是标题切分还是启发式策略都依赖文档自身的结构质量, 缺乏结构的文档最终会落到递归分隔符切块模式。所以切片策略固然重要但是原始文档和解析后的质量也很重要。WeKnora的分片策略和颗粒度我感觉已经可以支撑大部分知识库应用场景了而且项目还有知识图谱本篇暂未展开。如果你也在开发自己的RAG知识库系统这套分片策略非常具有参考价值大部分场景已经够用了。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

最新新闻

日新闻

周新闻

月新闻