Skip to content

Codex Plan 模式实战:复杂需求为什么不要直接让 AI 写代码

前面几篇我们已经介绍了:

text
Codex CLI
AGENTS.md
常用命令
Prompt

到了这里,已经可以把一个比较完整的任务交给 Codex。

例如:

text
给用户表增加一个 nickname 字段,
补充对应 DTO 和查询接口,
修改完成后运行相关测试。

这种需求通常比较简单。

Codex 可以:

text
阅读代码

找到相关文件

修改代码

运行测试

但是如果需求变成:

text
把现在的余额系统增加“冻结余额”能力,
同时保证充值、提现、转账和奖励逻辑不受影响。

情况就完全不同了。

因为这个需求背后可能涉及:

text
数据库
余额模型
钱包流水
提现
转账
事务
并发
幂等
旧接口兼容
历史数据

如果直接告诉 Codex:

text
帮我实现。

它可能很快就开始修改代码。

问题是:

text
它真的已经理解整个影响范围了吗?

这就是复杂任务为什么需要:

text
Plan First

也就是:

先规划,再实现。


1. 什么是 Plan?

Plan 可以简单理解成:

text
在修改代码之前,
先把这个任务想清楚。

完整过程更接近:

text
Requirement

Read

Understand

Explore

Plan

Confirm

Implement

Test

Review

而不是:

text
Requirement

Write Code

Plan 阶段最重要的特点是:

text
先不修改代码

Codex 当前的任务主要是:

text
阅读
搜索
分析
推理
设计

等方案明确以后,再进入:

text
Implement

2. Plan 和 /plan 不是完全一回事

这里需要先区分两个概念。

第一个是:

text
Plan

也就是:

text
规划阶段

第二个是:

text
/plan

也就是某个 Codex CLI 版本可能提供的具体交互入口或协作方式。

Codex CLI 仍然在持续更新。

不同版本中:

text
Plan
Collaboration Mode
Slash Command
交互入口

可能发生变化。

因此当前版本到底提供什么命令,应该优先查看:

text
/help

但无论当前版本有没有一个固定的:

text
/plan

都不影响我们使用:

text
Plan First

因为完全可以直接告诉 Codex:

text
先进入规划阶段。

阅读相关代码并给出实现方案。

当前阶段不要修改任何文件。

本质上就是:

text
Plan

3. 为什么不能复杂需求一上来就 Implement?

假设需求是:

text
增加用户余额冻结功能。

如果直接:

text
帮我实现用户余额冻结功能。

Codex 可能看到:

text
user_balance

然后马上设计:

text
balance
frozen_balance

接着修改:

text
Entity
Mapper
Service
SQL

表面上看:

text
功能实现了

但真实业务可能还有:

text
提现应该扣 available 还是 balance?

转账时冻结余额能不能使用?

冻结失败以后是否需要流水?

解冻是不是幂等?

一个订单能不能重复 freeze?

旧用户 frozen_balance 怎么初始化?

并发 freeze 是否可能超额冻结?

冻结和扣款之间是什么关系?

如果这些问题没有先想清楚:

text
代码写得越快
风险反而越大

4. Coding Agent 最大的问题不是不会写代码

现在的 Coding Agent 往往很擅长:

text
生成代码
修改多个文件
执行命令
修复编译错误

真正困难的是:

text
它是否理解了正确的问题?

如果问题理解错了:

text
高质量代码
+
错误方案
=
高质量地实现错误需求

所以复杂任务中最重要的并不是:

text
让 Codex 快点写

而是:

text
先确认它准备怎么写

这就是 Plan 的价值。


5. 哪些任务建议先 Plan?

不是所有任务都需要。

例如:

text
修改变量名
修复拼写
增加 null 判断
增加简单 DTO 字段
补一个简单测试

一般可以直接实现。

但下面这些任务,非常建议先 Plan:

text
架构调整
数据库结构修改
跨模块重构
支付逻辑
钱包逻辑
登录认证
权限系统
接口迁移
并发问题
数据一致性
性能优化
复杂线上 Bug
大型依赖升级

可以用一个简单标准判断:

text
如果改错以后代价比较高
→ 先 Plan

6. Plan 阶段到底应该做什么?

一个比较完整的 Plan 通常应该回答:

text
① 当前代码是怎么工作的?

② 需求会影响哪些模块?

③ 需要修改哪些文件?

