我为什么把 AI 开发做成“对抗式”:Codex + Claude Code 双模型工作流
文章目录
- 1 -> 为什么需要“对抗式开发”
- 2 -> 单 Agent 直写 vs 对抗式双模型
- 3 -> 三个角色:实现方、审查方、最终裁决者
- 4 -> 一次完整对抗式开发流程
- 5 -> 不是所有任务都需要重流程
- 6 -> 审查不是聊天,而是结构化契约
- 7 -> P0 / P1 / P2:让问题有优先级
- 8 -> 安全加固:送审前先过脱敏门
- 9 -> Fail Closed:失败不是通过
- 10 -> Human Gate:为什么人必须保留最终裁决权
- 11 -> Task Shape:防止交付任务悄悄变平台工程
- 12 -> 一次任务的序列图
- 13 -> 怎么落地:从手动 MVP 到工程化
- 14 -> 什么时候不要用这套流程
- 15 -> 这套流程真正解决的不是“谁更聪明”
- 16 -> 最后:对抗式开发不是制造摩擦,而是控制风险

1 -> 为什么需要“对抗式开发”
很多人第一次把 AI 接进开发流程时,会自然走向一种模式:
给 Agent 一个需求,让它读仓库、写代码、跑测试、总结结果。
这个模式短期很爽,但一旦任务复杂起来,问题会迅速暴露:
- 它可能读错上下文;
- 它可能为了完成任务而过度修改;
- 它可能把失败解释成成功;
- 它可能遗漏安全、权限、数据、迁移风险;
- 它可能把未经脱敏的 diff、日志或配置发给外部模型;
- 它可能让人误以为“AI 说通过了,所以可以合并”。
核心问题不是 AI 不够聪明,而是:
单 Agent 流程把“实现、审查、判断、证明”都压在同一个角色身上,天然缺少制衡。
所以我更倾向于把 AI 开发流程设计成“对抗式”:
Codex 负责实现,Claude Code 负责只读审查,人类保留最终裁决。
这不是让两个 AI 互相吵架,而是把不同角色的职责边界切清楚。
2 -> 单 Agent 直写 vs 对抗式双模型
| 维度 | 单 Agent 直写 | Codex + Claude Code 对抗式 |
|---|---|---|
| 角色 | 一个 AI 同时实现和自证 | Codex 实现,Claude 只读审查 |
| 审查独立性 | 弱,容易自我合理化 | 强,审查方不改代码、不读仓库、不跑工具 |
| 上下文来源 | Agent 自己探索 | Codex 提供计划、diff、验证结果 |
| 风险控制 | 依赖 Agent 自觉 | 有脱敏门、JSON 契约、Human Gate |
| 失败处理 | 容易被包装成成功 | quota、schema error、空输出都 fail closed |
| 人类角色 | 最后看一段总结 | 关键节点确认计划、裁决争议、决定合并 |
一句话:
对抗式开发的目的不是让流程更复杂,而是让复杂任务中的风险更可见、更可审、更可裁决。
3 -> 三个角色:实现方、审查方、最终裁决者
3.1 -> Codex:实现方
Codex 的职责是:
- 读仓库;
- 理解需求;
- 制定计划;
- 写代码或文档;
- 跑测试、lint、typecheck、构建;
- 整理 diff 和验证结果;
- 裁决审查反馈。
它是主动推进任务的人。
3.2 -> Claude Code:审查方
Claude Code 的职责是:
- 只做只读审查;
- 不读仓库;
- 不改文件;
- 不跑工具;
- 不复用历史会话;
- 只看 Codex 提供的脱敏输入包;
- 输出固定 JSON 审查结果。
它是对抗式验证者,不是第二个实现者。
3.3 -> 人类:最终裁决者
人类负责:
- 确认最终计划;
- 裁决 P0/P1 争议;
- 决定是否合并;
- 决定是否发布;
- 决定是否使用生产凭据;
- 决定是否进行客户沟通或真实外发。
核心原则:
两个 AI 都满意,不等于代码正确;合并和发布决策权永远在人。
4 -> 一次完整对抗式开发流程
这个流程有几个关键点:
- 先计划,后实现:非简单任务不能上来就改代码。
- 先审计划,再审 diff:避免方案方向错了还继续实现。
- 审查方只读:不允许两个 AI 同时改同一份代码。
- Codex 裁决反馈:Claude 不是老板,审查意见要和代码事实对齐。
- 人类确认计划:尤其是架构、权限、迁移、生产路径。
- 失败不等于通过:Claude 超限、schema 错误、空输出、脱敏阻断,都不能算审查通过。
5 -> 不是所有任务都需要重流程
对抗式开发不是“所有事都上重流程”。它更适合非简单任务和高风险任务。
| 任务类型 | 推荐处理方式 |
|---|---|
| 简单问答、低风险解释 | 直接回答 |
| 单文件小改、格式整理 | Codex 直接做,简单验证 |
| 多文件改动、用户可见行为变化 | 走完整对抗式开发 |
| 架构、迁移、CI/CD、自动化变化 | 走完整对抗式开发 |
| 认证、权限、支付、数据删除、隐私、密钥处理 | 必须走高风险流程 |
| 安全方案、长期规范、审查门禁设计 | 至少走轻量对抗分析 |
| 模糊场景 | 默认按高风险处理,先分析再决定 |
可以用一个简单路由图判断:
6 -> 审查不是聊天,而是结构化契约
如果审查只是自然语言聊天,很容易出现三个问题:
- 审查结论模糊;
- 问题优先级不清;
- 无法稳定自动化处理。
所以方案里把 Claude 的审查输出固定成 JSON 契约。
一个简化版结构可以长这样:
{
"schema_version": "1.0",
"review_input_quality": {
"status": "sufficient",
"missing": []
},
"request_satisfaction": {
"status": "satisfied",
"notes": []
},
"approach_assessment": {
"status": "reasonable",
"notes": []
},
"risks": {
"security": [],
"regression": [],
"test_gap": [],
"other": []
},
"findings": [
{
"priority": "P1",
"title": "缺少关键验证",
"evidence": "验证结果没有覆盖核心路径",
"recommendation": "补充对应测试或手工验证"
}
],
"recommended_decision": "fix_before_merge"
}
这里最关键的不是字段名,而是审查顺序:
- 是否满足用户请求;
- 方案是否合理,有没有过度或不足;
- 有没有 bug、回归、安全、测试风险;
- 输入是否足够,不够就明确说不够。
7 -> P0 / P1 / P2:让问题有优先级
| 优先级 | 含义 | 处理方式 |
|---|---|---|
| P0 | 必须修。数据损坏、安全漏洞、无法构建、核心功能不可用、未脱敏外送密钥或 PII | 不修不能继续 |
| P1 | 应该修。明确回归、缺关键测试、边界情况明显破坏、计划明显不足 | 默认修,争议升级人类 |
| P2 | 建议修。可维护性、可读性、局部设计质量、低风险流程改进 | Codex 可采纳或说明不采纳 |
这套优先级的价值是:
不让审查意见混成一团,也不让“建议优化”误伤交付节奏。
P0/P1 必须有证据、位置、失败模式和建议修复方式。没有证据的严重指控,不能靠语气变成阻塞项。
8 -> 安全加固:送审前先过脱敏门
对抗式开发里最容易被忽略的是:审查输入本身可能带风险。
你把 diff、日志、配置、测试数据发给外部模型之前,必须先问:
这里面有没有密钥、客户数据、PII、生产路径、内部链接、提示注入内容?
安全加固版方案里最重要的一条是:
送审前必须 fail closed。命中高风险内容就中止,而不是带病送审。
| 风险点 | 处理方式 |
|---|---|
.env、私钥、证书、密钥文件 |
不外送 |
| token、api key、password、带口令连接串 | 命中即中止 |
| 邮箱、手机号、卡号等低置信 PII | 打码 |
| 客户数据样本 | 不外送或抽象化 |
| 验证日志过长 | 截断,只保留必要头尾 |
| diff 或日志中的提示注入 | 作为不可信数据包裹 |
| 脱敏无法完成 | 审查失败,不算通过 |
可以把它理解成一道门:
9 -> Fail Closed:失败不是通过
很多流程出问题,不是因为没有审查,而是因为“审查失败被当成通过”。
在这套方案里,下面这些情况都不能算通过:
| 失败类型 | 处理方式 |
|---|---|
| Claude quota / rate limit / 429 | 不自动重试循环;标记为 need_more_context |
| 空输出 | 不算通过 |
| JSON schema 校验失败 | 不算通过,可有限重试 |
| 脱敏阻断 | 不算通过,必须清理输入或换安全摘要 |
| 审查方权限不安全 | 不算通过 |
| 审查输入不完整 | 不算通过 |
高风险任务里,如果 Claude 到限额,不能说“那就算过了”。正确做法是:
- 暂停;
- 等额度恢复;
- 或由人类确认备用审查方;
- 或明确降级路径和残余风险。
这就是 fail closed:
系统不确定时,默认不放行。
10 -> Human Gate:为什么人必须保留最终裁决权
对抗式开发不是把决策权交给两个 AI。
Human Gate 的边界必须非常硬:
| 事项 | 决策权 |
|---|---|
| 合并到主分支 | 人 |
| 部署或发布 | 人 |
| 使用生产凭据 | 人 |
| 对客户外发 | 人 |
| 重大范围变更 | 人 |
| P0/P1 争议 | 人 |
| 是否接受 reviewer 降级 | 人 |
为什么?
因为 AI 可以帮助发现问题、生成方案、提出风险,但它不承担业务后果。
Claude 说 proceed,不等于可以合并。Codex 说修好了,也不等于可以发布。最终责任必须由人确认。
11 -> Task Shape:防止交付任务悄悄变平台工程
方案里还有一个很实用的分类:Task Shape。
| 类型 | 定义 | 风险 |
|---|---|---|
| Delivery-shaped | 目标是完成一个具体交付 | 容易被 AI 扩大范围 |
| Platform-shaped | 目标是沉淀工具、协议、基础设施 | 容易过度设计 |
为什么要分?
因为 AI 很容易把一个简单交付任务,顺手改造成“平台升级”。
例如用户只是要修一个功能,AI 却开始重构协议、改自动化、加框架、动 CI。这些不一定错,但必须经过人确认。
原则是:
delivery-shaped 任务不能未经确认变成 platform-shaped 工作。
这条规则能防止“看起来很专业的过度工程”。
12 -> 一次任务的序列图
这个图里最重要的一点是:Claude 不直接接触仓库,Codex 不把 Claude 的结论当圣旨,人类不放弃最终判断。
13 -> 怎么落地:从手动 MVP 到工程化
不要一开始就把这套流程做成很重的平台。更实际的路径是四步:
13.1 -> 第一步:手动 MVP
先让 Codex 在对话里严格执行:
- 只读探索;
- 输出计划;
- 送 Claude 计划审查;
- 裁决反馈;
- 请求人类确认;
- 实现并验证;
- 送实现后审查;
- 修复有效问题。
这一步的目标不是自动化,而是先验证流程有没有价值。
13.2 -> 第二步:持久化规则
把关键规则写入项目级或全局的指导文件,例如:
- 什么时候必须走对抗流程;
- Claude 必须只读;
- 送审前必须脱敏;
- JSON schema 必须固定;
- Claude 失败不能算通过;
- 人类保留哪些闸门。
这可以避免长上下文、换会话、压缩上下文之后流程遗忘。
13.3 -> 第三步:包装审查入口
用统一入口封装 Claude 调用,避免每次手写命令时漏掉:
- fresh session;
- no tools;
- JSON schema;
- effort max;
- 脱敏检查;
- 日志归档;
- schema guard;
- 失败码处理。
这里不建议在博客里直接复制内部脚本。更好的方式是说明原则:
能被脚本强制的,不要靠人记忆。
13.4 -> 第四步:审查产物归档
每次审查都应该留下可追溯产物:
- 审查阶段;
- recommended decision;
- P0/P1/P2 数量;
- 关键问题;
- 模型信息;
- 原始 JSON 路径或无文件说明;
- 脱敏和截断说明;
- 验证命令和结果。
这样后续出了问题,团队能回看当时到底审了什么、漏了什么、谁做了决策。
14 -> 什么时候不要用这套流程
对抗式开发不是银弹。
不适合的场景:
- 简单事实问答;
- 低风险格式整理;
- 很小的单文件改动;
- 用户明确要求跳过外部审查;
- 时间极端紧急且风险很低的热修。
但跳过也要有边界:
简单任务可以轻流程,但不能把高风险任务伪装成简单任务。
尤其是这些场景,不要裸奔:
- 权限;
- 隐私;
- 密钥;
- 支付;
- 数据删除;
- 生产核心路径;
- CI/CD;
- 自动化;
- 迁移;
- 客户数据;
- 对外发送。
15 -> 这套流程真正解决的不是“谁更聪明”
很多人会把多模型协作理解成:
让一个模型写,让另一个模型挑错。
这只是表层。
更深的一层是:
把实现、审查、证明、裁决拆成不同责任,让每一步都有输入、有输出、有边界、有失败处理。
Codex 的价值在于推进任务,Claude 的价值在于独立审查,人类的价值在于判断和承担责任。
所以这套流程的核心不是“两个 AI 比一个 AI 强”,而是:
一个可审计、可复用、可失败关闭的人机协作系统,比一个全能但不可控的 Agent 更适合复杂工程。
16 -> 最后:对抗式开发不是制造摩擦,而是控制风险
如果任务很简单,这套流程当然显得重。
但当任务涉及多文件、架构、权限、隐私、生产路径、自动化、长期规范时,流程本身就是质量保障。
我对这套方案的理解可以压缩成四句话:
Codex 负责把事情做出来。
Claude 负责从另一个角度挑战它。
脱敏门负责保证不把不该发的东西发出去。
Human Gate 负责把最终责任留在人手里。
对抗式开发不是让 AI 互相否定,而是让 AI 的能力在边界内发挥作用。
真正值得追求的不是“AI 自动完成一切”,而是:
让复杂任务在 AI 推进、AI 审查、人类裁决之间形成稳定闭环。
更多推荐


所有评论(0)