《Codex 入门指南》

1
特别说明:此文由ChatGPT生成,后续由我本人编辑、修改而成。

0 引言:从驾驶员到塔台

1956 年,美国联邦航空管理局面临一个前所未有的难题:随着喷气式客机的普及,天空中的飞机数量激增,传统的目视管制方式——地面人员拿着望远镜盯着跑道——已经无法保障安全。他们的解决方案不是训练更多的飞行员,而是建立了一个全新的角色:空中交通管制员。管制员不驾驶任何一架飞机,但他同时监控数十架飞机的航线,协调冲突,确保每一架都安全着陆。从此,航空业的核心范式从“驾驶”转向了“调度”。

七十年后,软件开发正在经历类似的转变。

如果你用过 Cursor,你体验的是一种“副驾驶”模式:你坐在驾驶位写代码,AI 坐在旁边提建议。你输入一行,它补全下一行;你描述需求,它在你眼前修改文件。你始终“在环内”(Human-in-the-loop),每一步都亲眼看到、亲手确认。这很好,但它有一个根本限制——你一次只能飞一架飞机。

OpenAI Codex macOS App 提供了另一种可能:你从驾驶员变成了塔台。你不再逐行指导 AI 写代码,而是给出高层意图——“为这个项目添加用户管理模块”——然后 Codex Agent 在隔离环境中自主完成整个任务:分析代码库、规划方案、生成代码、运行测试,最终交给你一份完整的 diff 或 Pull Request。在 Codex 里,你可以同时启动多个 Agent 线程——一个在添加新 API,另一个在修复 Bug,第三个在生成测试——就像管制员同时引导多架飞机着陆。

但当你从驾驶舱走上塔台,一个新的问题随之出现:你怎么知道每架飞机都在正确的航线上?

在 Cursor 里,答案很简单——你看到每一行代码在你眼前生成,不对就立刻纠正。但在 Codex 里,Agent 是在后台自主工作的,你不可能盯着每一行。这时候,你需要的不是更好的眼力,而是更好的“雷达系统”:测试覆盖率是你的雷达屏幕,CI 流水线是你的预警系统,AGENTS.md 中的项目规范是你画好的航线。这些基础设施在以前是“锦上添花”的好习惯,在 Agent 式编程时代则变成了“没有就不能起飞”的硬性前提。

换一种说法:你的工程基本功不是被 AI 取代了,而是被 AI 放大了。基础好,效率倍增;基础差,混乱也倍增。

本指南面向有经验的 Java 后端工程师,假定你已熟悉 IDE 和大语言模型的基本用法。我们不会讲“什么是 Prompt”,而是聚焦于:如何在 Codex macOS App 中高效地委派任务、管理多个 Agent、以及建立可靠的验证闭环——从驾驶员思维,切换到塔台思维。

1 三种模式:信任的光谱

管理学中有一个经典概念叫“委派阶梯”(Delegation Ladder),描述的是上级把工作交给下级时,信任和自主权的不同层级:最低一级是“我说你做,做完给我看”;中间一级是“你自己做,但在独立空间里做,做完我审查”;最高一级是“你全权负责,做完直接交付”。

Codex 的三种运行模式——Local、Worktree、Cloud——恰好对应了这条信任阶梯的三个台阶。

1.1 Local 模式:我说你做

Local 模式是信任的最低级:Agent 直接在你当前的项目目录上工作,所有修改即时生效,就像你自己在编辑文件一样。你全程看着它,随时可以叫停。

适合的场景: 改一个配置、加一行注解、快速试验一个想法——那些即使搞砸了也能用 git checkout 秒恢复的小事。

Java 项目提示: Local 模式的好处是 Agent 修改代码后,你可以直接在内置终端运行 mvn compile./gradlew build 验证——不需要额外配置依赖环境,因为所有依赖都在你的本地仓库里。

但 Local 模式有一个明显的限制:没有隔离。Agent 的改动和你自己未提交的改动混在一起,如果它改错了关键文件,你得自己收拾残局。所以在使用前,确保你的工作区是干净的。

1.2 Worktree 模式:你自己做,做完我审查

