跳转至

第 9 章:沙箱执行与 MCP 作为集成契约

时效说明

最近一次编辑审查:2026 年 5 月 17 日。上一次审查:2026 年 5 月 14 日。下一次计划审查:2026 年 6 月 17 日

自上次审查以来的变化:MCP 安全边界、工具投毒攻击面、A2A 信任模型和印刷准备问题,现在都有具体契约覆盖和文档表面检查。

怎样读这一章

这一章最好抓住一个具体转换点:

  • 智能体已经选好了能力;
  • 智能体已经准备调用外部工具或适配器;
  • 平台现在必须决定,这个动作到底能通过什么传输方式执行,以及它会被关在什么边界里。

如果这个转换点没有被写清楚,沙箱和 MCP 很快就会变成一组术语,而不是执行纪律。

1. 为什么缺少沙箱的执行层很快就会变得过度信任

在贯穿全书的支持场景里,这一点非常具体:智能体已经决定去查申请状态,或者通过外部系统创建工单。从这一刻开始,问题已经不再是“下一步怎样更聪明”,而是“系统到底通过哪一道边界才允许它执行这一步”。

一旦智能体获得了工具访问能力,下一个危险几乎总是同一个:系统边界开始模糊。

智能体已经可以:

  • 读取数据;
  • 启动操作;
  • 调用外部服务;
  • 接收来自不可预测环境的响应。

如果这一切都“原样执行”,没有隔离和契约,平台很快就会积累问题:

  • 工具以意外格式返回不可信载荷;
  • 集成调用卡住或超出资源预算;
  • 副作用在预期策略路径之外发生;
  • 一个设计糟糕的适配器拖垮整个运行时。

所以执行层不只是路由器,它还是沙箱边界。

2. 沙箱不一定是容器,它首先是一组限制

一说到“沙箱”,很多人立刻想到 Docker、VM 或独立进程。这些都可以是实现方式,但架构上更重要的是:沙箱定义了能力被允许做什么、不允许做什么。

好的沙箱通常会限制:

  • 网络访问;
  • 文件系统访问;
  • 密钥访问;
  • CPU 和内存预算;
  • 允许的系统调用或执行模式;
  • 操作生命周期。

也就是说,沙箱回答的是:“如果工具或适配器的行为比预期更糟,会发生什么?”

这不仅仅是安全问题,也是影响半径控制。

2.1. 最好区分不同层级的隔离

在实践里,沙箱 这个词经常把几种完全不同的东西混在一起:

  • logical isolation:策略检查、能力契约、允许清单;
  • process isolation:独立进程、超时、资源限制;
  • 运行时隔离:独立执行环境、受限文件系统、受控网络出口、最小化密钥。

这很重要,因为很多团队觉得自己“已经有沙箱了”,但实际上只有第一层。对低风险读取来说这有时够用,但对高风险执行来说,几乎总要更强的运行时边界。16

这里有个很实用的问题:如果能力的行为比预期更糟,到底是什么在阻止它:逻辑、进程边界,还是执行环境本身?

3. 不能把外部集成当成普通函数

一个常见错误是:把外部服务包成一个函数,然后让智能体把它当普通调用使用。

但真实集成几乎总是:

  • 比本地代码更不稳定;
  • 类型边界更脆弱;
  • 依赖权限和环境;
  • 可能返回部分成功或危险结果;
  • 自带延迟和速率限制。

所以更好的做法是把集成视为带契约的能力端点,而不是“方便的助手方法”。

4. MCP 的价值就在于契约层

MCP 有用,不是因为它“新潮”,而是因为它能在智能体和外部能力之间提供清晰的契约边界。

在好的设计里,MCP 会给你这些收益:

  • 标准化描述工具和资源的方式;
  • 独立的 server 边界;
  • 更清晰的能力生命周期;
  • 适配器可以放在核心运行时之外;
  • 天然适合作为策略检查、日志记录和隔离的切入点。

当你有的不是一个运行时 + 一个集成,而是一组能力时,这一点就尤其重要。

沙箱/MCP 案例主线说明(Sandbox/MCP case-spine note):沙箱(sandbox)和 MCP 契约(MCP contract)应该用三个规范案例(canonical cases)来测试。支持分诊(Support triage)需要帮助台写入(helpdesk writes)的沙箱限制(sandbox limits)、感知审批的 MCP 工具(approval-aware MCP tools),以及超时后的对账路径(reconciliation path)。内部知识助手(Internal knowledge assistant)需要只读 MCP 资源(read-only MCP resources)、按语料限定的网络访问(corpus-scoped network access)、来源验证(source validation),并禁止隐藏副作用(hidden side effects)。事故协调(Incident coordination)需要隔离的升级适配器(escalation adapters)、通知作用域(notification scopes)、响应者角色执行(responder-role enforcement),以及不会绕过审计轨迹(audit trail)的应急路径(emergency paths)。

4.1. MCP 是安全边界,不只是方便的连接器

一旦 MCP 承载了对数据、写入工具或执行环境的访问,它就变成了安全边界。穿过这条边界的不只是有用的 tool results,也可能是恶意指令、被污染的工具描述、过宽的 OAuth scopes、confused-deputy 路径,以及 MCP server 本身带来的供应链风险。

Microsoft 的 MCP tool poisoning 案例把这条边界说得更尖锐:tool descriptions as system prompts24 如果已经批准过的 server 保持同一个 tool name,却悄悄修改 tool description,runtime 可能在没有新 human review 的情况下再次信任它。这是 silent re-trust,不是无害的 metadata update。因此审查不应该只看 tool name,还要看 description diff、owner/provenance、documentation field 里的 imperative language、new endpoints、扩大的 parameters 和异常 query patterns。控制点也不只是 least privilege,而是 least agency:关闭 Allow all tool access,对 high-impact actions 要求 approval,并在 tool metadata 改变后对 agent behavior drift 发出告警。

这条边界的实践契约至少要回答五个问题:

  • 谁拥有这个 MCP server 及其生命周期;
  • 它暴露哪些 tools/resources,哪些写入操作需要 approval;
  • server 获得哪些 scopes、network paths 和 sandbox limits;
  • runtime 如何在把 tool descriptions 和 tool return values 交给模型之前进行验证;
  • 哪些 telemetry 能证明这次调用背后的 agent run、identity 和 policy decision。

