# Codex 编程实战教程：把 Coding Agent 用成可验证的工程队友

> 来源基础：本文基于 Towards Data Science 文章《How to Maximize OpenAI’s Codex》的 Gemini 摘要整理，并加入面向实战落地的补充模板。原文核心观点是：Codex 的优势在于严格执行明确指令、速度快、适合窄范围任务；但它可能漏掉关联修改，因此必须配合计划、隔离、测试和验收闭环。

## 适合谁

- 已经会用 Codex CLI / IDE，但结果不稳定的开发者。
- 想让 Codex 处理真实项目，而不是只写代码片段的人。
- 希望降低 AI 改坏代码、越界修改、无法验收风险的团队。

## 一句话原则

**把 Codex 当成“严格执行型工程代理”，不要只给目标；要同时给边界、上下文、验证命令和停止条件。**

## 0. Codex 更适合做什么

Codex 的强项不是“猜出你所有意图”，而是“按清楚的任务合同执行”。

更适合：

- 精准修 bug。
- 局部重构。
- 补测试。
- 为已有代码添加一个小功能。
- 根据明确验收标准修改前端/接口。

不适合直接裸跑：

- 跨多个模块的大重构。
- 生产数据库、K8s、权限、支付、消息发送等高风险操作。
- 需求还没想清楚的探索型任务。
- 没有测试、没有运行命令、没有回滚路径的旧项目。

## 1. 最小可用工作流

每次让 Codex 编程，都按这 6 步走：

1. **隔离工作区**：新建 git branch 或 worktree。
2. **给任务合同**：目标、范围、禁止事项、相关文件、验收命令。
3. **先让它读代码和计划**：复杂任务先计划，别直接改。
4. **执行最小修改**：只改必要文件。
5. **让它自测**：运行测试、lint、类型检查、浏览器验证。
6. **人工复核 diff**：看它是否越界、漏改、硬编码、删测试。

推荐心智模型：

```text
不是：帮我把这个功能做了
而是：在这些边界内完成这个变更，并用这些命令证明它可用
```

## 2. 项目准备：让 Codex 有稳定上下文

在项目根目录放一个 `AGENTS.md`，告诉 Codex 项目规则。

示例：

````markdown
# AGENTS.md

## 项目

这是一个 Python/FastAPI 项目。

## 常用命令

```bash
uv sync
uv run pytest -q
uv run ruff check .
uv run ty check .
```

## 编码规则

- 新增函数必须有类型注解。
- 禁止硬编码 token、密码、IP。
- 禁止修改 migrations，除非任务明确要求。
- 修 bug 必须补回归测试。

## 完成标准

任务完成前必须：

1. 说明改了哪些文件。
2. 运行相关测试。
3. 汇报失败项和未验证项。
````

预期效果：

- Codex 每次进入项目都能先读到规则。
- 你的要求不用在每个 prompt 里重复写。
- 验证命令变成默认完成标准，而不是事后补救。

失败处理：

- 如果 Codex 没读 `AGENTS.md`，在 prompt 里明确写：`先读取 AGENTS.md 和 README.md，再计划。`
- 如果项目没有测试命令，先让 Codex 写一个最小 smoke test 或运行脚本，不要让它只凭肉眼判断。

## 3. Worktree：并发任务要隔离

文章提到 Codex 没有 Claude Code 那种内置 worktree 体验，可以用 shell alias 补足。

示例 alias：

```bash
# 放到 ~/.bashrc 或 ~/.zshrc
codex-wt() {
  if [ -z "$1" ]; then
    echo "usage: codex-wt <worktree-name>"
    return 1
  fi

  current_repo=$(basename "$(git rev-parse --show-toplevel)")
  branch="codex/$1"
  target="../${current_repo}-$1"

  git fetch --all --prune
  git worktree add -b "$branch" "$target"
  cd "$target" || return 1
  codex
}
```

使用方式：

```bash
cd ~/code/my-api
codex-wt fix-login-timeout
```

预期结果：

```text
../my-api-fix-login-timeout 被创建
新分支 codex/fix-login-timeout 被创建
Codex 在隔离工作区启动
```

