跳转到主要内容

Agent 出站预算:速率不等于可达范围

速率限制约束的是 agent 行动的速度,而非它能到达的地方。出站控制必须是一份目的地与能力预算,在代理层强制执行,并在每次运行后对账。

深色背景下带发光丝线的光纤电缆微距照片

语料库中的模式

在各类事故记录与事后复盘中,反复出现同一种特征:一个 agent 触达了某个活跃的第三方端点——政府门户、零售平台、消息通道——而操作者从未下达过这样的指令。公开讨论往往诉诸对齐(alignment)话语:模型想要某样东西,模型失控了。而运维层面的特征更狭窄,也更可处理。agent 解析出了一个不在其预期范围内的目的地,而周边的控制机制没有察觉,因为这些控制机制被设计用来约束流量,而非可达范围。

这一区分之所以重要,是因为它决定了究竟哪种控制手段能真正解决问题。如果故障源于对齐失败,那么修复手段是更好的策略或更好的 prompt。如果故障源于路由与可达范围,那么修复手段是一份出站预算,以一组目的地与能力的形式表达,并在 agent 框架之外强制执行。

为什么速率预算会漏掉它

速率预算限制的是单位时间内的请求数。这是一种从 API 网关继承而来的减载控制,其关注点是保护后端免受嘈杂客户端的干扰。它回答的是多少,而不是去哪里。

直接来看这个故障模式。一个发往非预期主机的、格式良好的 HTTP 请求,落在任何合理的速率预算之内。每分钟一个请求,是大多数操作者都会认为保守的速率预算;而它也足以在第三方系统上提交表单、发布消息或触发工作流。速率限制永远不会触发,因为流量微不足道。这个请求并不过量;它只是被发往了错误的地方。

混淆之所以产生,是因为速率限制与可达范围限制常常被一起部署,而且两者都位于网络边界附近。但它们属于不同的控制类别。速率限制是容量控制。可达范围限制是授权控制。容量控制在负载下会优雅降级;授权控制对每个目的地而言是二元的。把前者当作后者的替代品,就会让目的地集合处于不受约束的状态。

故障不在于流量。它在于可达目的地的集合,以及 agent 在每个目的地所持有的能力。

设计一份可达范围预算

Woman using a laptop in a server room with blue-lit server racks

可达范围预算是对一次 agent 运行可以触及的目的地类别的枚举,并绑定每个类别所允许的能力。它属于运行规格(run specification),而不是工具定义。

这一放置位置是刻意的。工具定义描述的是工具在一般情况下能做什么;运行规格描述的是这一次特定运行被允许做什么。如果可达范围声明在工具上,那么每一个加载该工具的运行都会继承该工具的全部可达范围,操作者也就失去了为特定任务划定范围的能力。如果可达范围声明在运行上,那么同一个工具可以在只读摘要任务下以狭窄预算加载,而在确实需要写入的任务下以更宽的预算加载。

一条预算条目将一个目的地类别与一组能力配对。目的地类别应当粗到可维护,又具体到有意义:一个内部文档主机、一个具名合作伙伴 API、一个公共数据源、一个消息通道。能力应当取自一个小的封闭词汇表,例如:

read-only fetch
authenticated write
form submission
file transfer (inbound)
file transfer (outbound)

词汇表应当是封闭的,这样预算才能被机械地比较和 diff。开放式的能力字符串会招致漂移。

有两个属性让这份预算在实践中可用。

第一,它在一次运行内是单调的。agent 可以收窄自己的可达范围——丢弃一个它不再需要的目的地类别——但未经新的授权事件,它不得扩大范围。收窄是安全操作,因为它只移除能力。扩大是特权操作,因为它增加可达范围,并且它应当产生一条可审计记录:谁授权了这次扩大、针对哪个目的地、针对哪种能力、在运行中的哪个时点。

第二,预算在运行开始前声明,而不是从观察到的行为中推断。一份从 agent 恰好Aerial view of a rooftop solar panel array capturing sunlight for renewable energy](/media/circuit-board-macro-5a0c33-e1886b.jpg)

预算的好坏取决于它被强制执行的那个点。三个强制执行点承担了大部分分量。

在出站代理处解析目的地,而不是在 agent 框架内部。 如果由框架强制执行可达范围,那么控制就与框架的工具调用路径、插件模型和版本耦合在一起。一次框架替换就会悄无声息地移除这项控制。位于 agent 运行时与网络之间的出站代理,无论请求由哪个框架产生,都能强制执行可达范围。代理解析目的地——主机、端口,以及在适用时解析后的地址——并在建立连接之前对照该运行声明的预算进行检查。agent 框架可以被替换,而无需触碰控制平面。

将拒绝记录为一等事件。 被拒绝的请求应当产生一条结构化事件,携带所请求的目的地、被拒绝的能力、运行标识符,以及本可放行它的那条预算条目(如果有的话)。拒绝不是需要被过滤掉的噪声;它们是某次运行试图超出其可达范围的首要信号。它们应当与成功请求一同可查询,而不是被埋在调试日志里。

每次运行后对账。 运行完成后,将观察到的目的地集合与声明的预算进行比较。出现偏差——触达了未声明的目的地,或行使了未授予的能力——就是缺陷。它应当像任何其他缺陷一样被分诊,找出根因并修复,而不是被当作一件奇闻记录下来。对账这一步,正是把预算从一份静态声明变成反馈回路的关键。

一个诚实的权衡

可达范围预算会牺牲运维灵活性。每一个新的目的地类别都是对运行规格的一次变更,这意味着在 agent 能够与一个新主机通信之前,需要经过一个变更管理步骤。在合法目的地集合确实开放的环境中——例如会沿着公共网络上的引用一路追踪的研究型 agent——严格枚举并不现实,操作者会忍不住声明一个宽泛的类别,比如公共互联网,只读。

这种诱惑并非致命,但应当被点名。一个宽泛的只读类别仍然约束了能力,而风险恰恰主要集中在这里:读取一个公共页面很少是有害行为,而提交表单或写入一个需要认证的端点则不然。这个权衡是真实的,但也是有边界的。另一种选择——完全不声明可达范围,用速率限制来充当授权——不是权衡;那是控制的缺位。

务实的立场是:从一份真正被强制执行的粗略预算开始,然后随着观察到的目的地集合趋于稳定而逐步收窄。一份会拒绝错误事物的粗略预算,比一份只存在于纸面上的精确预算更有用。

封面照片:Brett Sayles / Pexels。

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

相关阅读

这能回答的问题

Why is a rate limit not sufficient to control an agent's network reach?

A rate limit caps requests per unit time, which is a capacity control. A single well-formed request to an unintended host is within any sane rate budget, so the limit never engages. The failure is not volume; it is the set of reachable destinations and the capabilities held at each.

Where should an agent's reach budget be declared?

In the run specification, not the tool definition. Declaring reach on the tool means every run that loads the tool inherits the tool's full reach. Declaring it on the run lets the same tool operate under a narrow read-only budget for one task and a wider budget for another.

Why enforce reach at an egress proxy rather than inside the agent framework?

Framework-level enforcement is coupled to the framework's tool-calling path and version, so a framework swap silently removes the control. An egress proxy between the runtime and the network resolves the destination and checks it against the run budget regardless of which framework produced the request.

What should happen when an agent's observed destinations diverge from its declared budget?

Treat divergence as a defect. Reconcile the observed destination set against the declared budget after each run, and triage any undeclared destination or ungranted capability with a root cause and a fix, rather than noting it as a curiosity.