Claude Code 会话中途 key 被停用:不丢上下文地接回来
讲解 Claude Code 会话中途因 API key 失效或停用而中断时,如何保留工作状态、以最小代价换用新 key,并尽量续上原有上下文,避免从头重建对话。
先说结论:能救的是「工作状态」,不一定能救「会话进程」
Claude Code 本质是一个跑在终端里的长会话客户端。key 失效时通常表现为请求直接报鉴权错误,进程本身可能还没退出,也可能因为连续失败而中断。
需要区分两件事:
- 会话历史:这次对话里已经产生的上下文。它由客户端维护,能否在新进程中恢复取决于客户端是否把会话落盘、以及换 key 后能否读到同一份会话存档。
- 工作状态:你在仓库里改过的文件、跑过的命令结果、结论性的判断。这部分只要落在磁盘上就还在。
所以可靠的恢复策略不是「指望会话原样复活」,而是先把不可再生的信息固定下来,再换 key,再看能不能续上。
第一步:在换 key 之前先固化状态
发现报鉴权错误时,不要立刻反复重试。重复失败只会刷屏,还会掩盖真正的错误码。按顺序做:
- 停止发送新请求,保留当前终端窗口,不要关闭。
- 用客户端自带的会话保存能力(多数情况会话文件已自动落盘)确认当前对话还在。
- 让模型做一次「交接总结」——如果此刻还有任何可用通道(换 key 后第一件事也可以做这个),把当前任务目标、已完成改动、待办项、关键文件路径、失败的尝试列成清单。
- 把这份清单写进仓库里的文件(比如临时笔记或任务 issue),而不是只留在对话里。文件是不会随进程消失的。
这一步的意义在于:即使会话完全接不回来,你也能用一份几行的清单在新会话里重建上下文,成本远低于从头复述整个排查过程。
第二步:换上新的 key
聚合型 API 服务通常一个 key 就能访问多个模型,所以换 key 往往只改一处。常见做法有两种,优先选后者以外的方式取决于你对「不污染 shell 历史」的要求:
- 环境变量:在启动客户端的同一个 shell 里设置鉴权变量后再启动。适合临时切换、一次性的排障。
- 项目级配置:把 key 写进项目目录下被 git 忽略的配置文件,让这个项目固定指向某个 key。适合长期项目、多人共享同一份仓库配置骨架。
不管用哪种,注意三点:
- 环境变量的优先级通常高于配置文件,改了配置文件却没生效,先检查 shell 里是否有残留的旧变量。
- 新 key 只写在本地、写进
.gitignore覆盖的文件里,别提交。 - 换完先发一个最小请求验证鉴权通过,再恢复正式工作,避免把长上下文浪费在一次失败的调用上。
第三步:尝试续上原会话
如果客户端把会话历史存在本地,重新启动时通常可以选择继续之前的会话而不是新建。能续上的前提是两条:
- 会话存档还在,且没有被新会话覆盖;
- 新 key 对应的账号能读到同一份存档(同一台机器、同一个用户目录一般没问题)。
续上之后,第一件事不是继续干活,而是核对状态:让模型复述它认为的当前目标与已完成改动,和你在第一步写下的清单对照。不一致的地方以文件清单为准,因为它没有被上下文压缩或摘要裁剪过。
接不回来时:用清单做冷启动
会话确实恢复不了也不必重来一遍。用一个新会话,把第一步那份清单作为第一条消息贴进去,明确三件事:任务目标、已改动的文件与原因、下一步要验证什么。
这等价于给新会话注入了最小可用的上下文,比让模型重新读一遍整个仓库更省 token,也更不容易跑偏。
预防:让下一次中断代价更低
- 把结论落到文件:重要的判断、验证结果、失败原因写进仓库,而不是只存在于对话里。
- 分阶段提交:每完成一个可验证的小步就提交一次,中断后
git diff就是你的状态快照。 - 缩短单次会话跨度:长会话本身带来的上下文压缩和状态漂移,比 key 失效更难排查。任务边界清晰时主动开新会话。
- 准备备用 key 通道:手边留一个可用的鉴权配置,切换成本就是改一个变量。
一个常见误区
不要指望「换 key 后原请求会重放」。鉴权失败发生在请求入口,模型并没有看到那次输入,所以没有任何输出可以恢复。上下文能不能续,取决于客户端存档,而不是服务端记住你。把精力放在状态固化上,比研究怎么「重试成功」更实际。