1970 年代,丰田在制造业引入了一个激进的理念:每个工位都可以拉一根绳子叫停整条生产线(安灯系统)。这个看似降低效率的做法,实际上大幅提升了质量——因为问题在发生的瞬间就被发现和隔离,而不是等到成品出厂后才召回。

Worktree 模式体现了类似的哲学。每次启动新线程时,Codex 自动创建一个 Git worktree——你仓库的一个隔离副本。Agent 在这个独立空间里自由发挥,而你的主分支纹丝不动。做完了,你在 Review 面板里逐行审查 diff,满意了才合并;不满意,丢弃整个 worktree 就行,零成本。

这是 Codex 最核心的能力所在。 你可以同时开三个线程:

线程 1:在 UserController 中添加分页查询接口
线程 2:为 OrderService 补充单元测试
线程 3:重构 PaymentService,将硬编码的配置提取到 application.yml

三个 Agent 各自在独立的 worktree 上工作,互不干扰。这就像你同时委派了三个开发者,各自在自己的分支上干活。你只需要在他们提交 PR 时做审查。

Java 项目提示: 新的 worktree 默认不包含构建产物(target/ 目录为空)。如果 Agent 需要运行测试,你需要在 Codex 的 Local Environment 配置中设置初始化脚本:

1
mvn dependency:resolve -q && mvn compile -q

这样每次创建新 worktree 时会自动下载依赖并编译,确保 Agent 可以正常运行测试。

1.3 Cloud 模式:你全权负责

2020 年,SpaceX 的猎鹰 9 号成为第一枚完全自主着陆的轨道级火箭。从发射到着陆,无需任何人类遥控操作——飞行计算机根据预设参数和实时传感器数据自行完成一切。但这不意味着工程师们在发射后就去喝咖啡了。他们事先做了大量工作:编写飞行程序、设置安全边界、模拟各种故障场景。自主执行的前提是充分的事前准备。

Cloud 模式就是 Codex 的“自主着陆”模式。Codex 在 OpenAI 的云端沙盒中克隆你的远程仓库,Agent 在完全隔离的云环境中执行任务,完成后自动提交 Pull Request。你的电脑可以关机,Agent 照样工作。

Cloud 模式有一个独特优势:Agent 可以自动执行命令。 在 Local 和 Worktree 模式中,出于安全考虑,Agent 不会自行运行 Shell 命令(比如 mvn test),需要你手动执行。但在 Cloud 的沙盒里,一切都是隔离的,可以放心让 Agent 自主构建和测试。你在 AGENTS.md 中告诉它:

1
2
3
4
## 构建与测试
- 构建命令:`mvn clean package -DskipTests`
- 测试命令:`mvn test`
- 代码格式检查:`mvn spotless:check`

Cloud Agent 会执行这些命令,确保代码编译通过、测试全绿,然后才生成 PR。就像猎鹰 9 号的飞行计算机——事前把规则定义好,执行过程完全自主。

前置条件: Cloud 模式需要你提前配置 GitHub 仓库权限,并在仓库中放置 AGENTS.md 文件(下一章详述)。

1.4 怎么选?

维度 Local Worktree Cloud
隔离性 无,直接改本地文件 有,独立 Git 工作树 完全隔离,云端沙盒
并行能力 单线程 多线程,各自独立 多线程,各自独立
自动执行命令 需手动确认 需手动确认 可自动执行
适合任务规模 小改动 中等功能开发 大型/长时间任务
结果交付方式 本地文件直接改动 工作树分支,可合并 自动提交 PR
本地资源占用 中(多个工作树) 几乎为零

本质上,这三种模式是信任和自主权的渐进——从“你做我看”到“你做完我审查”再到“你全权负责”。日常开发建议以 Worktree 为主——它就像丰田的安灯系统,给了 Agent 充分的行动空间,同时保留了你随时“拉绳叫停”的权力。

2 AGENTS.md:对齐问题的微缩版

人工智能研究中有一个核心难题叫“对齐问题”(Alignment Problem):如何确保一个自主行动的智能体,真正按照你的意图行事,而不是按照它自己“理解”的意图?这个问题在 GPT 和 Claude 的层面是哲学性的,但在 Codex Agent 的层面,它非常具体:你怎么让一个自主编码的 Agent 遵循你项目的架构规范、编码风格和安全约束?

答案是 AGENTS.md

