3 minute read

我把 Codex 变成了一个多模型代码审查团队

GPT 负责调度,Kimi、MiniMax 和 Pi 分别担任专业审查员

过去使用 Codex 进行代码审查,通常是把代码、分支或 Pull Request 交给同一个模型。

它负责理解改动、发现问题、判断严重程度,最后再生成审查报告。

这种方式足够简单,也很容易使用,但它存在一个明显的问题:

从发现问题到验证问题,所有判断都可能来自同一个模型。

如果模型第一次阅读代码时忽略了某个风险,它在第二次检查自己的结论时,也可能继续忽略同一个风险。

随着 Codex 对自定义 Subagent 的支持逐渐完善,我们可以采用一种更接近真实软件团队的工作方式:

Codex 主 Agent
负责理解任务、拆解范围和调度流程

Kimi Code Reviewer
负责独立代码审查

MiniMax Code Reviewer
负责从另一个模型视角检查缺陷

Pi Code Reviewer
调用独立审查器提出候选问题,再逐条验证

最终形成的已经不再是一个模型独自完成全部工作,而是一套由主 Agent 统一调度的多模型代码审查系统。

🚀 本篇笔记所对应的视频:


一、为什么要让不同模型担任不同角色?

多模型系统的意义,并不是简单地让三个模型重复检查同一份代码。

如果只是把同一个 Prompt 同时交给多个模型,再把结果拼接起来,通常只会产生大量重复内容。

更有效的做法,是先为每个 Agent 设定清晰的职责边界。

例如:

Agent 主要职责
主 Agent 确定审查范围、创建子 Agent、汇总与验证结果
Kimi Reviewer 独立检查正确性、安全性、并发和兼容性问题
MiniMax Reviewer 从另一个模型视角补充代码缺陷和测试风险
Pi Reviewer 调用独立审查流程,并验证候选问题是否真实存在

这样的设计有两个直接价值。

第一,减少单一模型的盲区

不同模型的训练数据、推理方式和代码偏好并不完全相同。

同一个问题可能被 GPT 忽略,却被 Kimi 或 MiniMax 发现。

多模型不能保证一定正确,但可以扩大审查覆盖面。

第二,把“发现问题”和“确认问题”分开

一个模型提出问题,并不意味着这个问题可以直接写进最终报告。

更可靠的流程应该是:

第三方模型提出候选问题
          ↓
主 Agent 重新打开对应代码
          ↓
检查触发路径与实际影响
          ↓
必要时运行测试或静态检查
          ↓
确认后才进入最终报告

也就是说,其他模型负责提供新的观察角度,主 Agent 负责最终证据校验。


二、整体架构:主模型保持不变,第三方模型只服务于专用 Agent

这套系统中最重要的设计原则,是把主 Agent 和第三方 Subagent 的模型配置彻底分开。

整体结构如下:

用户任务
   ↓
Codex 主 Agent
   ├→ Kimi Code Reviewer
   ├→ MiniMax Code Reviewer
   └→ Pi Code Reviewer
          ↓
   汇总、去重与验证
          ↓
       最终报告

主 Agent 继续使用默认的 OpenAI 模型,负责:

  • 理解用户任务;
  • 确定代码审查范围;
  • 选择需要调用的 Reviewer;
  • 等待子 Agent 返回;
  • 删除重复问题;
  • 验证问题是否成立;
  • 输出最终审查结果。

第三方模型则只绑定到指定的自定义 Agent。

例如,只有显式调用 Kimi Reviewer 时,任务才会被路由到 Kimi。

普通 Subagent 不会因为系统中注册了 Kimi,就自动切换到 Kimi 模型。没有明确指定 Agent 类型时,它仍可能继承主 Agent 的模型配置。

这可以避免一个非常危险的问题:

为了增加一个第三方 Reviewer,却意外把整个 Codex 主 Agent 都切换到了第三方模型。

因此,第三方模型的连接信息、模型目录和认证逻辑,都应该被限制在独立的 Provider 和 Agent 配置中,而不是放入主配置的全局层级。


三、代码审查 Agent 必须默认保持只读

