文档怎么切:先保留语义,再讨论向量索引
理解切块、重叠、元数据与向量索引的职责,用窗口切分示例观察边界与证据完整性。
能说明块大小、重叠和索引参数分别影响什么,并保留可追踪的文档位置。
切块决定“一个可检索单元里保留多少意思”,向量索引决定“怎样更快找到候选单元”。两者相关,但不是同一个问题。
如果切块已经把条件和结论分开,换一个更快的索引也不会把证据自动修好。先观察文档结构,再调检索参数。
从文档结构开始
标题、段落、列表、表格和代码块往往带有语义边界。优先避免把表格表头与数据、操作前提与操作步骤、代码与解释拆到完全无法关联的块里。
每个块保留文档 ID、版本、标题路径和原文位置。检索结果可能需要回查相邻段落,引用也要依赖这些位置。
重复切分同一个版本,应得到稳定或可映射的块标识。更新时删除过期内容,不能只追加新块而让旧结论继续被召回。
块大小与重叠的取舍
块太小可能缺少上下文,太大可能把大量无关内容带入结果。重叠能缓和边界问题,却增加索引体积与重复证据。
没有适合所有资料的固定大小。技术说明、表格和长篇叙述需要分别观察。最终用代表性查询评估,而不是只看切出来的块是否整齐。
用窗口观察边界
下面按字符切分,只用于演示位置和重叠;它不是面向生产的语义切分器,也不能代替模型 token 计数。
def windows(text, size, overlap):
if size <= 0 or not 0 <= overlap < size:
raise ValueError("invalid window settings")
chunks = []
start = 0
while start < len(text):
end = min(start + size, len(text))
chunks.append({"start": start, "end": end, "text": text[start:end]})
if end == len(text):
break
start = end - overlap
return chunks
text = "Keep the condition next to its conclusion."
chunks = windows(text, size=18, overlap=5)
assert chunks[1]["start"] == chunks[0]["end"] - 5
assert chunks[-1]["end"] == len(text)
assert all(c["text"] == text[c["start"]:c["end"]] for c in chunks)
for chunk in chunks:
print(chunk)
把原文换成有标题和表格的说明,观察窗口是否留下了完整意思。这个观察通常比立即选一个向量库更能暴露问题。
向量和索引分别负责什么
Embedding 把输入映射到向量空间。向量距离是候选检索信号,不直接表示答案是否真实。查询与文档的编码方式要与所选模型一致。
HNSW 等近似索引通过图结构加快近邻搜索,通常需要在召回率、延迟和内存之间取舍。索引参数无法弥补错误的文档解析、过期资料或权限遗漏。
对于专有名词、标识符与精确关键词,词法检索也有价值。是否组合词法与向量召回,应由你自己的查询集决定。
下一步
挑选十个问题,使用两套切块方案检索。比较正确证据是否出现、是否完整,以及上下文中有多少重复资料。
保留输入、切分版本与结果 ID,进入下一篇,把这些观察变成可重复的检索评测。
资料来源与延伸阅读
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Efficient and robust approximate nearest neighbor search using HNSW
资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。