Skip to content
claude ~ codex/34-capstone— 16 min read

34 · 综合实战:从零给一个 TODO 小工具加功能、提交一次

📚 系列导航:上一篇〔33 Windows 使用要点 〕把 Windows 上那些容易卡住人的坑——路径、换行符、终端、沙箱差异——一条条理顺了。这一篇咱们不讲新功能,干一件更过瘾的事:把前面三十几篇学的零件,亲手装成一台能跑的整机。下一篇〔35 命令与配置速查表 〕再把全篇用到的命令、配置键一张表收口,当工具书随时翻。

兄弟们,今天不上课,咱们一起从零做一个小东西。

我手上有个特别朴素的命令行小工具——一个 Python 写的 todo.py,能添加待办、列出待办,就这俩功能。它有个明摆着的缺:加完的事,干完了删不掉,只能眼睁睁看着列表越堆越长。这一篇,咱们就把「删除待办」这个功能,从交代背景、派活、设权限,一路做到自验证、git 提交,完整走一遍

说白了,前面每一篇都在讲「某一个零件怎么用」——AGENTS.md 怎么写、提示词怎么提、权限怎么设、git 怎么交给它。单看都懂,但真到一个活儿上,这些零件该按什么顺序、怎么咬合,很多人是懵的。这一篇就是那张「装配图」。

我不会假设你电脑上正好有这个项目。第 01 节我带你两分钟把这个 todo.py 建出来,之后每一步你都能照着我敲,敲完亲眼看到结果。这是一篇「跟做」文章,不是「看懂」文章——光看不动手,等于没读。

看完这一篇,你会拿到:

  • 一条从零到提交的完整开发链路,每一步都对应前面某一篇,串成肌肉记忆
  • 一份能照抄的 AGENTS.md、一句结构完整的派活提示词、一组真实命令和预期输出
  • 「让 Codex 自己跑测试验证、不达标不收工」的实操姿势
  • 一次干净的 git 提交是怎么交给 Codex、又由你把最后那道关的
  • 一张「这一步在用哪一篇的本事」的全链路对照表,以后做任何项目都能套

⚠️ 下文凡涉及具体命令、参数、默认行为,都以 Codex 官方文档 为准;模型名、界面文案这类会随版本变的东西,看到时以你本地 codex --help 和实际显示为准,本篇不写死。


01 先把「靶子」立起来:两分钟造一个 TODO 小工具

动手之前得有个东西给你动。咱们先手工把这个项目建出来——之后所有操作都围着它转

类比:这就像装修前先得有套毛坯房。 没有房子,再好的设计图也落不了地。这个 todo.py 就是咱们的毛坯房,简单到一眼能看完,但「该有的墙都在」——有数据、有功能、有入口,正好够咱们加一面新墙(删除功能)。

找个空目录,建一个 todo.py,内容如下(Mac / Linux / Windows 都一样,Python 3 即可):

python
# todo.py
import sys

TODOS = []

def add(item):
    TODOS.append(item)
    print(f"已添加:{item}")

def list_todos():
    if not TODOS:
        print("(暂无待办)")
        return
    for i, item in enumerate(TODOS, 1):
        print(f"{i}. {item}")

def main():
    if len(sys.argv) < 2:
        print("用法:python todo.py [add <内容> | list]")
        return
    cmd = sys.argv[1]
    if cmd == "add":
        add(" ".join(sys.argv[2:]))
    elif cmd == "list":
        list_todos()
    else:
        print(f"未知命令:{cmd}")

if __name__ == "__main__":
    main()

建好后,先跑一下确认它活着:

bash
python todo.py add 买咖啡豆
python todo.py list

预期输出:

text
已添加:买咖啡豆
(暂无待办)

注意这里有个「特性」——因为每次运行都是新进程,TODOS 这个内存列表跑完就清空了,所以 list 那次看到的是空的。这不是 bug,是咱们这个最小靶子的设定,先记着,第 05 节验证时会用到它。

最后,把它纳入 Git 管理(后面要提交):

