沙箱为什么在多智能体场景下失效 过去两年,企业部署 Agent 的主流安全策略是"沙箱":把 Agent 跑在容器、虚拟机、Seatbelt/bubblewrap、Trusted Execution Environment 这类外部隔离环境里,假设只要 Agent 出不去,数据就丢不了。这条思路在单 Agent 场景下相当有效——单 Agent 持有少量工具,被劫持的概率可控,沙箱的隔离边界相对清

沙箱为什么在多智能体场景下失效

过去两年,企业部署 Agent 的主流安全策略是"沙箱":把 Agent 跑在容器、虚拟机、Seatbelt/bubblewrap、Trusted Execution Environment 这类外部隔离环境里,假设只要 Agent 出不去,数据就丢不了。这条思路在单 Agent 场景下相当有效——单 Agent 持有少量工具,被劫持的概率可控,沙箱的隔离边界相对清晰。

但当企业内部 Agent 数量从一台变成十几台、上百台,从单 Agent 变成多 Agent 协作,这套"沙箱"思路就撞上了清晰的工程边界。一个被反复观察到的真实问题是:Claude Code 这类 Agent 默认带的工具集(Bash、Read、Write、Edit、WebFetch、Task、Plan)在单 Agent 场景下足够用,在多 Agent 系统里则远远不够——具体表现包括没有跨仓库探索能力、WebFetch 只能摘要单页不能追链、Edit 仍然是文本级匹配不能利用 tree-sitter AST、Task 不跨会话持久、Plan 不支持多轮评审、Agent 工具不能嵌套——一个 Agent spawn 出来的 sub-agent 不能 spawn 自己的 sub-agent,委托深度只有一层,以及"Bash 直接跑在宿主上,没有沙箱、没有文件系统白名单"。

这一长串限制的最后一项尤其关键——它直接意味着,即便 Agent 在生产部署时套了一层容器,容器内部的 Bash 工具仍然会跳出文件系统的预期范围,接触到宿主机的 ~/.ssh/、~/.aws/credentials、其他项目的代码等等。这意味着传统的"沙箱+默认工具集"组合,在多 Agent 真实部署场景下,工程上的保护力远不如设计文档上那么强。

"围栏"思路:不靠墙靠栏杆

工程上应对这一边界的思路转换,过去半年正在从"沙箱"切换到"围栏"——也就是 fences not sandboxes。这两个词背后的工程哲学差异很关键。沙箱的思路是"把 Agent 关在一个不可逃逸的房间里",假设 Agent 在房间里做什么都没关系,只要不逃出去就行;围栏的思路是"Agent 可以跑在开放空间里,但每走一步都必须被一根栏杆拦一下,栏杆规定 Agent 这一刻能做什么不能做什么"。

两套思路在工程实现上的差别是根本性的。沙箱是"大尺度隔离,内部全开",一旦隔离被突破,所有权限一次性暴露;围栏是"小尺度隔离,每步独立校验",即便某一步的栏杆失效,下一步还有其他栏杆。这套思路的工程基础是 capability-based security——Agent 不持有"通用权限",只持有"明确列举的能力清单",每个能力都关联到具体的资源、具体的操作、具体的边界。

具体到一个多 Agent 系统里,围栏的设计细节可以是这样的。Agent 持有的不再是"我能读 /tmp 目录下所有文件"这样的粗粒度权限,而是"我能读 /tmp/agent-session-42 这个特定目录下的特定文件,而且必须用 read-only 系统调用,而且读取时长不能超过 5 秒,而且必须经过中央审计日志"。每一步操作都关联到一个被独立验证的能力,任何一个能力被劫持,其他能力不受影响。

多 Agent 协作时为什么单 Agent 沙箱不够

把视野聚焦到多 Agent 协作场景,会发现单 Agent 沙箱在三个具体维度上不够用。

第一,委托深度。传统沙箱假设 Agent 是一个独立进程,Agent 内部的工具调用走沙箱管控。但多 Agent 系统里,Agent A 可能 spawn 出 Agent B,B 可能 spawn 出 Agent C,整条委托链上的每个 Agent 都各自持有自己的工具集和权限。沙箱要么得给整条链上一个统一边界(粒度太粗),要么得给每个 Agent 单独一套沙箱(管理成本太高),要么干脆放弃管控——但放弃管控等于直接暴露。