代码审查和代码实现是两种不同的职责。

如果 Reviewer 在发现问题后立即开始修改代码,就容易出现以下情况:

  • 审查范围不断扩大;
  • 原始问题被修改操作掩盖;
  • 多个 Reviewer 同时编辑同一文件;
  • 主 Agent 无法判断问题来自原始代码还是新修改;
  • 审查任务悄悄变成实现任务。

因此,我为所有 Code Review Subagent 设置了相同的基本原则:

默认只读
不主动编辑文件
不创建提交
不扩大任务范围
不把风格偏好当成缺陷

Reviewer 应重点检查:

  • 明确的正确性错误;
  • 安全风险;
  • 数据丢失;
  • 并发与生命周期竞态;
  • 错误处理缺失;
  • API 或平台兼容性;
  • 具有实际影响的性能问题;
  • 重要测试缺失。

每一条问题还必须回答三个问题:

问题发生在哪里?
什么场景会触发?
会造成什么实际影响?

如果没有足够证据,就不应该为了让报告显得“有内容”而编造 Finding。

没有发现可执行问题时,直接说明没有验证到明确缺陷,反而更加可靠。


四、最容易踩坑的地方:跨模型任务交接

主 Agent 和第三方 Subagent 使用不同模型和 Provider 时,最大的难点往往不是模型路由,而是任务上下文如何传递。

在实测中,常见的上下文交接方式存在三种情况。

传递完整历史

看起来最保险,但完整历史可能同时携带父 Agent 的模型类型、角色状态和内部上下文。

对于自定义第三方 Agent,这可能导致:

  • Agent 类型继承错误;
  • 自定义模型配置没有生效;
  • 子 Agent 被当成父 Agent 的延续;
  • 第三方模型收到它无法理解的上下文。

完全不传历史

这种方式看似最干净,但第三方 Subagent 可能根本收不到当前用户的实际任务。

结果通常是:

  • 子 Agent 不知道应该审查什么;
  • 开始检查无关目录;
  • 根据仓库内容自行猜测任务;
  • 返回与用户要求无关的报告。

只传递当前任务轮次

在这次配置中,更可靠的方式是只让子 Agent 继承当前一轮任务。

这样既可以保留当前用户的明文要求,又不会把父 Agent 的完整历史、角色和模型状态全部带入子线程。

它解决的是一个非常实际的问题:

第三方模型必须知道“现在要做什么”,但不一定需要知道主 Agent 之前所有的思考过程。

这也是跨 Provider Subagent 能否稳定工作的关键。


五、还要防止 Subagent 递归创建 Subagent

当父任务中包含“创建 Reviewer 并执行审查”之类的描述时,第三方 Subagent 有可能把这条父级指令也当成自己的任务。

于是可能出现:

主 Agent 创建 Kimi Reviewer
       ↓
Kimi Reviewer 又尝试创建 Kimi Reviewer
       ↓
新的 Reviewer 继续创建 Reviewer

这会造成无意义的递归调用。

因此,每个专用 Subagent 的角色指令都应该明确:

直接执行被委派的任务,不要再次创建或委派给其他 Codex Agent。

在联调过程中,还应当让不同角色清楚自己的身份:

主 Agent:
负责创建子 Agent 并等待结果

Reviewer:
直接执行 Code Review,不再继续委派

在多 Agent 系统里,“你是谁”与“你应该做什么”同样重要。


六、三种 Reviewer 的职责应该怎样区分?

1. Kimi Code Reviewer

Kimi Reviewer 是一个独立的只读代码审查 Agent。

它适合检查:

  • 代码正确性;
  • 安全问题;
  • 数据丢失;
  • 并发与生命周期问题;
  • 错误处理;
  • 兼容性;
  • 重要测试缺失。

它的价值在于,为主 Agent 提供一个不同模型的独立审查视角。


2. MiniMax Code Reviewer

MiniMax Reviewer 的职责与 Kimi Reviewer 类似,但使用不同模型。

同时保留两个 Reviewer,并不是为了证明哪个模型一定更强,而是为了观察:

  • 哪些问题两个模型都会发现;
  • 哪些问题只有一个模型发现;
  • 两个模型对风险等级是否存在分歧;
  • 是否出现大量重复或低质量 Finding。