④ 数据模型是否需要变化?

⑤ API 是否会变化?

⑥ 有没有兼容性问题?

⑦ 有没有事务和并发风险?

⑧ 有没有幂等问题?

⑨ 怎么测试?

⑩ 怎么判断实现完成?

所以 Plan 不是:

text
列一个 TODO List

而是:

text
建立完整的修改模型

7. 第一步:先让 Codex 阅读现状

不要直接问:

text
这个功能应该怎么设计?

最好先让 Codex:

text
理解当前实现

例如:

text
分析当前用户余额系统。

先不要修改代码。

请找到:

1. 余额数据结构
2. 余额查询入口
3. 所有余额增加入口
4. 所有余额扣减入口
5. 钱包流水
6. 提现流程
7. 转账流程
8. 事务控制
9. 幂等机制
10. 相关测试

完成以后总结当前余额系统的完整调用关系。

这一步可以叫:

text
Explore

也就是:

text
探索代码

8. 为什么 Explore 和 Plan 最好分开?

因为:

text
没有理解现状
就很难设计正确方案

例如 Agent 一开始可能认为:

text
余额只在 UserBalanceService 修改

但搜索以后发现:

text
充值
奖励
提现
转账
后台补单

都存在不同入口。

这时候 Plan 自然会发生变化。

所以更可靠的流程是:

text
Explore

建立事实

Plan

设计修改

而不是:

text
猜测当前架构

直接 Plan

9. Plan 阶段要求 Codex 给出“证据”

这是一个非常实用的技巧。

不要只让 Codex说:

text
余额修改主要在 WalletService。

可以要求:

text
说明判断依据。

列出:

- 文件
- 类
- 方法
- 调用关系

例如:

text
请基于实际代码分析。

每个结论尽量指出:

文件
类名
方法名

如果无法从代码确认,
明确标记“未确认”,不要猜测。

这样 Plan 会更可靠。


10. 第二步:分析影响范围

理解现状以后,再让 Codex回答:

text
这个需求会影响哪里?

例如冻结余额功能:

text
请分析增加冻结余额以后可能影响的范围。

至少检查:

1. 余额查询
2. 提现
3. 内部转账
4. 充值
5. 奖励
6. 后台人工调整余额
7. 钱包流水
8. 定时任务
9. 数据统计
10. API 返回结构

最终可能得到:

text
wallet
├── balance
├── transaction
├── withdraw
├── transfer
└── reward

这一步叫:

text
Impact Analysis

也就是:

text
影响分析

11. 为什么影响分析很重要?

很多 Bug 并不是:

text
新代码本身写错

而是:

text
新代码破坏了旧逻辑

例如增加:

text
frozenBalance

提现改了。

但是:

text
后台余额统计

还在直接读取:

text
balance

于是:

text
用户端余额
后台余额
财务余额

出现不同结果。

这种问题只有在修改之前进行:

text
Impact Analysis

才更容易发现。


12. 第三步:让 Codex 给出具体修改方案

完成 Explore 和 Impact Analysis 以后,再进入真正的 Plan。

例如:

text
基于刚才的分析,
给出实现用户余额冻结功能的方案。

要求:

1. 明确数据模型怎么修改
2. 明确 Service API
3. 明确 freeze 流程
4. 明确 unfreeze 流程
5. 明确最终扣款流程
6. 说明事务边界
7. 说明幂等方案
8. 说明并发控制
9. 说明旧数据兼容
10. 说明测试方案

列出预计需要修改的文件。

当前阶段仍然不要修改代码。

注意最后一句:

text
仍然不要修改代码

这样可以避免 Agent 在 Plan 过程中提前开始实施。


13. 一个好的 Plan 应该具体到什么程度?

太粗:

text
1. 修改数据库
2. 修改 Service
3. 增加测试

这种 Plan 几乎没有意义。

比较好的 Plan 应该至少说明:

text
改什么
为什么改
在哪里改
怎么验证
有什么风险

例如:

text
1. user_balance 增加 frozen_balance

原因:
需要区分可用余额和冻结余额。

兼容:
默认值为 0,保证历史用户数据兼容。

2. UserBalanceService 增加 freeze/unfreeze

freeze:
available balance 减少
frozen balance 增加

要求:
同一业务 sourceId 必须幂等。

3. WalletTransaction 增加 FREEZE / UNFREEZE 类型