适用场景：

- 一个 Codex 处理 bugfix。
- 另一个 Codex 处理测试补充。
- 第三个 Codex 做只读代码审查。

失败处理：

- 如果提示 `not a git repository`：先进入项目根目录。
- 如果提示 branch 已存在：换一个 worktree 名称，或删除旧 worktree。
- 如果 Codex 在错误目录启动：先执行 `pwd && git status` 验证当前位置。

## 4. Prompt 模板：把任务说成合同

### 通用模板

```text
你是这个仓库的编码代理。先读取 AGENTS.md、README.md 和相关文件，再行动。

目标：
- <一句话说明要完成什么>

范围：
- 允许修改：<文件/目录>
- 不允许修改：<文件/目录/行为>

上下文：
- 相关错误：<报错/日志/截图>
- 相关文件：<路径列表>

执行要求：
1. 先给出 3-5 步计划。
2. 只做最小必要改动。
3. 如果发现需求会影响范围外文件，先停下来说明。
4. 不要新增依赖，除非我明确批准。
5. 不要修改测试来掩盖问题。

验证：
- 运行：<测试命令>
- 运行：<lint/type 命令>
- 如果命令失败，汇报失败原因和下一步，不要假装完成。

完成汇报：
- 改动文件
- 验证命令和结果
- 剩余风险
```

### 为什么这样写

Codex 很擅长执行明确指令，但不一定会主动补足上下文。这个模板把“目标、边界、验证、停止条件”一次性写清楚，减少越界和漏验收。

## 5. 三个可直接复制的实战案例

### 案例 A：精准修 bug

场景：登录接口偶发超时，怀疑是外部请求没有 timeout。

给 Codex 的 prompt：

```text
先读取 AGENTS.md、README.md，以及 src/auth/ 下的登录相关代码。

目标：
修复登录接口调用外部用户服务时可能无限等待的问题。

范围：
- 允许修改 src/auth/ 和 tests/auth/。
- 不允许改数据库 schema。
- 不允许新增依赖。

上下文：
生产日志里出现：
TimeoutError: login request exceeded gateway timeout

执行要求：
1. 先找出外部 HTTP 调用位置。
2. 为外部调用设置明确 timeout。
3. 补一个回归测试，模拟外部服务超时。
4. 不要修改与登录无关的业务逻辑。

验证：
- uv run pytest tests/auth -q
- uv run ruff check src/auth tests/auth
```

预期输出：

```text
修改 src/auth/client.py：为 HTTP 请求增加 timeout
新增 tests/auth/test_login_timeout.py：覆盖超时路径
pytest 通过
ruff 通过
```

人工复核重点：

- 是否只改了登录相关文件。
- timeout 是否来自配置或常量，而不是散落魔法数字。
- 测试是否真的模拟超时，而不是只测 happy path。

失败处理：

- 如果 Codex 修改了大量无关文件：要求它回滚非必要 diff，只保留 timeout 修复和测试。
- 如果测试失败但它说完成：让它贴出失败命令和错误摘要，再继续修。

### 案例 B：前端小功能 + 浏览器自测

场景：给设置页增加“复制 API Key”按钮。

给 Codex 的 prompt：

```text
先读取 AGENTS.md、前端 README，以及 settings 页面相关组件。

目标：
在设置页 API Key 字段旁边增加复制按钮。

范围：
- 允许修改 src/pages/settings/ 和对应测试。
- 不允许改认证逻辑。
- 不允许把真实 API Key 写入测试或源码。

执行要求：
1. 增加复制按钮。
2. 点击后调用浏览器 Clipboard API。
3. 成功后显示“已复制”，2 秒后恢复。
4. 为按钮行为补测试。
5. 如果项目支持 Playwright，启动页面并实际点击验证。

验证：
- npm test -- settings
- npm run lint
- 如可用：npx playwright test settings-copy-api-key.spec.ts
```

预期验收：

```text
页面出现复制按钮
点击按钮后提示“已复制”
剪贴板写入 mock API key
测试和 lint 通过
```

失败处理：

