Agent 可靠性的双地图:攻击面与责任闭环
做 Agent 安全设计时,最容易犯的错误,是只画一张图。
一种团队只画攻击面:prompt injection、恶意网页、memory poisoning、工具滥用、数据外泄。它能告诉你“敌人从哪里进来”,却不告诉你出事时谁有权阻断、撤销和恢复。
另一种团队只画控制面:身份、RBAC、policy、审批、审计、kill switch。它能告诉你“系统有哪些门”,却不一定知道攻击到底沿哪些信息路径绕过这些门。
真正可运营的 Agent 系统需要两张图同时存在:
- Agent-Attack-Surface:不可信信息如何进入、被解释、写入状态、触发动作并继续传播;
- Agent-Security:系统如何检测、判定、授权、执行,以及在失败后撤销和恢复。
再加上 Verifiable-Agent-Engineering 的验证原则,三者合起来才形成完整的可靠性工程。
第一张图:攻击从哪里进入
Agent 的输入不只是用户 prompt。
一个生产 Agent 可能同时读取网页、邮件、文档、搜索结果、RAG、长期记忆、工具返回值、其他 Agent 的消息和历史产物。每多一种来源,就多一个信任域转换点。
可以把攻击路径压缩成五步:
不可信来源
↓
感知 / 检索
↓
上下文解释
↓
记忆 / 状态写入
↓
工具 / 外部动作
↓
新产物继续传播
这里最重要的变化,是攻击不再等于恶意指令。
Agent-Traps 说明攻击可以利用人类与机器解析路径的差异;Context-Collapse 说明低信任内容进入同一上下文后,数据与指令可能在语义层被压平;FORGE 类证据进一步说明,即使完全没有“忽略上一条指令”这类载荷,普通网页内容本身被污染,也可能改变模型的判断。
因此,“我们已经做了 prompt injection 检测”远远不等于攻击面已经闭合。
第二张图:出了问题谁能真正关门
知道攻击路径,只解决了“看见风险”。
生产系统还必须回答另一组问题:
检测
↓
判定
↓
授权
↓
执行
↓
撤销 / 恢复
这正是 Agent-Security 的五阶段责任链。
检测
Agent-Observability 负责告诉系统:
- Agent 访问了什么;
- 调用了什么工具;
- 哪些状态发生变化;
- 哪些事件可以被关联成一条行为链。
但日志存在不等于覆盖完整,更不等于已经理解风险。
判定
判定层回答:
我们看见的东西,到底是不是问题?
这里需要 policy、reference、证据和独立验证。Policy-as-Code-for-Agent-Governance 的价值,是把不可妥协的规则移出模型自由解释空间。
但 policy 写成代码,也不能自动证明 policy 本身正确。
授权
Distinct-Principal-Identity 和最小权限设计回答:
谁正在执行这个动作?它凭什么有权这么做?
身份、权限范围、有效期、资源边界和预算应尽可能绑定到具体主体与任务,而不是让 Agent 继承一个长期存在的万能凭证。
执行
真正高影响的动作不应只靠模型“决定不做”。
模型可以提出动作,但放行动作的最后一道门应尽可能是模型外的确定性机制:schema、reference monitor、sandbox、network policy、tool gateway 或其他 runtime enforcement。
Agent-Containment 的目标不是让模型永远不犯错,而是让模型犯错时仍然越不过系统边界。
撤销与恢复
这是最容易被遗漏的一层。
撤销 token,不等于撤销已经发出去的邮件;停止 workflow,不等于第三方 API 没有提交交易;把 Agent 标记成 cancelled,也不等于外部世界已经恢复到安全状态。
Alert-Closed-Loop 提醒我们:真正的闭环必须到“有人接住、采取行动、确认结果、复盘”为止。
两张图如何叠在一起
攻击面与责任链可以直接做成一个二维矩阵:
| 攻击阶段 | 必须问的控制问题 |
|---|---|
| 感知 / 检索 | 来源是否被标记?低信任内容能进入哪些上下文? |
| 上下文解释 | 数据与指令是否隔离?模型判断之外是否还有 policy gate? |
| 状态写入 | 谁允许写 memory / RAG / 用户偏好?是否可追溯和撤销? |
| 工具调用 | principal 是谁?权限、参数、次数、资源范围是否受限? |
| 外部效果 | 是否有 receipt / read-back?执行失败或未知提交怎么处理? |
| 传播 | 新产物是否保留 provenance?下一跳 Agent 是否知道来源? |
| 人类接管 | 谁收到告警?是否有上下文、权限和时间完成处置? |
这张表的价值在于,它逼迫团队同时回答两个问题:
- 攻击者能走到哪里?
- 系统在哪一层真正拥有控制权?
如果只回答第一个,得到的是威胁情报。
如果只回答第二个,得到的是治理架构图。
只有两者相交,才是安全工程。
第三层:验证“门真的有效”
即使攻击面和责任链都画出来,仍然可能只是架构设计。
Verifiable-Agent-Engineering 要求再多问一步:
我们凭什么相信这些控制真的有效?
验证至少需要覆盖四种对象:
- 结果:最终输出或外部状态是否符合要求;
- 路径:是否经过规定的关键检查点;
- 证据:判定所需的信息是否完整、可信且可追溯;
- 行为边界:系统是否在该拒绝、升级、停止时真的这么做了。
这也是为什么单一 success rate 不够。
一个任务“成功”可能同时伴随:
- 越权读取;
- 被污染证据;
- 未记录的工具调用;
- 不正确但碰巧通过测试的结果;
- 已取消但仍提交的外部动作。
生产级验证必须把“结果成功”和“过程是否在控制边界内”分开。
最小可落地的工程清单
一个不想过度设计的团队,可以先实现最小闭环:
- 列出输入与信任域:user、web、email、RAG、memory、tool output、agent message。
- 列出所有外部动作面:文件、HTTP、数据库、消息、云 API、支付/审批等高影响动作。
- 给 Agent 独立身份:不要默认复用人的万能凭证。
- 把不可妥协规则放到模型外:权限、资源范围、参数 schema、限额、网络出口。
- 记录关键状态变化:至少能把一次任务从输入追到工具调用和外部结果。
- 为高影响动作设计 read-back:不能只相信“API 调用返回成功”。
- 设计撤销与恢复路径:谁能停、停什么、什么已经无法撤回。
- 做攻击面回放:显式 injection、无指令内容污染、memory poisoning、恶意 tool output 都要测。
- 验证人类接管:告警是否真正送达有权限、有上下文的人。
- 把失败编码回系统:事故之后更新 policy、test、eval 或 action boundary,而不只修当次结果。
一个重要的边界
这套框架不是为了证明“Agent 可以完全安全”。
相反,它接受三个现实:
- 模型行为是概率性的;
- 外部环境是不可信且持续变化的;
- 高影响动作一旦离开本地 runtime,撤销常常不是原子操作。
因此目标不是消灭所有错误,而是让错误:
更难进入、更难放大、更早被发现、更容易被阻断,并且在发生后能够确定外部真实状态。
这比“让模型更听话”更接近 Agent 可靠性的工程底座。
关联知识
- Agent-Attack-Surface:攻击从哪里进入、如何传播
- Agent-Security:检测到恢复的责任闭环
- Verifiable-Agent-Engineering:怎样证明控制和结果可信
- Agent-Traps:攻击 taxonomy
- Agent-Containment:限制最坏后果
- Agent-Observability:构造可追踪行为链
- Policy-as-Code-for-Agent-Governance:把治理规则移到模型外
- Distinct-Principal-Identity:建立主体、权限与责任边界
- Alert-Closed-Loop:让告警最终变成人类行动与结果确认