RAG分块策略深度对比:语义分块 vs 文档感知 vs 层级分块

RAG分块策略深度对比:语义分块 vs 文档感知 vs 层级分块

为什么分块策略如此重要? 在RAG系统中,分块(Chunking)是影响检索质量的第一道关卡。同样的文档、同样的Embedding模型、同样的LLM,仅仅因为分块策略不同,检索准确率可以相差30%以上。 核心矛盾在于:块太大,检索精度下降(噪声多);块太小,上下文不足(语义不完整)。 好的分块策略要在这两端之间找到最优解。 六种分块策略全面对比 1. 固定大小分块(Fixed-Size Chunking) 最简单的策略:按固定token数切分,带overlap。 from langchain.text_splitter import RecursiveCharacterTextSplitter splitter = RecursiveCharacterTextSplitter( chunk_size=512, chunk_overlap=50, separators=["\n\n", "\n", "。", "!", "?", ",", " "], ) chunks = splitter.split_text(document) 参数 推荐值 说明 chunk_size 256-1024 取决于文档类型,技术文档建议512 chunk_overlap 10-20% 防止语义在切分边界断裂 优点:实现简单、速度快、可预测 缺点:可能在句子中间切断,破坏语义完整性 适用:快速原型、均匀文本(如日志、评论) 2. 语义分块(Semantic Chunking) 不按固定大小切,而是按语义相似度断点切。当相邻句子的语义相似度低于阈值时,在此处分块。 from semantic_chunker import SemanticChunker from langchain_openai import OpenAIEmbeddings # 基于Embedding相似度的语义分块 chunker = SemanticChunker( OpenAIEmbeddings(model="text-embedding-3-large"), breakpoint_threshold_type="percentile", # 或 "standard_deviation" breakpoint_threshold_amount=95, # 百分位阈值 ) chunks = chunker.split_text(document) 工作原理: 句子1 → 句子2 → 句子3 → 句子4 → 句子5 0.92 0.88 0.45↓ 0.91 0.87 ↑ 语义断点(相似度骤降) 在这里切分 # 自定义语义分块实现 import numpy as np from sklearn.metrics.pairwise import cosine_similarity def semantic_chunk(text, embeddings_model, threshold=0.5): """基于句子间语义相似度的自适应分块""" sentences = split_into_sentences(text) # 计算每对相邻句子的相似度 embeddings = [embeddings_model.embed(s) for s in sentences] similarities = [ cosine_similarity([embeddings[i]], [embeddings[i+1]])[0][0] for i in range(len(embeddings) - 1) ] # 找到相似度低于阈值的位置作为断点 chunks = [] current_chunk = [sentences[0]] for i, sim in enumerate(similarities): if sim < threshold: chunks.append(" ".join(current_chunk)) current_chunk = [sentences[i + 1]] else: current_chunk.append(sentences[i + 1]) chunks.append(" ".join(current_chunk)) return chunks 优点:语义完整、适应文档结构 缺点:计算开销大(每句话都要Embedding)、块大小不可控 适用:长文章、研究报告、新闻 ...

2026-06-30 · 4 min · 695 words · 硅基 AGI 探索者
Reranker模型选型:Cohere vs BGE vs Jina对比

Reranker模型选型:Cohere vs BGE vs Jina对比

为什么需要Reranker? RAG检索分两个阶段: 第一阶段:召回(Recall) Embedding向量检索,快速从百万文档中召回Top-K(K=20-50) 优势:速度快(<50ms) 劣势:精度有限(Embedding模型容量小,语义理解浅) 第二阶段:精排(Precision) Cross-Encoder Reranker对Top-K重新打分排序 优势:精度高(Cross-Encoder能深度理解query-doc关系) 劣势:速度慢(需对每个候选单独计算) Reranker的本质:用更强的模型对初筛结果做精排,用少量延迟换取显著的精度提升。 Cross-Encoder vs Bi-Encoder Bi-Encoder (Embedding模型): Query ──► Encoder ──► [向量] ◄── Encoder ◄── Document │ 余弦相似度 快但浅 Cross-Encoder (Reranker): [Query, Document] ──► Encoder ──► 相关性分数 慢但深 Cross-Encoder将query和document拼接后一起输入模型,能捕捉两者间的细粒度交互关系,这是Bi-Encoder做不到的。 三大Reranker深度对比 1. Cohere Reranker import cohere co = cohere.Client(api_key="your-key") def cohere_rerank(query, documents, top_n=5): results = co.rerank( model="rerank-v3.5", query=query, documents=documents, top_n=top_n, ) reranked = [] for result in results.results: reranked.append({ "document": documents[result.index], "relevance_score": result.relevance_score, "index": result.index, }) return reranked 特点: ...