- 如果 Clipboard API 在测试环境不可用，让 Codex 使用 mock/stub，而不是跳过测试。
- 如果 Playwright 失败，要区分是页面 bug、测试选择器问题，还是本地浏览器环境问题。

### 案例 C：局部重构但防止越界

场景：把订单金额计算从 controller 移到 service。

给 Codex 的 prompt：

```text
先读取 AGENTS.md、订单模块 README，以及 src/orders/ 相关代码。

目标：
把订单金额计算逻辑从 controller 移到 service，使 controller 只负责请求/响应编排。

范围：
- 允许修改 src/orders/controller.py、src/orders/service.py、tests/orders/。
- 不允许改数据库模型。
- 不允许改 API 响应字段名。
- 不允许重写整个订单模块。

执行要求：
1. 先列出当前金额计算逻辑的位置。
2. 提出最小迁移方案。
3. 保持现有 API 行为不变。
4. 为 service 层金额计算补单元测试。
5. 如发现其他模块依赖旧函数，先说明，不要擅自大范围改。

验证：
- uv run pytest tests/orders -q
- uv run ruff check src/orders tests/orders
- 如项目有类型检查：uv run ty check src/orders
```

预期验收：

```text
controller 变薄
service 有可单测的金额计算函数
订单相关测试通过
API 字段未变化
```

失败处理：

- 如果 Codex 开始重命名 API 字段：立即要求回滚接口层变化。
- 如果它发现关联代码必须改：让它先输出影响范围，再由你决定是否扩大任务。

## 6. Plan Mode 与执行模式怎么用

根据文章经验，Codex 的推理等级和模式会影响结果。

推荐规则：

- 小 bug：普通模式 + 明确边界。
- 中等功能：先 Plan Mode，再执行。
- 大重构：先只读计划，人工确认后分阶段执行。
- 高风险任务：只允许只读分析，不允许自动执行。

Prompt 示例：

```text
这次先只做计划，不要修改文件。

请输出：
1. 你需要读取哪些文件。
2. 可能影响哪些模块。
3. 最小安全改动路径。
4. 测试和回滚方案。
5. 哪些点需要我确认。
```

当计划可接受后，再给执行 prompt：

```text
按刚才计划执行第 1 阶段，只修改 <文件列表>。
完成后运行 <命令> 验证。
如果需要扩大范围，先停下来说明原因。
```

## 7. YOLO / 高权限模式的安全边界

文章倾向于给 Codex 高权限，以减少交互中断。但在真实工程中，不能把“模型很少犯错”当成安全策略。

开启高权限前至少满足：

- 工作区是 git branch 或 worktree。
- 测试数据库与生产数据库隔离。
- 当前 shell 没有生产写权限 token。
- `.env` 不会被提交。
- 有一条命令能重建测试环境。
- 有明确的停止条件，例如检测到 migration、delete、drop、deploy、send email 就暂停。

安全 prompt：

```text
你可以自动读写当前工作区文件和运行本地测试。

但遇到以下情况必须停止并请求确认：
- 删除文件或批量移动文件。
- 修改 migrations、infra、k8s、terraform、CI/CD。
- 执行数据库写入、DROP、DELETE、TRUNCATE。
- 调用外部生产 API。
- 发送邮件、消息或触发部署。
- 新增或升级依赖。
```

## 8. 验证闭环：让 Codex 自测，但不要只信它的总结

最低验证矩阵：

- Python：`pytest`、`ruff`、`ty/mypy`。
- Node：`npm test`、`npm run lint`、`npm run typecheck`。
- 前端 UI：Playwright/Cypress 或人工浏览器检查。
- API：单元测试 + 一条本地 curl/smoke。
- 数据库：迁移 dry-run、回滚方案、测试库验证。

要求 Codex 输出证据：

```text
完成后请贴出：
1. git diff --stat
2. 修改文件列表
3. 每条验证命令的退出状态
4. 失败命令的错误摘要
5. 你没有验证的内容
```

人工验收命令：

```bash
git diff --stat
git diff -- src tests
git status --short
```

不要接受这种完成汇报：

