Claude Code 用文件做计划,上下文断了也不丢

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

Claude Code 用文件做计划,上下文断了也不丢

Agent 干到一半上下文满了,压缩完回来反问你「刚才做到哪」。Claude Code 用文件做计划就是堵这个洞:阶段和进度写进仓库里的 markdown,会话没了它还在。

作者CodePass 技术编辑

会话里的计划为什么留不住

同一句指令,写在 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 那层强制。

参考资料