分片质量决定RAG检索上限!8种主流分片方法深度解析(附代码示例)

张开发
2026/4/18 0:31:45 15 分钟阅读

分享文章

分片质量决定RAG检索上限!8种主流分片方法深度解析(附代码示例)
在实际工程中分片直接决定了RAG系统的召回率是否能检索到相关信息精度检索内容是否干净、无噪声上下文利用率token是否被浪费。所以说分片的质量等于检索质量的上限。目前主流的分片方法有固定长度分片Fixed-size Chunking基于语义的分片Semantic Chunking结构感知分片Structure-aware Chunking滑动窗口分片Sliding Window递归分片Recursive Chunking基于查询优化的分片Query-aware Chunking多粒度分片Multi-granularity Chunking带metadata的分片我们对以上的方法展开说说固定长度分片Fixed-size Chunking这种方法是按照token / 字符数切分如256 / 512 tokens通常带overlap重叠。优点简单稳定工程实现成本低embedding分布均匀易于并行处理缺点语义被切断句子 / 段落被拆开上下文不完整 → 影响回答质量适用场景baseline系统非结构化文本日志爬虫数据大规模数据快速上线代码示例按字符切分from typing import List def fixed_size_chunk(text: str, chunk_size: int 500, overlap: int 100) - List[str]: if chunk_size 0: raise ValueError(chunk_size must be 0) if overlap chunk_size: raise ValueError(overlap must be smaller than chunk_size) chunks [] start 0 step chunk_size - overlap while start len(text): end start chunk_size chunk text[start:end].strip() if chunk: chunks.append(chunk) start step return chunks if __name__ __main__: text 这是一个很长的文本。 * 200 chunks fixed_size_chunk(text, chunk_size100, overlap20) for i, c in enumerate(chunks[:3]): print(f--- chunk {i} ---) print(c[:80], \n)代码示例按单词切分from typing import List def fixed_word_chunk(text: str, chunk_size: int 100, overlap: int 20) - List[str]: words text.split() if chunk_size 0: raise ValueError(chunk_size must be 0) if overlap chunk_size: raise ValueError(overlap must be smaller than chunk_size) chunks [] step chunk_size - overlap for start in range(0, len(words), step): chunk_words words[start:start chunk_size] if chunk_words: chunks.append( .join(chunk_words)) return chunks基于语义的分片Semantic Chunking其方法是根据语义边界切分例如段落句子等。优点chunk语义完整检索质量显著提升缺点chunk大小不均实现复杂可能过大超过token的限制使用场景文档问答PDF论文法律金融医疗文本代码示例基于段落的语义分片import re from typing import List def paragraph_chunk(text: str, max_chars: int 800) - List[str]: paragraphs [p.strip() for p in re.split(r\n\s*\n, text) if p.strip()] chunks [] current for p in paragraphs: candidate f{current}\n\n{p}.strip() if current else p if len(candidate) max_chars: current candidate else: if current: chunks.append(current) # 单段过长继续硬切 if len(p) max_chars: for i in range(0, len(p), max_chars): piece p[i:i max_chars].strip() if piece: chunks.append(piece) current else: current p if current: chunks.append(current) return chunks基于相邻句子相似度的语义分片思路是先切句子计算相邻句子的相似度如果相似度突然下降认为主题发生切换之后在该处进行chunk真正工程实现一般会用embedding模型。适用场景主题切换明显的长文比固定切分更注重语义边界结构感知分片Structure-aware Chunking这种方法是利用文档结构Markdown标题HTML标签PDF结构sectiontablecaption代码函数类优点强语义对齐高可解释性很适合长文档缺点依赖结构解析质量对脏数据效果差适用场景技术文档API文档代码库代码示例按照markdown标题切分import re from typing import List, Dict HEADER_RE re.compile(r^(#{1,6})\s(.*)$) def markdown_header_chunk(markdown_text: str) - List[Dict]: lines markdown_text.splitlines() chunks [] current_header {level: 0, title: ROOT} current_content [] for line in lines: m HEADER_RE.match(line.strip()) if m: if current_content: chunks.append({ header_level: current_header[level], header_title: current_header[title], content: \n.join(current_content).strip() }) current_content [] current_header { level: len(m.group(1)), title: m.group(2).strip() } else: current_content.append(line) if current_content: chunks.append({ header_level: current_header[level], header_title: current_header[title], content: \n.join(current_content).strip() }) return [c for c in chunks if c[content]] if __name__ __main__: md # RAG系统 这是简介。 ## 分片策略 这里讲分片。 ## 检索策略 这里讲检索。 ### 稠密检索 这里讲embedding检索。 chunks markdown_header_chunk(md) for i, c in enumerate(chunks): print(f--- chunk {i} ---) print(c)在实际工程中通常会把父标题路径也存进去并且对太长section再做递归切分另外metadata里记录doc_id / section_path / source。代码示例用ast解析python文件import ast from typing import List, Dict def python_code_chunk(code: str) - List[Dict]: tree ast.parse(code) lines code.splitlines() chunks [] for node in tree.body: if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)): start node.lineno - 1 end getattr(node, end_lineno, start 1) snippet \n.join(lines[start:end]) chunks.append({ type: type(node).__name__, name: node.name, start_line: node.lineno, end_line: end, content: snippet }) return chunks if __name__ __main__: code import os def foo(x): return x 1 class Bar: def baz(self, y): return y * 2 for chunk in python_code_chunk(code): print(chunk[type], chunk[name]) print(chunk[content]) print()滑动窗口分片Sliding Window这种方法是固定窗口overlap优点是减少语义断裂提高召回。缺点是数据冗余会提高embedding成本会检索重复内容。适用场景QA系统长上下文推理递归分片Recursive Chunking这种方法是按照优先级逐层切分段落 → 句子 → 单词 → 字符。直到满足chunk size。优点尽量保持语义完整自动适配不同文本缺点不完全语义感知代码示例递归分片import re from typing import List def split_by_paragraph(text: str) - List[str]: return [p.strip() for p in re.split(r\n\s*\n, text) if p.strip()] def split_by_sentence(text: str) - List[str]: # 简化版中英文句子切分 parts re.split(r(?[。!?\.])\s, text) return [p.strip() for p in parts if p.strip()] def recursive_chunk( text: str, max_chars: int 500, min_chars: int 100 ) - List[str]: def helper(block: str) - List[str]: block block.strip() if not block: return [] if len(block) max_chars: return [block] paragraphs split_by_paragraph(block) if len(paragraphs) 1: result [] current for p in paragraphs: candidate f{current}\n\n{p}.strip() if current else p if len(candidate) max_chars: current candidate else: if current: result.extend(helper(current)) current p if current: result.extend(helper(current)) return result sentences split_by_sentence(block) if len(sentences) 1: result [] current for s in sentences: candidate f{current} {s}.strip() if current else s if len(candidate) max_chars: current candidate else: if current: result.append(current) current s if current: result.append(current) return result # 再不行就硬切 hard_chunks [] for i in range(0, len(block), max_chars): piece block[i:i max_chars].strip() if piece: hard_chunks.append(piece) return hard_chunks raw_chunks helper(text) # 可选把太小的块与前一个合并 merged [] for chunk in raw_chunks: if merged and len(chunk) min_chars: merged[-1] chunk else: merged.append(chunk) return merged if __name__ __main__: sample 第一段。这是一段介绍性内容。用于说明背景。 第二段比较长。它包含更多细节。适合进行递归切分。 这里继续补充一些句子。让文本稍微更长一点。 第三段是总结。 chunks recursive_chunk(sample, max_chars60) for i, c in enumerate(chunks): print(f--- chunk {i} ({len(c)} chars) ---) print(c)基于查询优化的分片Query-aware Chunking根据用户查询动态构建chunklate chunking检索后再切query-guided segmentationdynamic context assembly优点极高相关性上下文利用率高缺点系统复杂latency增加多粒度分片Multi-granularity Chunking这个方法需要同时维护小chunk精确匹配大chunk上下文完整检索时融合hybrid retrieval优点recall context双优化。缺点index成本翻倍需要rerank。带metadata的分片这种方法就是chunk不只是只有字符串。至少有chunk_iddoc_idsourcesectionpositiontoken_count 或 char_count代码示例from typing import List, Dict def chunk_with_metadata(text: str, doc_id: str, source: str) - List[Dict]: raw_chunks fixed_size_chunk(text, chunk_size500, overlap100) results [] for i, chunk in enumerate(raw_chunks): results.append({ chunk_id: f{doc_id}_chunk_{i}, doc_id: doc_id, source: source, position: i, char_count: len(chunk), content: chunk, }) return results if __name__ __main__: docs chunk_with_metadata(这是一个测试文档。 * 100, doc_iddoc_001, sourcekb/manual.md) print(docs[0])01什么是AI大模型应用开发工程师如果说AI大模型是蕴藏着巨大能量的“后台超级能力”那么AI大模型应用开发工程师就是将这种能量转化为实用工具的执行者。AI大模型应用开发工程师是基于AI大模型设计开发落地业务的应用工程师。这个职业的核心价值在于打破技术与用户之间的壁垒把普通人难以理解的算法逻辑、模型参数转化为人人都能轻松操作的产品形态。无论是日常写作时用到的AI文案生成器、修图软件里的智能美化功能还是办公场景中的自动记账工具、会议记录用的语音转文字APP这些看似简单的应用背后都是应用开发工程师在默默搭建技术与需求之间的桥梁。他们不追求创造全新的大模型而是专注于让已有的大模型“听懂”业务需求“学会”解决具体问题最终形成可落地、可使用的产品。CSDN粉丝独家福利给大家整理了一份AI大模型全套学习资料这份完整版的 AI 大模型学习资料已经上传CSDN朋友们如果需要可以扫描下方二维码点击下方CSDN官方认证链接免费领取【保证100%免费】02AI大模型应用开发工程师的核心职责需求分析与拆解是工作的起点也是确保开发不偏离方向的关键。应用开发工程师需要直接对接业务方深入理解其核心诉求——不仅要明确“要做什么”更要厘清“为什么要做”以及“做到什么程度算合格”。在此基础上他们会将模糊的业务需求拆解为具体的技术任务明确每个环节的执行标准并评估技术实现的可行性同时定义清晰的核心指标为后续开发、测试提供依据。这一步就像建筑前的图纸设计若出现偏差后续所有工作都可能白费。技术选型与适配是衔接需求与开发的核心环节。工程师需要根据业务场景的特点选择合适的基础大模型、开发框架和工具——不同的业务对模型的响应速度、精度、成本要求不同选型的合理性直接影响最终产品的表现。同时他们还要对行业相关数据进行预处理通过提示词工程优化模型输出或在必要时进行轻量化微调让基础模型更好地适配具体业务。此外设计合理的上下文管理规则确保模型理解连贯需求建立敏感信息过滤机制保障数据安全也是这一环节的重要内容。应用开发与对接则是将方案转化为产品的实操阶段。工程师会利用选定的开发框架构建应用的核心功能同时联动各类外部系统——比如将AI模型与企业现有的客户管理系统、数据存储系统打通确保数据流转顺畅。在这一过程中他们还需要配合设计团队打磨前端交互界面让技术功能以简洁易懂的方式呈现给用户实现从技术方案到产品形态的转化。测试与优化是保障产品质量的关键步骤。工程师会开展全面的功能测试找出并修复开发过程中出现的漏洞同时针对模型的响应速度、稳定性等性能指标进行优化。安全合规性也是测试的重点需要确保应用符合数据保护、隐私安全等相关规定。此外他们还会收集用户反馈通过调整模型参数、优化提示词等方式持续提升产品体验让应用更贴合用户实际使用需求。部署运维与迭代则贯穿产品的整个生命周期。工程师会通过云服务器或私有服务器将应用部署上线并实时监控运行状态及时处理突发故障确保应用稳定运行。随着业务需求的变化他们还需要对应用功能进行迭代更新同时编写完善的开发文档和使用手册为后续的维护和交接提供支持。03薪资情况与职业价值市场对这一职业的高度认可直接体现在薪资待遇上。据猎聘最新在招岗位数据显示AI大模型应用开发工程师的月薪最高可达60k。在AI技术加速落地的当下这种“技术业务”的复合型能力尤为稀缺让该职业成为当下极具吸引力的就业选择。AI大模型应用开发工程师是AI技术落地的关键桥梁。他们用专业能力将抽象的技术转化为具体的产品让大模型的价值真正渗透到各行各业。随着AI场景化应用的不断深化这一职业的重要性将更加凸显也必将吸引更多人才投身其中推动AI技术更好地服务于社会发展。CSDN粉丝独家福利给大家整理了一份AI大模型全套学习资料这份完整版的 AI 大模型学习资料已经上传CSDN朋友们如果需要可以扫描下方二维码点击下方CSDN官方认证链接免费领取【保证100%免费】

更多文章