```text
已完成，应该可以工作。
```

可以接受这种完成汇报：

```text
已完成。
修改：src/auth/client.py, tests/auth/test_login_timeout.py
验证：uv run pytest tests/auth -q 通过；uv run ruff check src/auth tests/auth 通过
未验证：未运行全量测试，建议合并前跑 uv run pytest -q
```

## 9. 常见坑

### 坑 1：任务太大

症状：Codex 改了很多文件，最后测试跑不起来。

处理：把任务切成阶段。

```text
停止当前实现。请只保留第一个可验证的小步骤：<步骤名>。
其他改动先回滚或列为后续任务。
```

### 坑 2：Codex 太听话，漏掉关联点

症状：它只改了你点名的文件，忘了测试、类型、调用方。

处理：在 prompt 里加入关联检查。

```text
完成目标修改后，请搜索所有调用方和相关测试。
如果发现必须同步更新的关联点，先列出来，再修改最小必要部分。
```

### 坑 3：Codex 太自由，越界重构

症状：它顺手格式化、重命名、调整架构。

处理：明确非目标。

```text
本任务不是重构任务。不要修改命名、目录结构、公共 API 或无关格式。
如果你认为必须重构，先停止并说明理由。
```

### 坑 4：自测不真实

症状：它说测试通过，但只跑了一个不相关命令。

处理：指定命令和验收输出。

```text
必须运行以下命令：...
如果命令不存在，先说明，不要替换成无关命令。
```

## 10. 一周落地路线

第 1 天：

- 给一个现有项目补 `AGENTS.md`。
- 明确测试、lint、类型检查命令。

第 2 天：

- 用 Codex 修一个小 bug。
- 要求它补回归测试。

第 3 天：

- 用 worktree 并发跑两个低风险任务。
- 人工比较两个任务的 diff 范围。

第 4 天：

- 接入浏览器验证工具，如 Playwright。
- 让 Codex 完成一个 UI 小改并自测。

第 5 天：

- 尝试一个中等重构，但只允许先做计划。
- 人工确认计划后分阶段执行。

第 6 天：

- 整理常用 prompt 模板。
- 把项目禁区写进 `AGENTS.md`。

第 7 天：

- 复盘：哪些任务 Codex 做得好，哪些任务需要 Claude Code/人工主导。
- 固化团队验收 checklist。

## 11. 最小 Checklist

每次交给 Codex 前：

- [ ] 当前在 git branch/worktree。
- [ ] 任务目标一句话说清。
- [ ] 明确允许和禁止修改范围。
- [ ] 给出相关文件/错误/日志。
- [ ] 指定测试、lint、typecheck 命令。
- [ ] 写明高风险停止条件。

Codex 完成后：

- [ ] 看 `git diff --stat`。
- [ ] 检查是否有无关文件变更。
- [ ] 检查是否硬编码秘密、IP、token。
- [ ] 检查测试是否新增或更新。
- [ ] 运行关键验证命令。
- [ ] 记录未验证项。

## 12. 推荐默认 Prompt

```text
先读取 AGENTS.md、README.md 和相关代码，然后再行动。

目标：<写清楚目标>

范围：
- 允许修改：<路径>
- 禁止修改：<路径/行为>

约束：
- 不新增依赖。
- 不修改无关文件。
- 不跳过或删除测试。
- 不硬编码 secrets/IP/token。
- 遇到数据库、部署、CI/CD、infra、外部写操作时停止并请求确认。

流程：
1. 先输出简短计划。
2. 执行最小必要改动。
3. 补或更新测试。
4. 运行验证命令。
5. 汇报 diff、验证结果和未验证项。

验证命令：
- <命令 1>
- <命令 2>
```

## 结论

Codex 的实战价值来自“明确合同 + 自动执行 + 可验证闭环”。它越像一个可审计的工程队友，越能稳定产出；它越像一个没有边界的万能助手，越容易制造不可控 diff。

最简单的起点不是复杂工具链，而是三件事：

1. 写好 `AGENTS.md`。
2. 每个任务用合同式 prompt。
3. 每次完成都用测试和 diff 验证。
