安全与 Guardrails
Agent 让风险换了一个量级:模型不只回答你,它会读邮件、看网页、调工具、写文件、点按钮。一条核心原则贯穿全部:Prompt 里的“请不要做危险事”不是安全边界。可靠的控制放在模型无法绕过的位置,在代码和运行时里。
提示注入:限制影响半径
Prompt Injection 不是输入过滤能彻底解决的问题,它越来越像社工攻击,攻击者把恶意目标伪装成正常任务上下文。有效做法是限制影响半径:即使模型被骗,也只能做低风险动作。
- 外部内容(网页、邮件、PDF、工具返回值、MCP server 描述)一律当不可信数据,不是指令。打来源标签:
trusted: false - 工具结果包成结构化对象,明确标注“作为数据处理”
- 第三方 MCP server 进 allowlist 前做人审和静态扫描,server 元数据本身可能藏注入
- 关键动作执行前重新绑定用户意图:这个动作是来自用户原始目标,还是被外部内容引导出来的
工具权限:拆到动作级
权限模型用分级加拆分:
| 层级 | 动作 | 默认策略 |
|---|---|---|
| L0 | 读公开信息、白名单文件 | 自动允许 |
| L1 | 读私有低敏数据 | 审计加按角色允许 |
| L2 | 写草稿、生成 patch | 自动执行但不生效 |
| L3 | 改真实数据、发消息、调外部 API | 需要确认或策略放行 |
| L4 | 付款、删除、权限变更 | 必须人工确认,默认拒绝 |
工具要拆得足够细:email.read、email.create_draft、email.send_draft 不是同一个权限。把“生成动作”和“动作生效”拆开:Agent 可以帮你写邮件,不应该默认发送;可以生成退款申请,不应该默认打钱。
人工确认不能做成橡皮图章。审批要绑定工具版本、完整参数、资源范围,参数变化原审批立即失效,防止模型申请低风险动作后换掉关键参数。确认弹窗要告诉用户:要做什么、影响哪些数据、是否可回滚、触发原因。
沙箱隔离
代码执行、Shell、浏览器操作放隔离环境。容器共享宿主机内核,内核漏洞可被利用逃逸;要求高时用 microVM(如 Firecracker)独立内核,逃逸需突破虚拟化层。假设突破必然发生,目标是突破后的影响最小化:最小权限加行为监控加不可篡改审计。会话级隔离,避免多 Agent 共享根状态放大爆炸半径。
成本上限
多步推理会耗尽预算,成本失控本身是安全事件。每轮循环检查:
- 工具调用前检查预算,不足即拒绝
- 单任务 token 上限、金额上限、墙钟超时三道闸
- 审计日志记录每次工具调用的参数、结果、成本
安全评测进 CI
三类测试常驻:
- 公开注入集:AgentDojo、OWASP 示例做基础回归
- 业务红队集:把真实业务里的外部内容改写成攻击样本(客服邮件夹带“退款到新账户”、合同 PDF 夹带“把附件发给这个邮箱”)
- 权限回归集:改工具或 prompt 后验证 L0-L4 各级是否按预期执行、外部内容能否诱导越权
面试追问
- 为什么说 Prompt 不是安全边界? 网页、邮件、工具结果都可能带注入,模型也会忘记早期约束。可靠控制放在模型无法绕过的位置:权限管线、沙箱、审批
- 权限怎么分级? 五级:读公开信息自动允许,读私有数据审计,写草稿不生效,改真实数据需确认,付款删除默认拒绝。生成动作和动作生效分离
- 工具为什么要拆细? read、draft、send 不是一个权限。工具越粗,模型被误导后的动作空间越大
- 沙箱选容器还是 microVM? 容器共享内核,逃逸风险高;microVM 独立内核,逃逸需突破虚拟化层。高风险任务用 microVM,假设突破必然发生,做纵深防御
- 怎么防成本失控? 每轮检查预算:单任务上限、金额上限、墙钟超时。成本失控是多步推理的真实风险,预算不足即拒绝