2.1 一份“入职手册”

每个有过带新人经验的工程师都知道:新人入职第一天,你不可能通过口头嘱咐让他记住所有规矩。你需要一份文档,写清楚“我们这里怎么做事”。AGENTS.md 就是这份文档——只不过读者不是人类新人,而是 AI Agent。

它放在仓库根目录,Codex 在每次启动任务时自动读取。没有它,Agent 就像一个空降到项目的新人,只能靠猜测行事;有了它,Agent 从第一秒就知道项目用什么技术栈、怎么构建、有哪些铁律不能违反。

在 Cursor 中,你可以通过多轮对话持续纠偏——Agent 犯了错,你随时可以说“不是这样,应该那样”。但 Codex 的工作模式不同,尤其在 Cloud 模式下,Agent 是异步执行的,你没有机会中途插话。AGENTS.md 是你在“发射前”唯一的对齐窗口。写得越清楚,Agent 偏离预期的概率就越低。

Temporal 团队是一个值得参考的实践:他们在 AGENTS.md 中详细写明了如何格式化代码、如何运行 Gradle 构建和测试,确保 Codex 的每次改动都符合项目要求。

2.2 Java 项目 AGENTS.md 模板

以下是一份面向 Java 后端项目的参考模板。一个好的 AGENTS.md 回答了 Agent 最关心的五个问题:这个项目是什么?怎么跑起来?代码该怎么写?什么不能碰?怎么验证?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 项目说明

## 概述
这是一个基于 Spring Boot 3.2 的电商后端服务,使用 Java 17,Maven 构建。
项目采用分层架构:Controller → Service → Repository。

## 技术栈
- Java 17 / Spring Boot 3.2
- Spring Data JPA + MySQL 8.0
- Redis(缓存)
- JUnit 5 + Mockito(测试)
- MapStruct(DTO 转换)
- Flyway(数据库迁移)

## 构建与测试
- 编译:`mvn clean compile`
- 运行测试:`mvn test`
- 完整构建:`mvn clean package`
- 启动服务:`mvn spring-boot:run`

## 项目结构
```
src/main/java/com/example/shop/
├── controller/ # REST 控制器,只做参数校验和结果封装
├── service/ # 业务逻辑
├── repository/ # 数据访问层(JPA Repository)
├── entity/ # 数据库实体类
├── dto/ # 请求/响应 DTO
├── config/ # 配置类
├── exception/ # 自定义异常和全局异常处理
└── util/ # 工具类
```

## 编码规范
- 遵循阿里巴巴 Java 开发手册
- Controller 层不写业务逻辑,只做参数校验和 Service 调用
- 使用 @Slf4j 记录日志,禁止使用 System.out.println
- 异常统一抛出自定义 BusinessException,不要直接抛 RuntimeException
- 数据库字段用下划线命名,Java 属性用驼峰命名
- 所有 REST 接口返回统一响应格式:Result<T>(code, message, data)

## 禁止事项
- 不要修改 src/main/resources/db/migration/ 下的已有迁移文件
- 不要修改 pom.xml 中的依赖版本(如需新增依赖请说明理由)
- 不要在循环中进行数据库查询(N+1 问题)
- 不要硬编码配置值,使用 @Value 或 @ConfigurationProperties
- 不要使用 Java 8 之前的日期 API(使用 java.time.*)

## 测试要求
- 新功能必须附带单元测试
- Service 层测试使用 Mockito mock Repository
- Controller 层测试使用 @WebMvcTest + MockMvc
- 测试方法命名:should_预期行为_when_条件
- 确保所有测试通过后再提交

2.3 对齐是一个持续过程

如果你读过《人机对齐》,你会知道对齐不是一次性的事——它需要持续的观察、反馈和修正。AGENTS.md 也是如此:

  • 从简单开始:先写核心的构建命令、项目结构和编码规范,不需要一次性面面俱到。
  • 记录 Agent 的“常见错误”:如果你发现 Agent 反复在某个地方犯错(比如总是忘了加 @Transactional),就把对应的规则加进去。每一条新规则,都是你从 Agent 的错误中提炼出来的“对齐补丁”。
  • 纳入版本控制AGENTS.md 应该和代码一起提交到 Git。团队成员都能受益,而且当项目规范变化时可以追溯。

