14|上下文压缩:到底压掉什么,丢失后又如何恢复
本章目录
本章预备知识
压缩把长历史换成短状态,通常有信息损失。必须区分已确认事实、仍待验证的假设、真实副作用和原始证据位置,不能把一段流畅摘要当精确任务快照。
本章各题列出所需基础。可先完成相应基础课,也可通过自检确认掌握程度。
进入深读前的小检查:在“补丁已写入但返回超时”的故事里保留unknown状态,解释为什么摘要若只写“执行失败”会诱发重复动作。
术语带虚线时可点击速查。公式中的字母先看定义;不要用猜缩写替代推导。
这一章围绕一个长任务,给出压缩前、候选摘要、验证和恢复的完整过程。没有公开方法能够保证任意未来问题所需的所有细节都被一个短摘要保留;可行目标是面向任务保护关键状态,并让原始证据可恢复。
沿着对象与状态理解本章
压缩最危险的不是少一句背景,而是把“未执行”写成“已完成”,把“禁止”写成“准备做”。先对照本图保留命题、版本、否定与未决状态,再考虑缩短多少Token。
下方图解的固定输入在“输入与适用条件”中声明。它用于解释本章机制,不与本章其他独立例子的数值暗中接续。
压缩要保留行动所依赖的事实
把一百轮历史压成几句话,最容易丢什么?
像交班给另一位同事:对方最需要目标、禁止事项、已经做完的事、还没核实的事,以及到哪里看原证据。原始日志可以外置,但决定下一步动作的区别不能抹平。摘要也不是执行数据库,不应凭它判定不可重复动作是否已完成。
输入与适用条件:构造的exclude修复场景;有意保留“集成测试尚未运行”这一否定状态。错误摘要只作为反例,禁止当作推荐模板。
1 / 5 · 原历史有很多噪声
窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。
工具输出、失败尝试和重复讨论可以很长。压缩的目标是减少历史占用,不是美化成“进度不错”。
可恢复快照默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。
为什么需要
有限窗口无法一直保留全部原始对话,但任务需要连续推进。
怎样实现
保留必要状态与引用,压缩后核对,再从原始来源恢复细节。
可能的代价与误解
摘要重写可能把猜测变结论,多轮摘要还可能累计偏移。
如何判断是否做对
比较压缩前后允许的下一步动作是否一致,而不只是文本相似度。
Q053|Compaction与截断、Prompt Cache、外部记忆有什么根本区别?
核心回答
截断直接删除部分内容;摘要压缩把原内容改写成较短表示,通常有损;专用compaction接口可能生成服务特定的不透明状态;Prompt Cache复用计算,不改变逻辑输入;外部记忆把内容存到上下文之外,需要再检索。不能把这五件事统称为“模型记住了”。[COMPACT][CONTEXT]
同一历史的五种处理结果
长任务已有40轮:读了20个文件、排除了3个根因、改了2个文件、跑了测试。最新目标是补齐边界情况。
直接截断前30轮,可能连“不改公共API”的原始约束一起删掉。摘要保留“修复exclude,测试通过”,看似简洁,却丢掉测试对应哪个版本、哪些测试、是否有跳过,以及一个尚未确认的远程动作。外置完整日志只保留路径,能恢复,但模型下一步需要知道何时去读哪段。缓存则可能让40轮原文计算更便宜,却仍占逻辑上下文和注意力处理空间。
较好的教学摘要会区分:
目标:修复exclude匹配,不改变公共函数签名。
已确认:问题位于路径规范化;证据 E12=filter.py@r42:60-95。
已排除:配置未加载;test_config_load在r42通过,日志L8。
已修改:filter.py、test_filter.py,当前工作树r43。
已验证:目标测试在r43通过;全集回归尚未运行。
未决:远程任务c19超时,副作用未知,禁止自动重复提交。
下一步:核对c19结果;随后运行相关回归。
原始记录:trace-17及证据索引;不要把假设当结论。
这份摘要仍未包含每行代码,但保存了行动需要的约束、证据入口和状态。它能支持恢复,而不是声称无损保留所有思考。
四种“减少负担”的动作分别改变了什么
输入与条件。历史有100条工具日志、三个已确认事实和一个待核查动作。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1截断 | 直接删除最旧80条日志 | 长度下降,但其中独有证据可能无法从剩余文本恢复。 |
| 2摘要压缩 | 用短状态记录替代部分历史 | 事实与未完成动作保留得好不好需要验证。 |
| 3计算缓存 | 仍提供原逻辑上下文,复用部分已有计算 | 不改变文本知识内容,也不是长期记忆。 |
| 4外部记忆 | 把可复用事实带来源存储 | 下一任务是否能用到,还取决于检索和有效性检查。 |
| 5组合 | 大日志外置、摘要保留路径、必要时补读 | 通过可恢复证据降低当前输入量。 |
把过程连起来。名字都可能带“缓存”或“记忆”,但变化的是文本、计算还是外部状态,必须分别说明。
边界与反例。不透明压缩状态不能当成普通可读摘要;示例采用显式文本摘要便于教学。
追问:不透明压缩块是否比文本摘要必然更可靠?
不能仅凭不可读得出结论。专用状态可能更适合模型继续处理,也可能含有产品特有信息,但仍需测后续任务质量。不可读意味着人工检查方式不同,不意味着数学上无损。应保留应用侧关键状态和证据,不把一切托付给不可见表示。
追问:把历史压成原来的10%是否足够?
压缩比只是长度指标。删掉90%重复日志可能无害,删掉一句“不允许删除数据库”就可能严重。应先定义保真对象与风险,再调压缩比。任意固定比例都不是普遍正确的目标。
追问:压缩后模型还能回忆出没保存的细节吗?
它可能根据上下文和训练知识猜到,但不能把猜测当恢复。若原始证据还在,可通过工具重新读取;若已经删除且压缩没有保留,就没有可靠依据。工程上应明确“未知”而不是允许模型补齐一段似是而非的历史。
Q054|一次安全压缩应该按什么顺序运行?为什么要避免边执行边替换?
核心回答
先确定一致的历史/状态快照,再产生压缩候选,验证关键不变量,构建新上下文并切换;在验证失败时保留旧状态或回退。压缩不是简单调用总结模型后覆盖一个字符串。Codex的固定源码快照展示了重建并替换历史的具体路径,但本节事务式检查是通用教学设计。[CODEX-SRC]
七步过程与每步失败后果
- 选择边界。 尽量在工具调用完成、阶段目标清楚时压缩。若有running/unknown动作,必须显式带入状态,不能消失。
- 冻结快照。 记录历史版本v与当前任务版本。压缩过程中若新消息到达,要么排队,要么在切换前重新合并;否则会覆盖用户新约束。
- 提取关键对象。 目标、否定约束、已验证事实、证据引用、已完成动作、未决问题及下一步。关键对象可来自结构化状态,不全依赖模型回忆。
- 生成候选。 要求不把未确认假设升级成事实,保留来源与版本。若是专用API则遵守其输入/输出状态契约。
- 检查不变量。 关键ID和约束是否存在,unknown动作是否仍unknown,证据版本是否一致,否定词是否丢失。
- 重建上下文。 重新加入需要的固定指令、工具定义、当前环境和候选压缩状态;避免重复或错误提升权限。
- 条件切换。 仅当原快照版本仍有效时切换,保存旧记录索引和压缩版本。压缩失败不应把有效历史清空。
这七步不意味着每个聊天工具都需要复杂数据库。短任务可以根本不压缩;轻量实现可用只写一次的新文件与原子重命名;涉及并发和长期任务时才需更强版本条件。
摘要生成期间又发生一个工具结果,怎样不丢掉它
输入与条件。开始压缩时历史版本h=20;工具c7尚在运行。摘要针对1—20生成期间,c7完成,历史追加事件21。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1拍快照 | 记录压缩覆盖到事件20 | 给候选摘要一个明确边界。 |
| 2生成摘要 | 输入快照1—20 | 它不可能凭空知道还没出现的21。 |
| 3提交检查 | 当前历史已到21 | 不能拿候选摘要直接覆盖全部历史。 |
| 4正确拼接 | 摘要代表1—20,随后保留原事件21 | 维护call_id配对与顺序。 |
| 5并发更复杂 | 若事件21改变了摘要中的关键状态 | 重建当前状态或重新压缩,不能让succeeded同时仍标pending。 |
| 6原子发布 | 新历史和其版本标识一起切换 | 避免下一轮看见半旧半新的组合。 |
把过程连起来。压缩是有并发写入风险的状态转换,不只是调用一次“总结”模型。
边界与反例。这是可选设计模式,不声称所有厂商实现相同;只对不可变追加历史时简单拼接成立。
追问:什么时候触发压缩最合适?
考虑剩余窗口、预计下一工具结果、阶段边界、历史相关性与缓存得失。只在100%窗口时触发太晚,因为压缩调用本身也要处理历史;太早又可能浪费成本或丢掉即将使用的细节。阈值是保护线,不是唯一信号。
追问:压缩调用自己超限怎么办?
可先清理明确可恢复的冗长工具输出、分块提取关键状态,或使用支持的服务端机制。不能未经检查只删最早内容,因为最早可能含根本约束。产品可能有特定降级路径,学习源码时要看其错误分支,而不是假设压缩永远成功。
追问:连续多次摘要为什么可能逐渐失真?
后一轮常以先前摘要为输入,早期不确定性或细节一旦丢失,可能被当成已经确定的简化结论继续强化。解决方式不是无限增加摘要长度,而是保留可回溯证据、稳定事实表及周期性原文核对,对重要结论避免只引用“前一份摘要”。
Q055|压缩后怎样找回原始证据?摘要与外部存储如何协作?
核心回答
摘要应保存足够的定位信息和读取触发条件;外部存储保留原始证据及版本。恢复是重新读取对应记录并核验是否仍适用,不是让模型凭摘要扩写。引用需要可解析、可授权、可验证。
沿一个证据引用走到底
摘要中写E12=filter.py@r42:60-95。下一步要编辑当前r44时,模型不能直接把r42当当前代码。Harness或工具应读取r44对应区域,并检查相关逻辑是否变化;r42证据仍能解释历史根因,但补丁必须针对当前版本。
日志引用也要带范围与意义。例如L8: command=pytest test_config_load, revision=r42, exit=0,不是只有/tmp/log.txt。临时文件可能已被清理,路径可能被覆盖。对长期任务,重要日志应放在生命周期明确的存储,或保存足够小的关键输出副本。
恢复触发可来自具体问题:准备修改曾经讨论的函数、发现当前摘要与源码不一致、需要对外声明某测试通过、重新考虑已排除方案。没有触发时不必把全部历史重新读回,否则压缩收益被抵消。
摘要写“配置已变更”,下一步要怎样找回依据
输入与条件。摘要记录timeout=5,证据指向 config.json@v8,下一步准备部署;当前工作树却是v9。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1判断所需精度 | 部署需要当前有效配置 | 一句摘要不能承担执行依据。 |
| 2取回证据 | 按路径和版本读取v8 | 确认摘要没有改写数字或单位。 |
| 3检查当前 | 读取v9对应字段 | 若变为7,应重新判断,不复用过期结论。 |
| 4无法读取 | v8已不存在且v9权限不足 | 状态应是证据缺口,而非“默认还等于5”。 |
| 5恢复上下文 | 只加入与部署决策相关字段和版本 | 无需重新读全仓库历史。 |
把过程连起来。好摘要既表达状态,也让关键结论能回到原始证据;证据重取还必须核对时效。
边界与反例。版本引用在存储系统中必须真实可解析;仅写一个看似正式的路径并不自动具备可恢复性。
依据与适用范围:[CONTEXT]。示例输入和场景由本书明确设定。
追问:引用包含hash是否总是必要?
不是。版本号、不可变对象ID或受控仓库commit常已足够。hash用于识别精确内容很有价值,但不应为每句说明都增加签名、校验链和复杂结构。按“内容变化会不会导致错误动作”决定验证强度;hash也不证明内容本身正确。
追问:原始证据需要永久保存吗?
不一定。保存时间与重现、合规、隐私和成本有关。短期噪声可较早清理;关键决策、不可逆动作和长期经验依据应有适当保留。删除前要让依赖引用失效或迁移,而不是留下看似可用的死链接。
追问:有RAG是否可以不做任务摘要?
RAG擅长按问题找内容,但未必知道当前进度、哪些动作已执行、哪些结果未知。任务摘要提供“现在该做什么”的控制视图,检索提供“需要时去哪找”的证据视图。两者互补,不能用语义检索替代副作用日志。
Q056|如何评估压缩保真?只比较摘要与原文相似度为什么不够?
核心回答
压缩应评估关键事实/约束保留、错误新增、状态一致性,以及压缩后的真实继续执行。词面相似不代表行动信息保留;一个很短但准确的状态表可能比长篇复述更可靠。
构建可复现的检查任务
在压缩前准备一组问题,答案必须由历史确定:禁止修改哪个API?哪个假设已排除?当前文件版本是什么?测试是通过、失败还是未运行?哪个远程动作结果未知?每个问题关联证据,避免评判者自己凭印象打分。
压缩后让系统只用新状态回答并继续下一步。检查不能仅靠“关键词还在”:不需要回滚和需要回滚都含“回滚”;“测试已通过”与“测试尚未通过”词面相似却含义相反。要核对否定、条件、数量、时序和资源身份。
至少分三个实验组:完整历史、不带保护的摘要、带结构化状态和证据引用的摘要。在相同任务和预算下比较继续完成率、重复操作、关键约束违反、Token与时间。多次运行观察随机性;真实商业模型的结果必须实际调用才能报告,本包只提供方法与确定性反例,不伪造此类胜率。
如何检查压缩是否把“未确认”改成“已成功”
输入与条件。压缩前基准事实:F1只读,F2测试通过于v7,F3当前v8未测,F4调用c7结果未知。候选摘要只写“测试通过,修改完成”。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1逐项问答 | 检查是否仍可回答F1—F4 | 发现摘要缺少只读、版本和unknown状态。 |
| 2事实保留 | “测试通过”只支持v7 | 不能据此给v8发通过标签。 |
| 3状态反例 | c7未知被改成完成 | 这是错误事实,不只是遗漏。 |
| 4任务续跑 | 让确定性检查器尝试交付v8 | 正确系统应要求补测并核查c7。 |
| 5指标拆开 | 统计保留、错误新增和继续执行行为 | 摘要字数减少不能替代这三项。 |
把过程连起来。压缩质量需要评估保留的信息、引入的错误和下游行动,不靠语言流畅度判分。
边界与反例。规则检查仅覆盖显式设定事实,不能证明自然语言摘要所有语义都保真;真实模型仍需实际任务评测。
追问:怎么防止为已知检查题过拟合摘要?
保留一部分未参与摘要设计的后续问题,加入不同任务与不同位置的约束;使用真实继续执行而非只答固定问答。已知检查题可作为最低保障,但不能证明对所有未来问题都无损。
追问:什么时候宁可保留更长上下文?
正在进行精细代码修改、需要比较多个原始片段、短期内会反复核对细节时,保留原文可能优于摘要。任务即将结束时,额外压缩调用也可能没有收益。压缩是手段,不是每个长对话必须履行的仪式。
追问:能否给出“压缩无损”的严格标准?
若要求对任意未来查询都能恢复原文所有信息,短摘要一般无法保证。更实际的是定义任务相关不变量集合和可恢复来源,声明在这些检查上的保留情况。严格边界比空泛承诺“保留全部重要信息”更有工程价值。