如果两个 Reviewer 返回同一个问题,主 Agent 仍需要重新验证。

多个模型意见一致,只能提高关注优先级,不能直接代替证据。


3. Pi Code Reviewer

Pi Reviewer 的设计更特殊。

它本身仍然由主模型运行,但会调用一个受限、只读的 Pi 审查器,让 Pi 使用另一个模型进行第二轮独立审查。

其工作流程是:

Codex Reviewer 确定审查范围
          ↓
调用只读 Pi Reviewer
          ↓
Pi 返回候选问题
          ↓
Codex 逐条重新检查代码
          ↓
确认或否决每一条候选问题
          ↓
只报告通过验证的问题

这里最关键的原则是:

Pi 的输出只是审查证据,不是最终答案。

Pi 返回的问题必须被重新打开、重新定位和重新验证。

需要删除:

  • 纯风格建议;
  • 重复问题;
  • 没有代码证据的猜测;
  • 超出审查范围的问题;
  • 无法复现的影响;
  • 与当前 diff 无关的旧问题。

这种结构比直接转发 Pi 的回答更加可靠,因为它形成了“外部发现—本地验证”的两阶段流程。


七、不要用一条 Warning 判断路由是否成功

自定义模型接入 Codex 时,终端可能出现模型元数据相关的 Warning。

很多人看到 Warning 后,会立刻认为第三方模型没有真正运行。

但模型目录警告和模型路由失败是两件不同的事情。

判断 Subagent 是否真的使用了指定模型,应同时检查:

  • 子线程记录的模型名称;
  • 子线程记录的 Provider;
  • 自定义 Agent 的角色名称;
  • 子 Agent 是否能够真实调用允许的工具;
  • 本地代理是否记录到相应模型请求;
  • 上游请求是否成功返回。

也就是说,不要只看终端里的一行提示。

真正可靠的判断来自完整的运行链路:

Agent 角色正确
+
模型正确
+
Provider 正确
+
工具调用真实发生
+
请求日志匹配

八、本地代理最常见的问题,不一定来自模型

当第三方模型通过本地代理接入 Codex 时,还需要注意系统网络环境。

如果系统启用了全局 HTTP 代理,本来发往本机服务的请求,也可能被错误转发到外部代理。

表现通常是:

  • 本地服务明明已经启动,Codex 却无法连接;
  • 浏览器或终端测试结果不一致;
  • GUI 启动的程序与 shell 中表现不同;
  • 请求莫名超时或返回代理错误。

解决思路不是不断修改模型参数,而是先确认:

  • 本地回环地址已经排除在全局代理之外;
  • GUI 应用继承了正确的环境;
  • 本地模型列表接口可以直接访问;
  • 请求没有被其他代理软件接管。

这是本地 Agent Harness 中非常典型的一类问题:

看起来像模型错误,实际是网络路径错误。


九、配置被代理工具覆盖,比配置写错更难发现

另一类常见问题是:配置最初完全正确,但代理工具重启、切换 Provider 或重新接管后,主配置被自动重写。

结果可能是:

原本:
主 Agent 使用 OpenAI
Kimi 只用于指定 Reviewer

重启后:
主 Agent 也被改成 Kimi

这种错误非常隐蔽,因为用户可能仍然看到 Codex 正常运行,却不知道模型路由已经变化。

更可靠的做法是:

  • 明确谁是主配置的唯一事实来源;
  • 将第三方 Provider 限制在独立配置段;
  • 配置修改采用原子写入;
  • 重启后自动检查主模型;
  • 避免两个程序反复覆盖同一个文件;
  • 每次升级或切换 Provider 后重新执行烟雾测试。

如果确实需要自动修复配置,脚本应当具备幂等性:

无论执行一次还是执行多次,最终配置都保持相同。


十、如何验证多模型 Subagent 真的工作了?

仅仅看到主 Agent 输出一句“Kimi 已完成审查”,并不能证明 Kimi 真的运行过。