3 高级技巧

3.1 管理长上下文:别让工作记忆溃堤

1956 年,认知心理学家乔治·米勒发表了他最著名的论文《神奇的数字 7±2》,揭示了人类短期记忆的容量限制——我们一次大约只能记住 7 个信息单元。超过这个阈值,信息就会开始相互干扰,出现遗忘和混淆。

大语言模型面临着惊人相似的困境。虽然它们的“工作记忆”(上下文窗口)远大于人类——可以容纳数十万 token 的内容——但这并不意味着它们对窗口内的每一条信息都同样敏感。研究者和开发者的经验一致表明:当对话内容达到模型上下文容量的 30-40% 时,早期的细节开始被弱化,模型的注意力聚焦在最近的交互上。越往后,越容易出现“明明告诉过它但它就是忘了”的情况。

解决方案和人类应对记忆限制的策略如出一辙——分块(chunking)和外部化(externalization)。

多开线程,而非拉长对话

米勒发现,人类绕过 7±2 限制的方式是“组块化”——把零散信息编成有意义的单元。对 Codex 而言,这意味着把大型需求拆分为多个聚焦的线程:

线程 1:生成基本项目框架和实体类
线程 2:实现 Controller 和 Service 层
线程 3:添加认证和权限控制
线程 4:编写测试和文档

每个线程专注一个子问题,上下文更集中,出错概率更低。这不仅仅是工程技巧,而是在适应模型的认知架构。

主动要求总结

人类的另一个记忆策略是“笔记”——把重要信息写下来,释放大脑去处理新问题。对 Codex 同样适用:当一个线程的对话进行到一定长度时,让 Agent 把当前状态“写下来”:

请总结目前已完成的功能、修改的文件清单、以及尚未完成的部分。

然后在新线程的开头贴上这段总结继续工作。这比让 Agent 在一个超长对话里“记住”所有细节可靠得多——就像你不会把整本教科书背下来,而是做好笔记然后带着笔记去考试。

控制 Token 消耗

长对话消耗大量 token,既拖慢响应速度,也增加成本。OpenAI 曾展示 Codex 利用约 700 万 tokens 自主开发一个 3D 游戏的案例,但这样的用量不适用于日常开发。如果输出明显变慢,考虑终止当前线程,分段处理。

3.2 调用 Shell 命令与本地工具链

内置终端与核心节奏

每个 Codex 线程附带一个内置终端,你可以在其中执行任意 Shell 命令。这带来了一个高效的工作节奏,也是 Codex 日常使用的基本循环:

  1. 在对话中让 Agent 生成代码
  2. 切到终端运行 mvn test
  3. 如果测试失败,把错误日志复制回对话框
  4. Agent 分析失败原因并修复
  5. 再次运行测试,直到通过

这个“编码 → 测试 → 反馈 → 修复”的循环,本质上就是控制论中的反馈回路——系统做出动作,观测结果,根据偏差修正,再次行动。闭环越短,收敛越快。

三种模式下的命令执行差异

模式 Agent 能否自动执行命令 你需要做什么
Local 不能(需你确认) 手动在终端执行,复制结果反馈给 Agent
Worktree 不能(需你确认) 同上
Cloud 可以(沙盒环境) 在 AGENTS.md 中配置命令,Agent 自动执行

扩展技能(Skills)

如果你希望在本地模式下也能让 Agent 自动执行特定命令,可以编写自定义 Skill——例如创建一个 run_tests 技能,让 Agent 调用时实际执行 mvn test 并将结果返回。这属于高级用法,需要遵循 Codex 的安全沙箱限制。

3.3 调试支持与 IDE 集成

喂给 Agent 错误日志

最直接的调试方式:把异常栈粘贴给 Codex。例如:

运行 mvn test 后,UserServiceTest.should_throw_when_user_not_found 测试失败,错误如下:

1
2
3
4
org.opentest4j.AssertionFailedError:
Expected: org.springframework.web.server.ResponseStatusException
But was: java.util.NoSuchElementException
at com.example.service.UserServiceTest.should_throw_when_user_not_found(UserServiceTest.java:42)

请分析原因并修复 UserService 中的逻辑。

