Codex 一遇大 diff 就停下来:怎么把任务切小

Codex 跑到一半撞上 context 或 token 上限就停了,留下半个 patch。如何拆任务、走多 PR、或者换大 context model。

你让 Codex “把 auth module 重构到用新的 session API”。四十分钟后它中途停了:PR 改了 8 个文件,另外 6 个动过的文件还留着 // TODO: migrate this 注释。或者 transcript 结尾是 “Context window exceeded” 或 “Maximum tool calls reached”。Codex 干了真活,但中途预算耗尽,你的 branch 现在半新半旧。

这不是 Codex 的 bug——是任务跨的代码量超过了 model context + 它的 tool-call 预算。解药是开工前的范围纪律,加上几个 harness 层面的开关(选 model、把改动拆成多 PR plan、把要改的文件精确列出来)。

常见原因

1. 任务跨的文件太多,context 装不下

你要重构 auth module,30 个文件、8k 行。哪怕 context 有 200k token,Codex 要读每个文件、产生 edit。跑到一半,下一个文件的内容塞不进还在跑的 plan 旁边。

如何判断:transcript 结尾是 context_length_exceededMaximum context reached,或者跑了 N 个文件后干脆没下文。

2. Tool-call 预算用光

Codex harness 一般对每个 task 限 tool call 数(常见 50-200)。长 refactor 烧 call 飞快:read_fileapply_patch、再 read_file 验证、run_shell 跑 type check。任务还没做完就撞上限。

如何判断:transcript 结尾是 “tool calls exhausted”,或者明显还有活没干 agent 就不出 action 了。

3. patch 里某个文件巨大

5000 行的 generated 文件(lockfile、SVG、vendored 库)进了 diff。读和写它一次就吞掉一大块预算。

如何判断git diff --stat 里某个文件改了几千行。或者 agent “卡” 在单个文件上不动。

4. Codex 重复读已经在 context 里的文件

Model 跟丢了它已经加载过什么,对同一个 path 调三次 read_file。每次都吃 token。最后一半 context 是重复的文件内容。

如何判断:transcript 里搜对同一 path 的重复 read_file。老 harness 没 memoization 的多见。

5. 任务太开放(“全部清理一遍”)

你写 “把 auth module 清理一下”。Codex 理解成 “重写 12 个文件”,但你本来只想 “把 auth module 里的 User.uid 全改名成 User.id”。开放任务的范围会一直膨胀直到撞预算。

如何判断:对比你的任务描述和 Codex 实际动的文件。它动了没关系的东西(“既然来了,顺便…”),就是范围没设界。

最短修复路径

Step 1:任务窄到一个动词 + 一个 module

差:「重构 auth module。」 好:「只在 src/auth/*.ts 里,把 User.uid 改名成 User.id。改所有 call site。Test 文件只做机械改名。」

好的 prompt 包含:

  • 一个动词:rename、extract、replace、delete、add
  • 一个范围:path glob 或文件列表
  • 一个 non-goal:“不要碰 X、Y、Z”
# 推荐的 Codex 任务模板

GOAL: <一句话,一个动词>
SCOPE: <显式文件列表或 glob>
NON-GOALS: <哪些不要碰>
ACCEPTANCE: <测试通过 + 1 个具体检查>

Step 2:大改拆成多 PR plan

跨 >10 文件的改动,写 plan 让 Codex 每个 PR 跑一步:

# Auth 迁移 plan

PR 1:新增 `Session` API,和老的 `auth.cookie` 并存(caller 暂不动)
PR 2:迁移 `src/auth/login.ts``src/auth/logout.ts`
PR 3:迁移 `src/auth/middleware/`(3 个文件)
PR 4:迁移 `src/pages/api/` 的 caller(10 个文件,机械改)
PR 5:删除旧 `auth.cookie`,更新 README

每个 PR 都小到能在一次 Codex run 里塞下。Reviewer 也跟得上。

Step 3:prompt 里预先列出要改的文件

省掉 agent 自己 discover 的步骤:

要改的文件(仅限这些):

- src/auth/session.ts
- src/auth/cookie.ts
- src/auth/middleware/withAuth.ts
- tests/auth/session.test.ts

如果你需要改不在这个列表里的文件,停下来问。

既缩小 working set 又防 scope creep。

Step 4:让 agent 跳过 lockfile 和 generated 文件

AGENTS.md 里写:

## 规划时跳过的文件

除非明确要求,不要完整读这些:

- package-lock.json、pnpm-lock.yaml、yarn.lock
- 超过 200 行的 *.svg
- src/generated/**
- public/**
- *.min.js、*.min.css

要更新 lockfile,跑 `npm install`,不要手动编辑。

这些是预算大户。agent 一行一行读它们永远不值。

Step 5:大任务换大 context model

Codex CLI 之类的 harness 都能挑底层 model。真正跨多文件的任务,换成 harness 里最大 context 的 model:

# Codex CLI 例子
codex --model gpt-5.5 --max-tool-calls 200 "执行 PLAN.md 里的 plan"

harness 允许调高 tool-call 上限的话也调——但要先把范围切好。范围没切的任务,预算越大产生的烂摊子越大。

Step 6:让 Codex 停下来时写 resume note

AGENTS.md 里:

如果你的 context 或 tool call 不够用,停下来之前写一个文件
`.codex/resume.md`,包含:

- 哪些文件做完了
- 哪些文件改了一半(当前状态是什么)
- 哪些文件没动
- 下一个该做的具体动作是什么

`.codex/resume.md` 一起 commit 进 PR。

下一次 run 从这个 note 接着干,不用重新 discover 状态。

预防

  • 每个任务窄到一个动词 + 一个 module + 显式文件列表
  • 跨 >10 文件的改动拆成多 PR plan
  • AGENTS.md 里列出要跳过的 path(lockfile、generated、public asset)
  • 实在需要大改,用 harness 里最大 context 的 model
  • 让 Codex 写 .codex/resume.md 以便中断后能续上
  • 每次 agent 跑完,diff 一下 file 列表,多动了就把 prompt 收紧

相关

标签: #Codex #agent #排查 #PR 体积