rag中切片策略怎么搭配

来自夹夹 QQ 群讨论,审核后公开 · 。查看原始讨论

提问

rag中切片策略怎么搭配

回答

回复 群友 8780

切片策略不是单独选的,是先按“问题长什么样”定检索单元,再选切法。顺序反过来做,切得再精细也没用。

先说最核心的一条判断:切片的粒度应该匹配你要回答的问题粒度。问题答案落在一句话里(“这个函数默认超时多少”),就该切小、切到句子或短段;答案要靠一整节才能拼出来(“这个方案的取舍是什么”),切太碎就是自残,因为单块信息不完整,模型只能猜。所以先看你的 query 分布,别看网上的最佳实践。

几种切法的机制差别,用具体场景说:

定长切分(按 token 数固定,加 overlap)。好处是块大小可控、embedding 成本可预算,坏处是它不认识语义边界,一刀下去经常把定义和它的限定条件切开,于是“支持 X”和“不支持 X”落在两块里,检索命中哪块都可能答反。适合日志、聊天记录这类没有明确结构的文本。

递归切分(按段落、章节、句子逐级往下试,直到塞进目标长度)。这是默认首选,因为它优先在最大语义边界断开。你 docx、md 里的标题层级正好是它的天然分隔符,只要别把标题正文切散。

结构化切分(按 md 标题、HTML 标签、代码函数、表格行来切)。结构越明确,越应该用它,不要退回定长。代码库按函数切、API 文档按 endpoint 切、法规按条款切,成块天然有主题一致性。

父文档 / 小块索引(small-to-big)。索引阶段用小块保证命中精度,召回后向上取父文档喂给模型保证上下文完整。这是“碎和完整矛盾”的正解:小块负责找得准,大块负责答得全。对长文档、技术手册这种最值得上。

语义切分(把相邻句子嵌入,相似度骤降处断开)。听着漂亮,实际风险是切出来的块大小不可控、而且同一个文档重跑结果可能不一样,检索行为变得不可复现。只有在文本结构极弱、又确实需要保持话题完整时才考虑。

再说搭配,也就是常被忽略的几件事:

一是块大小和你的 embedding 模型要对齐。小模型(几百维、短上下文)塞 2000 token 的块效果会明显下降,因为编码器把信息压平了。大体量块得配长上下文的 embedding。

二是切分和 rerank 是配套的。小块召回宽一点、召回条数拉高到 20 到 50,再用 rerank 收敛到 5 条喂模型,这是目前性价比最高的组合。如果预算紧、只做向量相似度直接 top5,那就得靠中等大小的块来兜底。

三是别丢了元数据。每个块必须带来源文件、章节路径、原始位置。否则检索到半句话你没法回溯,也没法在 prompt 里告诉模型“这段话属于哪一节”。

四是有标题或小标题的文档,把标题路径拼进块内容里再嵌入。这一条实践里收益很大,尤其对“某章某节讲的是什么”这类问题,因为标题本身携带了块脱离上下文后丢失的主题信息。

落到你的场景上,我建议这样起步:md 或文档类用递归切分,目标 400 到 800 token、留 10% 到 15% 重叠,块头拼接标题路径;技术长文叠一层父文档召回;然后拿你手上二三十个真实问题跑一遍,看答案是被切碎害的,还是检索没召回,再动参数。别一开始就上语义切分,它通常不是第一层能带来的收益。

所属话题:Agent 工程