会话与上下文管理
同一个 Agent 会话越拖越长,并不是越聊越聪明。随着对话历史、读进来的代码和工具输出不断累积,模型要在更多内容里找线索,判断反而容易变差。本章讲三件事:什么时候该重开一个会话,怎么把一段工作交接给下一个会话,以及一个会话失控时怎么识别和止损。
先要分清上下文的两个来源。一类是系统提示、常驻 steering 和工具定义等基础内容;按条件加载的 steering、skill 正文只在触发后进入上下文。另一类是随任务累积的内容,包括读进来的文档和代码、对话历史及工具返回。两类内容都会占用上下文,也可能因过长、无关、重复或互相冲突而干扰判断;区别在于任务负载会随着工作推进持续增长,更容易在单个会话里失控。
16.1 重开的时机
窗口占用比例不能单独决定是否重开。它能提示容量是否接近上限,却不能说明模型还能稳定利用多少信息:相同比例下,相关且一致的材料与重复、冲突的材料带来的影响不同。应把窗口比例与实际表现放在一起判断。
任务负载的影响并不是到某个固定比例才出现。在需要跨越大量内容做推理的任务上,输入越长,模型越容易漏掉中间的信息,这个退化从远未填满窗口时就开始了。所以没有一条适用于所有项目的固定清理线;从多少开始明显变差,取决于任务类型和模型,要靠在自己的项目里观察来定。
下面两个信号比单看窗口比例更直接:
| 信号 | 说明 | 处置 |
|---|---|---|
| 累积任务负载明显变重 | 一个会话里读进了大量代码和文档、对话拖了很多轮、工具返回堆积 | 判断仍稳定时先压缩;阶段结束或无法有效压缩时交接重开 |
| 同一个问题纠正两次还错 | 对同一处连续纠正两次,模型仍给出偏离的结果 | 停止追加提示,核对需求、材料、工具和当前状态,再决定是否重开 |
同一个问题纠正两次还错,是止损信号,不是对根因的诊断。问题可能来自上下文污染,也可能是需求含糊、材料缺失、约束冲突或工具能力不足。继续追加提示之前,先确认是哪一类问题;如果旧对话已经持续把判断带偏,再换到不继承旧对话历史的新会话。
重开也有固定成本:下一个会话通常需要重新读取交接材料和必要文件。只因历史变长就频繁重开,未必节省成本或提高质量。判断仍稳定、目标没有改变时,优先压缩;判断已经偏离、当前阶段已经结束、要切换工作线,或即将触及容量上限时,再交接重开。
当前工具提供 /compact 或同类压缩功能时,可以用摘要替换冗长的中间历史。摘要的目标是留下当前目标、关键决策、已改文件和下一步,但不能保证识别或纠正已经形成的错误前提。压缩适合同一工作线仍要继续、判断尚未明显偏离的情况,可以在负载开始变重时执行,不必等到接近容量上限;它不能代替阶段交接。
自动摘要可能漏掉限制条件、误写完成状态,或丢失失败原因。压缩后先核对目标与不可改范围、已经完成的工作、关键决策、当前文件状态和下一步。需要保留完整历史时,应在压缩前按工具支持的方式导出或留档。
摘要也可能遗漏操作的先后顺序。Claude Code 的一个 issue 记录过这样的状态回退:改动仍在测试,压缩后的 Agent 却按摘要里过时的下一步准备提交。这个案例不能证明所有 Agent 都有同样的问题,但说明摘要中的进度不能替代实际状态。继续工作前,应以文件、版本和检查结果确认当前进度。
16.2 交接与接续
一段工作需要跨会话继续时,要把它交接给下一个会话。交接不是复制聊天记录,而是留下接续真正需要的信息:
| 交接项 | 内容 |
|---|---|
| 目标与边界 | 当前要完成什么,哪些内容不在范围内 |
| 状态锚点 | 对应的分支或提交,工作区是否有未提交改动,环境处于什么状态 |
| 已完成与证据 | 已经完成的工作,运行过的检查及结果 |
| 结论与疑点 | 已确认的结论,走不通的路径及原因,仍待核实的事项 |
| 接续入口 | 必须读取的材料,第一个待办及其对应文件 |
本手册用 /td-handoff 生成交接,用 /td-resume 读取并接续。
交接文档的价值在于它是筛过的上下文。原始会话里混着大量探索、试错和工具输出,其中大部分对接续没有用。交接把结论和待办留下,把无关过程丢掉;下一个会话不继承整段旧对话,也能从明确的状态继续。
接续不是零成本。下一个会话通常要重新读取交接提到的文档和材料;读得越多,起步时的任务负载越重。交接文档应当区分必读材料、按需材料和不必重读的过程记录,让接续会话只加载当前步骤真正依赖的部分。不同工具的缓存和恢复机制不同,不能用某一次实测的消耗推算所有工具。
接续还有一条纪律:交接文档记录的是写下它时的状态,不代表现在。代码、数据和环境之后可能发生变化,原会话也可能记录有误。接续时要重新核对下一步依赖的关键结论,通过命令、文件或实际环境确认它们仍然成立。需要重新尝试已经否决的路径时,应先说明原理由为什么不再成立。
通过标准:新会话不读取旧聊天记录,也能确认当前版本和工作区状态,找到支撑关键结论的证据,并知道第一个待办;不能确认的内容已经标为待核实,而不是写成既定事实。
16.3 失控信号与止损
会话有时会陷入一种状态:看起来还在干活,实际已经不再推进。常见的几种表现:
| 表现 | 看起来像 | 实际上 |
|---|---|---|
| 原地打转 | 反复修改同一处 | 每轮换个说法,问题没解决,甚至绕回之前试过的做法 |
| 偏离目标 | 还在写代码 | 慢慢忘掉开头定的规则、格式和约束,做的已经不是最初要的 |
| 错误滚雪球 | 顺着往下做 | 早一步判断错了被当成地基,后面越走越偏,不回头 |
| 丢失状态 | 继续操作 | 记不清文件改到哪、哪些检查跑过、当前在什么位置 |
| 反复确认不落地 | 说”再检查一遍” | 复查只是把原结论复述一遍,没有新的证据或新的工具调用 |
这些表现说明当前工作方式已经不能可靠推进,但根因不一定都是上下文过长。还要检查目标是否含糊、必要材料是否缺失、工具或权限是否不足、外部依赖是否阻塞,以及早期判断是否已经带偏后续工作。没有分清原因就继续追加提示,可能只会增加噪音。
止损的步骤:
- 停下,不要继续用追加提示掩盖问题。
- 检查问题来自上下文、任务定义、材料、工具、权限还是外部依赖。
- 判断已有产物中哪些可靠、哪些可疑,以落盘文件和可重复验证的结果为准,不以会话里的说法为准。
- 记录可靠产物对应的版本和证据,把可疑部分标为待核实;项目允许时再用提交保存检查点。
- 上下文或状态已经失真时,交接后重开;缺少权限、材料或外部条件时,先处理实际阻塞。
并行本身不是问题,无法独立验证和汇总才是。只把边界清楚、不会同时修改同一批文件、能够分别验收的子任务并行出去;共享前提多、结果必须互相等待的任务仍应串行。主会话无法逐份核对返回结果时,停止继续派发,先分批汇总并处理已有结果。
本章小结
窗口占用比例只能提示容量,是否压缩或重开还要看任务负载和实际表现。同一工作线仍然稳定时先压缩;阶段切换、判断偏离或状态失真时,固定可靠产物并交接重开。交接要带版本、证据和下一步,接续时重新核实关键结论;并行任务则按能否独立验收和可靠汇总控制范围。
参考与出处
- 长上下文下模型对中段信息的利用随输入变长而下降:Lost in the Middle: How Language Models Use Long Contexts
- 真实任务里输入越长性能越退化,而非窗口填满才退化:Chroma: Context Rot
- 压缩用摘要替换较早的对话历史,默认摘要可能遗漏后续需要的信息:Anthropic: Compaction
- 压缩摘要遗漏操作时间线并导致状态回退的案例:Claude Code issue #24792