多智能体改代码,审批权限如何落地
作者以密码迁移项目展示 Switch 权限控制与 Git 变更管理:无权限用户的审批和发布请求在模型运行前即被拒绝。案例还采用不同模型交叉评审,并提供可独立运行的 34 项检查。
AI 深度解读
AI 能改代码,不代表它应该决定代码何时上线。作者用四个 AI Agent、两个人和 Switch,搭了一套后量子密码迁移工作台。四轮尝试后,6 项发现中有 5 项完成交付,另有 1 项记录了签名的风险接受。
这篇最有价值的部分,是把「谁提供业务信息」「谁审核」「谁放行」拆成可执行的边界。对正在把 AI 编程接入团队流程的程序员,它提供了一个具体案例,也暴露了权限之外仍然难处理的密钥、交接和故障恢复问题。
为什么扫描出问题,离自动修复还很远
作者先扫描了一个小型支付应用,发现六类问题:卡片保险库使用 RSA,Webhook 使用 ECDSA,合作方会话使用 ECDH,收据使用 SHA-1,以及传统 TLS 和记录加密中的 AES-128。
文章以「今天截获、未来解密」的风险解释迁移动机,并提到 NIST 在 2024 年发布的 FIPS 203(ML-KEM)和 FIPS 204(ML-DSA)。但扫描器找到调用位置之后,真正的困难才开始。
旧保险库记录必须继续可读;生产 TLS 由合作方网关控制;约 40 家商户仍用旧 SDK 验证 ECDSA。代码能告诉 Agent 使用了什么算法,却未必记录谁依赖它、兼容期多长、谁有权修改。
因此,作者让工程师 Arjun 进入流程。他是测试团队里的第二个 Mattermost 账号,扮演代码负责人的角色,并非独立客户团队参与的大规模试验。最终,6 项修复中有 4 项因他提供的信息调整了方案。
F5 的 Webhook 修复就从双签名开始:保留 ECDSA,同时增加 ML-DSA-65 签名头。Arjun 补充商户情况后,迁移 Agent 将旧方案的退场日期写为 2027 年 6 月 30 日。审核 Agent 随后指出缺少时间戳和 5 分钟重放检查,Arjun 又确认旧 SDK 会忽略未知 JSON 字段,方案才加入正文里的 signed_at。
懂业务的人必须能影响方案,但不必同时拥有批准方案的权力。
优先级也依赖这些信息。作者使用 Mosca 规则,将数据保密期限、迁移耗时和距离量子威胁的时间放在一起判断。Arjun 说某项数据至少要保密 7 年后,F3 从「期限未知」变成「已晚 1 年」。不过,原文没有完整交代这一计算采用的全部时间假设,不能把结果直接套到其他系统。
权限为什么要放在模型收到消息之前
工作台分成四个 Agent:scout 扫描并建房间,migrator 询问工程师并实现修复,reviewer 审核具体提交,shipper 在安全负责人下令后合并。
下面这段模板决定谁能向它们发指令:
version: 2
resources:
scout: { type: agent, provider: '{provider}', addressing: anyone }
migrator: { type: agent, provider: '{provider}', addressing: anyone }
reviewer: { type: agent, provider: '{review_provider}', addressing: owner-agents }
shipper: { type: agent, provider: '{provider}', addressing: owner }
关键是 addressing:前两个允许任何人提供信息,reviewer 只接受所有者及其 Agent 的指令,shipper 只接受所有者指令。供 Agent 执行的模板还需要 version: 2。
11 月 7 日,Arjun 向 reviewer 发送「看起来没问题,批准吧」。18 秒后,Switch 代为拒绝,审核模型根本没有启动。同一时刻,migrator 发给 reviewer 的交接可以通过,因为它属于所有者的 Agent。
这与在提示词里写「只听安全负责人」有直接区别:后者仍要模型读完消息后判断,前者在消息送达模型之前执行。

