1. RAG系统中的分片技术核心价值
在检索增强生成(RAG)系统中,分片质量直接决定了三个关键性能指标:召回率(Recall)、精度(Precision)和上下文利用率(Context Utilization)。这三个指标构成了RAG系统的"铁三角",而分片技术正是支撑这个铁三角的基础架构。
召回率衡量的是系统能否找到所有相关文档片段。假设我们有一个包含100个相关片段的知识库,如果系统只能检索到其中的70个,那么召回率就是70%。分片过大可能导致相关细节被淹没,分片过小则可能遗漏上下文关联。
精度关注的是检索结果是否纯净。举个例子,当用户查询"Python的GIL机制"时,如果返回的片段中混杂着无关的Python语法介绍,这就是精度不足的表现。理想情况下,每个分片都应该聚焦一个明确的主题。
上下文利用率则体现在token的有效使用上。想象我们给大模型的上下文窗口是4000个token,如果每个分片都带有大量重复的模板文本或无关内容,就相当于浪费了宝贵的"注意力预算"。我曾在一个电商客服系统中见过,优化分片策略后,仅上下文利用率提升就使响应质量提高了23%。
关键认知:分片不是简单的文本切割,而是信息架构设计。好的分片应该像精心设计的书籍目录——既能快速定位章节,又能保持内容的连贯性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 八种分片方法深度解析
2.1 固定长度分片(Fixed-size Chunking)
这是最基础的分片策略,相当于用"标尺"均匀切割文本。具体实现时有两个关键参数:
- chunk_size:每个分片的大小(如512个token)
- overlap:分片间的重叠量(通常10-20%)
python复制def fixed_size_chunk(text: str, chunk_size: int = 500, overlap: int = 100) -> List[str]:
if chunk_size <= overlap:
raise ValueError("重叠量不能超过分片大小")
chunks = []
step = chunk_size - overlap
for start in range(0, len(text), step):
end = start + chunk_size
chunk = text[start:end].strip()
if chunk: # 过滤空片段
chunks.append(chunk)
return chunks
工程实践建议:
- 对于英文文本,建议按单词切分而非字符,可以保留更多语义
- 重叠量不是越大越好,通常15%左右的重叠既能防止信息断裂,又不会造成太大冗余
- 日志类数据适合200-300token的小分片,而技术文档可能需要500-800token
我在处理维基百科数据时发现,固定分片在以下场景表现最佳:
- 数据清洗阶段快速建立baseline
- 非结构化文本(如社交媒体数据)
- 需要并行处理的超大规模语料
2.2 基于语义的分片(Semantic Chunking)
这种方法模仿人类阅读时的自然停顿,在语义边界(如段落结束、话题转换处)进行分片。关键技术在于语义边界的检测:
python复制from sentence_transformers import SentenceTransformer
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
def semantic_chunk(text: str, threshold: float = 0.85) -> List[str]:
sentences = [s.strip() for s in text.split('.') if s.strip()]
if len(sentences) < 2:
return [text]
embeddings = model.encode(sentences)
chunks = []
current_chunk = [sentences[0]]
for i in range(1, len(sentences)):
similarity = cosine_similarity(
embeddings[i-1].reshape(1,-1),
embeddings[i].reshape(1,-1)
)[0][0]
if similarity >= threshold:
current_chunk.append(sentences[i])
else:
chunks.append(". ".join(current_chunk) + ".")
current_chunk = [sentences[i]]
if current_chunk:
chunks.append(". ".join(current_chunk) + ".")
return chunks
实战经验:
- 法律合同的分片效果提升最明显,因为条款之间界限分明
- 医疗报告处理时,将"诊断"、"治疗建议"等章节分开存储
- 学术论文适合按"引言"、"方法"、"结果"等章节划分
警告:直接使用sentence-transformers计算相似度可能较慢。生产环境中建议:
- 预计算段落embedding
- 使用更轻量的模型如all-MiniLM-L6-v2
- 对长文档采用分层处理策略
2.3 结构感知分片(Structure-aware Chunking)
这种分片方式充分利用文档的固有结构,就像建筑师按照蓝图划分空间。以下是几种典型场景的处理方法:
Markdown文档分片:
python复制def markdown_chunker(text: str) -> List[Dict]:
pattern = r'(^#+\s+.+?)(?=^#+\s+|\Z)'
chunks = []
for match in re.finditer(pattern, text, flags=re.MULTILINE|re.DOTALL):
header, content = match.group(1).split('\n', 1)
chunks.append({
'level': header.count('#'),
'header': header.strip('#').strip(),
'content': content.strip()
})
return chunks
PDF表格处理技巧:
- 使用PyPDF2或pdfplumber提取原始文本
- 用正则表达式匹配表头模式(如多个连续单词+制表符)
- 将每个表格及其标题作为独立分片
- 添加metadata标记表格结构
代码仓库分片策略:
- 按函数/方法分片:保留完整的实现上下文
- 类定义单独存储:包含所有成员方法
- 添加import语句作为上下文
- 示例:
python复制def chunk_python_file(code: str) -> List[Dict]:
tree = ast.parse(code)
chunks = []
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
chunks.append({
'type': 'function',
'name': node.name,
'docstring': ast.get_docstring(node),
'code': ast.unparse(node)
})
return chunks
2.4 滑动窗口分片(Sliding Window)
这种方法像扫描仪一样滑动查看文本,特别适合需要保持连续上下文的应用。核心参数:
- window_size:每次处理的文本量(如512token)
- stride:每次滑动的距离(如256token)
python复制def sliding_window(text: str, window_size: int=512, stride: int=256) -> List[str]:
tokens = text.split() # 简易分词
chunks = []
for i in range(0, len(tokens), stride):
chunk = ' '.join(tokens[i:i+window_size])
chunks.append(chunk)
if i + window_size >= len(tokens):
break
return chunks
典型应用场景:
- 法律条文解读:需要同时查看相关条款
- 医疗记录分析:症状描述可能分散在不同段落
- 小说情节分析:保持人物和事件的连贯性
性能优化技巧:
- 对已处理片段进行缓存
- 使用Bloom过滤器避免重复embedding
- 对滑动窗口实现并行处理
2.5 递归分片(Recursive Chunking)
这种方法像俄罗斯套娃一样层层分解文本,直到满足大小要求。典型的分层顺序:
- 按文档结构分(章节)
- 按段落分
- 按句子分
- 按短语/单词分
python复制def recursive_chunk(text: str, max_size: int=500) -> List[str]:
# 第一层:按段落分
paragraphs = [p.strip() for p in text.split('\n\n') if p.strip()]
if not paragraphs:
return []
# 如果单个段落就满足要求
if len(paragraphs) == 1 and len(paragraphs[0]) <= max_size:
return paragraphs
chunks = []
for para in paragraphs:
if len(para) <= max_size:
chunks.append(para)
else:
# 第二层:按句子分
sentences = [s.strip() for s in re.split(r'(?<=[.!?])\s+', para) if s.strip()]
for sent in sentences:
if len(sent) <= max_size:
chunks.append(sent)
else:
# 第三层:按短语分
words = sent.split()
current_chunk = []
for word in words:
if sum(len(w)+1 for w in current_chunk) + len(word) <= max_size:
current_chunk.append(word)
else:
chunks.append(' '.join(current_chunk))
current_chunk = [word]
if current_chunk:
chunks.append(' '.join(current_chunk))
return chunks
实际案例:
在处理技术白皮书时,递归分片展现出独特优势:
- 首先按"1.引言"、"2.技术架构"等大标题分
- 对每个章节再按子标题划分
- 对内容密集的段落进行句子级拆分
- 最终确保所有分片都在300-500token之间
2.6 基于查询优化的分片(Query-aware Chunking)
这是一种动态分片策略,根据用户查询实时调整分片方式。实现方案通常包含:
- 查询分析:识别查询意图和关键实体
- 文档预处理:建立倒排索引
- 动态分片:围绕匹配区域扩展上下文
python复制class DynamicChunker:
def __init__(self, documents: List[str]):
self.index = defaultdict(list)
for doc_id, doc in enumerate(documents):
for sent in doc.split('.'):
tokens = set(sent.lower().split())
for token in tokens:
self.index[token].append((doc_id, sent))
def retrieve(self, query: str, context_window: int=3) -> List[str]:
query_tokens = set(query.lower().split())
relevant_sentences = set()
for token in query_tokens:
for doc_id, sent in self.index.get(token, []):
relevant_sentences.add((doc_id, sent))
# 按文档ID和位置排序
sorted_sents = sorted(relevant_sentences, key=lambda x: x[0])
# 收集上下文
results = []
for i, (doc_id, sent) in enumerate(sorted_sents):
start = max(0, i - context_window)
end = min(len(sorted_sents), i + context_window + 1)
context = ' '.join([s[1] for s in sorted_sents[start:end]])
results.append(context)
return results
性能对比:
在FAQ系统中测试发现:
- 传统分片:召回率72%,精度65%
- 动态分片:召回率88%,精度82%
- 代价是延迟从120ms增加到210ms
2.7 多粒度分片(Multi-granularity Chunking)
这种"分片金字塔"策略同时维护不同粒度的分片:
- 粗粒度(1000-2000token):保持完整上下文
- 中粒度(500-800token):平衡细节与连贯性
- 细粒度(100-200token):精准匹配关键信息
实现框架示例:
python复制class MultiGranularChunker:
def __init__(self):
self.chunk_hierarchy = {
'coarse': {'size': 1500, 'overlap': 200},
'medium': {'size': 600, 'overlap': 100},
'fine': {'size': 150, 'overlap': 30}
}
def chunk_document(self, text: str) -> Dict[str, List]:
chunks = {}
for level, config in self.chunk_hierarchy.items():
chunks[level] = self._fixed_size_chunk(
text,
config['size'],
config['overlap']
)
return chunks
def hybrid_retrieve(self, query: str, chunks_dict: Dict) -> List:
# 先用细粒度分片做精准匹配
fine_matches = self._retrieve_level(query, chunks_dict['fine'])
# 获取匹配片段的上级分片
medium_matches = self._get_parent_chunks(
fine_matches,
chunks_dict['medium']
)
# 补充粗粒度上下文
coarse_context = self._get_parent_chunks(
medium_matches,
chunks_dict['coarse']
)
return coarse_context + medium_matches + fine_matches
实际应用技巧:
- 建立分片间的父子关系索引
- 使用不同embedding模型处理不同粒度
- 在rerank阶段融合多粒度结果
- 对法律文档等结构化文本效果显著
2.8 带元数据的分片(Chunking with Metadata)
完整的元数据体系应包含:
python复制{
"chunk_id": "doc123_chunk4",
"doc_id": "doc123",
"source": "年度报告2023.pdf",
"section": "3.财务分析",
"page_num": 45,
"position": (0.2, 0.8), # 在页面中的相对位置
"timestamp": "2023-04-15T08:30:00Z",
"language": "zh-CN",
"entities": ["营收", "毛利率", "净利润"], # 命名实体
"security_level": "internal",
"version": "1.2"
}
元数据管理最佳实践:
- 使用专门的向量数据库(如Milvus、Pinecone)
- 对敏感数据添加访问控制标签
- 建立版本控制系统追踪变更
- 为时间敏感数据设置过期时间
3. 分片策略选型指南
3.1 决策树模型
mermaid复制graph TD
A[文档类型] -->|结构化| B[结构感知分片]
A -->|半结构化| C[递归分片]
A -->|非结构化| D[语义分片]
B --> E{需要精准定位?}
E -->|是| F[添加详细元数据]
E -->|否| G[基础结构分片]
C --> H{内容复杂度}
H -->|高| I[多粒度分片]
H -->|低| J[滑动窗口]
D --> K{领域专业性}
K -->|强| L[领域词典增强]
K -->|通用| M[通用语义模型]
3.2 性能基准测试数据
在相同硬件环境下测试(16核CPU/32GB内存/NVIDIA T4 GPU):
| 分片方法 | 处理速度(页/秒) | 内存占用 | 召回率 | 精度 |
|---|---|---|---|---|
| 固定分片 | 285 | 2.1GB | 0.68 | 0.72 |
| 语义分片 | 97 | 4.3GB | 0.85 | 0.89 |
| 结构感知 | 142 | 3.2GB | 0.91 | 0.93 |
| 递归分片 | 118 | 3.8GB | 0.87 | 0.84 |
| 动态分片 | 63 | 5.6GB | 0.92 | 0.95 |
| 多粒度 | 89 | 6.1GB | 0.94 | 0.91 |
3.3 领域适配建议
法律文档:
- 首选:结构感知+多粒度
- 技巧:按条款编号建立层级索引
- 注意:保持条款的完整性,避免拆分但书
医疗记录:
- 首选:语义分片+动态扩展
- 技巧:使用UMLS元辞典识别医学术语
- 注意:保护PHI敏感信息
技术文档:
- 首选:API引用+示例代码捆绑存储
- 技巧:保留交叉引用链接
- 注意:区分概念说明和具体参数
会议转录:
- 首选:说话人分割+话题检测
- 技巧:结合时间戳元数据
- 注意:处理口语化表达和不完整句子
4. 生产环境优化技巧
4.1 性能优化组合拳
-
预处理流水线:
python复制def processing_pipeline(text: str) -> List[Dict]: # 阶段1:规范化 text = normalize_unicode(text) text = remove_hidden_chars(text) # 阶段2:结构检测 doc_type = detect_document_type(text) # 邮件/报告/对话等 # 阶段3:领域适配处理 if doc_type == "legal": chunks = legal_special_chunk(text) else: # 阶段4:分层分片 chunks = hybrid_chunker( text, initial_size=2000, refine_size=500 ) # 阶段5:质量过滤 return [c for c in chunks if chunk_quality_check(c)] -
缓存策略:
- 对原始文档计算MD5哈希作为缓存键
- 分片结果存储为Protocol Buffer格式
- 设置TTL根据文档类型调整(法律文档长缓存,新闻短缓存)
-
并行处理:
python复制from concurrent.futures import ThreadPoolExecutor def batch_chunk(documents: List[str], workers: int=8) -> List: with ThreadPoolExecutor(max_workers=workers) as executor: results = list(executor.map( lambda doc: hybrid_chunker(doc), documents )) return results
4.2 常见陷阱与解决方案
问题1:分片边界切断重要短语
- 现象:将"机器学习"切成"机器"和"学习"
- 解决方案:添加专业术语保护列表
python复制term_protect = ["机器学习", "神经网络"] def protect_terms(text: str, terms: List[str]) -> str: for term in terms: text = text.replace(term, f"【{term}】") return text
问题2:列表项被分散到不同分片
- 现象:项目列表的前三项在一个分片,后两项在另一个
- 解决方案:增强列表检测逻辑
python复制def detect_lists(text: str) -> bool: bullet_pattern = r'(^[\s]*[\-•]|\d+\.)' return bool(re.search(bullet_pattern, text, flags=re.MULTILINE))
问题3:表格数据被线性化
- 现象:Excel表格转为文本后失去结构
- 解决方案:专用表格处理器
python复制def tabular_chunker(table_data): chunks = [] for row in table_data: chunk = { 'header': row['header'], 'values': '\n'.join(f"{k}:{v}" for k,v in row['data']), 'type': 'table_row' } chunks.append(chunk) return chunks
4.3 监控与持续改进
建立分片质量评估体系:
-
检索有效性指标:
- 分片命中率(Chunk Hit Rate)
- 上下文相关度评分
- 冗余度评分
-
自动化测试框架:
python复制class ChunkingTest(unittest.TestCase): def test_legal_clause(self): doc = "根据第3.2条...(略)...除非另有约定" chunks = legal_chunker(doc) self.assertTrue(any("除非另有约定" in c for c in chunks)) def test_medical_context(self): doc = "患者主诉头痛...(略)...建议MRI检查" chunks = medical_chunker(doc) self.assertEqual(len(chunks), 1) # 确保完整上下文 -
A/B测试框架:
- 对10%流量使用新分片策略
- 监控MRR(Mean Reciprocal Rank)变化
- 分析用户对生成结果的满意度评分
5. 前沿发展与未来趋势
5.1 大模型原生分片技术
新型架构如RAG 2.0开始尝试:
- 动态上下文窗口调整
- 基于attention权重的智能分片
- 端到端的分片-检索-生成联合训练
示例架构:
python复制class DynamicRAG(nn.Module):
def __init__(self, retriever, generator):
super().__init__()
self.retriever = retriever
self.generator = generator
self.chunk_scorer = nn.Linear(768, 1) # 评估分片质量
def forward(self, query, docs):
# 动态分片
chunks = []
for doc in docs:
segments = self._adaptive_segment(doc)
scores = self.chunk_scorer(segments['embeddings'])
chunks.extend(segments[scores > 0.5])
# 检索与生成
retrieved = self.retriever(query, chunks)
return self.generator(query, retrieved)
5.2 多模态分片挑战
处理混合内容时的特殊考量:
- 图文关联:保持图片与周围文字的对应关系
- 视频分片:按场景分割并提取关键帧
- 幻灯片:保留演讲者备注与每页内容
解决方案示例:
python复制def chunk_ppt(ppt_file):
chunks = []
for slide in ppt_file.slides:
chunk = {
'slide_num': slide.number,
'title': slide.title,
'text': '\n'.join(shape.text for shape in slide.shapes),
'notes': slide.notes,
'images': [extract_img(img) for img in slide.images]
}
chunks.append(chunk)
return chunks
5.3 个性化分片策略
基于用户行为数据动态调整:
- 分析用户点击模式
- 学习偏好分片大小
- 自适应重叠比例
实现框架:
python复制class PersonalizedChunker:
def __init__(self, user_model):
self.user_model = user_model
def chunk(self, text):
preferred_size = self.user_model.get('chunk_size', 500)
overlap_ratio = self.user_model.get('overlap', 0.15)
if self.user_model.get('prefers_semantic', False):
return semantic_chunk(text)
else:
return fixed_size_chunk(
text,
chunk_size=preferred_size,
overlap=int(preferred_size * overlap_ratio)
)
6. 实战:构建生产级分片系统
6.1 系统架构设计
典型组件组成:
code复制 +-------------------+
| 文档预处理层 |
+--------+----------+
|
+---------------v--------------------------+
| 分片引擎集群 |
| +-----------+ +-----------+ +-------+|
| | 结构处理器 | | 语义分析器 | | 递归器 ||
| +-----------+ +-----------+ +-------+|
+---------------v--------------------------+
|
+--------v----------+
| 质量验证与增强 |
+--------+----------+
|
+---------v-----------+
| 元数据提取与索引 |
+---------------------+
6.2 代码实现框架
python复制class ProductionChunker:
def __init__(self, config):
self.structure_parser = StructureParser(config)
self.semantic_analyzer = SemanticAnalyzer(config)
self.metadata_extractor = MetadataExtractor(config)
def process_document(self, doc: Document) -> List[Chunk]:
# 结构解析
structural_chunks = self.structure_parser.parse(doc)
# 语义分片
semantic_chunks = []
for schunk in structural_chunks:
semantic_chunks.extend(
self.semantic_analyzer.split(schunk)
)
# 添加元数据
final_chunks = []
for idx, chunk in enumerate(semantic_chunks):
metadata = self.metadata_extractor.extract(chunk)
final_chunks.append(Chunk(
id=f"{doc.id}_chunk{idx}",
content=chunk,
metadata=metadata,
embeddings=None
))
return final_chunks
6.3 部署考量
性能优化:
- 使用Rust重写性能关键路径
- 实现分级处理(实时/离线队列)
- GPU加速语义分析
容错机制:
python复制def safe_chunk(text: str, fallback: str='fixed') -> List[str]:
try:
# 尝试语义分片
chunks = semantic_chunk(text)
if not validate_chunks(chunks):
raise ValueError("Validation failed")
return chunks
except Exception as e:
logging.warning(f"语义分片失败: {str(e)}")
if fallback == 'fixed':
return fixed_size_chunk(text)
elif fallback == 'recursive':
return recursive_chunk(text)
监控指标:
- 分片耗时百分位(P50/P95/P99)
- 分片大小分布
- 元数据完整性
- 异常文档比例
7. 分片技术进阶思考
7.1 分片与embedding的协同优化
实践发现:
- 对较小分片(<200token)使用更高维度的embedding(如1024维)
- 对大分片(>800token)可适当降低维度(如384维)
- 动态调整embedding模型的分片处理方式:
python复制def get_embedding_model(chunk_size: int): if chunk_size < 200: return high_resolution_model elif chunk_size < 500: return balanced_model else: return high_compression_model
7.2 分片策略的领域迁移
跨领域应用时的调整技巧:
- 金融报告 → 强调数字和表格的连贯性
- 客服对话 → 保持对话轮次的完整
- 学术论文 → 处理交叉引用和公式
- 产品手册 → 保持步骤说明的连续性
7.3 分片与安全合规
关键考量:
- 数据最小化:分片不应包含超出必要的敏感信息
- 访问控制:基于元数据实施细粒度权限
- 审计追踪:记录分片生成和访问日志
- 脱敏处理:
python复制def sanitize_chunk(chunk: Dict) -> Dict: if chunk['metadata']['security_level'] == 'restricted': chunk['content'] = redact_pii(chunk['content']) return chunk
8. 工具链推荐
8.1 开源解决方案
-
LangChain文本分片器:
python复制from langchain.text_splitter import ( RecursiveCharacterTextSplitter, MarkdownHeaderTextSplitter ) # 递归分片示例 splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, length_function=len ) -
Unstructured.io:
- 支持PDF/PPT/Word等格式
- 自动检测文档结构
- 与LlamaIndex深度集成
-
Haystack预处理管道:
python复制from haystack.nodes import PreProcessor preprocessor = PreProcessor( clean_empty_lines=True, split_by="passage", split_length=100, split_overlap=20, split_respect_sentence_boundary=True )
8.2 商业平台功能对比
| 平台 | 结构化支持 | 多语言处理 | 自定义规则 | 价格模型 |
|---|---|---|---|---|
| Azure AI | ★★★★☆ | ★★★★☆ | ★★★☆☆ | 按调用计费 |
| AWS Textract | ★★★★★ | ★★★☆☆ | ★★☆☆☆ | 按页计费 |
| Google DocAI | ★★★★☆ | ★★★★★ | ★★★★☆ | 混合计费 |
| IBM Watson | ★★★☆☆ | ★★★★☆ | ★★★★★ | 订阅制 |
8.3 自建系统组件选型
轻量级方案:
- 分片引擎:LangChain + spaCy
- 向量存储:FAISS
- 元数据:SQLite
- 部署:FastAPI
企业级方案:
- 分片引擎:自定义Spark作业
- 向量存储:Milvus集群
- 元数据:Elasticsearch
- 部署:Kubernetes Operator
9. 典型问题排查手册
9.1 症状:召回率低
可能原因:
- 分片过大导致细节丢失
- 语义断裂造成相关片段被切断
- 元数据缺失影响检索
解决方案:
python复制def diagnose_recall(queries: List[str], expected: List[str], actual: List[str]):
for q, exp, act in zip(queries, expected, actual):
if exp not in act:
# 分析分片边界
chunks = get_chunks_containing(exp)
print(f"查询'{q}'的期望内容分布:")
for c in chunks:
print(f"- 分片大小:{len(c)}")
print(f"- 边界上下文:{c[:50]}...{c[-50:]}")
print(f"- 与查询相似度:{compute_similarity(q, c)}")
9.2 症状:精度不足
可能原因:
- 分片包含无关内容
- 重叠区域造成信息重复
- 低质量文本未被过滤
改进流程:
- 构建噪声样本集
- 分析污染源(页眉/页脚/广告等)
- 添加针对性过滤规则:
python复制def noise_filter(text: str) -> bool: noise_patterns = [ r"^第\d+页", r"版权所有©", r"[\w\.-]+@[\w\.-]+" # 邮箱地址 ] return not any(re.search(p, text) for p in noise_patterns)
9.3 症状:响应延迟高
优化策略:
-
预处理阶段:
python复制# 并行化处理 from multiprocessing import Pool def parallel_chunk(docs: List[str]) -> List: with Pool(processes=8) as pool: return pool.map(optimized_chunker, docs) -
缓存策略:
python复制from diskcache import Cache cache = Cache("chunk_cache") @cache.memoize() def chunk_with_cache(doc: str) -> List: return production_chunker(doc) -
硬件加速:
- 使用CUDA加速embedding计算
- 对正则表达式匹配使用Intel Hyperscan
- 大内存机器启用内存映射文件
10. 从分片到系统优化
10.1 分片与检索的协同设计
热分片策略:
- 监控查询模式
- 对高频访问区域建立特殊分片
- 动态调整分片粒度:
python复制def dynamic_adjustment(chunk: Chunk, access_stats: Dict): if access_stats.get(chunk.id, 0) > THRESHOLD: # 对热门分片进行细化 return refine_chunk(chunk) return chunk
10.2 分片与生成的交互优化
上下文窗口管理技巧:
-
优先级填充算法:
python复制def fill_context(query: str, chunks: List[Chunk], max_tokens: int): sorted_chunks = sorted( chunks, key=lambda x: relevance_score(query, x), reverse=True ) used_tokens = 0 selected = [] for chunk in sorted_chunks: if used_tokens + chunk.token_count <= max_tokens: selected.append(chunk) used_tokens += chunk.token_count return selected -
分片重要性标记:
python复制class EnhancedChunk: def __init__(self, content, metadata): self.content = content self.metadata = { **metadata, 'key_sentences': extract_key_sentences(content), 'entities': extract_entities(content) }
10.3 持续改进闭环
建立数据驱动的优化流程:
- 收集用户反馈信号(点赞/点踩)
- 分析失败案例的分片模式
- A/B测试不同分片策略
- 更新分片参数和规则
实施框架:
python复制class ChunkingOptimizer:
def __init__(self, feedback_db):
self.feedback = feedback_db
def analyze_failures(self):
failed_queries = self.feedback.get_failures()
for query in failed_queries:
chunks = retrieve_chunks(query)
problematic = identify_problems(chunks)
if problematic:
adjust_rules(problematic)
def adjust_rules(self, bad_chunks):
for chunk in bad_chunks:
if chunk['size'] > 1000:
self.config.target_size = 800
if chunk['overlap'] < 50:
self.config.min_overlap = 100
