上下文管理实践:何时重开会话,何时进行压缩

作者:袖梨 2026-09-17

使用 AI 辅助编程时,一个原本进展顺利的对话可能在多轮交互后逐渐失控:模型开始忽略约束、重复修改同一处代码,解释越来越多,结果却越来越差。遇到这种情况,继续补充提示词未必有效,更关键的是识别上下文何时已经过载,并决定该压缩当前会话,还是整理状态后重新开始。

本篇是《从头重新学 AI 编程》系列第 5 篇。

前四篇我们聊了角色转变、Spec、AGENTS.md、还有怎么冷启动一个旧项目。这些东西铺垫完,从这一篇开始,我想聊一个几乎每个用 AI 写代码的人都遇到过,但很少有人真的想明白的问题。

你跟 AI 聊着聊着,突然发现它好像变笨了。

刚才还挺聪明的,现在开始犯一些莫名其妙的低级错误。你明明前面说过不要改某个文件,它又去改了。你让它修一个 bug,它修完顺手又给你引入一个新的。它的解释越说越长,但你看 diff,越来越看不懂它到底在干嘛。

这种时候你第一反应是什么?

我以前的第一反应是,这模型今天是不是抽风了,或者是不是我 prompt 没写好。然后我就开始换着花样写 prompt,越写越长,越写越细,结果它该犯的错还是犯。

后来我才搞明白,大多数时候根本不是模型的问题,也不是 prompt 的问题,是上下文出问题了。

Pasted image 20260627172145.png
这个事我在第 1 篇其实埋过一个钩子,当时我说我用 Claude Code 聊了二十多轮之后它开始忘事。这一篇就把那件事彻底讲清楚。

你可以把 AI 的上下文窗口理解成它的短期记忆。它一次能装的东西是有限的,装了多少文件内容、记了多少轮对话、有没有注意到你强调的那个约束,这些全在抢同一份预算。

会话越长,这个预算就越紧张。旧的对话、旧的文件内容、旧的报错信息,全都堆在里面占着地方。AI 的注意力被一点点稀释,输出质量自然就往下掉。

它不是变笨了,是脑子被塞满了。

想明白这一点之后,问题就变成了,我怎么知道它什么时候塞满了?

我自己总结了四个信号,一旦出现,基本就说明该换会话了。

第一个信号,AI 开始忘记前面的约束

你前面白纸黑字说过「不要改 migration 文件」,它现在又去改了。你纠正过一次的错误,它过几轮又犯了一遍。

这不是它故意不听话,是前面那条约束已经被后面几十轮对话挤出了它的注意力范围。它不是不想遵守,是真的「想不起来」了。

第二个信号,反复修改同一个地方

一个地方改了三遍还是不对。你指出问题,它改;改完你再看,它又改回去了;你再指出,它又改回来。

它在绕圈。上下文里同时存在太多互相矛盾的信息,它自己已经分不清哪个版本才是对的了。

第三个信号,解释越来越长,但 diff 越来越差

AI 的回复越写越长,给你分析一大堆「为什么这么改」「我考虑到了什么什么」,听起来还挺像那么回事。但你把它的废话扒开看实际的 diff,改得一次比一次离谱。

这个我觉得是最隐蔽的一个信号。解释变长,往往是它在用话术填充自己的不确定。它其实自己也不知道该怎么改了,但它不会直接跟你说「我不知道」,而是用一大段分析把这个心虚盖住。

第四个信号,一个任务聊了几十轮还没收敛

正常情况下,一个边界清晰的任务,十轮左右应该能有个结果。如果你已经聊了二三十轮还在反复调整,那大概率不是需求本身的问题,是上下文已经乱了。

这四个信号你记住,平时跟 AI 干活的时候留个心眼。但说实话,等这些信号都冒出来了才换,已经有点晚了。

Pasted image 20260627172703.png
更好的策略是,别等。在自然停顿点主动换

什么叫自然停顿点。

做完一件事的时候,就是一个。比如登录功能做完了,接下来要做主页,这时候你就该开新会话。别把「做登录」攒下来的一堆旧信息,原封不动带进「做主页」这个新任务里。那些信息对新任务一点用没有,纯占地方。

切到不连贯话题的时候,也是一个。你前一秒还在跟它讨论数据库设计,下一秒要去调样式,这两件事八竿子打不着,开新会话。

还有一个信号比较主观,但我觉得特别准,就是你感觉这个对话「变沉重了」的时候。怎么形容呢,就是你往上滚动找之前说过的话,发现要滚好久;你每次回到主题之前,得先扫一遍前面在干嘛;AI 的回复也开始变慢。这种「重」的体感一上来,基本就是该换了。

最后还有个最硬的指标,Claude Code、Cursor 这些工具都会显示上下文用量。过半了你就开始留意,到了七八成,就该安排收尾了。

好,说到换会话,这里有个很多人会踩的坑。