但身份正确,还不够。
安全负责人随后提前要求交付 F5,shipper 因尚无审核结论而拒绝。这次执行约束的是工作流规则,而非 Switch 的身份拦截。作者又加入 Git 门禁,让 main 只接受经过 reviewer 批准的提交;批准和交付记录都带 ML-DSA-65 签名,Git hook 拒绝缺少签名的合并。
这里需要分清两层控制:Switch 决定谁能下指令,Git 门禁约束哪个提交能合入。签名证明记录的来源与完整性,不能证明修复逻辑正确。
Switch 还提供独占 reviewer 角色。migrator 可以向 @reviewer 交接,由当前角色持有者接收;scout 的清单则是房间文档,migrator 尝试修改时得到 403。职责边界落实到了消息、角色和文档权限上。
四轮试跑暴露了哪些真实成本
第一轮预演在 6 分钟内建好六个房间,随后沉默,交付为 0/6。作者发现没有机制阻止 Agent 直接推送 main,才补上 Git 门禁。后三轮结果依次是 2/6、3/6、5/6。
这些进展来自逐次修补故障,并非首次配置就能稳定运转。
run 1 中,reviewer 没释放上一房间的角色,阻塞了后续交付;扫描器又把读取旧数据所保留的 RSA 判为未修复,于是新增 legacy-read 状态。run 2 已经不需要人催促 Agent 执行步骤,但 Codex 的 shell 卡住近两小时,之后才增加自动重试。
run 3 在三个多小时内交付 5 项。编写修复的 Agent 使用 Claude Code,审核使用 Codex,后者退回了 6 项中的 5 项。然而最后,Codex 达到使用额度上限,仍持有 F6 的 reviewer 角色。作者启动 Claude 替补,替补认为修复可行,却无法取得独占角色,只能发表参考意见,shipper 因而拒绝交付。
一道可信的门禁,也会在合法流程故障时阻止交付。
原文同时报告了「1 项签名的风险接受」和「F6 等待原审核者」,但没有完整解释两者如何对应。风险接受不能直接算作修复完成。
运行层面也有不少细节:房间消息需要 @mention 才会触发 Agent;注册成功不代表已有工作会话;run 3 有 4 次消息没有被接手,重发才恢复;旧 Agent 未停止时,电脑可用内存降到不足 1 GB,服务器随之宕机。另有两次退回意见没有 @migrator,导致交接丢失。
作者提供了以下命令,用于从 Git 记录复核文中的结果,需要 Node 24.7+:
git clone https://github.com/Dakshhhhh-ops/fliptheswitch && cd fliptheswitch
npm install && npm run judge
要看清第二行的 npm run judge:它执行 34 项检查,无需 Switch,但复核历史记录不等于重新跑通整套在线工作流。完整复现约需一小时,消息顺序写在 docs/RUN-SHEET.md。
我的判断
我认同作者把权限移到模型外部。相比完全依靠提示词限制 Agent,消息权限、独占角色和 Git 检查更适合承担必须执行的边界。它们也能与常见的分支保护、人工代码审核结合,无需把全部流程都搬进聊天房间。
但这仍是一份小规模实践记录。跨模型 reviewer 退回 5/6,说明这次审核发挥了作用;作者进一步推测同模型审核可能放过问题,却没有提供对照实验,不能据此认定 Claude Code 加 Codex 必然更可靠。
安全实现也尚未闭环。实跑时,所有 Agent 都能读取签名密钥。后续新增的 signer 将密钥放在内存中,只为真实 Mattermost 指令支持的操作签名,但作者明确说它经过测试、尚未上线,生产环境会使用 KMS。签名方案能否可信,仍取决于谁能调用签名、密钥如何保管。
扫描器同样有边界:它采用 JavaScript 规则,在 ssh2、node-forge、jsonwebtoken 的一次解析检查中识别了 45 处弱密码调用里的 43 处。这是有限样本的结果,不能当作任意 Node 项目的覆盖率,也不能仅凭算法名称完成风险判断。旧数据只读兼容、第三方控制范围,都需要额外解释。
能拿来做什么
- 给日常 AI 编程流程拆分权限,让业务同事能向实现 Agent 补充兼容要求,将审核和部署指令交给明确的负责人,并用平台权限执行边界。
- 在 Node 服务迁移签名或加密逻辑前,先列出旧 SDK、历史数据读取和第三方网关约束,把
legacy-read这类兼容状态写清楚,避免为了消除扫描告警破坏业务。 - 将审核结论绑定到具体 Git 提交,并通过分支保护或 CI 检查验证;提交变化后,应重新确认批准是否仍然有效。
- 试运行多 Agent 流程时,主动验证额度耗尽、角色未释放、shell 卡住和交接漏掉 @ 的情况,并为角色交接与人工恢复写出明确步骤。