bash
git init
git add todo.py
git commit -m "init: TODO 小工具初版"

预期会看到 Git 报告创建了一次提交。靶子立好了,下面正式开工。

💡 一句话总结:先两分钟手工造出 todo.py 这个最小可跑的靶子并纳入 Git,之后每一步才有的放矢。


02 第一步:写 AGENTS.md,把项目背景一次交代清

Codex 一进项目是张白纸——它不知道这是什么项目、用什么跑、有什么规矩。开工前的第一件事,是给它一份「交接清单」。 这正是〔11 项目说明书 AGENTS.md 〕讲的事。

类比:这像给临时来帮忙的工人贴一张「现场须知」。 工人手艺再好,进了你家不知道「电闸在哪、哪面墙不能砸、干完往哪倒垃圾」,照样帮倒忙。AGENTS.md 就是贴在门口那张须知,Codex 每次开工先看一眼。

在项目根目录建 AGENTS.md,照抄这份(短、准、只写它真用得上的):

markdown
# TODO 小工具

一个命令行待办工具,纯 Python 3 标准库,无第三方依赖。

## 运行
- 添加:`python todo.py add <内容>`
- 列出:`python todo.py list`

## 约定
- 只用标准库,不要引入任何第三方包
- 新功能要保持现有命令行风格(`python todo.py <命令> <参数>`
- 改完必须能用上面的命令跑通

## 测试
- 如果还没有测试文件,用标准库 `unittest` 新建 `test_todo.py`
- 改完跑:`python -m unittest`

记住〔11 篇〕里那个血泪教训——别把唯一有用的规矩埋进一百行废话里。我去年就吃过这亏,AGENTS.md 写了一百四十行,最关键的「禁用 npm」埋在第 140 行,Codex 注意力早被前面稀释没了,转头就 npm install。所以这份须知我刻意压到二十行内:每一条都是它干这个活儿真会用到的,没有一句公司简介、产品愿景。

💡 一句话总结:开工第一步先写一份短而准的 AGENTS.md,把「怎么跑、什么规矩、怎么测」交代清,且只写它真用得上的,别注水。


03 第二步:派活——目标 + 范围 + 约束 + 验收,一句说全

须知贴好了,该派活了。派活的质量,直接决定它干出来的活儿有多准。 这是〔13 提示词写法 〕的核心:一句信息量约等于零的「加个删除功能」,它只能脑补;把「四件套」说全,它才不跑偏。

类比:派活像给装修工下一张工单。 你不能只说「这屋子改一下」,得写明:改成什么样(目标)、动哪面墙别动哪面(范围)、用什么材料(约束)、怎么算验收合格(验收)。四样缺一样,工人就得自己猜,猜错了你返工。

进项目,起一个 Codex 会话:

bash
codex

然后把这句结构完整的需求递给它(你可以直接复制):

text
给 todo.py 加一个「删除待办」功能。

目标:支持 `python todo.py done <序号>`,按 list 显示的序号删除对应待办。
范围:只改 todo.py,新增/修改测试文件;不要动命令行整体风格,不要引第三方包。
约束:序号从 1 开始;序号越界或非数字时,打印友好提示而不是报错崩溃。
验收:用 unittest 覆盖「正常删除、越界、非数字」三种情况,`python -m unittest` 全绿。

对比一下下面这两种派法,差距一目了然:

❌ 含糊派活✅ 四件套派活
「加个删除功能」明确命令格式 done <序号>
没说改哪、动多大框定范围:只动 todo.py + 测试
没说边界怎么处理约束:越界 / 非数字要友好提示
没说怎么算做完验收:三类用例 + unittest 全绿

我自己的真实体感:把验收标准写进提示词,是性价比最高的一句话。 上个月我让 Codex 给一个解析脚本加容错,头一回偷懒没写验收,它「改完了」但对空文件直接崩;我把「空文件、超大文件、乱码三种都要不崩」补进去重派,一次过。Codex 的天花板,常常是被你自己的提问方式锁死的。

💡 一句话总结:派活用「目标 + 范围 + 约束 + 验收」四件套把话说全,缺哪件它就在哪件上脑补;尤其把验收标准钉进去,等于告诉它「不达标不收工」。


04 第三步:设好权限——让它能改文件、能跑测试,但别放飞

派活之前(或会话刚起时),得先想清楚:这个活儿要让 Codex 动多大? 这是〔15 权限、沙箱与审批 〕的事——沙箱管「它能碰到哪」,审批管「动手前问不问你」。

类比:这像给上门的工人发一张门禁卡。 卡的权限给小了,他改个东西还得一遍遍喊你开门,烦;给大了,他能溜达进你卧室翻抽屉,悬。咱们这个活儿,要的就是「能在这个项目目录里改文件、跑测试,但出不了这扇门」

对这个活儿,推荐用「工作区可写 + 按需审批」这一档——它能在项目目录里自由改文件(含新建、删除)、能跑 python -m unittest,但碰到改工作区之外的文件、联网这类越界动作会停下来问你。命令行临时指定:

bash
codex --sandbox workspace-write --ask-for-approval on-request

或者写进 ~/.codex/config.toml 当默认(TOML 格式的配置文件):

toml
# ~/.codex/config.toml
sandbox_mode = "workspace-write"
approval_policy = "on-request"

三个关键默认值,照〔15 篇〕记牢,省得踩坑:

你以为实际默认(workspace-write 下)
它能随便联网下包网络默认是
.git 目录随它改.git 默认只读保护
改哪儿都行只在工作区目录内可写

千万别学我当年图省事把 sandbox_mode 写成 danger-full-access 当全局默认。去年冬天我在一个没初始化 Git 的临时目录里让它「清下没用的文件」,完全访问模式下没有「工作区」这道圈拦着,它直接在我家目录里翻了起来——我按 Esc 打断那一下,后背是凉的。这个 TODO 小项目用 workspace-write 足够,缰绳别松到不该松的地方。

💡 一句话总结:开工前先用沙箱和审批划好圈——workspace-write + on-request 让它能改能测但出不了项目门;danger-full-access 这种全局默认是给自己挖坑。


05 第四步:让它自验证——跑测试,不达标不收工

Codex 说「改完了」不等于真做对了。最省心的做法,是让它自己跑测试、自己确认绿了再交给你——你只当最后的验收员。这一步把〔13 篇〕的「验收标准」真正落了地。

类比:这像让厨师出菜前自己先尝一口。 你在派活时(第 03 节)已经写明「python -m unittest 全绿」算验收,等于提前递了把尺子。现在 Codex 改完会照这把尺子自测:跑测试 → 看是否全绿 → 没绿就接着改。你不用盯着它每一步,等它端上来的是「已经尝过、确认没问题」的成品

因为咱们派活时就把测试要求写进了 AGENTS.md(第 02 节那个 ## 测试)和提示词里,Codex 通常会主动新建 test_todo.py 并在改完后跑一遍。它跑测试时,你大概会在终端看到类似:

text
...
----------------------------------------------------------------------
Ran 3 tests in 0.003s

OK

看到 OKRan 3 tests,说明它给的三类用例(正常删除、越界、非数字)都过了。万一它没主动跑,你补一句催它

text
跑一下 python -m unittest,把结果贴出来;有不过的就改到全绿再停。

这里有个〔01 节〕埋的细节要提醒你:因为 TODOS 是内存列表、进程结束就清空,你没法用「先 add 再 done 再 list」这种命令行手测真正验证删除逻辑——list 永远是空的。所以这个功能的正确验证方式只能靠单元测试,在同一个进程里 adddone 再断言。这恰恰说明:该让它跑测试自验的活儿,别用肉眼手测糊弄过去。

我自己有个铁规矩:凡是让 Codex 改了逻辑,结尾必带一句「跑测试并贴结果」。 有一次我嫌麻烦没让它跑,肉眼看 diff 觉得没问题就合了,结果一个边界把生产环境搞挂了——从那以后,「自验证」这一步我一次都不省。

💡 一句话总结:派活时把测试命令写进验收,改完让 Codex 自己跑 unittest 跑到全绿再交付;内存态、状态类逻辑尤其要靠测试验,别用肉眼手测蒙混。


06 第五步(可选):什么时候该叫子代理或 MCP 来搭把手

这个 TODO 小活儿,一个主代理顺手就干完了,用不上子代理,也用不上 MCP。但综合实战(capstone)的意义是让你认得「什么时候该升级装备」,所以这节讲清边界——知道何时不用,和知道何时该用,一样重要

类比:这像装修时要不要叫外援。 给一面墙刷漆,你自己一人就办了;可要是十个房间同时刷、还得查一份外部的色卡标准,那就该喊帮手、该翻资料了。子代理是帮手,MCP 是资料通道。

两条判断线,记住就行:

  • 活儿「又多又能并行」→ 叫子代理。 比如不是删一个功能,而是要把二十个文件里的过期写法批量改掉。这时让主代理拆活、多个子代理并行去改,比一个人顺序磨快得多。怎么拆、怎么派,看〔21 子代理 〕——记住它的脾气:只有你开口它才拆,不会自作主张。
  • 活儿「要够外部世界」→ 接 MCP。 比如删除前要先查公司内部某个系统「这条待办是否已归档」,这种 Codex 自己够不着的外部能力,就靠 MCP 这个「外接口」接进来,见〔20 用 MCP 接外部工具 〕。
这个活儿要不要升级为什么
todo.py 加一个删除功能❌ 不用单文件小改动,主代理够了
把 20 个文件的过期写法批量改掉✅ 子代理又多又能并行,拆出去快
删除前要查外部系统的归档状态✅ MCPCodex 够不着外部,得接口子

说句实话,新手最常犯的不是「该用没用」,而是**「不该用硬上」**——一个三行的小改动也要拆五个子代理,纯属给自己添乱。先用最朴素的单代理把活干完,真撞上「又多又并行」或「够不着外部」的墙,再升级。

💡 一句话总结:小活儿一个主代理就够,别硬上重装备;「又多又能并行」才叫子代理(21 篇),「要够外部世界」才接 MCP(20 篇)。


07 最后一步:git 提交——它来打草稿,你来按下确认

功能做对、测试全绿,临门一脚是把这次改动干净地提交。这是〔26 Git 与 GitHub 集成 〕的本事,也是整条链路的收口:审查和提交信息它来拟,按下提交那一下你来定。

类比:这像签合同前的「双签」。 一方拟好条款(Codex 看 diff、写提交信息),另一方逐条核对再落笔(你审一眼、确认提交)。提交是会进历史的「定稿」,这道关必须有人按,而那个人是你

在会话里直接交代:

text
把这次改动提交一下:先看 git status 和 git diff,再写一条中文提交信息,前缀用 feat:,提交前把变更和信息列给我确认。

Codex 处理 git 提交,常见做法是按这个节奏来:

text
1. git status   —— 看有哪些变更
2. git diff      —— 审具体改了什么
3. git add       —— 把要提交的加进暂存
4. git commit    —— 写好信息、创建提交

⚠️ 实验性,可能变化:让 Codex 自己执行 git commit 落库,依赖一个叫 codex_git_commit 的实验性开关,默认是关的。所以你照做时,更稳的姿势是:让 Codex 帮你看 diff、拟提交信息,最后那条 git commit 你自己敲——既拿到它的草稿,又把「按下提交」这一步牢牢攥在自己手里。

为什么 git commit 这一步天然就有道关卡?因为在 workspace-write 沙箱下,.git 目录是只读保护的(〔15 篇〕讲过这条),动到提交这种越界动作往往要先经你确认。这正好给你留出扫一眼的机会:改的文件对不对、提交信息说人话没、有没有把不该提的东西(比如临时文件)也带进去了。确认无误,再放它落锤。你可以期待一条类似这样的提交信息:

text
feat: 新增按序号删除待办功能并补充 unittest 用例

提交完,亲手核一遍最稳:

bash
git log --oneline -1

预期输出(哈希值你本地不一样,正常):

text
a1b2c3d feat: 新增按序号删除待办功能并补充 unittest 用例

我的真实习惯是:git commit 这一下,我从不开「全自动」让它无人值守地提。〔15 篇〕那条贯穿全书的红线——「审查它来当,放行你来按」——在提交这一步体现得最明显。倒不是怕它写错信息,是怕它把我没留意的半成品一起带进了历史,回头清理比当场看一眼贵多了。

💡 一句话总结:提交让 Codex 打草稿(看 diff、拟信息),但 git commit 那一下你亲自确认再放行——这是贯穿全书的「审查它来当、放行你来按」红线在收口处的落点。


08 回头看整条链:每一步在用哪一篇的本事

走完一遍,把这条链路拎起来看,你会发现前面三十几篇不是孤立的知识点,是一条流水线上的工位。这张表你以后做任何项目都能直接套:

步骤这一步在干什么对应篇
① 立靶子造出最小可跑的 todo.py 并纳入 Git本篇
② 写须知AGENTS.md 交代背景、怎么跑、什么规矩11
③ 派活目标 + 范围 + 约束 + 验收,四件套说全13
④ 设权限workspace-write + on-request 划好圈15
⑤ 升级(按需)又多又并行叫子代理、够不着外部接 MCP21 〕〔20
⑥ 自验证让它跑 unittest 跑到全绿再交付13
⑦ 提交Codex 拟 diff 与信息,你确认后 commit26

这条链的顺序不是我拍脑袋排的,是真实开发的自然节奏:先让它懂项目(须知),再说清要什么(派活),再框住它能动多大(权限),干完自己验(测试),最后定稿入库(提交)。

模型选什么、推理强度配多大,这条链路里我用的就是默认那套——旗舰 gpt-5.5 + 默认推理强度(一般是 medium,这个 TODO 小活儿完全够用,没必要拉到 high。要是你碰上的是「跨模块大重构」那种硬骨头,再回〔30 怎么选模型 〕按场景调档。这一篇我刻意全程用默认配置走,就是想让你看清:链路本身才是主角,调参是锦上添花。

💡 一句话总结:须知 → 派活 → 权限 →(按需升级)→ 自验证 → 提交,这条顺序是真实开发的自然节奏;前面每一篇都是这条流水线上的一个工位,串起来才是「会用 Codex」。


小结

这一篇没教新功能,干的是「把零件装成整机」:

  • 立靶子:手工造一个最小可跑的 todo.py 并纳入 Git,让后续每一步都有的放矢。
  • 写须知:短而准的 AGENTS.md,只写它真用得上的,别注水稀释关键规矩。
  • 派活:「目标 + 范围 + 约束 + 验收」四件套说全,把验收钉进去等于「不达标不收工」。
  • 设权限workspace-write + on-request 划好圈,别拿 danger-full-access 当全局默认。
  • 自验证:让它自己跑 unittest 到全绿,状态类逻辑尤其靠测试验,别肉眼蒙混。
  • 提交:Codex 拟草稿、你按确认——「审查它来当、放行你来按」这条红线在收口处落地。

你现在应该能:拿到任何一个小需求,不再东一榔头西一棒子,而是按「须知 → 派活 → 权限 → 自验证 → 提交」这条链,把前面学的零件咬合成一次干净、可复现、自己心里有底的开发。这,就是「会用 Codex」和「听说过 Codex」的真正分界线。


下一篇〔35 命令与配置速查表 〕,咱们把整个 Codex 篇用到的命令、配置键、常用斜杠命令收进一张能随时翻的速查表——你刚跟着做完这一遍,正好趁热想一个问题:这条链路里,哪几个命令是你下次盲敲都不会错的,哪几个还得回头查? 那张表,就是为「还得查」的那部分准备的。