用于记录冻结和解冻流水。

4. 增加并发测试

验证两个并发 freeze 不会导致 available balance < 0。

这才是真正有实施价值的 Plan。


14. Plan 最重要的输出之一:文件清单

我非常推荐让 Codex 在 Plan 最后列出:

text
预计修改文件

例如:

text
预计修改:

1. UserBalance.java
2. UserBalanceService.java
3. UserBalanceServiceImpl.java
4. WalletTransactionType.java
5. UserBalanceMapper.xml
6. V20260830__add_frozen_balance.sql
7. UserBalanceServiceTest.java

为什么很有用?

因为你可以快速判断:

text
修改范围是不是合理?

如果一个简单需求突然出现:

text
修改 37 个文件

就应该检查:

text
是不是方案设计过度了?

15. Plan 也是控制 Scope 的工具

上一篇讲 Prompt 时,我们介绍了:

text
Scope

Plan 可以进一步验证 Scope。

例如你告诉 Codex:

text
只允许修改 wallet 模块。

但 Plan 分析以后发现:

text
order 模块也依赖余额接口

这时候 Codex 不应该偷偷修改:

text
order

而应该告诉你:

text
当前 Scope 可能不足。

原因:
order 模块直接依赖旧余额行为。

建议:
扩大范围到 order,
或者保持旧接口兼容。

这就是 Plan 的另一个价值:

text
在真正修改前暴露冲突

16. 第四步:人工 Review Plan

Plan 生成以后:

text
不要马上回复“开始”

先看几个重点。

是否理解需求?

例如你要:

text
冻结余额

Agent 是否误解成:

text
锁定整个账户

修改范围是否合理?

text
应该改 5 个文件
却准备改 30 个文件?

有没有改变 API?

text
本来要求兼容
结果 Plan 准备删除旧字段?

有没有引入新依赖?

text
现有能力能解决
却准备增加新框架?

数据库方案是否安全?

text
有没有删除字段?
有没有修改历史 migration?

测试是否覆盖关键风险?

text
并发
幂等
边界
异常

Plan Review 本质上就是:

text
在代码产生之前做一次设计 Review

17. 修改 Plan,而不是让 Codex 重新猜

如果 Plan 大体正确,但某些地方不满意,可以直接修改。

例如:

text
方案整体可以。

调整以下几点:

1. 不新增 Redis 分布式锁
2. 使用现有数据库乐观锁
3. 不新增 wallet_freeze 表
4. frozen_balance 直接放 user_balance
5. API 返回保持完全兼容

基于这些约束重新整理最终 Plan。

仍然不要修改代码。

这比:

text
不行,重新想

更有效。

因为你保留了:

text
已经正确的部分

只调整:

text
有问题的决策

18. 第五步:明确批准 Implement

Plan 确认以后,再告诉 Codex:

text
按最终方案实施。

最好继续保留关键约束:

text
按最终 Plan 实施。

要求:

1. 只修改 Plan 中列出的文件
2. 如果实施过程中发现必须扩大范围,先停止并说明原因
3. 不修改现有 public API
4. 不新增第三方依赖
5. 不提交 Git
6. 修改完成后执行计划中的测试
7. 最后检查 git diff

这时候 Codex 才正式进入:

text
Implement

19. Implement 阶段不要让 Plan 失效

一个常见情况是:

text
Plan 很好

但是实现过程中 Agent 发现新问题,然后开始:

text
自由发挥

所以可以提前约定:

text
如果发现 Plan 与实际代码不一致:

不要自行扩大任务。

先说明:

1. 发现了什么
2. 为什么原 Plan 不成立
3. 建议怎么调整

这个规则对于复杂项目非常有价值。

因为:

text
Plan

不是为了做完以后好看。

而是为了:

text
控制实施过程

20. 第六步:Test

代码修改完成以后,不要直接结束。

应该按照 Plan 中的验证方案执行:

text
Compile

Unit Test

Integration Test

Git Diff

例如:

text
完成实现以后:

1. 编译 wallet 模块
2. 运行 UserBalanceServiceTest
3. 运行提现相关测试
4. 运行转账相关测试
5. 检查 git diff

如果测试失败:

text
Codex

读取错误

分析

修复

重新测试

这才是完整 Agent Workflow。


21. Plan 阶段就应该设计测试

不要等代码写完才问:

text
应该测什么?

