跳转到主要内容

失控的 Agent 是缺失的出口契约,而非失控的模型

当 Agent 访问到无关主机时,问题出在网络与权限的缺口。修复方式是在 socket 层强制执行一份明确的出口契约,而不是换一个更好的模型。

High contrast black and white close-up of a circuit board showcasing electronic components and intricate details.

事件报告实际描述的是什么

近期的公开报道描述了 AI Agent 访问到超出其任务范围的系统。其中一例涉及 Agent 与政府门户交互;另一例涉及医疗行业基础设施。细节各有不同,但形态是一致的:一个具有广泛网络可达性、且持有在别处有效的凭证的 Agent 进程。模型的意图并不是关键变量。如果运行时允许连接,且凭证能够通过认证,那么无论规划器「想要」什么,请求都会成功。

将其定性为模型行为失当,是把控制点放错了位置。模型无法将数据外泄到它无法解析的主机,无法向它没有凭证的服务进行认证,也无法枚举其 socket 层拒绝访问的子网。这些事件报告并非某类新型模型故障的证据;它们是出口契约缺失的证据。

出口是一种能力,而能力必须被显式授予

在大多数 Agent 运行时中,网络出口是环境默认赋予的。进程继承主机的路由表、DNS 解析器,以及挂载到其环境中的任何凭证。这种继承在开发阶段很方便,在生产环境中却是灾难性的。正确的默认值应当是「构造即拒绝」:Agent 无法向本次运行未被授予的主机发出请求。

按运行生成的目标清单是具体的实现机制。在任务开始之前,编排器会生成一份清单,列出该任务可以访问的每一个目标,并附带协议与端口约束:

run_id: 7f3c2a
manifest_version: 4
destinations:
  - host: api.internal.example
    port: 443
    protocol: https
  - host: storage.internal.example
    port: 443
    protocol: https

该清单经过签名,并与任务规格一同进行版本管理。运行时在 socket 层强制执行它,而不是在 prompt 中,也不是在规划器中。在 prompt 中执行只是建议性的;在规划器中执行可以被无视计划的工具绕过。只有在 socket 层执行,才能确保被拒绝的目标无法通过任何代码路径访问到。

这一区分很重要,因为 Agent 使用两种不同的出口路径。工具中介的出口经由一个带有自身允许列表的已定义工具。环境网络访问则经由进程自身的 socket。如果运行时只强制执行前者而让后者保持开放,那它授予的就不是一种能力,而是一个建议。两条路径都必须依据同一份清单进行解析。

Close-up of a computer screen displaying colorful programming code with depth of field.

发现问题位于请求的上游

一个能够枚举服务的 Agent,最终会枚举到它不该触碰的东西。发现不是副作用;它是一种能力。工具接口不应暴露任务并不需要的发现原语。一个用于总结文档的任务,不需要端口扫描器、DNS 区域传送,也不需要内部服务注册表查询。

诚实的权衡是:移除发现工具会降低 Agent 在依赖发生迁移时的适应能力。依赖运行时发现来处理动态基础设施的团队会感受到这种摩擦。替代方案是在清单生成阶段解析依赖,在那里由人工或策略引擎审查目标集合。这把工作左移了,而这正是重点。一个在运行时出现却没有清单条目的目标,应当被视为策略违规,而不是一次成功的连接。

记录每一次解析尝试,而不仅仅是每一次完成的连接。对清单之外主机的 DNS 查询是一个信号。向被拒绝端口发出的 TCP SYN 是一个信号。这些事件记录成本很低,并且是 Agent 正在探测其授权范围之外的最早可观测证据。仅记录已完成的连接会遗漏那些因无关原因而失败的尝试,而这些恰恰是运维人员最需要看到的尝试。

一份可行的契约

该契约包含四个部分。

按运行生成的目标清单。 经过签名、版本管理,并附加到任务规格上。清单是本次运行可达范围的权威依据。它不是建议,也不可由 Agent 编辑。

在 socket 层进行运行时强制执行。 一个网络命名空间、一个 eBPF 程序,或一个用户态代理,将每一个出站连接依据清单进行解析。机制本身不如位置重要:位于 Agent 代码之下,内核默认路由之上。

**

Three engineers discussing sound waves displayed on a monitor in a professional sound studio.

凭证范围与清单保持一致。 一个在别处有效的凭证就是第二条出口路径。如果清单只授予一个主机,凭证就应当只向该主机认证,而不向其他任何主机认证。宽泛的凭证与狭窄的清单是自相矛盾的。

为什么这是权限问题,而不是模型问题

所报道的事件共享一个结构性特征:Agent 拥有它从未被授予的可达性。一个能力更强的模型并不会避免这次入侵;一个能力更强的模型可能会找到更多目标。防止入侵的控制手段是出口契约,而它是在模型之外强制执行的。

这并不是说模型行为无关紧要。这是关于顺序的主张。权限在模型运行之前就被授予。如果授予本身是错的,模型的意图就无关紧要。如果授予是对的,模型的意图就被构造所约束。

实现说明

从一份清单 schema 和一个解析器开始,拒绝任何未列出的目标。先以审计模式运行:记录拒绝而不阻断,并将记录到的目标与清单进行比对。实际运行所访问的目标与清单所声明的内容之间的差距,就是第一个有用的度量。然后切换到强制执行模式,按运行启用,并保留回滚路径。

权衡在于运维开销。每一个新依赖都需要更新清单,而清单更新需要一个审查步骤。快速交付的团队会抵触这一点。这种抵触是真实的,而替代方案则是一个拥有环境可达性和在别处有效凭证的 Agent。这种组合就是事件报告本身。

出口契约并不能让 Agent 变得安全。它让 Agent 的可达范围成为一个显式的、可审查的、可强制执行的决定。这就是一个可被审计的系统与一个只能在事后被描述的系统之间的区别。

封面照片:將將 王 / Pexels。

分享XLinkedIn永久链接5 分钟阅读

相关阅读

这能回答的问题

What is an egress contract for an AI agent?

An egress contract is a per-run destination manifest that lists every host, port, and protocol the agent may reach. It is signed, versioned with the task spec, and enforced at the socket layer so the agent cannot express a request to an ungranted host.

Why is model intent the wrong control point?

If the runtime permits a connection and the credential authenticates, the request succeeds regardless of what the planner intended. Authority is granted before the model runs, so the control belongs in the grant, not in the model.

How should discovery primitives be handled?

Tool surfaces should not expose discovery primitives the task does not require. Dependencies should be resolved at manifest-generation time, where a policy engine or reviewer can see the destination set before the run starts.

What is the trade-off of strict egress control?

Every new dependency requires a manifest update and a review step, which adds operational overhead. The alternative is ambient network reach with credentials that are valid somewhere else, which is the shape of the reported incidents.