Codex 会根据异常类型、堆栈信息和测试代码定位问题——在这个例子里,它可能会发现 findById 方法直接调用了 Optional.get() 而没有做空值处理,然后改为抛出 ResponseStatusException

让 Agent 生成调试辅助代码

当问题难以复现时,让 Agent 帮你搭建调试场景:

请为 OrderService.createOrder 方法中的库存扣减逻辑添加详细的 DEBUG 级别日志,记录每一步的中间状态(当前库存、扣减数量、扣减后库存)。

或者:

请编写一个单元测试来复现以下场景:当两个线程同时调用 deductStock 方法时,应该只有一个成功。

这相当于让 Agent 帮你搭好实验装置,你来观察结果——正如实验物理学家不会自己吹制每一个玻璃器皿,但一定自己解读实验数据。

MCP 与 IDE 集成

OpenAI 提供了 MCP(Model Context Protocol)让 Codex 与 IDE 协同工作。通过 MCP,Agent 可以访问 IDE 的调试接口——例如 Skyscanner 的工程师已将 Codex CLI 集成进 JetBrains IDE,使 AI 能使用断点调试和测试运行功能。对 Java 开发者而言,这意味着 Codex 有潜力通过 IDE 获取运行时信息(调用栈、变量值),从而更精准地诊断问题。目前这些集成仍需手动配置,但它展示了 AI Agent 与传统开发工具结合的方向。

4 Prompt 实战模板

管理学大师彼得·德鲁克曾说:“管理的本质不是命令,而是沟通。”这句话对 AI 编程同样成立。你写给 Agent 的 Prompt,本质上是一份委派指令——它的清晰程度直接决定了 Agent 的输出质量。一个模糊的“帮我加个接口”和一个结构化的需求描述,得到的结果可能天差地别。

以下是几个经过验证的 Prompt 模板,专为 Java 后端场景设计。它们的共同特征是:明确目标、提供约束、要求 Agent 先规划再动手。

4.1 新增 REST 接口

在本项目中新增一个 REST 接口,要求如下:

功能: 根据用户 ID 查询订单列表,支持分页
路径: GET /api/users/{userId}/orders
参数: userId(路径参数),page(默认 0),size(默认 20)
返回: Page<OrderDTO>,包含订单编号、金额、状态、创建时间

实现要求:

  1. Controller 层只做参数校验和结果封装
  2. Service 层处理业务逻辑
  3. 使用 Spring Data JPA 的分页查询
  4. 如果用户不存在,返回 404
  5. 返回格式遵循项目统一的 Result<T> 结构

请先列出你计划创建或修改的文件清单,确认后再开始编码。

要点: 最后一句“先列出文件清单”是这个模板的灵魂。它引入了一个轻量级的“计划-确认-执行”流程,让你在 Agent 动手之前就能发现理解偏差。

4.2 跨层重构

当前 UserController 中直接包含了用户数据的验证逻辑(邮箱格式校验、手机号校验、用户名唯一性检查),这违反了分层原则。

请重构:

  1. 将验证逻辑从 Controller 提取到 UserService
  2. 邮箱和手机号格式校验使用 javax.validation 注解(@Email, @Pattern)
  3. 用户名唯一性检查保留在 Service 层,通过 Repository 查询
  4. 保持所有现有 API 的行为不变
  5. 确保现有测试仍然通过

不要修改 UserRepository 和 User 实体类。

要点: 重构最怕的是牵一发动全身。明确声明“不要修改什么”和“保持什么不变”,就像给 Agent 画了一个施工围栏——围栏内随意施工,围栏外禁止动工。

4.3 生成单元测试

为 OrderService 编写 JUnit 5 单元测试,要求:

  • 使用 @ExtendWith(MockitoExtension.class)
  • Mock 所有依赖的 Repository 和外部服务
  • 覆盖以下场景:
    1. 正常创建订单(库存充足)
    2. 库存不足时抛出 BusinessException
    3. 用户不存在时抛出 BusinessException
    4. 订单金额计算正确(含优惠券折扣)
    5. 创建订单后库存正确扣减
  • 测试方法命名遵循 should_预期行为_when_条件
  • 使用 AssertJ 断言风格

生成完成后请运行 mvn test -pl :order-service 确认全部通过。