因为测试本身也是设计的一部分。

例如冻结余额:

text
正常冻结
余额不足
重复冻结
正常解冻
重复解冻
并发冻结
冻结后提现
冻结后转账
异常回滚
历史用户 frozenBalance = 0

如果 Plan 阶段已经列出这些测试:

text
实现方案

往往也会更加完整。

因为测试会反过来暴露:

text
设计遗漏

22. 第七步:Review

测试通过以后,继续:

text
Review 当前 Git Diff。

例如:

text
Review 当前冻结余额功能的 Git Diff。

重点检查:

1. 是否存在超额冻结
2. 是否存在重复冻结
3. 是否存在重复解冻
4. 事务是否完整
5. 异常是否正确回滚
6. 钱包流水是否一致
7. 是否破坏旧 API
8. 是否存在 BigDecimal 精度问题
9. 是否有与当前需求无关的修改

不要修改代码,只输出 Review 结果。

于是完整流程变成:

text
Explore

Plan

Plan Review

Implement

Test

Code Review

Developer Review

23. 一个完整的 Plan Prompt 模板

下面这个模板可以直接保存:

text
任务:

<需求>

当前阶段只做分析和规划,
不要修改任何文件。

第一步:理解现状

请阅读相关代码并说明:

1. 当前实现
2. 主要调用链
3. 数据模型
4. 事务边界
5. 相关测试

第二步:影响分析

分析这个需求可能影响:

1. 模块
2. API
3. 数据库
4. 异步任务
5. 缓存
6. MQ
7. 兼容性

第三步:给出方案

请给出:

1. 实现思路
2. 数据结构变化
3. API 变化
4. 具体修改点
5. 并发和事务处理
6. 幂等方案
7. 兼容方案
8. 测试方案
9. 风险

最后列出:

预计修改的文件清单。

要求:

- 基于实际代码分析
- 无法确认的信息明确标记“未确认”
- 不要为了完成 Plan 而猜测
- 当前阶段不要修改代码

24. Java / Spring Boot 重构 Plan 示例

假设需求:

text
把多个链 RPC Client 抽象成统一接口。

可以:

text
分析当前链 RPC 实现。

目标:

将不同链的公共 RPC 能力抽象为 RpcClient。

当前阶段不要修改代码。

请:

1. 找到所有 RPC Client
2. 找到所有调用方
3. 对比不同 Client 的公共能力
4. 对比链特有能力
5. 分析当前依赖关系
6. 判断哪些方法适合进入 RpcClient
7. 判断哪些逻辑应该保留在具体实现
8. 分析是否需要 RpcClientHolder / Factory
9. 分析异常模型是否需要统一
10. 分析现有调用方的迁移成本

给出最终接口设计。

列出:

- 新增文件
- 修改文件
- 删除文件
- 测试文件

要求:

不改变现有业务行为,
不新增第三方依赖,
保持现有调用兼容性。

先输出 Plan。

25. 数据库变更 Plan 示例

数据库修改更应该先 Plan。

例如:

text
需求:

给 stake_order 增加 settlement_time。

当前阶段不要修改。

请先分析:

1. stake_order Entity
2. Mapper
3. Mapper XML
4. 所有 settlement_flag 使用位置
5. 结算任务
6. 查询接口
7. 统计代码
8. migration 规则

然后设计方案。

要求:

1. 不修改历史 migration
2. 新增独立 migration
3. 旧数据必须兼容
4. 分析 settlement_time 是否允许 null
5. 分析是否需要索引
6. 不删除现有 settlement_flag
7. 保持旧 API 兼容

最后给出:

数据库变更
Java 变更
测试方案
回滚风险
修改文件清单

不要修改代码。

26. Bug Plan 和功能 Plan 不完全一样

新功能通常关注:

text
怎么实现

Bug 更应该先关注:

text
根因是什么

例如:

text
用户偶尔出现重复入账。

先不要修复。

请:

1. 找出所有入账入口
2. 找出 DepositRecord 状态变化
3. 找出余额更新方法
4. 找出定时任务是否可能重复执行
5. 找出 MQ / 重试机制
6. 找出唯一键
7. 找出事务边界
8. 找出幂等判断

要求:

先证明可能的重复入账路径。

不要直接增加 Redis 锁或数据库锁。

先输出:

根因假设
→ 代码证据
→ 复现路径
→ 修复方案
→ 测试方案

