为什么你的 Codex 总是"跑偏"?
如果你用过 OpenAI Codex 处理稍复杂的任务,大概率经历过这种场景:
- 做到一半忘了最初的目标
- 会话中断后一切从零开始
- 同一个错误反复尝试,不会换思路
根本原因很简单------Codex 没有持久化的工作记忆。每次工具调用后,上下文窗口里的原始目标就被新的输出挤掉了。
Planning-with-Files 正是为解决这个问题而生的开源技能(Skill)。它的核心思路朴素却有效:把计划写在磁盘上,每次操作前强迫代理重新读一遍。
核心概念:三文件规划模式
Skill 在你的项目根目录维护三个 Markdown 文件,各司其职:
| 文件 | 定位 | 何时更新 |
|---|---|---|
task_plan.md |
任务的"大脑"------阶段划分、进度标记、决策与错误记录 | 创建任务时、完成阶段时、做重大决策时 |
findings.md |
任务的"笔记本"------研究发现、技术决策及其理由 | 每次探索/搜索后(尤其第2次浏览必须更新) |
progress.md |
任务的"日记"------会话日志、测试结果、错误时间线 | 每次执行代码/测试后、阶段完成时 |
三者之间的关系:
arduino
task_plan.md ← 定义"做什么"
↓
findings.md ← 记录"发现了什么"
↓
progress.md ← 追踪"做到了哪"
安装:两种姿势
方案 A:项目级安装(推荐)
适合团队协作,配置随仓库走:
bash
# 在项目根目录执行
git clone https://github.com/OthmanAdi/planning-with-files.git /tmp/planning-with-files
# 复制 .codex 目录到项目中
cp -r /tmp/planning-with-files/.codex .
# 提交,团队成员拉取后自动拥有
git add .codex/
git commit -m "Add planning-with-files skill for Codex"
git push
rm -rf /tmp/planning-with-files
方案 B:全局安装
适合个人在多个项目中复用:
bash
git clone https://github.com/OthmanAdi/planning-with-files.git /tmp/planning-with-files
mkdir -p ~/.codex/skills
cp -r /tmp/planning-with-files/.codex/skills/planning-with-files ~/.codex/skills/
mkdir -p ~/.codex/hooks
cp -r /tmp/planning-with-files/.codex/hooks/* ~/.codex/hooks/
# ⚠️ 如果你已有 hooks.json,需要手动合并,切勿直接覆盖
cp /tmp/planning-with-files/.codex/hooks.json ~/.codex/hooks.json
rm -rf /tmp/planning-with-files
避坑警告 :不要同时在项目级
.codex/hooks.json和全局~/.codex/hooks.json中安装相同的 hooks。Codex 会两套都跑,每个生命周期事件触发重复提醒,体验堪比闹钟连环叫。
开启 Hooks:一行配置
编辑 ~/.codex/config.toml:
toml
[features]
codex_hooks = true
已有 [features] 段就加在下面,不要重复建段。没有这行配置,hooks 形同虚设。
验证安装
bash
# 确认 hooks 功能已开启
codex features list | rg '^codex_hooks\s'
# 确认 skill 文件存在(二选一)
ls -la .codex/skills/planning-with-files/SKILL.md # 项目级
ls -la ~/.codex/skills/planning-with-files/SKILL.md # 全局
# 确认 hooks 配置存在
ls -la .codex/hooks.json .codex/hooks/
如果 codex_hooks 不在 features 列表中,说明你的 Codex 版本不支持 hooks,需要先升级。
五个钩子:自动化的秘密
这是整个 Skill 最精妙的部分。五个生命周期钩子在后台默默工作,你不需要手动触发任何东西:
vbnet
┌─────────────────────────────────────────────────────────────────┐
│ SessionStart │
│ → 运行 session-catchup.py,恢复上次会话上下文 │
│ → 注入活跃计划的摘要信息 │
├─────────────────────────────────────────────────────────────────┤
│ UserPromptSubmit │
│ → 每次你发消息时,重新注入计划 + 近期进度 │
│ → 防止长对话中目标被稀释 │
├─────────────────────────────────────────────────────────────────┤
│ PreToolUse │
│ → 执行 Bash 前自动重读 task_plan.md 前30行 │
│ → "你要去哪?先看看计划" │
├─────────────────────────────────────────────────────────────────┤
│ PostToolUse │
│ → Bash 执行后提醒更新 progress.md │
│ → "做完了?记下来" │
├─────────────────────────────────────────────────────────────────┤
│ Stop │
│ → 阶段未完成时阻止停止,要求继续 │
│ → 全部完成后放行 │
└─────────────────────────────────────────────────────────────────┘
用一句话概括:hooks 让 Codex 像个有备忘录的健忘症患者------每次动手前都强迫自己看一眼目标。
实战:从零规划一个任务
Step 1:启动规划
在 Codex 中输入:
bash
/plan 为项目添加用户认证模块,支持 JWT 和 OAuth2 登录
Codex 自动在项目根目录创建三个文件,并在 task_plan.md 中生成初步阶段划分。
Step 2:定义阶段
task_plan.md 会生成类似这样的结构:
markdown
## Phase 1: 需求调研与方案设计
- [ ] 调研 JWT 和 OAuth2 在当前技术栈的集成方式
- [ ] 确定数据库 schema
- **Status:** in_progress
## Phase 2: 核心实现
- [ ] 实现 JWT 签发与验证
- [ ] 对接 OAuth2 Provider
- **Status:** pending
## Phase 3: 测试与文档
- [ ] 编写单元测试和集成测试
- [ ] 补充 API 文档
- **Status:** pending
Step 3:边做边记
这是最关键的环节。三文件不是摆设,必须持续更新:
| 发生了什么 | 更新哪个文件 | 写什么 |
|---|---|---|
| 搜索/研究了某技术方案 | findings.md |
添加到 Research Findings |
| 连续浏览2次搜索结果 | findings.md |
必须更新(2-Action 规则) |
| 做出技术选型决策 | findings.md |
添加到 Technical Decisions + 理由 |
| 完成一个阶段 | task_plan.md |
状态改为 complete |
| 执行了代码或测试 | progress.md |
记录 actions taken + 文件变更 |
| 遇到报错 | 两个文件都更新 | task_plan.md 加到 Errors 表,progress.md 加时间线 |
一个典型的更新流程:
markdown
1. 研究 JWT 库选型 → findings.md
2. 再研究 OAuth2 方案 → findings.md(第2次,必须更新!)
3. 决定用 foo_auth 库 → findings.md Technical Decisions
4. 写完 JWT 模块代码 → progress.md
5. Phase 1 完成 → task_plan.md 状态→complete
6. 运行测试发现 token 过期bug → task_plan.md + progress.md
Step 4:完成验证
当你认为任务完成时:
bash
./scripts/check-complete.sh
或者手动检查:
task_plan.md:所有 Phase 状态为completeprogress.md:所有阶段都有日志记录
如果未完成,Stop hook 会阻止 Codex 停下来,直到所有阶段标记为完成。
会话恢复:断了也能接上
长任务难免中断。下次启动 Codex 时,SessionStart hook 会自动运行 session-catchup.py,它读取三个文件的内容,把上次的上下文重新注入到新会话中。
你不需要做任何额外操作------打开 Codex,继续干活。
常见问题速查
| 症状 | 诊断 | 处方 |
|---|---|---|
| Hooks 完全没反应 | codex_hooks = true 未配置 |
检查 ~/.codex/config.toml,加完后重启 Codex |
| 每个提醒出现两次 | hooks.json 装了两份 | 删掉工作区或全局其中一份,保留一个位置 |
| 已有全局 hooks.json 怕覆盖 | --- | 手动合并 5 个 hook 条目(SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / Stop) |
| Windows 上 hooks 不生效 | Codex 当前在 Windows 禁用 hooks | 仅 skill 部分可用,hooks 自动化暂不支持 |
局限性说明
- Windows:OpenAI 官方文档明确指出 Codex hooks 在 Windows 上被禁用。Skill 文件可以安装,但自动化的钩子功能仅限 macOS/Linux。
- 会话隔离 :v2.36.1 起为 Codex 新安装默认开启会话隔离(通过
.planning/sessions/<session_id>.attached文件控制)。如果你的.planning/sessions/目录不存在,则保持旧版行为。 - 脚本同步 :历史版本中多次出现"脚本未同步到 IDE 目录"的问题(v2.34.1、v2.36.0、v2.36.2、v2.36.3 均有修复),升级后建议验证
.codex/hooks/下的脚本是否完整。
总结
Planning-with-Files 的设计哲学极其朴素:AI 代理不需要更聪明的记忆机制,它只需要一个写在磁盘上的备忘录,以及每次动手前强迫自己读一遍的习惯。
三文件 + 五钩子,没有黑魔法,没有复杂配置,但效果显著------你的 Codex 代理从"健忘的实习生"变成了"有笔记习惯的靠谱搭档"。
如果你在长任务中频繁遭遇目标漂移、会话断档、重复犯错,试试这个 Skill。五分钟安装,立刻见效。
本文基于 Planning-with-Files v2.36.x 版本编写,源码及文档见 GitHub。Codex hooks 协议细节以 OpenAI 官方文档 为准。