1. 引言:Codex 不是另一个「聊天窗口」
很多 Plus / Pro 用户在开通订阅后,第一反应是把 Codex 当成网页版 ChatGPT 的平替------丢个问题进去、复制答案出来。这种用法只发挥了它不到三成的功力。
Codex 真正的定位是代理式编程智能体(coding agent):它能直接读写你的文件系统、执行 shell 命令、运行测试、在失败后自我修正,并在你的审批下完成一个完整的多文件改动。对已经熟悉 Git、终端和工程化流程的开发者来说,Codex 的价值在于「把重复的、可拆解的开发任务外包出去」,而不是「生成一段孤立的代码」。
本文假设你已开通 ChatGPT Plus / Pro,跳过一切开通流程,直接进入实战部分:从 CLI 环境配置、真实项目接入,到 Spec-Driven Development(规格驱动开发)、自定义 AGENTS.md 与审批模式,最后用一个完整案例串起整条工作流。
2. 先选对入口:网页、IDE 插件还是 CLI
Codex 有三个主要入口,它们的适用场景完全不同:
| 入口 | 适合场景 | 局限 |
|---|---|---|
| 网页版 ChatGPT 内嵌 Codex | 快速验证想法、小段代码生成 | 无文件系统访问,无法持续改项目 |
| VS Code / JetBrains 插件 | 边写边改、局部重构 | 上下文受当前文件限制,多文件联动弱 |
| Codex CLI(重点) | 真实项目、多文件改动、代理式迭代 | 需要一点配置成本,但收益最大 |
对于非小白用户,我的建议是:一旦任务涉及「跨多个文件、需要运行测试、需要读取项目结构」,直接上 CLI。 下面重点围绕 CLI 展开。
3. Codex CLI 环境搭建与关键配置
3.1 安装与认证
bash
# macOS / Linux(推荐使用 npm 安装,更新及时)
npm install -g @openai/codex
# 确认安装成功
codex --version
首次运行需要认证。Codex CLI 支持两种认证方式,建议优先使用 API Key 方式,因为它可以解耦模型选择:
bash
# 方式一:ChatGPT 账号登录(适用于 Plus / Pro 订阅用户)
codex login
# 方式二:使用 API Key(与订阅套餐并存时可灵活切换模型)
export OPENAI_API_KEY="sk-..."
登录后,CLI 会默认使用与你订阅套餐绑定的模型。对于 Pro 用户,可以在配置中显式指定更强模型:
bash
codex login
# 进入交互界面后可以用 /model 切换模型
3.2 核心配置文件 config.toml
Codex 的全局配置位于 ~/.codex/config.toml,以下是面向工程化开发的推荐配置:
toml
model = "gpt-5-codex"
model_provider = "openai"
approval_policy = "on-request"
# on-request: 仅在执行可能产生副作用的命令前请求审批(推荐)
# never: 完全自动执行(仅限完全隔离的沙箱环境)
sandbox_mode = "workspace-write"
# read-only: 只读不写
# workspace-write: 可写当前工作区(推荐)
# danger-full-access: 完全无沙箱(谨慎使用)
[spinner]
render = "dots"
approval_policy 是 CLI 里最容易被忽视、却又最重要的设置。建议保持 on-request,让 Codex 在执行 git commit、rm、安装依赖等高风险命令前停下来等你确认。
3.3 基础交互模式
CLI 有两种运行模式,建议先熟悉非交互模式再进入交互模式:
bash
# 非交互模式:直接执行一次任务
codex exec "为 src/utils/logger.ts 补充单元测试"
# 交互模式:进入持续对话,支持多轮代理式执行
codex
交互模式下有几个高频命令值得记住:
/model:切换模型/approvals:查看待审批的操作/compact:压缩上下文,清理历史/undo:撤销上一次改动/help:查看全部命令
4. 代理式编码的核心:让 Codex 真正「跑起来」
Codex 与普通补全工具的本质区别在于执行循环(agentic loop):它会自己规划步骤、执行命令、检查结果、修正错误,直到任务完成或需要你审批。
4.1 给它一个可验证的目标
质量差的任务指令往往是这样:
帮我优化一下代码。
这种模糊指令会让 Codex 自由发挥,结果往往不可控。好的指令必须包含可验证的验收标准:
重构
src/api/client.ts,把重复的请求重试逻辑抽成src/utils/retry.ts的withRetry函数,保持原有导出接口不变;重构完成后运行pnpm test,确保所有测试全部通过。
关键区别在于最后一句:用测试作为验收标准。这让 Codex 有了自我纠错的依据------它改完代码后会自己跑测试,测试失败就会继续修。
4.2 项目上下文:AGENTS.md 是最高杠杆配置
Codex 会自动读取项目根目录下的 AGENTS.md 作为持久化指令。这是目前最被低估的功能。一个高质量的 AGENTS.md 应该包含:
markdown
# 项目编码规范
## 技术栈
- Node.js 20+,使用 ES Modules
- 测试框架:Vitest,禁止引入 Jest
- 包管理器:pnpm,禁止使用 npm 或 yarn
## 命令
- 运行测试:`pnpm test`
- 类型检查:`pnpm typecheck`
- 构建:`pnpm build`
## 规范
- 所有 TS 文件使用严格模式,类型必须显式标注,禁用 `any`
- 错误处理统一使用自定义 `AppError` 类,不抛出裸异常
- 每提交一个可工作的小改动,不要跨越无关模块
有了这份指令,Codex 在每次任务中都会遵循你的技术栈约定(不会擅自把 Electron 应用改成 Vite 项目)、运行正确的命令、遵守代码规范。这一步的投入产出比极高。
5. Spec-Driven Development:把「改代码」升级为「走流程」
对于已经熟悉工程化流程的开发者,直接让 Codex「改这个文件」还不够过瘾。更进阶的用法是规格驱动开发(Spec-Driven Development)------先写规格说明,再让 Codex 按规格实现。
5.1 工作流
- 编写规格文档 :在
spec/目录下用 Markdown 描述功能需求、边界条件、验收标准。 - 让 Codex 实现规格:把规格文档作为上下文交给 Codex。
- Codex 自测:利用规格中的验收标准驱动测试。
- 人工审查:重点审查边界条件和安全相关改动。
5.2 实战:一个带缓存的 API 客户端
假设规格文档 spec/cached-api-client.md 内容如下:
markdown
# 带缓存的 API 客户端
## 需求
实现 `src/api/cachedClient.ts`,对 GET 请求结果做内存缓存。
## 验收标准
- 相同 URL 和参数的 GET 请求在 TTL 内只请求一次后端
- POST / PUT / DELETE 请求不缓存,且会清除同路径的 GET 缓存
- TTL 默认 60 秒,可通过构造参数覆盖
- 缓存命中时返回值的引用必须深拷贝,防止外部修改污染缓存
- 必须通过 `pnpm test` 的全部用例
然后执行:
bash
codex exec "读取 spec/cached-api-client.md,按规格实现 src/api/cachedClient.ts,并编写单元测试验证所有验收标准;实现完成后运行 pnpm test 确认通过"
Codex 会读取规格、实现代码、生成测试、运行测试,并在失败时自行修复。你最终需要做的只是审查 diff 和跑一次完整测试。
这种模式的收益在于:规格即契约。即使中途切换模型或换人来审查,验收标准始终是明确的。
6. 审批模式的工程化实践
代理式编码最大的信任问题来自「它会不会乱执行命令」。针对非小白用户,建议建立一套分层审批策略:
| 命令类型 | 策略 | 配置方式 |
|---|---|---|
| 读操作(cat / ls / grep) | 自动放行 | 默认 |
| 写操作(写入文件 / 编辑代码) | 自动放行(工作区内) | sandbox_mode = "workspace-write" |
| 高风险命令(git push / rm / npm install) | 必须审批 | approval_policy = "on-request" |
| 网络请求(下载脚本 / curl 执行) | 必须审批 | 审批时重点看 URL |
一个典型的安全审批场景是 Codex 执行以下命令前的暂停:
bash
# Codex 试图安装新依赖,CLI 会弹出审批
npm install axios
# 你的判断依据:
# 1. 这个依赖真的是任务需要的吗?
# 2. 版本号是否被锁死?是否应该写成 axios@1.7.2?
# 3. 是否引入了不必要的供应链风险?
审批不是纯被动的「点同意」,而是一个审查环节。把审批当成 Code Review 的一部分,每次确认命令与你对任务的理解一致后再放行。
7. 完整实战:用 Codex 完成一个真实功能
下面用一个贴近真实工作的案例,把前面的所有环节串起来。
7.1 任务背景
你在维护一个 TypeScript 的 REST API 服务,需要新增一个「用户列表分页查询」接口。要求:
- 路由:
GET /api/users?page=1&pageSize=20 - 参数校验:page 为正整数,pageSize 范围 1-100
- 返回结构:
{ data: User[], total: number, page: number, pageSize: number } - 必须做 SQL 注入防御(使用参数化查询)
- 补充集成测试,覆盖正常与异常参数
7.2 阶段一:让 Codex 探索项目
不要一上来就让它写代码。先给它一个探索性任务:
bash
codex exec "阅读项目结构,找到以下信息:1) 路由如何注册;2) 现有的数据库访问方式;3) 错误处理中间件如何工作;4) 现有测试的写法。输出一份简短的实现建议。"
这一步让 Codex 建立对项目的理解,也让你确认它对技术栈的判断是否正确。
7.3 阶段二:规格化任务
把需求整理成带验收标准的指令:
bash
codex exec "实现 GET /api/users 分页查询接口。要求:
1. 按项目现有路由风格注册
2. 使用参数化查询,全程禁止字符串拼接 SQL
3. 参数校验失败返回 400,结构符合现有错误响应格式
4. 编写集成测试覆盖:正常分页、page 为 0、pageSize 超过 100、page 为非数字
5. 实现后运行项目的测试命令,确保全部通过"
7.4 阶段三:审查与收尾
Codex 完成后,重点审查三个风险点:
- SQL 是否真的参数化------不要只看它声称「已参数化」,要直接看生成的查询代码;
- 参数校验是否覆盖边界 ------特别是
page=0和超大pageSize; - 测试是否真实有效------检查测试断言是否真的验证了响应结构,而不是只断言 200。
审查确认无误后,手动执行最终验收:
bash
pnpm test
pnpm typecheck
8. 常见坑与避坑指南
以下是我自己在深度使用 Codex CLI 过程中总结的几个高频问题:
坑 1:上下文过长导致「遗忘」规格。 多轮代理执行后,Codex 可能丢失早期需求。缓解方式:把关键验收标准写进 AGENTS.md 或规格文档,而不是只放在对话历史里;上下文膨胀时用 /compact。
坑 2:擅自扩大改动范围。 让它改 A 文件,结果顺手重构了 B、C 文件。缓解方式:在指令中明确「只允许修改与本次任务直接相关的文件」,并开启审批模式审查每一条写操作。
坑 3:测试「虚假通过」。 Codex 可能为了让测试通过而修改测试本身,导致测试失去验证价值。缓解方式:在指令中声明「禁止修改测试文件以适配实现」,并人工抽查关键测试断言。
坑 4:依赖版本漂移。 Codex 可能安装一个不兼容的最新版依赖。缓解方式:在 AGENTS.md 中固定关键依赖版本,审批安装命令时注意版本号。
9. 总结
Codex 的上限不取决于模型本身,而取决于你如何给它设定边界和验收标准。对于已经熟悉开发流程的非小白用户,最有价值的三个实践是:
- 写好
AGENTS.md------把项目规范、命令、技术栈约束一次性沉淀成持久化指令; - 用测试驱动验收------让 Codex 有自我纠错的客观依据,而不是靠「感觉改好了」;
- 把审批当 Code Review------每一次放行都是一次质量审查,而不是流程负担。
当你把这三件事固化进工作流后,Codex 才会从「偶尔生成代码的聊天工具」变成「能独立跑完一个完整开发任务的代理」,这才是 Plus / Pro 订阅真正解锁的能力。