这里特别重要的是:

text
不要先给解决方案
先找根因

27. 性能优化 Plan 应该先找瓶颈

性能问题也不能直接:

text
帮我优化。

应该:

text
分析接口响应慢的问题。

当前阶段不要修改代码。

请检查:

1. SQL 数量
2. 单条 SQL 执行方式
3. 是否 N+1
4. Redis
5. RPC
6. MQ
7. 循环
8. parallelStream
9. 大对象加载
10. 分页
11. 索引
12. 日志

先找出有代码证据的性能瓶颈。

按照:

P0
P1
P2

给出优化优先级。

不要在没有证据的情况下进行架构重构。

Plan 的核心还是:

text
Evidence First

28. Plan 不要写得过度复杂

Plan 很重要。

但也不能变成:

text
任何一个小修改
都先分析 30 分钟

例如:

text
把 timeout 从 5 秒改成 10 秒

如果位置已经明确:

text
直接改

就可以。

可以简单按照风险分级。

低风险

text
拼写
变量名
简单配置
简单测试

直接:

text
Implement

中风险

text
单模块功能
Service 修改
接口逻辑
普通 Bug

可以:

text
Quick Plan
→ Implement

高风险

text
数据库
支付
钱包
认证
并发
架构
跨模块

建议:

text
Explore
→ Detailed Plan
→ Review
→ Implement

29. Plan 不是让 Codex 取代技术决策

还有一个误区:

text
既然 Codex 会 Plan,
那所有架构决策都让它决定。

不应该。

更合理的是:

text
Codex
→ 搜索代码
→ 提取事实
→ 分析方案
→ 提醒风险

Developer
→ 结合业务
→ 做关键决策

特别是:

text
数据库模型
资金安全
架构边界
兼容策略
生产风险

最终仍然应该由开发者负责。

Plan 的价值是:

text
提高决策质量

而不是:

text
取消人的决策

30. Plan 和 AGENTS.md 怎么配合?

可以这样理解:

text
AGENTS.md
→ 长期项目规则

Prompt
→ 当前需求

Plan
→ 当前需求的实施方案

例如:

text
AGENTS.md:

金额使用 BigDecimal
数据库必须 migration
禁止 git push

Prompt:

text
增加冻结余额功能

Plan:

text
具体修改哪些表
哪些 Service
事务怎么设计
怎么保证幂等
怎么测试

三者各自解决不同问题。


31. Plan 和 Prompt 的关系

上一篇我们总结:

text
Prompt

=

Context
+
Goal
+
Scope
+
Constraints
+
Verification
+
Output

对于复杂任务,可以进一步变成:

text
Prompt

Explore

Plan

Confirm

Implement

Verification

Review

所以 Plan 不是独立存在的。

它是:

text
复杂 Prompt

进入实现之前的重要阶段。


32. 一个推荐的真实开发工作流

以后遇到复杂需求,可以固定使用:

text
① git status

② codex

③ /status

④ 阅读 AGENTS.md

⑤ 给出任务 Prompt

⑥ Explore

⑦ Impact Analysis

⑧ Plan

⑨ Developer Review Plan

⑩ Implement

⑪ Compile / Test

⑫ Codex Review

⑬ git diff

⑭ Developer Review

⑮ Commit

这里最关键的变化就是:

text
需求

和:

text
写代码

之间多了一层:

text
Plan

33. 最后怎么理解 Plan?

如果只记一句话:

text
Plan 的目的不是让 Codex 多说一点。

而是在代码真正被修改之前,
先暴露错误理解、遗漏范围和设计风险。

简单任务:

text
Prompt
→ Implement

复杂任务:

text
Prompt
→ Explore
→ Plan
→ Review
→ Implement

尤其涉及:

text
Money
Database
Concurrency
Authentication
Architecture
Compatibility

更应该:

text
Think Before Write

最终可以把 Codex 的完整工作方式记成:

text
Read

Understand

Plan

Implement

Test

Review

其中:

text
Read
+
Understand
+
Plan

解决的是:

text
做正确的事情

而:

text
Implement
+
Test
+
Review

解决的是:

text
把事情正确地做完

当你开始真正使用这种方式以后,会发现 Coding Agent 的价值不再只是:

text
帮我快速生成代码

而是:

text
帮助我完成一个完整的软件工程任务

这才是 Plan First 真正重要的原因。