2026-06-30 · 4 min · 754 words · 硅基 AGI 推索者
rag rerank strategy

RAG重排序Rerank策略

引言 在RAG系统中,向量检索通常返回Top-K候选文档,但这些文档的排序精度往往不够理想——原因在于向量检索使用的是双塔模型(Bi-Encoder),查询和文档独立编码,无法捕获细粒度的交互特征。重排序(Rerank)通过使用更精细的交叉编码器(Cross-Encoder)对候选文档重新打分,显著提升排序质量。本文深入Rerank策略的原理、模型选择和工程实践。 为什么需要Rerank 双塔模型的局限 向量检索使用双塔模型:查询和文档分别编码为向量,通过点积或余弦相似度计算相关性。这种方式的优势是速度快(可以预计算文档向量),但局限在于: 缺乏交互:查询和文档在编码时没有交互,无法捕获词级别的匹配关系 语义粗粒度:向量相似度高不等于真正相关,可能存在"语义假阳性" 排序精度有限:Top-1的准确率通常只有60-70%,存在改进空间 Cross-Encoder的优势 重排序模型使用Cross-Encoder:将查询和文档拼接在一起输入模型,模型可以捕获两者的细粒度交互特征。这相当于让模型"逐字对比"查询和文档,排序精度远高于双塔模型。 两阶段检索架构 查询 → 向量检索(召回阶段)→ Top-20候选 → Rerank(精排阶段)→ Top-5最终结果 两阶段架构平衡了效率和精度:向量检索负责高效召回,Rerank负责精确排序。 Rerank模型选择 通用Rerank模型 Cohere Rerank:商业API,效果优秀,使用简单: import cohere co = cohere.Client('your-api-key') def cohere_rerank(query, documents, top_n=5): results = co.rerank( model='rerank-multilingual-v3.0', query=query, documents=documents, top_n=top_n ) return [documents[r.index] for r in results.results] BGE-Reranker:开源模型,支持本地部署: from FlagEmbedding import FlagReranker reranker = FlagReranker('BAAI/bge-reranker-large', use_fp16=True) def bge_rerank(query, documents, top_n=5): pairs = [[query, doc] for doc in documents] scores = reranker.compute_score(pairs) # 按分数排序 ranked = sorted(zip(documents, scores), key=lambda x: x[1], reverse=True) return [doc for doc, _ in ranked[:top_n]] bge-reranker-v2-m3:多语言支持,轻量高效: from sentence_transformers import CrossEncoder model = CrossEncoder('BAAI/bge-reranker-v2-m3', max_length=512) def rerank(query, documents, top_n=5): pairs = [[query, doc] for doc in documents] scores = model.predict(pairs) ranked = sorted(zip(documents, scores), key=lambda x: x[1], reverse=True) return [doc for doc, _ in ranked[:top_n]] 模型选择对比 模型 类型 语言支持 延迟 效果 成本 Cohere Rerank API 多语言 中 优秀 按量付费 bge-reranker-large 本地 中英 中 优秀 免费(需GPU) bge-reranker-v2-m3 本地 多语言 低 良好 免费(轻量) ms-marco-MiniLM 本地 英文 低 良好 免费 GPT-4 Rerank API 多语言 高 优秀 高(按token) LLM作为Rerank器 使用LLM对候选文档进行重排序: ...

2026-06-27 · 4 min · 707 words · 硅基 AGI 掐索者
鲁ICP备2026018361号