句子窗口切分是什么
句子窗口策略用单个句子当检索单元,同时把前后若干句打包成窗口(window)存进元数据:检索阶段按句子匹配,精度更高;命中后再把窗口文本替换回来送进生成,避免模型只看到一句孤立的话。它是长文档问答里在「检索精度」和「上下文完整」之间取的折中解。
基本信息
| 实现位置 | LlamaIndex 的 SentenceWindowNodeParser |
|---|---|
| 关键参数 | window_size,控制前后各取多少句 |
| 配套组件 | MetadataReplacementPostProcessor 负责窗口回填 |
| 代价 | 窗口文本随元数据存放,索引体积与存储成本上升 |
典型使用场景
- 长手册问答:条款都写成短句,句子级匹配明显优于整段匹配
- 法规与合同:单句常含条件限定,需要把前后句一起交给模型
- 日志与工单:短文本记录多,窗口能把相关上下文聚合起来
- 混合检索调优:句子级向量更短,同样维度下语义更集中
- 引用精确化:命中粒度为句,引用可标注到具体句子所在段落
句子窗口节点
句子窗口节点
from llama_index.core.node_parser import SentenceWindowNodeParser
# window_size=3 表示每句前后各取 3 句组成窗口,窗口存进 metadata
parser = SentenceWindowNodeParser.from_defaults(window_size=3)
nodes = parser.get_nodes_from_documents(documents)
print(nodes[0].metadata["window"][:100]) # 检索命中的是句子,回填的是窗口
# 生成前必须接 MetadataReplacementPostProcessor,否则模型只拿到单句
窗口大小取舍
| 设置 | 检索效果 | 注意事项 |
|---|---|---|
| window_size=1 | 上下文紧、噪声少 | 复杂问题常缺条件限定 |
| window_size=3 | 多数场景的平衡点 | 邻句开始引入无关内容 |
| window_size=8 以上 | 信息最全 | 信号被稀释,token 成本上升 |
| 未接回填处理器 | — | 模型只拿到单句,答案容易不完整 |
窗口只存在元数据里,不参与向量计算:入库时算的是句子向量,取回时才展开窗口,所以窗口大小可以调而不必重建索引。
句子切分本身依赖标点与语言规则,中文里分号、顿号密集的文本容易切成过长句,建议先看切分结果分布再定参数。
与固定长度切分相比,句子窗口的检索单元更短,同样 top-k 下召回的片段数量更多,重排阶段的候选规模要相应评估,否则生成侧上下文会被挤占。