尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

06-文本切分不是越小越好-Chunk大小对RAG的影响

06-文本切分不是越小越好-Chunk大小对RAG的影响 文本切分不是越小越好Chunk文本块大小对 RAG 的影响系列从零构建企业 RAG 知识库第 6 篇1. Chunk 是检索与生成之间的接口文档太长无法作为一个检索单元切得太碎又会丢失语义关系。Chunk 同时影响召回查询能否匹配到正确片段精度片段中有多少无关信息上下文答案需要的条件是否完整成本Embedding 数量与生成 Token溯源引用能否定位到有意义的段落。所以不存在适用于所有文档的“最佳 500 字”。合适大小由文档结构、问题粒度、目标模型 Tokenizer 和评测集共同决定。2. 字符数不等于 Token 数中文、英文、代码和表格的 Token 比例不同。生产系统应使用目标 Embedding/生成模型对应的 Tokenizer 计算预算。本文为保持纯 Python 可运行使用字符上限演示算法不能把该字符数称为真实 Token。3. 优先按语义边界切分fromdataclassesimportdataclassimportredataclass(frozenTrue)classSection:heading:strtext:strsource_position:intdataclass(frozenTrue)classTextChunk:chunk_id:strheading:strtext:strstart_position:intend_position:intdefsplit_sentences(text:str)-list[str]:保留句末标点避免切分后原文无法引用。partsre.split(r(?[。!?;]),text)return[item.strip()foriteminpartsifitem.strip()]标题、段落、句子、列表、代码块和表格行都是自然边界。只有单个语义单元超过上限时才考虑硬切。4. 句子打包算法fromhashlibimportsha256defchunk_section(section:Section,max_chars:int300,overlap_sentences:int1,)-list[TextChunk]:ifmax_chars20:raiseValueError(max_chars 不能小于 20)ifnot0overlap_sentences3:raiseValueError(overlap_sentences 必须在 0 到 3 之间)sentencessplit_sentences(section.text)ifnotsentences:return[]groups:list[list[str]][]current:list[str][]forsentenceinsentences:iflen(sentence)max_chars:raiseValueError(单句超过上限应进入长句专项切分)proposed.join(current[sentence])ifcurrentandlen(proposed)max_chars:groups.append(current)overlapcurrent[-overlap_sentences:]ifoverlap_sentenceselse[]currentlist(overlap)current.append(sentence)ifcurrent:groups.append(current)chunks:list[TextChunk][]cursorsection.source_positionforindex,groupinenumerate(groups):text.join(group)chunk_idsha256(f{section.heading}:{index}:{text}.encode(utf-8)).hexdigest()[:16]chunks.append(TextChunk(chunk_idchunk_id,headingsection.heading,texttext,start_positioncursor,end_positioncursorlen(text),))# 有重叠时位置是近似值精确实现应保留原句 offsetcursorlen(text)returnchunksOverlap重叠帮助保留边界上下文但会重复索引、增加存储并产生近重复召回。应通过评测选择而不是默认越大越好。5. 表格和代码不能照搬段落策略表格问题常依赖表头与某一行应让每个 Chunk 携带表名、表头和行定位。代码应以函数、类或语法树节点切分避免把函数签名与函数体拆开。合同与制度则适合保留章节路径退款制度 / 第二章 / 第三条 / 适用条件将标题路径附在 Chunk 文本或元数据中通常比单纯扩大 Chunk 更有效。6. 用实验选择大小fromdataclassesimportdataclassdataclass(frozenTrue)classChunkExperiment:strategy:strmax_size:intoverlap:intrecall_at_5:floatprecision_at_5:floatavg_context_size:floatdefchoose_experiment(results:list[ChunkExperiment])-ChunkExperiment:ifnotresults:raiseValueError(实验结果不能为空)# 示例约束先保证召回再在候选中选择更少上下文的方案eligible[itemforiteminresultsifitem.recall_at_50.90]ifnoteligible:raiseValueError(没有方案达到召回门槛)returnmax(eligible,keylambdaitem:(item.precision_at_5,-item.avg_context_size),)阈值仅是教学示例。真实实验应固定文档版本、Embedding、查询集和检索参数。7. 可复验测试deftest_chunk_size_and_overlap()-None:sectionSection(退款制度,第一条说明适用范围。第二条说明申请材料。第三条说明审核流程。,0,)chunkschunk_section(section,max_chars25,overlap_sentences1)assertlen(chunks)2assertall(len(item.text)25foriteminchunks)# 相邻块共享一个句子assertsplit_sentences(chunks[0].text)[-1]inchunks[1].textdeftest_oversized_sentence_fails_explicitly()-None:try:chunk_section(Section(标题,很*30。,0),max_chars20)exceptValueError:passelse:raiseAssertionError(超长句不能被静默处理)8. 对抗性审查不跨租户或跨权限文档合并 Chunk重叠 Chunk 去重后再交给模型标题和权限元数据不能在重新切分时丢失文档更新后用策略版本重建索引检查极长句、无标点文本、表格和代码不只看召回率还看上下文噪声、Token、延迟和引用体验。9. 总结Chunk 的目标是让“一个可回答的问题”尽量对应“一个语义完整、噪声有限、可定位的证据单元”。大小只是参数结构感知和可重复评测才是核心。
返回列表