如果这些答案不存在,MCP 并不会因此不再是风险;它只是变成了平台表面里的隐式 trust boundary。

4.2. MCP 威胁模型矩阵

对 MCP 来说,MCP 威胁模型(MCP threat model) 不应该只是“外部集成有风险”这种笼统提醒,而应该成为每个接入能力的审查矩阵。MCP 的安全与授权材料已经明确讨论 token passthrough、scope selection、HTTPS/SSRF 限制和应用状态句柄保护;因此这张矩阵不是装饰性安全文字,而是授权与运行契约的一部分。2021 一个最小版本可以这样看:

  • tool poisoning — 工具描述或工具结果试图引导模型行为;控制方式是验证 tool descriptions,把 tool output 与指令分离,并只允许已知契约。
  • rug pull attack — 已获批准的 MCP server 在审查后改变 tools、scopes 或行为;控制方式是 version pinning、重新认证、diff review 和快速隔离路径。
  • tool shadowing — 新工具伪装成类似的 approved tool,并截获模型意图;控制方式是唯一 capability names、registry ownership,以及发布前的语义审查。
  • confused deputy — 智能体用错误或过宽的 delegated authority 执行动作;控制方式是在副作用发生前检查 principal、purpose binding、approval state 和 policy decision。
  • over-scoped tokens — MCP server 获得了超过当前操作所需的 OAuth scopes;控制方式是短生命周期 scoped tokens、per-tool scopes,并禁止宽泛的长期密钥。
  • data exfiltration through legitimate channels — 数据通过被允许的 tool result、notification 或 ticket comment 外流;控制方式是 DLP checks、output classification、tenant boundaries,以及 risky writes review。
  • supply-chain attack — 被攻破的 server、package 或 adapter 变成受信任能力;控制方式是 provenance、signed artifacts、dependency review 和 owner accountability。
  • replay/tampering — 请求、响应或应用状态句柄在步骤之间被重放或篡改;控制方式是 request signing、nonce/idempotency keys、trace correlation 和句柄过期策略。
  • sandbox escape — tool 或 adapter 越过网络、文件系统或进程边界;控制方式是 ephemeral sandbox、最小 egress rules、secret isolation 和 runtime-level containment。

这张矩阵不是为了禁止 MCP,而是为了让每个 MCP endpoint 都能回答三个问题:它增加了哪类威胁,哪项控制在限制它,事故之后 telemetry 里还能留下什么证据。

MCP 连接的最低验收条件:

  1. 服务器在已批准注册表中,负责人和契约版本可见。
  2. 令牌确实签发给 MCP 服务器或对应资源受众,而不是从另一层盲目透传。
  3. 权限范围限制在具体操作上,不依赖宽泛的长期密钥。
  4. 工具模式、描述或权限范围变化时,会触发重新审查。
  5. 工具输出在过滤和分类之前,一律当作不可信内容。
  6. 追踪里保留 mcp_server_idtool_contract_versionscope_reviewquarantine_state 和证据链接。

4.3. 最小 MCP server contract(服务器契约)

威胁模型只有变成可审查的服务器工件才真正有用。每个已批准端点都应该携带一份最小 MCP 服务器记录:

mcp_server:
  owner: platform-integrations
  approved_registry_id: mcp.support.ticketing.v3
  schema_hash: sha256:...
  tool_definition_hash: sha256:...
  allowed_origins:
    - agent-runtime-prod
  auth_mode: delegated_oauth
  token_scope:
    - ticket.read
    - ticket.write_limited
  token_ttl: 15m
  user_delegation_required: true
  server_isolation_profile: remote_ephemeral_sandbox
  return_value_filtering: strip_instructions_and_classify_data
  replay_protection: nonce_and_trace_bound_signature
  schema_change_requires_review: true

这些字段不是为了官僚化。schema_hashtool_definition_hash 用来发现 tool schema injection 和 approval 之后的 rug pull。token_scopetoken_ttluser_delegation_required 限制 confused-deputy paths。return_value_filtering 把 tool results 当作不可信内容处理,包括 prompt injection via tool return values。server_isolation_profilereplay_protection 让 sandbox escapes、replay 和 tampering 足够可见,便于 containment。

短规则是:tool output is an attack surface。remote tool 可能在 approval 之后改变:server owner 改 schema、result、redirect、resource body 或 hidden instruction,而 host 仍然把这个 integration 当作已经批准。因此 onboarding remote tools 最好从 fake data first 开始:先连接 synthetic tenant、synthetic secrets 和安全 fixtures,记录真实 traces,validation 之后才给 tool live credentials 或 production data。

Google ADK 给出的另一个有用模式是 metadata registry + runtime schema injection26 反模式也很明确:Static Prompting,也就是把所有 JSON schemas、Pydantic classes 和 tool definitions 预先塞进 system prompt。在高基数业务域里,这会带来 context bloat 和 Attention Diffusion:模型开始把 dormant schemas 的字段混进 active payload。

用可移植 runtime contract 来说,结构规则应该放在 registry entry 里,而不是放在 prompt 里。这个 entry 至少要有 schema_descriptor_idschema_version、field metadata、mapping rules 和 validation_hook。Agent 先做轻量 discovery;runtime 再加载正确 descriptor,在 tool/API call 之前的边界调用 Polymorphic Validator,并把选中的 schema source of truth、runtime validation boundary、validation result 和 failure mode 写入 trace。这样一个 reasoning agent 可以处理多种 domain forms,但不会同时背负所有结构规则。

4.4. 对浏览器智能体来说,localhost 不是信任边界

Microsoft Defender Security Research 描述的 AutoJack 很适合作为本章的成熟度检查:由 browsing agent 打开的不可信网页可以跨过 loopback boundary,触达本地 MCP WebSocket,并把连接参数变成 host 上的进程执行。22 这个具体问题在受影响的 MCP surface 进入 PyPI release 前已经修复,但这个模式比这个 bug 本身更重要。