父 Agent 有可能根据已有上下文模拟一个看似合理的子任务结果。

因此,完整验证应至少覆盖以下几层。

第一层:配置语法

确认主配置和自定义 Agent 配置可以被真实解析器读取,而不是仅凭肉眼判断格式正确。

第二层:主 Agent 路由

发起一次真实任务,确认主 Agent 仍然使用预期的默认模型和 Provider。

第三层:第三方模型直连

绕过 Subagent 交接,直接测试第三方模型路由,确认本地代理能够收到请求并成功返回。

第四层:真实 Subagent 创建

由主 Agent 创建指定 Reviewer,并确认子线程中的:

  • Agent 角色;
  • 模型名称;
  • Provider;
  • 当前任务范围。

第五层:结果真实性

要求子 Agent 返回一个只有实际执行后才能获得的标记或证据。

例如:

  • 指定文件中的准确内容;
  • 独立工具调用结果;
  • 请求日志中的匹配记录;
  • 真实测试输出。

第六层:重启测试

重启代理工具和 Codex 后,再次确认:

  • 本地服务恢复;
  • 主模型没有被覆盖;
  • 第三方 Reviewer 仍然可以调用;
  • 已运行任务是否需要重新创建才能加载新配置。

只有这些步骤全部通过,才能说明系统不是“配置看起来正确”,而是真的完成了端到端路由。


十一、如何快速判断故障发生在哪一层?

第三方模型直接调用成功,但 Subagent 失败

说明模型连接和 Provider 大概率正常。

问题更可能出现在:

  • 父子任务交接;
  • 上下文传递;
  • Agent 类型;
  • 等待与结果回收机制。

Subagent 开始检查无关目录

通常说明它没有收到清晰的当前任务。

应优先检查上下文继承方式,而不是立刻修改模型参数。

请求曾经成功,后来出现上游繁忙

这通常属于上游容量问题。

不应直接把它判断为协议或本地代理配置错误。

代理重启后主模型发生变化

说明全局配置被代理工具重新接管。

应检查配置事实来源和重启后的覆盖逻辑。


十二、安全原则比配置技巧更重要

在接入第三方模型时,最容易被忽略的是凭据传播范围。

建议始终遵守以下原则:

  • API Key 只存放在专用凭据存储中;
  • 不把真实 Key 写入 Agent 配置;
  • 不把 Key 写入模型目录;
  • 不通过命令行参数传递 Key;
  • 不在测试输出中打印完整 Provider 配置;
  • 不把敏感配置截图发到公开平台;
  • 不向第三方 Reviewer 传递凭据文件和无关用户数据;
  • 一旦凭据出现在公共仓库或共享日志中,立即轮换。

尤其在使用 Pi 等外部审查器时,传递内容应严格限制在当前代码审查范围内。

对于大型 diff,可以只传递:

  • 变更文件列表;
  • 相关代码片段;
  • 明确的审查目标。

不要为了让模型拥有“完整上下文”,把整个用户目录、配置目录或凭据文件一起交给它。


结语

这套多模型代码审查系统,真正有价值的地方,不是 Codex 可以同时调用 Kimi、MiniMax 和 Pi。

而是我们开始把代码审查拆成不同责任:

主 Agent 负责调度
第三方模型负责独立发现
确定性工具负责验证
主 Agent 负责最终判断

这已经不再是简单的“换一个模型”。

它更接近一套小型的 Graph Engineering 工作流:

任务进入
→ 选择 Reviewer
→ 多模型独立审查
→ 汇总候选问题
→ 逐条验证
→ 删除重复和误报
→ 输出最终报告

但多 Agent 并不会自动带来更高质量。

真正决定系统可靠性的,仍然是:

  • 角色是否清晰;
  • 上下文是否正确传递;
  • 权限是否受到限制;
  • Finding 是否经过验证;
  • 路由是否可以被审计;
  • 失败能否被准确定位;
  • 凭据是否被严格隔离。

当这些基础工作真正做好之后,Codex 才不再只是一个独自工作的超级 Agent。

它开始变成一个能够调度不同模型、不同工具和不同审查路径的 AI 工程团队。

Comments