rag chunking strategy evaluation

RAG分块策略对比评估

引言 分块(Chunking)是RAG系统中承上启下的关键环节:上承文档解析,下接向量检索和生成。分块策略直接影响检索精度和生成质量——太大或太小的块都会导致问题。本文对主流分块策略进行系统对比评估,并提供选型建议。 分块为何重要 分块大小的影响 块过大的问题:单个向量难以准确表示大段内容的语义;检索时相似度分数被稀释;上下文窗口浪费在不相关信息上;增大embedding计算成本。 块过小的问题:语义不完整,检索到的块可能缺少上下文;需要检索更多块才能获得完整信息;增加索引存储和检索开销。 分块边界的影响 即使大小合适,切分位置不当也会导致问题:在句子中间切断导致语义破碎;在段落中间切分丢失段落级语义;切断实体与其描述的关联。 主流分块策略 策略一:固定大小分块 按固定token数切分,通常配合一定重叠: def fixed_size_chunk(text, chunk_size=512, overlap=50): """固定大小分块""" tokens = tokenizer.encode(text) chunks = [] for i in range(0, len(tokens), chunk_size - overlap): chunk_tokens = tokens[i:i + chunk_size] chunk_text = tokenizer.decode(chunk_tokens) chunks.append(chunk_text) if i + chunk_size >= len(tokens): break return chunks 优势:实现简单、速度极快、块大小可控。 劣势:可能在句子中间切断、不感知内容结构、不同文档可能需要不同大小。 适用场景:快速原型、格式统一的文档、对速度要求高的场景。 策略二:句子级分块 以句子为最小单位进行分块: import nltk def sentence_chunk(text, max_chunk_size=512): """按句子分块""" sentences = nltk.sent_tokenize(text) chunks = [] current_chunk = [] current_size = 0 for sent in sentences: sent_size = len(tokenizer.encode(sent)) if current_size + sent_size > max_chunk_size and current_chunk: chunks.append(" ".join(current_chunk)) current_chunk = [sent] current_size = sent_size else: current_chunk.append(sent) current_size += sent_size if current_chunk: chunks.append(" ".join(current_chunk)) return chunks 优势:保持句子完整性、语义边界更合理。 劣势:块大小不均匀、长句子可能导致超大块、段落结构可能被破坏。 适用场景:自然语言文本、新闻文章、博客内容。 策略三:段落级分块 按段落切分,合并过小段落: def paragraph_chunk(text, max_chunk_size=512, min_chunk_size=100): """按段落分块""" paragraphs = text.split("\n\n") chunks = [] current_chunk = "" current_size = 0 for para in paragraphs: para_size = len(tokenizer.encode(para)) if para_size > max_chunk_size: # 段落过大,降级为句子分块 sub_chunks = sentence_chunk(para, max_chunk_size) chunks.extend(sub_chunks) elif current_size + para_size > max_chunk_size and current_chunk: chunks.append(current_chunk) current_chunk = para current_size = para_size else: current_chunk = current_chunk + "\n\n" + para if current_chunk else para current_size += para_size if current_chunk and current_size >= min_chunk_size: chunks.append(current_chunk) elif current_chunk and chunks: chunks[-1] += "\n\n" + current_chunk return chunks 优势:保持段落完整性、适合结构化文档、语义连贯性好。 ...

2026-06-27 · 3 min · 504 words · 硅基 AGI 探索者
rag evaluation guide

RAG 系统评估指南:从检索到生成的全链路评测

RAG 评估的特殊性 RAG 系统由检索和生成两个阶段组成。传统评估只看最终回答质量,但 RAG 的问题可能出在检索阶段——检索到的文档是错的,再好的生成模型也无法给出正确回答。因此 RAG 评估必须是全链路的。 评估维度 用户问题 → [检索器] → 检索文档 → [生成器] → 最终回答 ↑ ↑ 检索质量评估 生成质量评估 检索质量指标 指标 含义 Context Precision 检索文档中相关部分的比例 Context Recall 答案所需信息被检索到的比例 Hit Rate 至少检索到一个相关文档的比例 MRR 相关文档的排名倒数均值 生成质量指标 指标 含义 Faithfulness 回答是否忠于检索文档(无幻觉) Answer Relevance 回答与问题的相关程度 Answer Correctness 回答与标准答案的匹配度 Hallucination Rate 无法从文档推导的陈述比例 RAGAS 框架 RAGAS 是最流行的 RAG 评估框架,支持无参考评估(不需要标准答案)。 from ragas import evaluate from ragas.metrics import ( faithfulness, answer_relevancy, context_precision, context_recall, ) from datasets import Dataset eval_data = Dataset.from_dict({ "question": ["什么是量子计算?", "如何防止SQL注入?"], "answer": [ "量子计算利用量子力学原理进行计算,使用量子比特...", "防止SQL注入的方法包括参数化查询、输入验证...", ], "contexts": [ ["量子计算利用量子力学原理...", "量子比特可同时处于0和1的叠加态..."], ["SQL注入通过嵌入恶意SQL语句实现...", "参数化查询是最有效方法..."], ], "ground_truth": [ "量子计算利用量子叠加和纠缠原理进行并行计算。", "使用参数化查询、输入验证、ORM来防止SQL注入。", ], }) results = evaluate(eval_data, metrics=[ faithfulness, answer_relevancy, context_precision, context_recall, ]) # {'faithfulness': 0.85, 'answer_relevancy': 0.92, # 'context_precision': 0.78, 'context_recall': 0.88} Faithfulness 详解 衡量回答中每个陈述是否能从检索文档推导: ...

2026-06-24 · 2 min · 301 words · 硅基 AGI 探索者
鲁ICP备2026018361号