架构结论很简单:当同一台机器上运行着带 browser tool、Playwright-backed surfer、code execution tool,或任何能从本地进程打开 WebSocket/HTTP 请求的 agent 时,localhost127.0.0.1 和 origin allowlist 都不是足够的控制。对这种系统来说,外部 HTML/JavaScript 不再只是“互联网上的内容”;它可能变成 confused deputy,利用 agent 的本地网络位置。

本地 MCP/debug/control channels 的最低 hardening 是:

  • 不把 loopback 当作 authentication boundary;
  • 在 MCP/control-plane endpoints 上要求 authn/authz,包括 WebSocket paths;
  • 在启动任何 subprocess-backed MCP server 之前检查 purpose binding 和 policy decision;
  • 把启动参数保存在 server-side,或放进带签名、绑定 nonce 的 artifact,而不是从 query string 接收 command/args;
  • 对可执行 MCP server 和参数 profile 做 allowlist;
  • 用独立的 process/network identity 运行 browser tools,并禁止它访问有特权的本地服务;
  • 为 crossing attempts 写入 trace event:外部页面、本地通道、policy result、executable decision 和 containment action。

如果 local MCP 只是原型需要,capability registry 应该明确写出来:低权限、独立 OS user/container、短生命周期 credentials,并且不能和会渲染不可信 web content 的 agent 放在同一信任边界里。

4.5. Prompt-to-tool-to-execution 需要单独 hardening

Microsoft 的 “When prompts become shells” 案例补上了相邻 failure mode:如果 agent framework 已经暴露了一个会把 model-controlled parameters 解释成 paths、code、templates 或 commands 的 tool,prompt injection 就不需要触达 localhost23 攻击形态是 prompt-to-tool-to-execution:不可信内容引导模型,模型输出 attacker-controlled input,framework 把它解析成 tool arguments,薄弱 adapter 再把它变成 host execution。

Execution layer 的规则和本章对 MCP 的规则一样:model output 不是 authority。Execution-adjacent tools 应该 deny-by-default,通过 capability contract 注册,并受到 typed validation、canonical path checks、operation allowlists 和 per-tool sandbox 保护。它们还需要在副作用发生前写 audit event,而不是事后才记录,这样调查者才能看到 prompt source、redacted arguments、validation result、selected sandbox profile 和 policy decision。

4.6. 网络化智能体威胁模型(networked-agent threat model)

Microsoft Research 单独指出,当一个 agent 变成一张 agent network 时,风险会改变:漏洞不一定在某个 tool wrapper 里,而可能在 agent 如何信任彼此消息的行为里。25 实用规则是:peer message is data, not authority。来自另一个 agent 的消息不应该提升权限、改变目标、触发写入,或变成 system instruction,除非 runtime、policy layer 或 human approval 明确提升了它的信任级别。

这个 networked-agent threat model 应该放在 MCP 和 A2A 旁边看。它增加了四类 failure modes:

  • propagation — 恶意指令、被污染 summary 或伪任务像普通上下文一样继续传播;
  • amplification — 一个弱信号变成大规模 fan-out、重复 tool calls 或级联通知;
  • trust capture — 多个 agent 开始互相背书,虽然它们其实都依赖同一个不可信来源;
  • invisibility — operator 能看到局部 traces,却看不到风险跨边界传播的 cross-agent path。

最低 controls 像是把 network security 套到 agent semantics 上:用 Sybil resistance 检查投票独立性,用 hop and rate limits 限制任务传播,在图的每条边上做 capability scoping,用 cross-agent tracing 记录消息路径,用 provenance logs 记录原始作者,并对试图变成 authority 的 peer-originated instructions 进入 quarantine。在 eval 里,这应该表现为一个相邻 agent 请求过高权限、重新包装 prompt injection 或触发过宽 fan-out 的场景,而系统能证明该 instruction 仍然只是数据。

4.7. 最好不要把 MCP host、client 和 server 搞混

MCP 周围常常会出现一些没必要的混乱,因为这些词听起来都很熟,但它们在系统里的角色其实很具体。

一个更清晰的理解方式是:

  • host 是拥有会话、并决定到底要连接哪些能力的应用或运行时;
  • client 是 host 为了和某一个 MCP server 通信而创建出来的协议侧组件;
  • server 是那个暴露工具、资源以及其他能力表面,并返回结构化结果的边界。

这会带来两个很实用的结论:

  • 一个 host 可以同时持有多个 client 实例;
  • 一个智能体运行时也可以同时和多个 MCP server 工作,而不是把它们揉成一个分不清边界的集成大泥团。

这看起来像术语细节,但其实很有帮助。MCP client 不是产品界面,也不是“智能体本体”。它是 host 和某个具体 server 边界之间的传输与契约层。

MCP 适合作为运行时和外部能力之间的契约层

flowchart LR
    A["智能体运行时"] --> B["执行层"]
    B --> C["策略与验证"]
    C --> D["MCP client"]
    D --> E["MCP server"]
    E --> F["类型化适配器"]
    F --> G["外部 API / 系统"]
    G --> F
    F --> E
    E --> D
    D --> B

5. 为什么要把适配器移出核心运行时

一旦 MCP 不再只是一个或两个手工接入的集成,问题就会升级为:谁在把 MCP 表面当作平台资产来治理,而不是当作开发者本地便利工具? Cloudflare 最近的材料很有价值,因为它把重点从“智能体会不会说 MCP”转向“团队怎样在规模化条件下发现、批准、路由和审计 MCP 端点”。1

这通常会把平台推向一个显式的 MCP 控制平面:

  • 用于实验的本地临时 MCP server;
  • 用于共享生产能力的受治理的远程 MCP server;
  • 用于已批准服务器的发现/门户层;
  • 位于访问边界的身份执行;
  • 围绕 MCP 路径本身的审计与 DLP 控制。

这会带来很多直接收益:

  • 单个集成的失败不容易拖垮中心运行时;
  • 更容易按能力限制网络、密钥和文件系统;
  • 不重写编排也能替换或升级某个适配器;
  • 契约更清晰;
  • 能力更容易独立测试。

当某些工具只读、某些会写外部系统、某些甚至执行代码或 shell 时,这一点尤其重要。

5.1. 企业级 MCP 需要的不只是协议,而是控制平面

