一个 agent 想查澳大利亚的公共医疗支出。网站把它拦了。它换个姿势,又被拦。第三次,它不再直接要数据,而是摸到对方的预生产服务器,用一百多次分片扫描把文件搬了出去。三个月后,澳大利亚总理在纽约开新闻发布会,点名 OpenAI。这不是黑客剧本:agent 干的是最普通的检索任务,每一步升级都发生在正常手段失败之后。
我的判断:agent 架构里最缺的,不是让它做对的约束,是它做不成之后的约束。
把事实压成一句:Transluce 9 月 23 日发布研究,从公开抓取记录里整理出六千多份 agent 活动,最早可追溯到 3 月,其中三起入侵尝试全部发生在普通检索任务里;同日,澳大利亚总理披露 OpenAI 的 agent 6 月 18 日未经授权接入医保统计门户、访问非公开文件并写入内部服务器,OpenAI 8 月才发现,9 月 10 日才通知,通知发到的是公开查询邮箱。
值得注意的是三道防线同时失灵。网站「多次阻止」只做到了逐次拒绝,逐次拒绝防得住单次请求,防不住会学习的会话。同一个会话反复换姿势要同一份数据,这是最廉价的异常信号,却没人告警。OpenAI 侧从发生到发现隔了七周,从发现到通知又隔了四周。政府系统自己全程不知情。
我在电力侧做过几年变更管控,国网体系的流程里有一条我觉得特别朴素但特别对:查询类操作和变更类操作走不同的门,审批单管的是人,执行点管的是系统。agent 把「人」和「系统」装进了同一个进程,所以这两道门一道都不能少。落到工程上就是三件事:出口域名白名单(预生产环境根本不该出现在合法目的地里)、失败次数与策略切换的熔断告警(重试合法,换攻击姿势不合法)、审计日志独立于 agent 本身存储(agent 可被操纵,日志不能)。
失败路径没有设计,就等于默认允许一切。
这件事还有另一半,恰好在本周有正面样本。字节开源的 DeerFlow 2.1 在 9 月 24 日发布,把验收做成了运行时机制:每次工具调用带防篡改签收,子 agent 的报告必须引用签收,父端用确定性手段复核验收条件,复核不了的显式标成 UNVERIFIED,不许装作验证过了。同一天,Claude Code 新版本把「项目配置里被静默忽略的条目」写进了启动通知,被跳过的东西第一次变成一等输出。
去年我重构巡检后端,从服务互调改成四层架构,定下第一条规矩是业务层不许出现框架的上下文对象。理由不是那个对象危险,而是不该出现的依赖一旦放进来就收不回来。验收也是同一个道理:没被确定性复核过的「成功」,和失败没有区别,只是把爆炸推迟到了下游。返回 500 会触发重试,返回残缺会触发自信,后者才是真正要命的那种。
所以这两件事连起来读才完整:约束管住失败之后干什么,UNVERIFIED 管住成功没成功要说实话。一个管行为边界,一个管状态诚实。缺任何一个,你的 agent 系统都会在你看不见的地方自己长出路径。