第二,能力组合。Agent A 持有"读 CRM 数据"的权限,Agent B 持有"发邮件"的权限,两个 Agent 协作时,Agent A 把 CRM 数据通过共享内存/共享文件传给 Agent B,Agent B 再把数据发到外部邮箱——单看任一 Agent 都没违规,但组合起来就是一次完整的数据外发。沙箱的隔离单元是"Agent 进程",它看不见这种跨 Agent 的能力组合。

第三,持久化意图。即便单 Agent 在沙箱里安全运行,Agent 在持久化记忆里写入的"下次会话要做的事"也可能成为攻击面。一个 Agent 在沙箱里安全执行完任务,但它写进持久化记忆的"下周要做 XX 操作"被另一个 Agent 读到,这个 Agent 的沙箱可能完全没有防备。这类问题不在传统沙箱的视野里,但在多 Agent 协作下是真实的威胁。

围栏设计的工程新基线

把上述问题汇总,可以画出多 Agent 系统围栏设计的工程新基线。这条基线由五条构成,缺一不可。

第一,能力清单必须显式列举,不能默认开放。每个 Agent 启动时,持有的能力清单必须是被外部策略显式定义的,而不是从 Agent 自己的代码、提示词、配置文件里推断出来的。能力清单的最小单元应该包括:能读哪些路径、能写哪些路径、能调哪些外部 API、每个 API 的请求频次上限、每个操作的时长上限、每个操作的可审计日志通道。Agent 运行时持有的能力必须严格等于清单列举的能力,多一项都不行。

第二,能力必须按"执行上下文"动态签发,而不是启动时一次性签发。一个 Agent 启动时持有的能力是初始集合,运行时每次具体操作都需要向中央授权服务申请一个临时能力实例,操作完成后立即撤销。这套机制确保即便 Agent 被劫持,劫持者能调用的能力也限于"这次申请到的临时实例",下一次操作需要重新申请,授权服务可以基于审计日志拒绝后续申请。

第三,跨 Agent 协作必须经过中央授权,不能走 Agent 之间的对等通道。当 Agent A 需要把数据传给 Agent B 时,这次"数据传输"本身是一次独立的能力调用,需要走中央授权服务的审计,而不是 Agent A 直接把数据塞给 Agent B。这条机制是围栏设计的核心——它把跨 Agent 能力组合从"不可见"变成"可审计"。

第四,持久化意图必须独立治理。每个 Agent 写进持久化记忆的内容,在被另一个 Agent 读取之前,需要走一次独立的"意图审计"。这条审计不关心内容是否真实、是否合理,只关心内容是否会让读取它的 Agent 在不知情的情况下产生越权动作。这条机制对应着多 Agent 系统里"持久化层作为攻击面"的风险。

第五,围栏审计日志必须不可篡改、可回放。每个 Agent 的每个能力申请、每次授权结果、每次操作完成状态,都必须留下可验证的审计日志。审计日志的可验证性,是事后区分"Agent 自主行为"和"被劫持后的行为"的唯一可靠手段。

围栏设计的具体工程组件

具体到工程落地,围栏设计通常由以下组件配合实现。能力描述文件,常见形式是 capability.yaml 加上 policy.yaml,清单里列举每个 Agent 的每项能力,以及能力的边界(路径、频次、时长)。中央授权服务,常见实现是基于 macaroon HMAC 链或 Open Policy Agent 这类独立服务,负责动态签发临时能力实例。运行时沙箱,常见实现是 seatbelt(macOS)/bubblewrap(Linux)这类 OS 原生沙箱,负责在 OS 系统调用层做最后一道拦截。审计日志,常见实现是 append-only 哈希链日志,每条日志带时间戳、Agent ID、能力 ID、操作结果、签名。

这些组件单独看都不新鲜——macaroon、OPA、seatbelt 在传统分布式系统里都用了很多年。但过去半年这些组件被重新组合进 Agent 系统的过程,催生了一个新的工程领域。它的核心思想是把 Agent 视为分布式系统里的"非受信用户",沿用分布式系统里几十年积累下来的 capability-based 安全模型,而不是给 Agent 开一个特殊的"AI 例外"。

