什么是 RAG 中的分块?为什么需要分块? 📅 发布时间:2026/8/20 14:42:28 👁 浏览次数: RAG中的分块核心概念与必要性分块Chunking是RAG系统中将长文档切分成多个小片段的过程。每个片段称为一个块Chunk是后续向量化和检索的基本单元。一、什么是分块1.1 直观理解想象一本1000页的医学教科书不分块把整本书作为一个单元无法精准定位到特定段落分块后切成若干章节、段落、甚至句子每个小块独立存储和检索原始文档1000页 │ ▼ 分块处理 ┌─────────────────────────────────────┐ │ 块1: 第1章 心血管系统概述 │ │ 块2: 第2章 高血压诊断标准 │ │ 块3: 第3章 高血压药物治疗 │ │ 块4: 第4章 高血压生活方式干预 │ │ ... │ │ 块10: 第2章 第3节 ACEI类药物 │ │ ... │ │ 块356: 第15章 第4段 病例讨论 │ └─────────────────────────────────────┘ │ ▼ 向量化 每个块 → 向量 → 存入向量数据库1.2 代码示例// 简单分块示例StringmedicalText 高血压是一种常见的慢性病。 诊断标准收缩压≥140mmHg或舒张压≥90mmHg。 治疗包括生活方式干预和药物治疗。 常用药物有ACEI、ARB、CCB等。 ;// 按句子分块ListStringchunksArrays.asList(高血压是一种常见的慢性病。,诊断标准收缩压≥140mmHg或舒张压≥90mmHg。,治疗包括生活方式干预和药物治疗。,常用药物有ACEI、ARB、CCB等。);二、为什么需要分块2.1 核心原因一览原因说明不分块的后果模型上下文限制LLM有token上限如4K-128K超长文本无法输入检索精准度小块更容易匹配具体问题大块包含无关信息召回率低语义粒度每个块代表一个独立语义单元粒度太粗难以定位答案成本控制只将相关块传给LLM每次都传全文token成本高性能优化并行处理多个块检索速度慢2.2 详细展开原因一模型上下文限制// 问题示例StringquestionACEI类药物的禁忌证是什么;StringfullTextloadFullTextbook();// 100万字// ❌ 不分块无法处理// 模型上下文窗口只有4K-128K tokenschatModel.call(fullTextquestion);// 超出限制// ✅ 分块后只取相关块ListDocumentChunkrelevantChunksretrieve(question);// 只取2个相关块StringanswerchatModel.call(questionrelevantChunks);// 在限制内原因二检索精准度不分块的问题文档块整章2000 tokens 高血压治疗包括ACEI类药物如依那普利、赖诺普利...大量内容... 药物副作用包括干咳、血管性水肿... ↑ 用户问ACEI类药物引起干咳怎么办 ──────────────┘整个章节被检索到但大部分内容无关难以精确定位到干咳相关内容向量相似度被其他内容稀释分块后块A: ACEI类药物包括依那普利、赖诺普利、培哚普利... 块B: ACEI类药物的常见副作用干咳发生率10-20%、血管性水肿... 块C: 干咳的处理方法换用ARB类药物、对症治疗... 用户问ACEI类药物引起干咳怎么办 → 精准匹配块B和块C原因三语义粒度控制// 不同粒度对比publicclassChunkGranularity{// 粒度太粗章节级voidtooCoarse(){ChunkchunknewChunk(第3章 心血管疾病治疗5000 tokens);// 问题β受体阻滞剂的心率控制目标// 检索结果整章但答案只在第3节第2段}// 粒度合适段落级voidappropriate(){ChunkchunknewChunk(β受体阻滞剂的心率控制目标静息心率55-60次/分,Map.of(section,3.2,topic,心率管理));// 问题β受体阻滞剂的心率控制目标// 检索结果直接命中这个块}// 粒度太细句子级voidtooFine(){ChunkchunknewChunk(静息心率55-60次/分);// 问题β受体阻滞剂的心率控制目标// 检索结果可能命中但丢失了上下文药物名称}}原因四成本优化不分块模式 用户问题 → 检索整本书 → 传递所有内容给LLM → 成本 全文字数 × 每次调用 分块模式 用户问题 → 检索相关块2-5个 → 只传递相关块给LLM → 成本 块大小 × 调用次数 成本对比 - 不分块100万字文档 × 1000次调用 10亿 tokens - 分块后500字/块 × 2块 × 1000次调用 100万 tokens 成本降低约 1000 倍原因五支持增量更新// 知识库更新场景publicclassIncrementalUpdate{// 不分块更新一个知识点需要重新处理整本书voidupdateWholeBook(){DocumentbookloadBook();book.updateSection(高血压诊断标准,新标准130/80mmHg);// 需要重新索引整本书1000页reindexAll(book);// 耗时、成本高}// 分块只更新相关块voidupdateChunks(){DocumentChunkchunkfindChunk(高血压诊断标准);chunk.updateContent(新标准130/80mmHg);// 只重新向量化这个块vectorStore.update(chunk);// 快速、低成本}}三、分块策略对比3.1 常见分块方法策略原理优点缺点适用场景固定大小按固定token数切割简单、可控可能打断语义通用、快速原型句子级按句子边界切割语义完整粒度太细短文本、FAQ段落级按段落边界切割保留上下文长度不固定通用文档语义级基于内容相似度聚类语义连贯计算复杂高质量需求结构级按标题/章节切割保留层次依赖格式结构化文档递归级先粗后细逐级切割灵活适应实现复杂长文档、混合内容3.2 医疗场景的分块策略ComponentpublicclassMedicalChunkingStrategy{/** * 临床指南按结构切割 */publicListDocumentChunkguidelineChunk(Stringtext,Structurestructure){// 保留章节层级ListDocumentChunkchunksnewArrayList();for(Sectionsection:structure.getSections()){DocumentChunkchunknewDocumentChunk();chunk.setContent(section.getContent());chunk.setMetadata(Map.of(section_title,section.getTitle(),section_level,section.getLevel(),guideline_name,structure.getTitle(),version,structure.getVersion()));// 章节过长则递归切割if(chunk.getTokenCount()800){chunks.addAll(recursiveChunk(chunk));}else{chunks.add(chunk);}}returnchunks;}/** * 药品说明书按字段切割 */publicListDocumentChunkdrugInsertChunk(Stringtext){// 预定义字段MapString,StringfieldsextractFields(text,List.of(通用名,商品名,适应证,用法用量,禁忌证,不良反应,注意事项,药物相互作用));returnfields.entrySet().stream().map(entry-{DocumentChunkchunknewDocumentChunk();chunk.setContent(entry.getValue());chunk.setMetadata(Map.of(field,entry.getKey(),drug_name,fields.get(通用名),type,drug_insert));returnchunk;}).collect(Collectors.toList());}/** * 患者病历语义切割 */publicListDocumentChunkmedicalRecordChunk(Stringtext){// 按时间线切割ListStringepisodesextractByTimeLine(text);returnepisodes.stream().map(episode-{DocumentChunkchunknewDocumentChunk();chunk.setContent(episode);chunk.setMetadata(Map.of(type,clinical_episode,date,extractDate(episode)));returnchunk;}).collect(Collectors.toList());}/** * 医学文献递归切割 */publicListDocumentChunkliteratureChunk(Stringtext){// 先按章节切割ListDocumentChunksectionChunkssplitBySections(text);ListDocumentChunkfinalChunksnewArrayList();for(DocumentChunkchunk:sectionChunks){if(chunk.getTokenCount()800){// 章节过长按段落再切割finalChunks.addAll(splitByParagraphs(chunk));}elseif(chunk.getTokenCount()200){// 章节过短合并到上一章mergeWithPrevious(finalChunks,chunk);}else{finalChunks.add(chunk);}}returnfinalChunks;}}四、分块的最佳实践4.1 黄金法则publicclassChunkingBestPractices{/** * 法则1保留边界上下文 */publicvoidoverlappingChunk(){// 块之间有重叠避免信息在边界处断裂TokenTextSplittersplitternewTokenTextSplitter(512,// 块大小50// 重叠50个token);// 块1: tokens 0-512// 块2: tokens 462-974 ← 与块1重叠// 块3: tokens 924-1486 ← 与块2重叠}/** * 法则2保留元数据 */publicvoidpreserveMetadata(){DocumentChunkchunknewDocumentChunk();chunk.setContent(ACEI类药物可引起干咳...);chunk.setMetadata(Map.of(source,高血压诊疗指南2024,section,第3章 药物治疗,page,156,author,中华医学会,confidence,0.95,doc_type,clinical_guideline));// 检索时可以按元数据过滤}/** * 法则3根据应用场景选择粒度 */publicChunkSizeselectChunkSize(ApplicationTypeappType){returnswitch(appType){caseQUESTION_ANSWERING-newChunkSize(300,50);// 细粒度caseDOCUMENT_SUMMARY-newChunkSize(800,100);// 粗粒度caseFACT_RETRIEVAL-newChunkSize(150,30);// 很细粒度caseCONTEXT_UNDERSTANDING-newChunkSize(500,75);// 中等粒度};}/** * 法则4支持父子块关系 */publicvoidparentChildChunking(){// 父块章节级用于上下文ParentChunkparentnewParentChunk(第3章 高血压药物治疗,本章介绍高血压的药物治疗方案包括...);// 子块段落级用于检索ListChildChunkchildrenArrays.asList(newChildChunk(ACEI类药物...,parent.getId()),newChildChunk(ARB类药物...,parent.getId()),newChildChunk(CCB类药物...,parent.getId()));// 检索时先找到子块再关联父块获取完整上下文ChildChunkretrievedsearch(ACEI禁忌证);ParentChunkcontextloadParent(retrieved.getParentId());// 答案 子块内容 父块上下文}}4.2 常见问题与解决方案问题影响解决方案语义断裂答案被切分到两个块增加重叠、使用语义切割粒度不当召回率低或成本高根据场景调整、A/B测试元数据丢失无法溯源和过滤保留来源、章节、页码表格/代码破坏结构信息丢失特殊处理、保留格式多语言混合分词不准确使用多语言分词器五、分块效果的量化评估ComponentpublicclassChunkingEvaluator{/** * 评估分块质量 */publicChunkingMetricsevaluate(ListDocumentChunkchunks,ListTestQuerytestQueries){intsemanticIntegrity0;// 语义完整性分数intretrievalAccuracy0;// 检索准确率intcontextSufficiency0;// 上下文充足度for(TestQueryquery:testQueries){// 检查答案是否完整包含在单个块中if(isAnswerInSingleChunk(query,chunks)){semanticIntegrity;}// 检查检索能否命中相关块if(canRetrieveCorrectChunk(query,chunks)){retrievalAccuracy;}// 检查块是否包含足够上下文理解答案if(hasSufficientContext(query,chunks)){contextSufficiency;}}returnnewChunkingMetrics(semanticIntegrity/(double)testQueries.size(),retrievalAccuracy/(double)testQueries.size(),contextSufficiency/(double)testQueries.size());}/** * 对比不同分块策略 */publicStrategyComparisoncompareStrategies(){returnStrategyComparison.builder().fixedSize(0.65,0.70,0.55).sentenceBased(0.55,0.85,0.45).semanticBased(0.85,0.80,0.75).structureBased(0.90,0.75,0.85).build();}}六、总结分块是RAG系统的基石它决定了检索的精度粒度合适才能精准匹配生成的品质上下文完整才能准确回答系统的成本块大小直接影响token消耗维护的便捷细粒度支持增量更新核心要点分块是为了在语义完整性和检索精度之间找到平衡医疗场景需要根据文档类型指南/说明书/病历采用不同策略重叠、元数据、父子关系是提升分块质量的三大技术分块策略需要通过实际评估来优化