想学习多 Agent 协作,可以从一个很小的任务开始:让 Codex 实现购物车总价函数,依次交给三个角色做需求分析、代码实现和独立验证。

这个任务用一个 Agent 也能完成。拆成三个角色,是为了看清楚如何定义职责、传递结果,以及在发现问题后返回修复。

本文整理自一次 Codex 学习会话中的购物车示例,并按 2026 年 10 月 21 日查阅的官方文档核对配置。原会话只展示了方案,没有实际运行这三个 Subagent;下面也不把教学示例当作已经跑通的结果。

先看三个角色怎样协作

主 Agent 接收用户需求并协调流程,三个 Subagent 分别负责:

  • analyst:明确输入、输出和验收用例。
  • implementer:按方案修改指定文件,并运行测试。
  • verifier:对照原始需求检查实际代码、补查边界,并独立运行测试。

下图中的箭头表示主 Agent 安排的执行顺序,每一阶段完成后才开始下一阶段。三个角色之间的交接由主 Agent 组织。

Codex 支持按明确请求或适用的项目指令调用 Subagent,并由主 Agent 等待和汇总结果。这里选择串行流程,是因为实现依赖分析,验证又依赖实现。官方 Subagents 文档

第一步:在项目里定义三个 Subagent

准备一个独立练习目录,用支持 Custom agents 的本地 Codex 客户端打开它,并确保本地可以运行 Python 3。不要直接在重要项目中试验。

项目级角色放在 .codex/agents/,每个 TOML 文件定义一个角色,必填字段是 name、description 和 developer_instructions。本例省略模型设置,继承父 Agent 的模型和推理配置。Custom agents 配置说明

1
2
3
4
5
6
7
8
9
cart-demo/
├── AGENTS.md
├── .codex/
│ └── agents/
│ ├── analyst.toml
│ ├── implementer.toml
│ └── verifier.toml
├── cart.py # 由 implementer 创建
└── test_cart.py # 由 implementer 创建

先创建三个角色文件。

.codex/agents/analyst.toml:

1
2
3
4
5
6
7
8
name = "analyst"
description = "将需求整理为实现范围和验收用例。"
developer_instructions = """
阅读项目规则和相关文件,只分析,不修改文件。
根据主 Agent 提供的原始需求,列出输入输出、边界条件、
建议修改的文件,以及包含预期结果的验收用例。
有影响实现的歧义时明确指出,不自行扩展需求。
"""

.codex/agents/implementer.toml:

1
2
3
4
5
6
7
8
9
name = "implementer"
description = "按分析结果实现指定文件并运行测试。"
developer_instructions = """
根据原始需求、分析结果和验收条件做最小实现。
只修改主 Agent 分配给你的文件,并运行指定测试。
你不是唯一参与者,不要覆盖或回滚其他人的修改;
发现已有改动时,应在其基础上适配。
返回修改文件、实现行为、实际测试命令及结果、未解决项。
"""

.codex/agents/verifier.toml:

1
2
3
4
5
6
7
8
9
name = "verifier"
description = "独立核对实现和验收条件,报告缺陷。"
developer_instructions = """
只验证,不修改文件。
阅读实际代码和测试,对照原始需求逐项检查,
不要只相信 implementer 的总结或测试通过的描述。
独立运行指定测试,检查遗漏的边界条件。
返回通过项、问题位置和复现方法、未验证项、验收结论。
"""

“不修改文件”是行为指令,不会创建独立的只读沙箱。 Subagent 继承父会话的权限和 sandbox 设置;需要限制实际访问范围时,应在父会话配置相应权限。权限与沙箱说明

第二步:用 AGENTS.md 约定交接顺序

TOML 定义角色职责,工作顺序则需要另外说明。AGENTS.md 适合保存项目中持续生效的协作规则。官方项目指令说明

将下面内容写入练习目录的 AGENTS.md;如果文件已经存在,只合并这一节,保留原有规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## Subagent 练习流程

当用户明确要求使用本流程时,主 Agent 按顺序协调:

