跳转到主要内容

沙箱契约:Agent 在触碰生产端点前必须证明什么

Agent 的围堵是一份权限与验证契约,而不是一条 guardrail prompt。每个工具边界都需要一个 agent 在运行时无法协商的前置条件。

数据中心内服务器机架的近景,展示网络线缆、指示灯和配线架。

失败模式:能力被授予,意图未被验证

这是一种反复出现的模式。一个 agent 被授权浏览某个系统,然后对它执行操作。或者它被授权读取一条记录,然后写入了一条。大多数事件就发生在这个缺口里——agent 被授予的动词与它实际执行的动词之间。授权通常是隐式的:一个具有读写范围的凭证,一个带有通用 http_request 签名的工具,一个能触达网段内任何东西的服务账号。意图通常是未经验证的:不存在任何产物能表明“这个特定的调用、针对这个特定的端点、带着这个特定的 payload,在离开进程之前已被检查过”。

事后日志无法弥合这个缺口。日志告诉你发生了什么;它们不会拒绝调用。如果 agent 与生产端点之间唯一的控制措施是系统提示里的一句话,那么这个控制就是建议性的。一个处于分布偏移下的模型、一个由检索到的文档携带的 prompt injection,或者一个已经漂移的 planner,都会把建议当作可选项。拒绝必须发生在一个 agent 无法争辩的地方。

沙箱契约有四个条款

沙箱契约是附加在工具边界上的、机器可校验的前置条件。它不是一份策略文档,也不是一条 prompt。它有四个条款,且四个条款都在模型之外强制执行。

范围

范围是 agent 可以使用的端点和动词的确切集合,以允许列表的形式表达。拒绝列表会失败,因为它必须枚举每一个危险操作,而危险操作的空间是开放式的。允许列表则默认拒绝:任何未被命名的都被拒绝。具体来说,范围是一组形如 (method, host, path-pattern, credential-id) 的元组,在请求被构造之前进行匹配。一个暴露自由格式 URL 的工具是没有范围的;它是一个多了几步的代理。

速率与爆炸半径

Close-up of a colorful business chart on a table with documents showing trends

速率是每个窗口内允许的调用次数,爆炸半径是首次异常时会发生什么。这两者应当放在一起,因为缓慢泄漏和突发爆发是不同的失败模式。契约应当为每个端点类别指定一个 token bucket,并在首次契约违规时硬停止,而不是软警告。诚实的权衡是:严格的限制会破坏合法的批处理工作,所以团队最终会采用少量预先批准的批量操作,各自携带自己的契约,而不是一个要么松到无意义、要么紧到无法使用的全局速率。

可逆性

工具能执行的每一个操作都应被归类为幂等、可补偿或禁止。幂等操作(读取、查找)可以自由重试。可补偿操作(可被删除的创建、可被撤回的消息)需要一条经过测试而非假设的、定义明确的补偿路径。禁止操作(不可逆的付款、凭证轮换、批量删除)绝不委托给 agent,无论 planner 有多自信。正是这一条款把“agent 犯了个错”从一次事件转变为一次回滚。

证明

证明是 agent 在下一步被解锁之前必须返回的证据。这是大多数团队会跳过的条款,也正是它让契约成为契约,而不是一个过滤器。在写入被提交之前,agent 返回一条结构化记录:契约 id、解析后的端点、payload 的哈希、dry-run diff,以及所用凭证的身份。网关根据契约校验该记录,只有通过后才为真实调用签发凭证。没有证明,网关可以强制执行范围,但无法区分一个计划中的操作和一个被劫持的操作。

这在技术栈中的位置

在工具网关处强制执行,而不是在系统提示里。Prompt 是建议Industrial plant with large tanks and chimneys against a lush mountain backdrop。

Server rack closeup

把出站流量控制和凭证签发当作两个独立的决策。出站控制回答的是“这个进程能否打开到该主机的连接?”凭证签发回答的是“这个特定的请求能否获得一个该主机会接受的 token?”将两者分开意味着一个被攻陷的 planner 无法扩大自己的范围:它或许能触达某台主机,但无法为契约之外的操作获得凭证。这就是网络策略与能力系统之间的区别,也是大多数 agent 框架目前做错的地方。

为每一份被接受的契约保留一份签名记录。当事件真的发生时,复盘应当是一次查询,而不是一个考古项目。一份签名的、仅追加的日志,记录契约 id、agent 身份、证明哈希和决策(允许/拒绝),让你能够确定性地重建这次运行。它也让你能够回答监管者和事件响应人员真正会问的问题:不是“模型说了什么?”,而是“这个 agent 被允许做什么,以及它在做之前证明了什么?”

团队本季度应该做什么

枚举 agent 能调用的每一个工具,并将每个标记为读取、写入、花费或发布。 这是一次坐下来就能完成的练习,通常会揭示出比任何人预想都更多的能力。这个分类驱动契约:读取类工具获得范围和速率;写入、花费和发布类工具额外获得可逆性和证明。

对于写入和花费类工具,要求在提交前有 dry-run 模式和一个人类可见的 diff。 dry-run 必须走与真实调用相同的代码路径,只是把提交步骤打桩。diff 是人类或自动化检查器所审查的产物。如果一个工具无法产出 diff,它就不适合被委托。

演练一次围堵演习:在运行中途吊销一个凭证,并确认 agent 默认拒绝。 预期行为是干净地停止并给出一个带类型的错误,而不是一个反复冲击端点的重试循环,或一个找到另一个凭证的 fallback。这次演习成本很低,它演练的是网关而不是模型,并且它能揭示出一个默认拒绝的系统与一个仅仅记录失败的系统之间的区别。

Medicare 事件提醒我们,围堵不是模型的一种属性。它是边界的一种属性:一组明确的前置条件,由 agent 在运行时无法与之协商的基础设施强制执行。把边界当作设计单元的团队会发现,大多数 agent 事件不再成为事件,而是变成被拒绝的调用。

封面照片:panumas nikhomkhai / Pexels。

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

相关阅读

这能回答的问题

Why can't a system prompt enforce agent containment?

Prompts are advisory. A model under distribution shift, a prompt injection in retrieved content, or a drifted planner can ignore them. Refusal must happen at infrastructure the agent cannot negotiate with, such as a tool gateway that holds credentials and resolves endpoints.

What are the four clauses of a sandbox contract?

Scope (an allowlist of endpoints and verbs), rate and blast radius (calls per window and the hard stop on first anomaly), reversibility (idempotent, compensatable, or forbidden), and attestation (the evidence the agent returns before the next step is unlocked).

Why separate egress control from credential issuance?

Egress answers whether a process can reach a host; credential issuance answers whether a specific request gets a token the host will accept. Separating them means a compromised planner can reach a host but cannot obtain a credential for an action outside its contract.

What is a containment drill?

A rehearsal in which a credential is revoked mid-run and the agent is expected to fail closed: a clean stop with a typed error, not a retry loop or a fallback credential. It tests the gateway rather than the model.