长文档处理时,截断和分段是两条路:截断简单但会丢失文档中间部分的内容,分段虽然要多轮请求,却能保留完整信息。Grok 4.5这类模型在单次请求中能接受的内容长度有上限,超过限制后,不能指望自动保留重点。处理前应该先确认当前环境的上下文上限,再把文档切成多个块,逐块问答后合并结果。
判断:当单篇文档接近或超过模型上下文上限时,截断会丢失关键信息,分段问答更稳。操作:按语义完整段落分块,逐块独立回答,再汇总对比。验证:用一份真实长文档跑完整流程,核对块数、耗时和最终回答是否覆盖原文关键信息。风险:分块太细切断因果链条,太粗块数多且汇总压力大;具体阈值需自行测试。
确定文档的边界与分块依据
分块的第一步不是数数字,而是找文档自身的边界。典型的自然边界是段落、句子和章节标题。
- 按段落切分:适用于合同、论文、产品文档这类有明确段落结构的文本。段落通常承载一个完整论点,直接以空行切分,能减少上下文被拦腰截断。
- 按句子切分:适用于聊天记录、日志、问答记录,这类文本段落不固定,一个“段落”可能包含多个说话人。按句子切可以保持每个语义单元独立。
- 按固定字数切分:适用于没有自然段落的纯文本。但必须设置相邻块重叠区域,否则关键信息落在切点时会被切断。
示例:如果一段文字过长,可以按句号先切成若干句,再组合成不超过上限的块。例如把“第一句。第二句。第三句。”切成“第一句。第二句。”和“第三句。”,保留句子完整。
实现无重叠分块函数
下面是一个无重叠分块函数,按段落切分后,再把段落组合成不超过指定字数的块。输出每块长度,便于检查是否均匀。
def chunk_by_paragraphs(text, max_len=2000):
paragraphs = [p.strip() for p in text.split('\n\n') if p.strip()]
chunks = []
current = ''
for para in paragraphs:
if len(current) + len(para) + 2 <= max_len:
current = (current + '\n\n' + para).strip()
else:
if current:
chunks.append((len(current), current))
current = para
if current:
chunks.append((len(current), current))
return chunks
chunks = chunk_by_paragraphs(long_text, max_len=1500)
for idx, (length, content) in enumerate(chunks):
print(f'第{idx + 1}块:{length}字')
函数先把连续空行拆成段落,再尽可能把多个段落装入一块。max_len 需要根据模型实际能接受的上下文长度下调,留出系统提示词和问题的空间。由于块之间没有共享内容,每块内容只在最终汇总阶段被引用一次。
设计多轮问答的提示词策略
分块之后,不要一次性把整个文档塞回模型,而是让模型按块回答同一个问题。第一阶段,给模型单个块和问题,要求只依据块内内容回答;如果块内没有答案,就明确说“未提及”。第二阶段,把多个块的第一轮回答拼在一起,让模型汇总。
第一阶段提示词:
你是文档分析助手。下面是一段文档片段,请基于片段内容回答问题。
如果片段中没有答案,只回复“未提及”。不要推断。
文档片段:
{chunk}
问题:
{question}
第二阶段提示词:
以下是同一文档多个片段的第一轮回答。请汇总这些回答:
- 合并重复观点,保留信息不遗漏
- 如果出现相互矛盾的答案,指出矛盾双方和对应片段编号
- 最终给出一个精简且完整的结论
片段回答:
{first_round_answers}
合并答案并处理冲突
第一轮回答可能来自不同片段,内容有重叠也有冲突。第二阶段不能只做“总结”,还要做一致性核对。让模型逐条对比不同片段的原始回答,并说明判断依据。
请对比下面同一文档不同片段的回答,输出三部分:
1. 一致的信息:合并为一条,不重复罗列
2. 矛盾的信息:列出矛盾双方、对应片段编号,以及原文中更贴近的依据
3. 无法判断的信息:保留原样,标记为“需人工确认”
片段1:...
片段2:...
片段3:...
如果某块回答“未提及”,直接忽略,不要参与冲突判断。最终回答应包含原文中出现的实体、数字和限定词,避免模型用常识补全。
用长文档测试整体流程
设计一个可重复的测试,确认分块和汇总没有丢信息。准备一份你打算处理的真实长文档,记录总字数;运行分块函数,观察块数和每块长度;逐块调用模型并记录耗时;再执行汇总,最后对照原文检查最终回答。
- 块数:块数过多意味着每块包含的上下文太少,后续汇总请求会变大;块数过少说明单块仍可能超限。
- 耗时:从发送第一块到拿到汇总结果的完整时间,如果远超单次问答耗时,说明块数需要调小或合并部分流程。
- 匹配度:把文档中关键数字、截止时间、责任主体等作为核对点,看最终回答是否全部还原。如果有关键词缺失,通常是分块边界把相关段落切开了,需要调整max_len或按更细的语义单元切分。
测试时不要只跑一次。同一文档可以尝试不同的max_len,比如从1500、2000、2500各跑一轮,记录哪一组能保持关键语义完整。只要块边界落在自然段落之间,且汇总回答能覆盖原文所有关键信息,这个流程就算可用。