很多团队都会在这里犯同一种成熟度错误。他们把 MCP 标准化成协议,却仍然用非正式方式接入服务器:有人把端点发进群聊,另一个团队把它复制进本地配置,很快就没人说得清哪些 MCP server 已获批准,哪些只是实验性的,哪些则悄悄绕过了正常评审。

更成熟的模型会把远程 MCP 当作平台控制平面的一部分:

  • 平台通过注册表或门户发布已批准的 MCP 端点;
  • 能力负责人被明确标注;
  • 身份认证由统一身份层中介,而不是藏在每个桌面客户端里;
  • 策略与 DLP 检查可以把 MCP 流量当作受治理的表面来观察;
  • MCP 端点的退役被当作正常生命周期事件处理。

一旦身份成为中心问题,下一个设计问题就会出现:到底是谁在为这次 MCP 动作授权,它使用的是谁的用户上下文? 这里需要托管 OAuth 边界,因为它能避免每个 MCP server 各自发明一套临时凭据故事。

这通常意味着:

  • 用户委派通过受治理的身份层发放;
  • token 是短生命周期的,并且可归因到具体主体;
  • MCP server 拿到的是有范围的访问权,而不是宽泛的长期密钥;
  • 平台可以在不重写每个适配器的情况下撤销或轮换访问权。

同一套模型也能解释 本地 MCP 什么时候仍然合理:原型验证、隔离实验,或者非常窄的团队本地工作流。但对共享业务能力来说,更合理的默认值通常应是:远程、受治理、可发现、可审计

Google Cloud 的 Gemini Enterprise Agent Platform remote MCP server 展示了同一边界的 managed 版本。9 外部 agent 或 IDE client 不需要拿到一组任意 cloud secrets;它连接的是 Google Cloud 内部的标准化 remote MCP endpoint,可以看到 generation、prediction、notebooks、endpoints、models、tuning、evaluation 和 prompts 等 toolsets,并通过 Agent Registry 做 discovery。架构结论是:如果 discovery、IAM Deny policies、tenant/data boundary、observability 和 lifecycle ownership 都在平台侧,而不是散落在客户端本地配置里,那么 managed remote MCP endpoint 就可以成为 capability boundary

AWS MCP Gateway and Registry 的框架让这类控制平面更具体。8 它把 MCP servers、AI agents、skills、workflows 和其他 AI assets 当成目录化实体,而不是散落的 endpoints。对本章有用的结论不是某个具体实现栈,而是职责划分:registry 管 discovery、ownership、security scanning、fine-grained access control 和 federation;gateway 路由 MCP tool calls,并写入 audit log。这比让每个 agent 或 desktop client 维护自己的私有服务器列表更像一个清晰的平台契约。

5.2. Shadow MCP 是影子 API 问题的新版本

当 MCP 变得非常容易接入时,团队也会得到一种新的 shadow IT 形式:未登记的 MCP server 已经承载真实业务动作,但其负责人、评审和控制模型却没有被正式化。1

这个反模式往往有很明显的信号:

  • 能力来自私人配置片段,而不是已批准目录;
  • 没有人能说清 MCP server 的负责人;
  • 认证依赖长期本地密钥;
  • 没有统一审计轨迹可以说明哪个智能体调用了哪个 MCP 端点;
  • 平台团队往往要到事故之后才知道它存在。

一个有用的平台清单可以很简单:

  • 这个 MCP server 是否在已批准的注册表里?
  • 谁负责它的生命周期与事故响应?
  • 哪一层身份边界在保护访问?
  • 哪个策略包管理写动作与审批?
  • 哪些遥测字段能证明哪个智能体在什么决策上下文下调用了它?

如果这些问题答不上来,问题就已经不只是“集成文档不完整”,而是平台在自己的控制模型之外制造了一条影子能力路径。

这里还有一个很关键的追问:平台能否重建这次 MCP 动作的授权链? 在成熟模型里,操作员应该能追溯出:

  • 是哪个用户或服务主体委托了访问;
  • 是哪个身份层签发或代理了 token;
  • 是哪个 MCP server 接受了这份委派作用域;
  • 是哪个智能体运行使用这份授权执行了动作。

如果这条链路无法重建,那么平台的可审计性就比协议表面看起来要弱得多。

5.3. MCP 作为通往 cloud API 的受治理访问路径

AWS Security Blog 最近的一条建议很有用,因为它把 MCP 描述成的不只是集成便利,而是通往 cloud resources 的受治理访问路径7 关键细节是:AI coding assistants 和 agents 往往也可以通过 shell、SDK 或任意代码执行直接访问 cloud API。如果这条路径仍然开放,那么带有良好 IAM 策略的 MCP server 只是其中一条路,而不是真正的控制边界。

因此 production agents 应该明确区分:

  • mcp_brokered_action:动作经过注册过的 MCP/tool gateway,拿到 scoped credentials,写入 audit event,并携带 policy decision;
  • direct_cloud_api_action:agent 从 shell/code environment 直接调用 SDK、CLI 或 HTTP API;
  • human_initiated_action:人类自己执行动作,agent 只准备 plan、diff 或 evidence packet;
  • delegated_agent_action:人类或 policy layer 把带 TTL、scope 和 trace correlation 的有限动作范围委托给 agent。

架构结论很严格:direct cloud API access 如果没有经过同一个 catalog、identity、policy 和 audit layer,就应该被视为 bypass path。对 runtime 来说,这会给 trace/control record 增加几个必要字段:actor_typedelegation_sourcecredential_scopecredential_ttlaccess_pathmcp_server_idpolicy_decision_idcalled_via_gateway。这样组织才能区分 human-initiated action 和 AI-driven action,并把 least privilege、organizational role governance 和独立 approval rules 应用到 agent 路径上,而不只是应用到人类 IAM。

如果团队还不能完全禁止 shell/SDK access,最低要求也应该是显式 bypass control:restricted shell profile、针对 cloud CLIs 的 denylist/allowlist、通过 proxy 的 network egress、direct cloud API calls detection,以及在 critical writes 进入 brokered gateway 之前阻断该 agent capability 的 release gate。

5.4. Cloudflare AI traffic controls 说明 web access 也是 policy surface