1. 实际调用 analyst 分析需求,等待最终结果。
2. 检查方案,将原始需求、方案、验收用例交给 implementer。
3. 指定 implementer 的文件归属,等待实现及测试结果。
4. 将原始需求、验收用例、修改文件和测试结果交给 verifier。
5. verifier 必须读取实际文件,并独立运行测试。
6. 有问题时,主 Agent 整理复现方法和修复要求,交回 implementer,
修复后再调用 verifier 复验;最多进行两轮修复。
7. 仍未通过时报告未完成项和原因,不宣布完成。
8. 最后由主 Agent 汇总改动、验证证据、未验证项和剩余风险。

必须实际调用三个角色,不能由主 Agent 模拟它们的回复。

交接时始终保留原始需求。否则,如果分析阶段漏掉了“折扣越界要报错”,后续实现和验证可能一起忽略这个要求。

第三步:发出一个完整任务

在该练习项目的 Codex 聊天中发送以下提示词。任务本身、修改范围和完成条件都写清楚,主 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
请实际使用项目定义的 analyst、implementer、verifier Subagents,
按照 AGENTS.md 中的流程,完成购物车总价函数。

函数:calculate_total(items, discount=0)
文件:cart.py

需求:
- items 是列表,每项包含 price 和 quantity。
- 总价为 sum(price * quantity) * (1 - discount)。
- 空列表在 discount 合法时返回 0。
- discount 范围为 [0, 1],包含两端。
- price 或 quantity 为负数、discount 越界时,抛出 ValueError。
- 即使 items 为空,也要验证 discount。
- 假定字段齐全、输入类型正确且数值有限;不处理货币舍入。

约束:
- implementer 只允许创建或修改 cart.py 和 test_cart.py。
- 测试使用 Python 标准库 unittest,不新增依赖。
- 验证命令:python3 -m unittest -v。
- 不执行 commit 或 push。

先等待 analyst 完成,再调用 implementer,最后调用 verifier。
每次交接都传递原始需求和验收用例。
发现问题则修复并复验,最多两轮修复。
主 Agent 最后给出改动、实际验证结果和未完成项。

这里特意补充了“空列表也要校验折扣”,避免实现先返回 0,漏掉参数检查。analyst 至少应提出这些用例:

输入场景 预期结果
单项 price=10, quantity=2,折扣 0.1 18
两项分别为 10 × 2 和 5 × 3,默认折扣 35
空列表,默认折扣 0
正常商品,折扣为 1 0
商品数量为 0 0
价格或数量为负数 ValueError
折扣为 -0.1 或 1.1,分别搭配空列表和正常商品 ValueError

这些是验收预期,没有被当作本次执行结果。涉及小数比较时,测试可以用 unittest.TestCase.assertAlmostEqual 检查结果;真实支付系统还需要另行设计金额精度和舍入规则。

怎样确认协作真的发生了

观察客户端中的 Subagent 活动和各角色结果,而不仅是最终回复里出现三个角色名。桌面客户端可以从主聊天中的活动记录打开子 Agent 查看工作;支持该功能的 CLI 可以用 /subagents 查看。查看 Subagent 活动

一次完整交付应能回答:三个角色是否实际被调用?implementer 修改了哪些文件?verifier 是否独立读代码、运行测试?还有哪些需求没有覆盖?

如果角色没有被识别,先核对文件位置、TOML 格式和 name,确认当前客户端已加载这些角色、项目允许委派且没有禁用 agents。不要把主 Agent 模拟的角色对话当作调用成功。

本例的 TOML 语法已做本地解析检查,文章也经过 Hexo 构建;三个自定义角色的加载、委派及购物车代码测试,未在当前环境验证。

熟悉串行交接后,再尝试并行执行互不依赖的检查,例如安全审查和测试覆盖检查。并行写文件需要划清归属,避免覆盖;每个 Subagent 都会额外消耗模型和工具资源,小任务未必因此更快或更省 Token。适用场景与开销

本文由 AI 辅助生成,如有错误或建议,欢迎指出。