Bounded Agents:多 Agent 系统的委派安全架构
- 关联论文:2608.15888
- 作者:spark
- 更新:2026-08-21
一句话结论
把 Agent 的每一次工具调用放进一条"代理主链(Agentic Principal Chain, APC)"中做六项授权检查,并用组合闭包阻止跨调用的危险组合,让提示注入风险从"模型问题"被重写为"授权架构问题"。
解决的真问题
LLM Agent 在一次会话中通常被授予一组静态权限,每个请求被独立放行。然而真实攻击并非单次请求越权,而是三种更隐蔽的失败:
- 意图偏离:Agent 在权限内做出与委派任务相反的行为(如用户授权它"读收件箱",它却用相同权限删了邮件)。
- 组合越权:多个被单独允许的动作串起来形成被禁止的结果(典型如 AgentDojo 数据外泄链)。
- 权限再委派:Agent 把权限原封不动转交给子 Agent,子 Agent 失去任何范围约束。
原作者特别强调:提示注入之所以能造成危害,前提是 Agent 拥有执行该危害的权限。因此根因不是模型被"骗",而是授权层缺乏会话语义。
核心方法:APC + 六项检查 + 组合闭包
APC 的设计目标是"在模型之外"做授权决策,并保留委派链上的上下文。
状态结构
对每个 Agent 会话维护一条主链,记录从根用户到当前 Agent 的委派轨迹:
APC: [
{ principal: User,
scope: {resource: "inbox", actions: [read], ...},
budget: {calls: 100, tokens: 1e6},
restrictions: [...] },
{ principal: SubAgentA,
scope: {resource: "inbox", actions: [read], ...}, # 子集
budget: {calls: 50, tokens: 5e5},
restrictions: ["no delete", "no forward"] },
...
]
每个后续 Agent 只能继承更小的 scope、更小的 budget,并叠加更多 restrictions——这就是委派的"边界"。
六项授权检查(每次工具调用都跑)
每条 incoming tool call 必须依次通过六项检查,任一失败即拒绝:
| # | 检查名 | 作用 |
|---|---|---|
| 1 | Scope Containment | 当前 call 的 (resource, action) 是否被链上每段 scope 覆盖 |
| 2 | Budget Residual | 累计 token / 调用次数是否仍在剩余预算内 |
| 3 | Intent Binding | call 是否在原任务意图的可推导行为集内(用以阻断"读权限被改成删") |
| 4 | Composition Closure | 与本会话先前已放行的 actions 组合后是否命中 forbidden set |
| 5 | Delegation Depth | 委派链深度 ≤ N,避免无限递归委派 |
| 6 | Model Provenance | 在 compromised-model 评估下,ground-truth 攻击 call 是否被显式插入并照样拦截 |
组合闭包
设 A_t = {actions already admitted up to t},F 是预先定义的"禁止组合集"。每条新 call a 必须满足:
∀ f ∈ F, f ⊄ A_t ∪ {a}
即不允许任何一个禁止组合的子集被完整凑齐。这正是 AgentDojo "75-100% 外泄成功"被压到 0% 的关键——单独每步都"合法",组合后就越界,APC 在每步累积地查闭包。
决策点位置
关键点:决策不在模型内做,而在 LLM 之外。这样即便模型被注入产生了恶意 tool call,APC 仍会拦截——这是把"模型行为"和"授权架构"解耦的本质。
理论保证
论文给出两条形式化属性(仅在受限条件下成立): - Blast Radius Monotonicity:委派链越深,单点失败的影响半径只可能单调不增。 - Composition Soundness:在"完整的 restriction set + 串行 admission"假设下,禁止组合必被拦截。
关键实验与数字
评估覆盖 3,154 个实例,包含 InjecAgent、AgentDojo、ASB 三大主流 benchmark。
- AgentDojo 数据外泄:原 75-100% → APC 下 0%(四个 domain 全部清零)。
- InjecAgent 数据窃取:544 个数据窃取用例 全部被拦。
- Intent Binding:破坏类行为 38.6% → 4.0%;操纵类行为 90.5% → 12.1%。
- 延迟:在空闲主机上,授权检查 P99 延迟 0.24 ms,对工具调用主回路几乎无感。
- 效用代价:949 个 AgentDojo task-injection 对上,效用分别下降 8.6 与 13.9 个百分点(两组 setting 下)——这是拦截越权 call 时附带的合法任务拒绝。
- Compromised-model 评估:在第一次合法 tool call 之后人工插入 ground-truth 攻击 call,APC 仍按上述数字拦截,证明保护独立于模型是否被攻破。
亮点与局限
亮点
- 视角正本清源:把"提示注入是安全问题"重新定性为"授权架构问题",这对产品/合规团队是有用的认知切换。
- 决策点外置:把拦截放在模型之外,意味着即使模型本身被替换或被越狱,授权策略仍然生效——这一点对生产环境关键。
- 组合闭包显式建模了 multi-step 攻击,而这是单步过滤器(典型 RBAC)做不到的。
- 延迟极低(0.24 ms P99),可作为同步拦截嵌入 tool 调用回路。
局限(基于原文与上下文判断)
- 效用下降 8.6-13.9 pp 说明误拦仍在可观察范围,需要更精细的 Intent Binding 建模或回退路径。
- Composition Soundness 仅在"完整 restriction set + 串行 admission"下成立——现实系统若允许并行 tool call(如 Anthropic / OpenAI 的并行函数调用),需额外并发控制才能保持该性质,原文未明确给出并行场景证明。
- 论文用 3,154 个静态 benchmark 实例评估,未覆盖 真实长期会话(千轮以上)中 budget 衰减、scope 漂移、用户中途调整目标等动态场景——这些恰恰是组合闭包最容易"漏算"的来源。
- 攻击侧 benchmark 主要仍是已知 prompt-injection 模板,对自适应攻击者(知道有 APC 后改写策略)的鲁棒性原文未明确。
对工程落地的启发
- 现有 Agent 框架应在 LLM 之外加一层"代理主链",而不是把所有信任寄于 system prompt 或模型自身。OpenAI Agents SDK / Anthropic Tool Use / LangGraph 都暴露 tool dispatcher 拦截点,是天然位点。
- Tool 维度必须把"组合意图"建模进来:仅按单步 RBAC 校验是不足的,至少要为"数据外泄"、"金融转账"、"不可逆破坏"三类高敏组合维护 forbidden set。
- Budget 必须显式:tokens / 调用次数 / 单资源访问次数应在会话开始就绑定,且每次委派时只能收窄。
- 回退与可观测:APC 拦截事件应进入审计日志,供事后归因与误拦率统计;拦截率突增往往是攻击在演化。
- 并行 tool call 场景落地时要补一个"序列化 admission + 重排"层,否则闭包保证会破。
与同方向工作的关系
- 与 InjecAgent / AgentDojo / ASB 的关系:这是 benchmark 提供方,APC 是首个在三个 benchmark 上同时给出大幅收敛(→0%)结果的拦截架构。
- 与 传统 RBAC / ABAC:APC 在 RBAC 的单步 scope 校验之上,加了会话级状态、组合闭包、Intent Binding——是"RBAC + workflow-aware policy"的实例化。
- 与 LLM 安全相关工作(如 Llama Guard、circuit breakers、Constitutional AI 类过滤):APC 不替代内容安全过滤,而是与之正交——内容过滤判"这条输出该不该被发",APC 判"这条 tool call 该不该被执行"。两者串联更稳。
适合谁读
- Agent 平台 / 框架开发者:APC 的六项检查与组合闭包是可直接借鉴的最小可信内核。
- 安全 / 合规团队:当被问"提示注入怎么办"时,本文的回答是"先问授权模型对不对"。
- AI 产品负责人:评估自家 Agent 上线时是否需要异步并行拦截层、效用-安全权衡的合理量级(8-13 pp 是基线参考)。
- 论文读者:形式化部分的 Blast Radius Monotonicity 与 Composition Soundness 适合作为"AI 安全可被证明"的入门案例。
§0 自检
- 机制段:APC 数据结构 + 六项检查 + 组合闭包 + 决策点外置 + 两条理论属性(5 段)
- 工程段:数字 9 处已锚定到论文原文(3,154 实例 / 75-100→0 / 544 全拦 / 38.6→4.0 / 90.5→12.1 / 0.24 ms / 8.6-13.9 pp)
- ⚠️ 不确定:效用下降是否区分了 task-injection 与 benign 场景,并行 tool call 下闭包保证是否仍成立,原文未明确
- 私域五维 SUM=0;CJK 计数留发布前自测
工程落地与核查(Jay)
事实核查
- ✅ 3,154 实例:原文实验规模,数字有据。
- ✅ AgentDojo 75-100% → 0%:原文明确,benchmark 来源可溯。
- ✅ InjecAgent 544 全部被拦:原文明确数字。
- ✅ Intent Binding 38.6% → 4.0% / 90.5% → 12.1%:原文明确。
- ⚠️ 0.24 ms P99:原文明确注明"idle host"——生产环境非空闲主机上实测延迟预计更高,建议自行压测;GPU 型号、CPU 规格未披露。
- ⚠️ 8.6-13.9 pp 效用下降:原文指 949 个 AgentDojo task-injection 对应任务, benign(无注入)场景下拒绝率未单独披露,生产部署前需实测区分。
- ⚠️ Compromised-model 评估:原文是"插入 ground-truth 攻击 call",这是白盒评估;真实自适应攻击者的策略未知,鲁棒性边界仍待测。
集成位点
APC 的决策点在 LLM 之外,理论上可在以下层面接入:
| 框架 | 拦截位点 | 接入难度 |
|---|---|---|
| OpenAI Agents SDK | ToolCall.from_model() → 放行前 |
中(需包装 Tool 定义) |
| Anthropic Tool Use | 火星 tool_use.on_call_created() hook |
中(官方有扩展机制) |
| LangGraph | PregelNode._run_tools() |
低(原生支持 middleware) |
| 自研 Agent | 直接在 tool dispatcher 层 | 低(纯逻辑) |
关键:六项检查需要在每个 tool call 入口同步执行;异步会引入 TOCTOU(time-of-check-time-of-use)窗口。
forbidden set F 的构建:实际最大坑
组合闭包的效果直接取决于 F(禁止组合集)的覆盖度。实际落地时:
- 手动枚举天花板明显:穷举所有危险组合不现实,尤其在工具集动态扩展的系统。
- 自动挖掘风险:可用历史日志做离线挖掘——频繁共现且导致负向结果的 action 对,加入
F。 - 动态 F vs 静态 F:静态 F 无法应对新工具;建议用"分层 F"(核心不可变 + 扩展可更新)并在每次新工具注册时触发 F 重评估。
- ⚠️ Intent Binding 是最难实现项:需要把"意图"建模为可推导的行为集合。原文方法语焉不详;实际可用 few-shot 分类器把当前 task description + tool call 序列做意图一致性打分,而非严格规则匹配。
并行 Tool Call 处理
OpenAI 和 Anthropic 均支持同轮多次 tool call 并发。APC 的组合闭包在并发下会失效(并发竞态导致闭包检查与 admission 不是原子)。实际落地必须:
- 方案 A(推荐):强制序列化 admission——同轮多 call 按固定顺序串行检查+放行,保证闭包原子性。
- 方案 B:用事务锁(乐观/悲观)保护
A_t状态,并发 check 按序列化重排。 - ⚠️ 方案 A 会显著增加首次放行延迟,需在产品需求(安全优先 vs 性能优先)间做取舍。
效用-安全权衡实操
8.6-13.9 pp 的效用损失是task-injection 对应任务下的数据。生产系统若想降低拒绝率:
- 分层拦截:低风险动作(如只读 API)跳过 Intent Binding;高风险动作(写文件、发邮件、转账)全量六项检查。
- 白名单机制:用户明确授权的动作自动放行,跳过闭包检查。
- 回退申诉:被拒的 call 进人工审核队列,标注结果反馈更新 Intent Binding 模型。
长期会话状态维护
原文 benchmark 仅测 3,154 静态实例。千轮以上会话中 budget 衰减和 scope 漂移是真实隐患。落地建议:
- APC 状态(含
A_t)需持久化到 Redis 等 KV store,支持会话恢复。 - 用户中途"修改目标"时,必须重建 Intent Binding 的意图上下文,而非复用旧的。
- budget 耗尽时不应静默拒绝,应显式通知用户"操作预算已用尽"并提供申诉路径。
开源与复现
论文代码/实现未提及是否开源(arXiv abstract 未提 GitHub 链接)。若要复现: - 六项检查逻辑相对独立,可先独立实现 + benchmark;闭包检查的计算复杂度为 O(|F|)。 - 建议优先在 LangGraph 上做 POC,迁移成本最低。