Cloudflare AI traffic controls 给本章补上了一条相邻但重要的边界:问题不只是 agent 怎样调用 MCP 或 cloud API,也包括外部网站怎样决定哪类 AI traffic 可以使用它的内容。3 Search / Agent / Training 的区分很适合作为 governance 信号。Search crawler、interactive Agent 和 Training crawler 有不同目的、资源所有者的不同预期,以及不同审计要求。

对 runtime 来说,实践结论是:outbound identity 不能简化成 user-agent string 或 IP allowlist。能访问 web 的 agent 应该声明 declared purpose,保留 audit trail,并至少区分:

  • search/indexing,也就是网站所有者期望被发现的路径;
  • interactive agent access,也就是 agent 代表用户行动;
  • training 或 dataset collection,也就是内容使用会改变同意和收益分配的场景。

Cloudflare 还展示了未来访问契约中的一个关键细节:Content-Signal 可以携带更细的条件,例如 use=reference;而 Verified 和 Forwarded 状态把已验证 identity 与通过 downstream service 传递的 transitive trust 区分开。对 agent architecture 来说,这意味着 transitive trust 必须被显式建模:如果 browser agent 或 retrieval-agent 通过中介获得访问权,trace 应该记录 original identity、forwarded identity、declared purpose 和 policy decision,而不只是最终 HTTP request。

因此,web-capable agent 的最小 policy matrix 至少应该包含四类决策:allow、block、monetize 或 audit-only。每个决策都应该绑定访问目的:Search / Agent / Training。否则 web access policy 很快会退化成脆弱的字符串列表,而不是资源所有者、用户和 agent platform 之间的契约。

Cloudflare Monetization Gateway 让 monetize 分支更具体,尤其是面向 agent-facing resource 的场景:web page、dataset、API 或 MCP tool 都可以成为带 x402-style payment flow 的 payment-gated resource4 对 agent architecture 来说,这不只是 billing feature。在发起 MCP tool call 或访问付费 retrieval resource 之前,runtime 需要先做 policy decision before the tool call:是否允许 spend、谁是 payer、哪个 spending cap 生效、payment proof 存在哪里,以及哪个 metering record 进入 audit trail。否则 agent 的 web/tool access 会悄悄变成缺少业务上下文的不可审查支出。

5.5. Browser as an action surface

GitHub Copilot browser tools in VS Code 展示了下一步:live browser 正在成为 agent 的常规行动环境,而不只是人工检查结果的外部工具。5 如果 agent 可以打开页面、click/type/hover/drag、读取 page content、收集 console errors、生成 screenshot 并运行 scripted flows,那么 browser 就应该被视为独立 execution surface。

这个 surface 的实践契约应该覆盖 stale DOM refs、auth/session state、non-deterministic UI 和 evidence snapshot。agent 不能只说“页面能用”;它应该留下可验证证据,比如 screenshot、DOM assertion、console errors、network trace,或绑定到 run/trace id 的其他 artifact。否则 browser automation 会变成又一个不透明的 tool call。

控制层也必须显式。用户自己的 tabs 需要 share/revoke 语义,agent-owned tabs 需要隔离 session、不能读取普通浏览器 cookies/storage,敏感 permission prompts 需要人类批准,enterprise 环境还需要 network domain controls 和 workspace trust。这样 browser tool 才是受治理能力,而不是 agent process 对全部 web state 的直接访问。

5.6. Secure MCP Tunnel 让私有可达性显式化

OpenAI Secure MCP Tunnel 为 private MCP server 增加了一种有用的部署模式:私有侧主动建立 outbound-only 连接,而不是从公网接受 inbound traffic。10 tunnel-client 运行在本来就能访问 private MCP server 的网络内,对 OpenAI-hosted endpoint 做 long-poll,拉取 queued MCP work,把 JSON-RPC requests 本地转发给 server,再通过同一路径返回 responses。这个形态还有天然的 backpressure 点:client 只请求自己准备好处理的工作量。

架构结论比“tunnels make private systems safe”更窄。Tunnel 应该是受治理的可达性机制,not a general-purpose network bridge。Private MCP server 仍然需要 owner records、schema hashes、scoped authorization、output filtering、request correlation 和 audit events。Tunnel record 应该说明哪个 product surface 可以调用它、它通向哪个 private MCP server、哪个 identity 认证了 tunnel-client,以及哪个 policy 决定 request 是否被允许。换句话说,Secure MCP Tunnel 有价值,是因为它把 narrow path 保持清楚:product endpoint -> tunnel service -> authenticated tunnel-client -> private MCP server -> filtered response。

5.7. Code Mode 会把 MCP portal 变成 progressive disclosure 层

Cloudflare 还展示了一个适合大型 MCP estate 的模式:不要把所有 tool schemas 一次性交给模型,而是把宽 API 表面放到一个只有搜索和执行两类窄操作的 portal 后面。2 在这个模式里,Code Mode 让模型先写代码搜索所需 endpoint definitions,再写代码调用找到的操作;这些代码在 MCP server portal 侧的沙箱中执行,而不是在主智能体会话里执行。

这在架构上不只是 token cost 问题。它改变了工具可见性模型:

  • 模型拿到的不是整个 capability catalog,而是搜索机制;
  • portal 成为 audit、DLP 和 identity enforcement 的检查点;
  • agent context 不会被几千个 schema tokens 撑大;
  • discovery 变成受治理动作,而不是隐式加载整个世界;
  • portal 侧 sandbox 会限制生成代码能做什么。

但这个模式仍然必须受治理。search/execute portal 不应该变成绕过 capability governance 的通道。它需要和普通 MCP endpoint 一样拥有 owner、allowed upstream servers、scope policy、sandbox profile、output filtering、trace correlation,以及 risky writes 的 review rules。否则团队只是把“prompt 里工具太多”换成了“可编程 portal 权限太宽”。

GitHub Agent Finder 从客户端侧展示了同一个转向:capability discovery 应该成为 runtime operation,而不是 prompt assembly 的习惯。6 Agent 应该能够在批准的 MCP servers、skills、canvases、agents 和 tools registry 中搜索,拿到针对任务的 ranked matches,并只加载实际需要的资源。关键 safety 细节是 discovery 受 managed settings 限制,而且不会悄悄安装或连接新资源。因此在 production architecture 中,trace 应该保存 capability_search_queryregistry_scope、ranked candidates、selected resource、policy decision,以及 human/platform approval state。