要点: 指定测试框架、Mock 方式、命名规范、断言风格——约束越多,输出越可控。最后一句指示 Agent 运行测试:在 Cloud 模式下它会自动执行;在本地模式下它会提示你手动执行。

4.4 排查 Bug

生产环境出现间歇性问题:用户下单后偶尔出现库存扣减成功但订单状态为“创建失败”的不一致情况。

请按以下步骤分析:

  1. 阅读 OrderService.createOrder 方法的完整逻辑
  2. 检查事务边界:@Transactional 注解是否正确放置
  3. 检查异常处理:是否有被 catch 后没有重新抛出的异常
  4. 检查外部调用:是否在事务内调用了外部服务(如发送消息队列),导致事务提交前外部状态已变更
  5. 给出根因分析和修复方案

先分析,不要直接改代码。分析完成后等我确认再修复。

要点: 给出结构化的排查步骤,引导 Agent 像资深工程师一样系统地分析问题。“先分析,不要直接改代码”这句话非常重要——它把 Agent 从“执行者”模式切换到“分析师”模式,避免它在没搞清楚问题之前就动手“修”出更多问题。

4.5 代码审查

请以高级 Java 工程师的视角审查以下改动(本次线程中的所有 diff),重点关注:

  1. 事务一致性:是否有遗漏的 @Transactional 或事务边界不正确
  2. 并发安全:是否有竞态条件或线程安全问题
  3. 异常处理:是否有未处理的 checked exception 或过于宽泛的 catch
  4. 性能隐患:N+1 查询、循环内数据库调用、缺少索引
  5. 安全漏洞:SQL 注入、敏感信息日志泄露、未校验的用户输入

对每个问题给出具体的文件名、行号和修复建议。

要点: 让 Agent 扮演“审查者”而非“实现者”——同一个 Agent 写的代码,换一个角色来审,往往能发现自己创作时的盲点。这和文学创作中“放一段时间再回头修改”的道理相通。

4.6 Automations:让 Agent 值夜班

Codex 支持 Automations 功能,让 Agent 定期执行例行任务——就像医院的夜班护士定时巡查病房。你可以设置:

  • 每日代码质量检查: 让 Agent 每天扫描代码库,检查是否有新增的 TODO 未处理、测试覆盖率是否下降。
  • CI 失败分析: 当 CI 流水线失败时,自动让 Agent 分析失败原因并提出修复建议,结果进入收件箱。
  • 依赖更新提醒: 定期检查 pom.xml 中的依赖是否有安全漏洞或重大版本更新。

在 OpenAI 内部,开发者已用 Automations 每日自动整理 Bug 列表、汇总 CI 失败原因、生成发布报告。你上班时打开 Codex 收件箱,昨晚的巡查报告已经在那里了。

5 实战示例:从零构建 Spring Boot REST 服务

纸上得来终觉浅。让我们通过一个完整示例,把前面所有概念串联起来。

场景: 构建一个用户管理 REST 服务,包含获取用户列表和按 ID 查询两个接口。使用 Spring Boot + 内存数据(简化起见)。本地已有 JDK 和 Maven 环境,以及一个空的 Git 仓库。

步骤 1:初始化项目

打开 Codex,选择项目目录 ~/Projects/UserService,启动新线程(选择 Worktree 模式)。发送:

使用 Spring Boot 3.2 + Java 17 初始化一个 Maven 项目,artifactId 为 user-service。
包含以下依赖:spring-boot-starter-web, spring-boot-starter-test。
创建主类 UserServiceApplication,配置 server.port=8080。
同时在项目根目录创建 AGENTS.md,写明构建命令(mvn clean compile)和测试命令(mvn test)。

Codex 会生成 pom.xml、主类、application.propertiesAGENTS.md。在 Review 面板中检查文件结构是否符合预期。

步骤 2:实现业务逻辑

确认项目框架后,在同一线程继续:

按照以下设计实现用户管理功能:

  1. 创建 User 实体类(id: Long, name: String, email: String),放在 entity 包下
  2. 创建 UserService,内部维护一个 ArrayList 作为模拟数据源,预置 3 个用户数据。提供 findAll() 和 findById(Long id) 方法
  3. 创建 UserController,提供:
    • GET /api/users → 返回所有用户
    • GET /api/users/{id} → 返回单个用户,找不到时返回 404
  4. Controller 通过构造函数注入 UserService