换会话不是把窗口一关就完事了。你直接关掉,前面攒的所有状态就全没了,新会话又是一张白纸,你还得从头解释一遍。这不就白干了。

正确的做法是,换之前先让 AI 写一份交接文档。

我自己一般是这么让它写的,

停一下。把现在的工作状态写到 docs/notes/handoff.md,包括,
1. 我们在做什么(任务、spec 链接)
2. 已经改了哪些文件
3. 哪些测试通过、哪些还没跑
4. 下一步计划是什么
5. 你脑子里现在有什么还没说出来的重要发现

最后那条我觉得特别关键。你让它把「还没说出来的发现」也写下来,往往能挖出一些它自己注意到了但一直没提的东西。

然后在新会话里,开头这样起,

读 AGENTS.md。读 docs/notes/handoff.md。我们继续上一个 session 没做完的事。

新会话的上下文是干净的,但它通过这两个文件继承了前一个会话最关键的状态。这种方式比任何所谓的「压缩」「清理」都靠谱。

Pasted image 20260627173244.png
说到压缩,你可能注意到 AI 工具里有个 /compact 命令,能把当前对话压成一个摘要继续聊。这玩意跟写 handoff 文件有啥区别?

我自己的理解是这样的。

handoff 文件是写到磁盘上的,内容你自己定,留什么不留什么你说了算,而且文件能 commit 进 git,跨天、跨人都能接着用。适合那种阶段性任务做完了、或者工作到深夜要睡了、或者要把活交接给同事的场景。

/compact 是在当前这个会话里压缩,保留哪些摘要是 AI 自己决定的,你只能被动接受它给你压成什么样。适合同一个任务还在进行中,你只是想腾点上下文空间接着往下跑。

这两个不是谁替代谁,是两个不同场景的工具。我自己一般是,单个任务跑得长就用 /compact 续航,任务做完了或者要跨天了就写 handoff 文件交接。

那万一你没忍住,错过了最佳换会话的时机,上下文已经乱成一锅粥了,怎么办?

这个时候最差的选择,就是继续硬聊。

你想想看,它已经在一个很糟的状态里了,你每多聊一轮,它就在更糟的状态下又回答一次,只会写出更烂的代码,做出更差的判断。这是个负向循环,越聊越深。

正确的做法是立刻抢救。让它把当前状态写到文件里,哪怕上下文已经很满了,这个动作通常还是能挤出来的。写完,开新会话,从文件里把状态加载回来接着干。

我给自己定了一条规矩,永远不要让一个塞满的会话直接结束,一定要从它嘴里榨出一份 handoff 再走

Pasted image 20260627174659.png
还有一种情况,我单独拎出来说一下,因为它跟上下文满了有点像,但其实不是一回事。

就是调试卡住了。

同一个 bug 你改了两次还是没好。AI 开始绕圈,试完方案 A 试方案 B,方案 B 不行又绕回方案 A,跟鬼打墙一样。

这种情况下上下文不一定满,但你跟它都已经陷进一个思维定式里了。继续在同一个会话里硬聊没用,因为前面那些失败的尝试还堆在上下文里,会持续干扰它的判断。

我的做法是,写一份卡点记录,然后开新会话。

卡点记录大概长这样,

# 卡点,登录接口返回 500

## 目标
修复登录接口的 500 错误

## 当前现象
POST /api/login 返回 500,没有具体错误信息

## 已经试过什么
- 方案 A,检查 auth 路由,没发现问题
- 方案 B,加 try-catch,错误信息被吞掉了

## 相关文件
- server/routes/auth.js
- server/db/schema.sql

新会话加载这份记录,上下文是干净的,但「已经试过什么」这部分又帮它排除了死路,思路反而更清晰。比在旧会话里继续绕圈有效得多。

Pasted image 20260627173957.png
聊到这里,这一篇其实就一句话能概括。

知道什么时候该停,比知道怎么往下做更重要

这话听着有点反直觉。我们总觉得用 AI 的本事在于会不会写 prompt、会不会调教它。但用得久了你会发现,真正拉开差距的,往往是那些「不写」的时刻,是你知道这个会话已经废了,该果断换一个的判断力。

四个信号你记住,忘记约束、反复改同一处、解释变长 diff 变差、聊几十轮不收敛。一旦出现,别恋战。换之前先写 handoff,让新会话能接上。

给你一个小练习。下次你跟 AI 干活的时候,留意一下上下文用量那个数字。等它过了一半,你就有意识地找一个自然停顿点,让 AI 写一份 handoff,然后开新会话继续。体会一下新会话那种「脑子重新清醒」的感觉,你就明白这一篇在讲什么了。

下一篇我们聊一个工具层面的东西,MCP,怎么给 Agent 接上外部工具和数据。如果你现在还没用过 MCP 也别有压力,可以先了解个概念,等真正需要的时候再回头落地。

相关文章

精彩推荐