5.8. Tool surface design 是 safety contract 的一部分

AWS 关于 MCP tool design 的实践框架给 Cloudflare Code Mode 补上了另一层:问题不只是 gateway 放在哪里,而是 agent 到底看见了哪种 tool surface13 如果 prompt 里预先塞进几十个相似工具、宽 schema 和含糊名称,平台会同时遇到 context bloat 和 tool confusion。模型可能选错操作、把相邻 schema 的字段混在一起,或者把通用工具当成绕过高风险动作的路径。

因此,好的 tool-surface contract 至少应该记录:

  • tool_taxonomy:read、write、execution、orchestration、introspection;
  • tool_visibility_mode:eager、lazy、search_then_execute 或 server_side_introspection;
  • max_active_tools:单步中同时可见工具的实践上限;
  • schema_constraints:必填字段、用 enum 代替自由文本、短描述,并禁止把隐藏策略写进 description;
  • argument_budget:模型在 active context 中真正需要持有多少参数;
  • agent_as_tool_policy:什么时候把复杂 sub-agent 发布成一个工具,而不是暴露所有内部操作;
  • tool_evaluation:覆盖 wrong-tool selection、schema confusion、unsafe default 和 noisy catalog 的测试。

一个简单启发是:如果一个工具无法被解释成单一操作、窄 schema 和明确 risk tier,它可能更适合作为 workflow、sub-agent 或 portal search path。反过来,如果五个工具只差一个不明显参数,差异更应该进入 enum、taxonomy 或 server-side discovery,而不是让模型靠长描述猜。

对 runtime 来说,这会变成可审查 trace:哪些工具可见,为什么这些工具被披露,是哪个 taxonomy node 或 search result 激活了它们,哪个 schema version 验证了参数,以及哪个 evaluation pack 证明模型不会混淆相似 tools。没有这条证据,“我们有 MCP gateway” 仍然留下盲区:gateway 管住了调用,却没有解释模型为什么一开始看见的是这组 tool surface。

5.9. Smartsheet remote MCP server on AWS:production remote MCP facade

Smartsheet remote MCP server on AWS 是一个有用的 production remote MCP facade 案例:one MCP layer serves internal and external agents,而不是为产品内 Smart Assist 和 external AI clients 暴露两套不同表面。14 架构教训是,MCP server 不只是现有 API 的薄 proxy,而是覆盖 domain services 和 intelligence layer 的 AI-optimized interface。

这个 surface 有四个关键性质。第一是 capability parity:internal Smart Assist 和 external clients 得到同一个 governed contract。第二是 schema-driven tool contracts:严格 JSON schemas、column-name validation 和 structured errors 会把模型挡在 hallucinated parameters 之外。第三是 token cost 变成 production control:progressive disclosure、response budgets 和 compact serialization 降低成本和 context pressure。第四是 access tiers、OpenTelemetry、audit events、per-user rate limits 和 production canaries,把 remote MCP 变成受治理的平台边界。

可移植 contract 是:single MCP facade → API gateway and OAuth validation → domain services and intelligence layer → schema-driven tools → token-budgeted responses → access tiers → OpenTelemetry and audit → canary workflow tests。它应该放在 Cloudflare portal 和 AWS tool design patterns 旁边看:gateway 说明谁能调用 tool,tool-surface contract 说明模型能看见什么,production facade 则说明一个 MCP layer 如何承受真实 agent bursts、governance 和 cost constraints。

5.10. Rules of Durable Objects:Durable Agent Identity

Cloudflare Rules of Durable Objects 补上了一个比 Agents SDK 更底层、但可以迁移到其他平台的 runtime pattern:Durable Agent Identity。如果 agent 有稳定名称,这个名称就应该是 atom of coordination,而不只是 log 里的标签。15 Requests、timers、wakeups 和 recovery paths 应该通过 deterministic IDs 汇聚到同一个 durable instance;否则平台可能制造出两个“同一个”agent,它们却独立修改同一片 state boundary。

对 agent architecture 来说有五条规则很关键。第一,deterministic IDs 应该来自 tenant/workspace/case/thread 这类稳定实体,而不是随机 run。第二,durable state 是 progress、leases、cursors 和 idempotency 的事实来源;process memory 只是 cache。第三,input and output gates 应该保护操作顺序:新工作不应看到 half-written state,external side effect 也不应早于 durable commit/evidence 发出。第四,idempotent alarms 是 delayed actions 的必要条件,因为 failure 后 alarm 可能再次触发。第五,unexpected shutdowns 是模型的一部分;recoverable work 应该从 durable checkpoint 继续,而不是依赖 in-memory timers, closures, or open fetches。

可移植 contract 是:request → deterministic agent instance → durable state gate → idempotent alarm/fiber/workflow → recovered execution → audited output gate。这不是替代 MCP gateway:MCP 管 capability boundary,Durable Agent Identity 管哪个 named agent instance 拥有状态,以及它怎样跨 restart 存活。

5.11. 短生命周期沙箱通常比常驻环境更好

Google 还有一个很有价值的提醒:对高风险能力来说,短生命周期的执行环境往往比常驻 worker 更健康。16

原因通常很直接:

  • 状态更不容易在运行之间泄漏;
  • 更容易限制密钥和临时文件的生命周期;
  • 清理更容易解释;
  • 一个脏适配器更不容易污染下一次任务。

常驻 worker 有时会赢在延迟,但经常输在隔离性和可解释性上。所以面对高风险执行,更合理的默认立场通常是:短生命周期优先,只有在明确需要时才保留持久环境

6. MCP 2026-07-28 核心是无状态的

MCP 2026-07-28 规范要求核心协议中的每个请求都自包含,并按消息协商协议版本。1819 旧的 initialize/initialized 握手和协议会话头已经移出核心。这样更容易做水平扩展和故障恢复,但并不等于应用不再需要状态。

架构上的结论必须说清楚:无状态协议不等于无状态应用。购物篮、浏览器、工作区或长任务仍然可以跨越一次调用,但状态必须显式、有边界、可审计。