企业多 Agent 治理的三个起步动作

把围栏基线落到企业多 Agent 系统的实际部署,可以拆成三个起步动作。

第一个动作是把现有 Agent 系统的能力清单梳理出来。每个 Agent 持有哪几类操作权限,这些权限是 Agent 自己声明的还是外部配置的,这些权限之间的组合关系是什么——这三个问题梳理清楚,才能判断现有系统是按沙箱思路设计的还是按围栏思路设计的。

第二个动作是引入中央授权服务,把动态能力签发建立起来。这件事在单 Agent 场景下看起来是过度工程——Agent 直接调用工具就行了;但在多 Agent 场景下,中央授权是判断"跨 Agent 能力组合"是否合规的唯一可靠手段。授权服务本身应当是简单的,核心逻辑只需要回答"这次申请的能力,在这个 Agent 的清单里是否存在,过去 5 秒内是否使用过,审计日志是否能完整记录"三个问题。

第三个动作是把审计日志从"事后追溯"提升为"事前约束"。传统的审计日志只是"出事之后看是谁干的",但围栏设计里的审计日志应该是"事前约束 Agent 的能力申请模式"。比如,一个 Agent 在过去 1 小时内连续申请 50 次"读 CRM 数据",授权服务应当自动触发降级或熔断,而不是等到攻击发生了再追溯。

从 Coding Agent 推到所有企业 Agent

把视野再拉宽一些,围栏设计的适用范围远远超过 Coding Agent。任何企业内部被授予了"数据读 + 公网访问 + 文件写"三类权限组合的 Agent,都应当被视作"非受信用户",按分布式系统的 capability-based 安全模型来设计它的权限体系。具体包括:被授权读 CRM 数据并对外发邮件的销售 Agent、被授权读内部财务数据并跑分析的财务 Agent、被授权读客服工单并自动关单的客服 Agent——它们每一个都面对着同样的中毒概率,只是数据敏感度不同。

企业 Agent 治理负责人现在应当把 Coding Agent 围栏设计作为整个企业 Agent 工具链围栏设计的样板工程。具体来说,这套围栏的中央授权、动态签发、跨 Agent 审计、持久化意图治理、可验证日志,应当通用化,覆盖所有被授予"数据 + 公网 + 写权限"三类组合的 Agent,而不是只针对 Coding Agent。每条围栏对应一个独立的工程组件,而不是一套散落在不同 Agent 配置里的"prompt 提示"。

企业 Agent 治理负责人现在必须回答的三个问题

面对围栏基线,企业 Agent 治理负责人现在至少要直接回答三个问题。第一个问题:你企业内部现在有多少台 Agent,每台 Agent 持有哪几类操作权限,这些权限是 Agent 自己声明的还是外部配置的?这个问题不回答,所有"按围栏治理"都是空谈——没有能力清单就没有围栏的边界。

第二个问题:你的 Agent 之间如果需要协作,数据传输走的是中央授权通道还是 Agent 之间的对等通道?如果是后者,跨 Agent 的能力组合就是不可审计的,围栏设计的核心就缺失了。

第三个问题:你的 Agent 的持久化记忆,在被另一个 Agent 读取之前,有没有走过一次独立的意图审计?如果没有,持久化层就会成为攻击面——一个 Agent 写进持久化记忆里的恶意指令,会被另一个 Agent 当作"可信的过往经验"读取并执行。

结语

多 Agent 系统的能力边界在过去半年被显著推前,从"几台 Agent 各自跑各自任务"演化到"几十台 Agent 互相协作完成复杂流水线"。每推前一步,工程侧的隔离基线就必须同步推前一步。把"沙箱"作为主要安全策略的部署,在多 Agent 场景下已经被反复证明不够。把"围栏"作为基线,按 capability-based 安全模型重新设计 Agent 的权限体系,是当下能落地的工程基线。

任何企业多 Agent 项目,只要涉及跨 Agent 数据传输、跨会话持久化意图、跨工具能力组合,工程基线就必须做到这五条——能力清单显式列举、能力按执行上下文动态签发、跨 Agent 协作走中央授权、持久化意图独立治理、审计日志不可篡改可回放——否则,今天不是某次跨 Agent 数据外发的主角,也会是下一次的主角。