读一份超过任何上下文窗口的合同:在一把 key 上分块重叠读、再拼回结论
本文介绍了一种处理超出任何模型上下文窗口的超长文档(如合同)的方法:通过重叠分块、逐块抽取关键信息,并在拼接时保留边界条款,最终形成完整结论。内容涵盖分块策略、提示词设计、结果合并与校验,并说明如何在一个 API key 上调用多个模型完成流程。
为什么需要分块读取
大语言模型的上下文窗口有限,而合同、标书、技术文档等经常远超这个限制。直接截断会丢失关键条款,尤其是定义、违约责任、附件引用等可能分布在文档任何位置的内容。因此需要将长文档切分为多个块,分别处理后再合并结果。
分块策略:重叠与边界保留
简单的等长切分容易在块边界处切断句子或段落,导致信息丢失。推荐使用带重叠的分块方式:
- 按语义边界切分:优先在段落、标题或列表项处切分,避免在句子中间断开。
- 设置重叠区域:相邻块之间保留一定比例的重叠(例如块大小的 10%~20%),确保边界附近的文本至少在一个块中完整出现。
- 记录块位置:为每个块保存其在原文中的起止位置,便于后续定位和引用。
逐块抽取关键信息
对每个块单独调用模型,要求抽取结构化信息。提示词应明确:
- 只提取当前块中明确出现的内容,不要推测。
- 输出格式固定(如 JSON),包含条款类型、原文摘录、块内位置。
- 对于边界处可能不完整的条款,标记为“可能跨块”,以便后续处理。
例如,可以要求模型返回:
{
"clauses": [
{
"type": "付款条款",
"text": "...",
"span": "block-3:120-200",
"cross_block": false
}
]
}
拼接与去重
将所有块的抽取结果按原文位置排序,然后合并:
- 对于重叠区域中重复出现的条款,根据原文位置去重,保留最完整的一条。
- 对于标记为“可能跨块”的条款,检查相邻块是否包含剩余部分,手动或自动拼接完整文本。
- 保留每个条款的原文引用,便于最终核对。
生成最终结论
将合并后的条款列表作为输入,再次调用模型生成总结或回答具体问题。此时输入已远小于原文,且关键信息已结构化,模型可以专注于推理和归纳。
在一个 API key 上调用多个模型
聚合站允许一个 key 调用多个模型,这为分块处理提供了灵活性:
- 抽取阶段可以使用成本较低的模型处理大量块。
- 最终总结阶段换用推理能力更强的模型。
- 如果某个块抽取结果不理想,可以换另一个模型重试,而无需切换账号或 key。
校验与迭代
分块方法可能遗漏隐含信息,建议:
- 随机抽取若干块,人工核对抽取结果是否准确。
- 对于关键条款(如违约责任、终止条件),在最终结论中标注原文位置,便于溯源。
- 如果发现某类条款频繁跨块,调整分块大小或重叠比例。
通过重叠分块、结构化抽取和谨慎拼接,可以在有限上下文窗口下处理任意长度的文档,同时保持关键信息的完整性。