6.1. 应用状态通过显式句柄传递

工具需要继续操作既有对象时,应接收普通参数,例如 basket_idbrowser_idworkspace_id。这种句柄:

  • 在服务器端绑定主体、租户、权限范围和有效期;
  • 每个请求都重新验证;
  • 本身不是权限证明;
  • 可以撤销、删除或替换,而不必重建隐藏的传输会话;
  • 在遥测中作为状态引用记录,而不是作为密钥。

这种分离避免把传输连续性悄悄变成授权。暂停或审批之后,运行时可以携带同一个应用句柄重新调用,但必须重新检查策略、权限和动作完整性。

6.2. 长任务与补充输入使用独立契约

对于一次响应无法完成的工作,Tasks 扩展让服务器返回任务句柄,客户端则显式查询、获取结果或取消任务。遥测应关联 task_id、原始调用、工具版本、进度、结果和取消原因;任务句柄和其他标识符一样,不能代替授权。

服务器需要额外输入时,会返回带有 requestState 和输入请求的 InputRequiredResult。用户回答后,客户端携带 inputResponses 重新发送原始调用。若操作会产生副作用,这次重试必须保留相同的幂等键和动作摘要,同时重新执行策略与审批时效检查。这样,连接中断就不会把人工输入变成隐式的重复写入。

6.3. 网关路由消息,而不是猜测隐藏会话

在 HTTP 配置中,Mcp-MethodMcp-Name 让网关无需解析完整消息体也能路由和观测 MCP 消息。ttlMscacheScope 提示允许的缓存方式,W3C Trace Context 则把请求关联到端到端追踪。这些字段仍然只是协议提示:服务器必须在每个请求上验证身份、参数和权限。

AgentCore Gateway 的扩展 MCP 支持仍是聚合 tools/listprompts/listresources/list 与资源模板、携带 outputSchema、动态列表和工具注解的有用案例。12 有价值的追踪字段包括 listing_modelisted_under_principaloutput_schema_hashtool_annotations。但 AWS 在 2025-11-25 发布的行为是该服务版本的供应商特定契约,并不是当前 MCP 核心的通用模型。11 平台应给兼容配置标明日期,不能把旧的会话延续语义投射到共享协议上。

7. 不是所有能力都需要同等级别的隔离

把集成至少分成三类会很有帮助:

  • 低风险读取能力;
  • 中风险业务动作;
  • 高风险执行能力。

例如:

  • read_kbsearch_docs 可以用较轻的执行限制;
  • create_ticketupdate_crm_record 需要更严格的策略和审计;
  • run_shellexec_sqldeploy_job 需要最强的沙箱和审批。

如果所有工具都被放进同一种宽松执行画像,平台要么不安全,要么很快就会因副作用产生事故。

8. 能力契约不应只包含输入/输出

很多团队对输入 schema 还能描述得不错,但运营契约常常完全缺失。而实践中,这部分往往更关键。

最好明确写出:

  • 认证模式;
  • 访问是平台拥有还是用户委派;
  • token 生命周期与续期规则;
  • 每项能力的作用域边界;
  • 委派授权需要记录哪些日志字段;
  • 如果委派访问在会话中途被撤销,运行时应该怎么处理。

  • read 或 write 属性;

  • 网络策略;
  • 密钥作用域;
  • 允许环境;
  • 超时预算;
  • 重试策略;
  • 审批要求;
  • 日志记录和脱敏规则。
capabilities:
  search_docs:
    transport: mcp
    mode: read
    network: internal_only
    secrets: none
    timeout_seconds: 8
    approval: none
  create_ticket:
    transport: mcp
    mode: write
    network: internal_only
    secrets: service_account_helpdesk
    timeout_seconds: 15
    approval: manager_for_high_priority
    protocol_profile: mcp-2026-07-28
    state_handle_argument: ticket_draft_id
    long_running_mode: tasks_extension
    additional_input: request_state
  run_shell:
    transport: sandboxed_exec
    mode: high_risk
    network: denied
    filesystem: workspace_only
    secrets: none
    timeout_seconds: 10
    approval: always

这已经不只是函数描述,而是能力的行为契约。

9. 沙箱执行应该返回执行事实,而不只是输出

如果沙箱只返回 stdout 或载荷,你就丢掉了一半的隔离层价值。

为了调查和控制,最好还能返回:

  • 退出状态;
  • 超时标志;
  • 资源使用摘要;
  • 副作用不确定性;
  • 脱敏日志;
  • 策略决策 ID。

这样执行层才能解释得更成熟:不是“命令失败了”,而是“操作在 8 秒后超时中止、网络被禁止、副作用未确认”。

9.1. 网络出口应该有自己单独的规则

很多事故发生,不是因为能力“坏了”,而是因为它能去到没人预期的目的地。

所以网络出口最好不要只当作沙箱的附属字段,而要被当成独立的契约表面:

  • denied
  • internal_only
  • allowlisted_external
  • brokered_via_gateway

如果这里没有显式规则,事后通常很难解释:为什么某个工具明明“没违反规则”,却突然跑去访问了外部目标。

对生产级平台来说,一个不错的默认值通常是:

  • 只读内部工具:internal_only
  • 外部 API 适配器:allowlisted_external
  • 代码执行和类 shell 工具:默认 denied

9.2. 把沙箱 manifest 当作执行契约

OpenAI 最近的 Sandbox Agents 文档给这个问题补了一种很实用的形态:沙箱不应只被描述成“容器”或“隔离环境”,而应通过显式的 Manifest、capabilities、permissions、workspace entries、snapshot 和 session state 来描述。17

这和本章的执行契约可以直接对齐。平台至少要回答四个问题:

  • 哪些文件、仓库、mounts 和 environment 会被物化进启动 workspace;
  • 哪些沙箱原生能力可用:filesystem、shell、memory、skills、compaction;
  • 命令、文件修改和文件读取使用哪些 permissions 与 run_as 身份;
  • 继续执行时到底使用 live sandbox_session、序列化的 session_state,还是从 snapshot 启动的新会话。