不要使用 Lombok,手动编写 getter/setter。

Codex 会在对话中描述它正在创建的文件,并在 Review 面板显示完整 diff。检查类结构、包路径、注解是否正确。

步骤 3:运行验证

切到线程的内置终端:

1
mvn spring-boot:run

启动后在另一个终端(或浏览器)访问:

1
2
3
curl http://localhost:8080/api/users
curl http://localhost:8080/api/users/1
curl http://localhost:8080/api/users/999 # 预期返回 404

如果启动失败(比如缺少依赖),把错误日志复制回对话:

应用启动失败,报错如下:[粘贴错误栈]。请分析原因并修复。

Codex 会定位问题并修改代码。这就是第 3 章提到的“编码 → 测试 → 反馈 → 修复”闭环的一次实际运转。

步骤 4:生成测试

新开一个线程(继续使用同一项目的 Worktree 模式),发送:

为 UserService 和 UserController 编写 JUnit 5 测试:

UserServiceTest:

  • should_return_all_users
  • should_return_user_when_id_exists
  • should_throw_when_id_not_found

UserControllerTest(使用 @WebMvcTest + MockMvc):

  • should_return_200_and_user_list
  • should_return_200_and_single_user
  • should_return_404_when_user_not_found

生成后请确认所有文件路径正确(放在 src/test/java 对应的包下)。

检查测试代码,然后在终端运行 mvn test。如果有测试未通过,反馈给 Agent 修正。

步骤 5:代码清理

所有测试通过后,让 Codex 收尾:

请检查整个项目:

  1. 为所有 public 方法添加 JavaDoc 注释
  2. 检查是否有冗余的 import
  3. 确保代码风格一致(缩进、空行等)
  4. 生成一段简短的 README.md,说明如何构建和运行

确认无误后,在应用中提交 Git commit,将 worktree 的改动合并回主分支。一个完整的 REST 服务就这样在 Codex Agent 的帮助下成型了。五个步骤,两个线程,整个过程你没有手写一行业务代码——但你审查了每一行。

6 Codex vs Cursor:何时用哪个

心理学家丹尼尔·卡尼曼在《思考,快与慢》中提出了两种认知模式:系统 1 是快速的、直觉的、自动化的;系统 2 是缓慢的、深思熟虑的、有意识的。Cursor 像系统 1——你和 AI 在快速交互中思考,逐行迭代,实时反馈;Codex 像系统 2——你花时间想清楚要什么,写好指令,然后让 Agent 在后台深度执行。

维度 Cursor Codex
本质定位 AI 增强的本地 IDE AI Agent 指挥中心
协作方式 你在环内,实时交互 你在环外,异步审查
粒度 逐行建议,精细控制 整块任务,完整交付
并行能力 单线程 多 Agent 并行
执行环境 本地 本地 / 云端沙盒
模型选择 可配置多种模型 OpenAI codex-1(GPT-5 系列)
适合场景 精细调试、交互式探索、学习 批量任务、功能开发、自动化

不是二选一,而是组合使用——正如人类大脑并非只用系统 1 或系统 2,而是根据任务特征灵活切换。很多团队的实践是:

  • 日常编码用 Cursor: 写小段代码、重构、Debug、交互式探索方案
  • 成块任务用 Codex: 生成样板代码、批量 CRUD、补全测试、跨文件重构
  • 批量修复用 Codex Cloud: 一次性修复多个独立 Bug,每个 Bug 一个线程,稍后统一 Review PR

一个实际的工作流可能是:先在 Cursor 里用 Plan 模式讨论技术方案(系统 2 式的深度思考),确认后用 Codex 的 Worktree 模式并行启动多个 Agent 实现各个模块(系统 2 式的批量执行),最后回到 Cursor 做精细调整和集成调试(系统 1 式的快速迭代)。

7 常见问题与使用建议

Q1: Agent 线程卡住不动了怎么办?

