Claude Code 用文件做计划,上下文断了也不丢
把 Claude Code 的计划写进仓库里的 task_plan.md,压缩和 /clear 之后还能接着干,附可直接抄的计划文件骨架。

Agent 干到一半上下文满了,压缩完回来反问你「刚才做到哪」。Claude Code 用文件做计划就是堵这个洞:阶段和进度写进仓库里的 markdown,会话没了它还在。
会话里的计划为什么留不住
同一句指令,写在 CLAUDE.md 里和在对话里随口说,压缩之后的命运完全不同。Anthropic 的官方文档把这条差别写得很明确:项目根目录的 CLAUDE.md 在 /compact 之后会被重新读盘并注入回会话,子目录里的 CLAUDE.md 不会自动重注入,只在下次读到那个目录的文件时才加载;而只在对话里给过的指令,压缩完就是没了。
TodoWrite 那种会话内清单属于后者。它活在上下文窗口里,窗口一重置就归零。任务跑到五十次工具调用以后,最初的目标本来就在被后面的日志挤,再叠一次压缩,agent 只能靠重新读代码猜自己走到哪。
同一份文档还提醒了另一件事:CLAUDE.md 是上下文,不是强制配置,官方建议单个文件控制在 200 行以内,越长遵守度越差。所以计划这种每轮都要看、还会不断变的东西,塞进 CLAUDE.md 也不合适,它需要一个自己的文件。
一个计划文件该有哪些字段
落到磁盘上的东西可以很少:一个计划、一份调研记录、一份执行日志,三个普通 markdown 文件就够,其余状态都不必持久化。
your-project/
├── task_plan.md # 阶段、勾选框、当前落点
├── findings.md # 调研结论和决策,边做边追加
└── progress.md # 会话日志和测试结果
task_plan.md 是恢复时唯一必读的那个。可以直接抄的骨架长这样:
# Task Plan: 订单导出接口重构
## Goal
一句话写清终态,不写过程。
## Next Step
下一步要做的那一个动作,动词开头。
## Current Phase
Phase 2
## Phases
### Phase 1: 摸清现状
- [x] 读 export 相关的 3 个文件
- [x] 现有字段映射记进 findings.md
- **Status:** complete
### Phase 2: 改写分页逻辑
- [ ] offset 换成游标分页
- [ ] 补 50 万行以上的边界用例
- **Status:** in_progress
## Decisions Made
| 决策 | 理由 |
|---|---|
| 用游标分页 | offset 在 50 万行之后稳定超时 |
## Errors Encountered
| 错误 | 第几次 | 处理 |
|---|---|---|
| 导出超时 | 1 | 加索引仍复现,改分页 |
字段顺序有讲究。Goal、Next Step、Current Phase 排在最前,是因为自动注入通常只截文件开头的一段(planning-with-files 默认是前 50 行),排在后面的阶段列表在长计划里会被截掉。阶段数控制在 3 到 7 个,每个阶段挂一行 Status:,取值只有 pending、in_progress、complete 三种,勾选框负责阶段内的颗粒度。
决策和错误两张表是最容易被省掉、也最值钱的部分。决策表让你三天后不用重新论证一遍为什么选了游标分页;错误表让 agent 不会把刚失败过的命令再跑一次。反过来,网页正文、长日志、整段代码不要抄进 task_plan.md,那会让每轮注入都变贵,取舍逻辑和 Agent 省 token 里那套一样。
执行过程中进度怎么被勾上
四条执行规则决定了文件会不会变成一写完就没人管的摆设:动手前先建计划文件;每做完两次查看或浏览类操作就把结论追加进 findings.md;所有错误都记,包括当场十秒修好的那种;同一个失败动作不重复第二次,换路子而不是重试。
勾选发生在阶段边界:一个 phase 的所有勾选框都变成 [x],就把 Status: 改成 complete,同时更新 Current Phase 和 Next Step。这三处一起改,注入的开头一段才是准的。
planning-with-files 用 hook 把这套动作变成机械的。它在 Claude Code 上注册 5 个生命周期 hook(UserPromptSubmit、PreToolUse、PostToolUse、Stop、PreCompact),在 Codex 上是 7 个,每轮开始时把计划用 ===BEGIN PLAN DATA=== 包起来塞回上下文,写文件之后提醒更新进度,停止前检查阶段是否都完成。
没有 hook 也能跑,代价是自觉:在 CLAUDE.md 里加一条「每完成一个 phase,先更新 task_plan.md 再继续」,然后自己盯着它有没有照做。
压缩或 /clear 之后怎么接上
恢复动作可以短到一句话:「读 task_plan.md 和 progress.md,从 in_progress 的那个 phase 继续」。落点写在磁盘上,新会话不需要你复述目标、复述已经做完的部分,也不需要它重新扫一遍仓库。
这正好卡在官方机制的缺口上。根目录 CLAUDE.md 压缩后会被重新注入,纯对话内容不会,那么把「本次任务当前状态」放进一个固定路径的文件,等于自己造了一块压缩幸存区。文件路径固定,恢复指令才能固定。
planning-with-files 还多做了一步 session catchup:它去 ~/.claude/projects/(Codex 走 ~/.codex/sessions/)里翻会话记录,找出计划文件最后更新时间之后发生的对话,生成一份补记报告,把那段没来得及写进文件的上下文捞回来。作者自测的内部基准里,硬性中断后带计划文件的会话平均 5.0 轮回到干活状态,没有任何计划方法的裸 agent 是 13.3 轮。这是项目作者自己跑的 v1 基准(2026-07-06),不是第三方评测,当参考量级看就行。
什么时候该主动压缩、上下文预算怎么分,另见 上下文窗口管理。
和内置 Plan Mode 的分工
两者管的是不同阶段。Plan Mode 管动手之前:让模型只读不写,把方案摊开给你批准。文件计划管动手之后:把已经批准的方案拆成阶段,在执行过程中持续记录哪个阶段做完了、遇到过什么错。
交接只有一步。Plan Mode 的方案批准之后,让 agent 把它按 phase 抄进 task_plan.md,再退出 Plan Mode 开始执行。从这一刻起,计划的载体从会话变成文件,压缩、崩溃、关终端都不再是终止事件。
要不要走这一步,看任务长度。只改两三个文件、十几分钟收工的活,Plan Mode 的临时方案够用,多写三个文件纯属开销。跨会话、要过夜跑、或者中途八成会触发一次压缩的活,才值得落盘。Plan Mode 本身的适用边界见 Plan Mode 什么时候该用。
这个仓库的定位和局限
planning-with-files 是社区项目,作者 Ahmad Othman Ammar Adi,MIT 许可,2026 年 1 月建仓,2026 年 8 月 1 日仍有提交,主分支 master,star 数在 2.5 万量级。它把上面这套做法打包成 Agent Skills 标准的 skill,附带 hooks 和一组斜杠命令,声称覆盖 60 多个 agent。它和 Anthropic 没有关系,README 里的 Anthropic 只出现在致谢段。
装法决定你拿到什么。Claude Code 插件路线(/plugin marketplace add OthmanAdi/planning-with-files)带 hooks 和斜杠命令;npx skills add 路线可能静默地没有 hooks,README 自己承认这一点,并提供 /plan-doctor 做自检。hooks 恰恰是这个项目区别于「手写三个文件」的全部价值,装完不验证等于白装。
README 首屏那个 96.7% 通过率也需要看清口径:作者用 skill-creator 框架自测,skill v2.21.0,模型 claude-sonnet-4-6,跑于 2026-03-06,衡量的是 agent 有没有照三文件格式维护文件,不覆盖长跑任务的目标漂移。三个文件都是普通 markdown,仓库默认把它们加进 gitignore,任务结束不自动归档,下一个任务直接覆盖,想留的东西得自己搬进提交或文档。
所以这篇的可迁移部分是那套字段和那条恢复指令,不是这个仓库。手写一份 task_plan.md,在 CLAUDE.md 里加一条更新规则,机制就立起来了一半,缺的只是 hook 那层强制。
参考资料
- OthmanAdi/planning-with-files — 社区 skill 仓库,三文件模式、hook 清单、安装路线差异与自测口径都写在 README 里
- templates/task_plan.md — 仓库自带的计划文件模板,本文骨架据此简化
- How Claude remembers your project — Anthropic 官方文档,说明 CLAUDE.md 的加载顺序、200 行建议与
/compact后的重注入行为