上下文压缩配置怎么做:给长对话留出可用空间的参数调整方法
上下文压缩配置要解决什么问题
上下文压缩配置,指的是在对话或文档内容接近模型上下文窗口上限时,用摘要、截断或选择性保留的方式腾出空间的参数设置。
它要回答三个问题:什么时候触发压缩、压缩后保留哪些内容、原始信息以什么形式留存。
如果你的应用已经出现“聊到后面模型忘了开头要求”或请求直接报上下文超限,通常不是模型能力问题,而是触发阈值、保留窗口和摘要质量没有对齐。
下面按配置顺序说明。
动手前的三个前提
- 明确模型的实际上下文窗口大小。不同模型差异很大,以你所用模型文档标注的 token 上限为准,不要凭印象填数字。
- 确认对话消息的存储结构。压缩需要区分系统提示词、历史消息、当前用户输入,系统提示词一般不能被摘要掉。
- 准备好 token 计数方式。多数 SDK 提供计数接口或分词器,压缩阈值应基于实际计数,而不是字符数估算。
触发阈值与保留窗口怎么设
触发阈值
常见做法是把触发点设在窗口使用率的 70% 到 80%。
留出余量有两个原因:一是当前这一轮请求本身还要占用空间,二是摘要结果也需要作为新消息写回历史。
以伪代码表示配置项:
COMPRESS_CONFIG = {
"max_context_tokens": 128000, # 按所用模型文档填写
"trigger_ratio": 0.75, # 使用率超过 75% 触发压缩
"keep_recent_messages": 6, # 保留最近 6 条原始消息
"summary_max_tokens": 800, # 摘要本身的上限
}
max_context_tokens 必须按实际模型填写,写大了会在请求阶段直接失败,写小了会过早压缩、丢失细节。
保留窗口
keep_recent_messages 决定最近多少条消息不参与摘要。
保留太少,模型会丢失刚发生的上下文;
保留太多,压缩腾出的空间又不够。
经验上保留最近 4 到 8 条消息,覆盖最近一到两轮完整问答即可。
需要特别处理的是系统提示词和工具定义:这两类内容应在压缩后原样保留,不进入摘要流程。
摘要提示词决定压缩质量
压缩后丢信息,多数不是阈值问题,而是摘要提示词太笼统。
让摘要只做“概括对话”容易丢掉具体参数、路径和未完成事项。
建议在摘要提示词中明确三类保留项:
- 用户已明确提出的约束条件,例如技术栈、命名规范、禁止使用的方案。
- 已确认的事实与结论,例如选定的参数值、已排查过的原因。
- 尚未完成的任务和待确认问题。
可以这样写:
请把以下对话压缩为结构化摘要,不超过 800 token:
1. 用户提出的所有约束和偏好,逐条列出;
2. 已确认的技术结论与具体参数值,保留原始数值;
3. 未完成的任务和待确认问题;
4. 不要复述寒暄内容,不要推测未出现的信息。
摘要产出后,把它作为一条系统或助手消息插入历史开头,再接上保留的最近消息,形成新的上下文。
配置完成后怎么验证
用一个包含具体约束的长对话做回归测试:先在前几轮提出若干明确要求,例如“接口路径统一用 /api/v2”,然后把对话推进到触发压缩,再问一个依赖早期约束的问题。
检查点有三个:
- 压缩确实触发,且触发时使用率没有超过窗口上限。
- 摘要中包含早期约束的具体值,而不是模糊表述。
- 压缩后的请求能正常返回,没有报上下文超限。
如果早期约束丢失,先检查摘要提示词是否要求保留具体数值,再检查保留窗口是否把关键消息误纳入摘要范围。
容易踩的几个坑
把阈值设到 95% 以上。 看似少压缩、保信息,实际常因当前请求额外占用而直接失败。
摘要不设上限。 摘要本身也可能很长,压缩后总 token 没降多少,形成反复压缩。
每次触发都重新摘要全部历史。 更稳妥的做法是只摘要“上次摘要加中间消息”,避免多次压缩后信息逐层失真。
忽略工具调用结果。 工具返回的大段 JSON 往往是 token 大户,应在进入历史前就截断或摘要,而不是等整体超限再处理。
常见疑问
压缩后模型回答变差,是模型问题吗? 多数情况是摘要丢了约束条件。
先对比压缩前后的摘要内容,确认关键参数是否保留。
能不能只靠截断不摘要? 可以,但截断会整段丢弃早期信息,适合早期内容确实无关的场景;
需要保留约束时,摘要更合适。
阈值应该固定还是动态? 固定阈值实现简单;
对话长度波动大时,可以按剩余空间动态计算,但要以实际 token 计数为准。
上下文压缩配置没有一组通用参数,关键是让触发阈值、保留窗口和摘要提示词互相配合,并用真实长对话验证信息是否完整保留。