先检查几个常见原因:

  • macOS 权限弹窗: Codex 读写受保护目录(Desktop、Documents 等)时,系统会弹出权限请求。如果弹窗被其他窗口遮挡,Agent 就一直在等。检查系统通知或切换到 Codex 窗口看是否有待确认的弹窗。
  • Git 锁文件: 在终端运行 git status。如果提示 .git/index.lock 存在,说明上一次 Git 操作异常中断。删除锁文件即可:rm .git/index.lock
  • 任务本身太复杂: 如果 Agent 长时间无输出,可能是任务范围过大导致模型陷入了过深的推理链。终止线程,将任务拆小重试。

Q2: 如何防止 Agent 改坏关键文件?

最有效的三道防线:

  1. Worktree 模式: 所有改动都在隔离分支上,不影响主代码。你审查 diff 后才决定是否合并。
  2. AGENTS.md 中声明禁区: 明确写出“不要修改 xxx 目录/文件”。Agent 会遵循这些约束。
  3. CI 卡口: 在合并前跑完整的测试和 lint 检查。一旦 Agent 的改动破坏了核心功能,CI 会立刻暴露。

真实踩坑案例: 有用户让 Codex 在 Cloud 模式下优化 SQL 查询,Agent 不仅改了 Service 层的查询逻辑,还“顺手”修改了 resources/db/migration/ 下的 Flyway 迁移文件——这在生产环境中是灾难性的,因为已执行过的迁移文件不允许修改。这个故事完美地说明了“对齐问题”的日常版本:Agent 确实在“优化”,但它不理解“哪些东西不能碰”这条隐性规则。解决办法很简单:在 AGENTS.md 中加一句“db/migration/ 目录下的已有文件禁止修改,如需变更数据库结构请创建新的迁移文件”。

Q3: Cloud 模式下 Agent 找不到项目的私有 Maven 依赖怎么办?

Cloud 模式在 OpenAI 的沙盒中运行,无法访问你公司内网的 Maven 私服(如 Nexus、Artifactory)。解决方案:

  • 方案一: 如果私有依赖不影响编译(只是运行时需要),在 AGENTS.md 中告诉 Agent 跳过:mvn compile -pl :your-module -am -Dmaven.test.skip=true
  • 方案二: 对于必须依赖私有库的项目,使用 Worktree 模式替代 Cloud 模式——本地环境能正常解析私有依赖。
  • 方案三: 将私有依赖发布到 GitHub Packages 等公网可访问的仓库,并在 pom.xml 中配置对应的 repository。

Q4: 如何控制 Token 消耗?

几个实用策略:

  • 限定输出范围: 不要说“帮我看看这个项目有什么问题”,而是说“检查 OrderService 中 createOrder 方法的事务一致性”。范围越精确,消耗越少。
  • 小步迭代: 一次处理一个功能点,不要试图在一个线程里完成整个模块。
  • 善用 AGENTS.md: 把项目背景信息写在 AGENTS.md 中,就不需要每次对话都重复说明——这和你给新同事写入职文档是一个道理,一次投入,长期受益。
  • 监控线程时长: 如果一个线程的响应变慢、输出质量下降,说明上下文已经过长。果断开新线程。

Q5: 有哪些提升效果的小技巧?

  1. 一个线程一个主题: 不要在同一个线程里又改 Bug 又加功能。就像你不会在一封邮件里同时讨论三个不相关的议题——信息越聚焦,沟通越高效。
  2. 先分析后编码: 对复杂任务,总是在 Prompt 末尾加上“先列出你的方案/计划,确认后再开始编码”。这避免了 Agent 理解偏差导致的大量返工。
  3. 善用 Review 面板的评论功能: 直接在 diff 上写评论(如“这里需要加事务注解”“这个字段名应该用 camelCase”),然后让 Agent 根据评论修改。这种定向反馈比重新描述需求高效得多。
  4. 让 Agent 解释自己的改动: 如果你不确定某段生成代码的逻辑,直接问“请解释你在 OrderService 第 45 行使用 CompletableFuture 的原因”。理解 Agent 的思路有助于你做出更准确的判断。
  5. Worktree + 并行的黄金组合: 当你有多个独立的任务时(如三个不同的 Bug),同时开三个 Worktree 线程并行处理,然后逐一 Review 合并。这是 Codex 相对于 Cursor 最大的效率优势——空中交通管制员同时引导多架飞机着陆,而不是一架一架排队等。