这样的 manifest 不能替代策略层。它让执行边界变得可审查:reviewer 可以看到什么进入了 workspace、智能体拿到了哪些权限,以及这项工作是否能安全地 resume 或 snapshot。

9.3. Brain / hands / session 作为隔离契约

Anthropic 的 Managed Agents 架构给本章提供了一个很实用的 runtime 形状:sessionharnesssandbox/tools 应该被看作彼此分离的接口,而不是一个装满神奇内部逻辑的容器。[^anthropic-managed-agents]

  • session 是事件、决策、tool calls、approvals 和结果的 append-only log;
  • harness 是可替换的 control loop,负责调用模型并路由 capability request;
  • hands 是真正读取文件、访问网络、产生副作用的 sandboxes、tools 和 adapters。

这种拆分不只是为了扩展性,它本身也是安全边界。harness 卡住时,session 仍应可读。sandbox 死掉时,session 不应跟着消失。operator 需要 debug 时,应该查看 events、profiles 和 snapshots,而不是进入一个同时持有用户数据的环境开 shell。

按本章的语言,一个 capability request 应该经过一条短链:

capability request → policy → contained execution → telemetry → incident/eval feedback

这条链让 containment 可以被审查:policy 选择执行 profile,hands 在受限环境内执行,telemetry 记录边界,assurance/eval loops 再用结果影响下一次决策。

10. 一个简单的能力分发示例

这个小骨架展示的核心思想是:传输和执行画像来自能力契约,而不是由模型临时决定。

from dataclasses import dataclass


@dataclass
class CapabilitySpec:
    name: str
    transport: str
    mode: str
    timeout_seconds: int


def dispatch_capability(spec: CapabilitySpec, args: dict) -> dict:
    if spec.mode == "high_risk":
        return {"status": "approval_required", "capability": spec.name}
    if spec.transport == "mcp":
        return {"status": "success", "transport": "mcp", "capability": spec.name}
    if spec.transport == "sandboxed_exec":
        return {
            "status": "success",
            "transport": "sandboxed_exec",
            "capability": spec.name,
        }
    return {"status": "validation_failure", "reason": "unsupported capability profile"}

它非常简单,但把一个正确前提固定下来:执行方式由平台决定,而不是模型每次重新发明。

11. 常见错误

这些问题现在会在两个层面重复出现:单个适配器层面,以及整个 MCP 资产层面。

这些问题一再重复:

  • 某项能力拿到了超出必要范围的网络访问权;
  • 密钥对过多适配器可见;
  • 工具结果把原始外部载荷直接拖进提示;
  • 超时存在,但副作用不确定性没有被建模;
  • MCP server 接上了,但策略和审计根本没延伸进去;
  • 沙箱名义上存在,但没有限制任何关键东西。

所以沙箱不能只是打勾功能,它必须成为执行设计的一部分。

12. 现在就该做什么

先过一遍这份短清单,把所有回答为“否” 的地方单独记下来:

  • 适配器是否和核心运行时分开?
  • 是否存在每项能力的执行画像?
  • 网络、文件系统和密钥是否被约束?
  • 是否清楚到底使用的是逻辑隔离、进程隔离还是运行时隔离?
  • 传输是否显式:direct、MCP、sandboxed_exec
  • 系统是否区分可信结果和部分可信结果?
  • 业务载荷之外是否保留执行事实?
  • 对高风险执行是否使用了短生命周期沙箱?
  • 能否解释为什么某项能力会在这次运行中被允许?

如果这些答案很模糊,那说明能力层还只是“一堆好用的集成”,而不是受管理的平台层。

13. 下一步做什么

先把执行画像和隔离边界固定下来,再进入重试、速率限制和回滚边界。

这一部分下一个自然主题是:幂等性、重试、速率限制和回滚边界。经过沙箱和能力契约之后,这才是把执行模型变成生产级的关键。


  1. Cloudflare, Scaling MCP adoption: Our reference architecture for simpler, safer and cheaper enterprise deployments of MCP 

  2. Cloudflare, Code Mode: give agents an entire API in 1,000 tokens 

  3. Cloudflare Blog, Your site, your rules: new AI traffic options for all customers 

  4. Cloudflare Blog, Announcing the Monetization Gateway 

  5. GitHub Changelog, Browser tools for GitHub Copilot in VS Code are generally available 

  6. GitHub Changelog, Agent finder for GitHub Copilot now available 

  7. AWS Security Blog, Secure AI agent access patterns to AWS resources using Model Context Protocol 

  8. AWS Open Source Blog, Governing AI Assets at Scale with MCP Gateway and Registry 

  9. Google Cloud, Build agents even faster with Gemini Enterprise Agent Platform’s fully-managed, remote MCP server 

  10. OpenAI, Secure MCP TunnelMaking private MCP servers reachable without making them public 

  11. AWS, Introducing stateful MCP client capabilities on Amazon Bedrock AgentCore Runtime 

  12. AWS, Extending MCP support for Amazon Bedrock AgentCore Gateway 

  13. AWS Machine Learning Blog, MCP tool design: practical approaches and tradeoffs 与 AWS Prescriptive Guidance, Design tools for AI agents 

  14. AWS Machine Learning Blog, How Smartsheet built a remote MCP server on AWS 

  15. Cloudflare, Rules of Durable Objects 

  16. Google Cloud, Introducing Agent Sandbox 

  17. OpenAI Agents SDK, Sandbox AgentsSandbox ConceptsSandbox clientsAgent memory 

  18. Model Context Protocol, Specification 2026-07-28 

  19. Model Context Protocol Blog, The 2026-07-28 MCP Specification Release Candidate 

  20. Model Context Protocol, Security Best Practices 

  21. Model Context Protocol, Authorization specification 

  22. Microsoft Security Blog, AutoJack: How a single page can RCE the host running your AI agent 

  23. Microsoft Security Blog, When prompts become shells: RCE vulnerabilities in AI agent frameworks 

  24. Microsoft Security Blog, Securing AI agents: When AI tools move from reading to acting 

  25. Microsoft Research, Red-teaming a network of agents: Understanding what breaks when AI agents interact at scale 

  26. Google Cloud, Beyond Static Prompts: Building Scale-Proof, Polymorphic Multi-Agent Systems with Google's ADK