7.5. 安全架构需要对工具调用和记忆访问施加细粒度控制
安全架构需要对工具调用和记忆访问施加细粒度控制
2025 年 11 月,一家电商公司的 AI 运维 Agent 在执行“清理过期日志”的指令时,自主追加了一条 --purge 参数。结果,不仅 30 天前的归档日志被删除,当天的实时交易流水也一同消失。事后复盘发现,Agent 并非遭遇攻击,只是忠实地组合了它“能访问的所有工具调用”去完成用户的模糊意图。
这不是 AI 失控,而是权限设计缺位。
当私有模型接入完成(如上一章所述),Agent 就正式成为了企业数据的“持钥人”。它可以调用 API、执行 Shell 命令、读写向量数据库中的长期记忆——这一切让 Agent 变得强大,但也让它变成一个危险的执行器。本章要解决的核心问题只有一个:怎么在赋予 Agent 能力的同时,确保它不会越权操作?答案藏在三个层层递进的防线里:工具权限分级与沙箱、记忆访问控制策略、以及覆盖所有变更的审计日志。
现象:Agent 越权不是意外,是缺少权限模型的必然结果
在 Hermes Agent 的安全设计文档中,有一组被反复提及的数据:2026 年初的 GitHub Issues 里,超过 40% 的“高危场景”反馈与工具调用权限过宽有关。典型案例如下:
| 场景 | 用户意图 | Agent 实际行为 | 漏洞根因 |
|---|---|---|---|
清理 /tmp 缓存 |
删除临时文件 | 递归删除 /tmp 下所有内容,包括其他服务的运行时 socket |
工具调用未限制路径范围 |
| 查询用户信息 | 从数据库读取姓名和邮箱 | 执行了一条无 WHERE 子句的 SELECT *,返回整表 |
SQL 工具权限未设定为只读 |
| 发送日报 | 调用企业微信 API 推送消息 | 同时读取了群聊历史记录并存入个人记忆 | API 密钥的 scope 过大 |
这些案例的共同点不是“Agent 发疯了”,而是工具调用权限与记忆访问权限没有细粒度控制。当 Agent 拿到一把万能钥匙时,我们不能期待它自己决定哪些门可以开——这个边界必须由架构预设。
核心维度一:工具权限分级与沙箱——按风险等级切分执行边界
第一道防线在工具调用的出口处。Hermes Agent 的内部设计中,Skill(技能)是一个基本执行单元,每个 Skill 对应一组工具调用。对 Skill 实施权限分级,本质是在回答一个问题:“这个 Agent 能碰什么,能碰多远?”
风险等级定义
根据调研资料中 Hermes 的危险命令列表和审批机制,可以将工具调用按风险分为四个等级:
| 等级 | 风险标签 | 允许的操作 | 限制 | 示例 |
|---|---|---|---|---|
| L0 | 只读 | 读取文件、查询 API、查询数据库 | 禁止任何写操作 | cat、SELECT、curl GET |
| L1 | 文件写入 | 创建/修改指定目录下的文件 | 路径白名单;禁止修改隐藏文件 | echo > /data/reports/ |
| L2 | 网络出站 | 调用外部 API、发送消息 | 目标域名/IP 白名单 | 企业微信 Webhook、Slack API |
| L3 | 命令执行 | 运行 Shell 命令、管理进程 | 必须通过危险命令审批;推荐使用容器沙箱 | systemctl restart、docker exec |
设计要点:
- L0~L1 是绝大多数“数据查询 Agent”需要的权限,应当设为默认值。
- L3 不应作为默认能力开放,必须由管理员显式赋权。
- 每个 Skill 声明自己所需的最低权限等级,Agent 运行时强制校验。
沙箱执行环境
Hermes 的安全文档明确指出:当使用 Docker/Singularity/Modal 等容器后端运行时,部分危险命令审批会自动跳过——因为容器本身已构成隔离边界。这不是放松安全,而是将信任从“审批人的判断”转移到“环境的约束”。
沙箱配置推荐(以 Docker 为例):
docker run --rm \
--read-only \
--tmpfs /tmp:noexec,nosuid,size=256M \
--network=none \
--cap-drop=ALL \
--security-opt=no-new-privileges \
hermes-agent:latest
表格形式总结如下:
| 沙箱策略 | 作用 | 适用风险等级 |
|---|---|---|
--read-only |
禁止写入容器文件系统 | L2~L3 |
--network=none |
禁止网络出站 | L3 |
--cap-drop=ALL |
移除所有 Linux Capabilities | L3 |
--tmpfs /tmp:noexec |
允许临时文件但禁止执行 | L1~L3 |
这种“即使 Agent 失控,攻击面也被锁定在容器内”的设计,是纵深防御的第一道物理隔离。
核心维度二:记忆访问控制策略——区分 user 和 system 记忆的读写边界
工具调用是“向外”的操作,记忆访问则是“向内”的操作。Agent 的长期记忆(通常存储在向量数据库或 Key-Value 存储中)分为两类:
| 记忆类型 | 归属方 | 可见性 | 典型内容 |
|---|---|---|---|
| user 记忆 | 终端用户 | 仅该用户可见(按 user_id 隔离) | 个人偏好、历史对话摘要、自定义指令 |
| system 记忆 | Agent 系统 | 所有实例可见(跨用户共享) | 系统配置、全局知识库、共享 Skill 定义 |
当前调研资料尚未明确给出 Hermes 记忆系统的权限控制细节,但从架构原则看,最小权限在此处的实践应是:
- user 记忆的隔离:Agent 处理用户 A 的请求时,只能读取/写入 user_id=A 的记忆分区。任何跨用户记忆访问都应被拦截。
- system 记忆的只读保护:普通 Agent 实例对 system 记忆仅有读取权限,修改操作必须经过管理 API 或人工审批。
- 记忆写入的意图确认:当 Agent 计划将对话中获取的信息写入 user 记忆时,应提示用户确认(尤其是涉及 PII 或敏感数据时)。
操作矩阵(推荐设计):
| 角色 | 读 user 记忆 | 写 user 记忆 | 读 system 记忆 | 写 system 记忆 |
|---|---|---|---|---|
| 普通 Agent 实例 | 仅自己的 user_id | 仅自己的 user_id(需意图确认) | 允许 | 拒绝 |
| 管理 Agent 实例 | 允许(审计记录) | 拒绝(不应修改用户数据) | 允许 | 允许(需审批) |
| 调试模式 | 允许(用户授权后) | 允许(用户授权后) | 允许 | 拒绝 |
这个矩阵的核心逻辑是:user 记忆是用户的隐私资产,system 记忆是团队的知识资产,不同的资产有独立的访问控制面。
核心维度三:审计日志与异常检测——让每一次越权尝试都被记录
即使有了分级和沙箱,安全架构的最后一环仍是“可观测”。如果一条危险命令被拒绝了,但没有任何记录,我们就失去了对攻击行为的感知能力。
需要记录的事件
| 事件类别 | 需记录的字段 | 保留周期建议 |
|---|---|---|
| 工具调用 | 用户 ID、时间戳、Skill 名称、完整命令、审批结果(通过/拒绝/超时)、执行环境 | 90 天 |
| 记忆变更 | 用户 ID、时间戳、操作类型(读/写/删)、记忆 key、变更内容摘要(非全文) | 180 天 |
| 权限变更 | 操作用户 ID、时间戳、变更详情(赋予/撤销哪个用户什么权限) | 永久 |
| 异常模式 | 触发规则 ID、时间戳、上下文快照 | 30 天(滚动分析) |
异常检测规则(示例)
从 Hermes 的危险命令匹配思路出发,可以扩展为一组持续运行的检测规则:
| 规则 | 检测逻辑 | 告警等级 |
|---|---|---|
| 高频拒绝 | 同一用户 1 分钟内触发 5 次以上工具调用被拒绝 | 中 |
| 记忆扫描 | 短时间内大量读取记忆 key 但无会话交互 | 高 |
| 权限逃逸尝试 | 被拒绝的 L3 命令后紧跟着尝试 L2 命令绕过审批 | 严重 |
| 非工作时间活跃 | 凌晨 2~5 点出现 L2 级以上工具调用 | 待确认(视业务而定) |
关键提醒:审计日志本身也是敏感数据——它记录了“谁在什么时候做了什么”。日志的存储应加密,访问权限应与生产环境权限分离。
结论:安全架构的核心不是“信任 Agent”,而是“不信任任何单一执行路径”
这三个维度——工具分级、记忆隔离、审计检测——共同构成了 Agent 安全的三脚架。它们回答的是同一个底层问题:如果 Agent 犯错了(或被诱导犯错了),破坏力能被限制在多大范围内?
不同场景下的推荐配置
| 使用场景 | 工具权限等级 | 沙箱模式 | 记忆隔离 | 审批模式 |
|---|---|---|---|---|
| 内部数据分析 Agent | L0(只读) | 无需沙箱 | user 隔离 | smart 模式 |
| 自动化运维 Agent | L1~L3 | Docker 沙箱 | user 隔离 + system 只读 | manual 模式(默认需审批) |
| 面向客户的对话 Agent | L0~L1 | 轻量沙箱(tmpfs) | user 隔离 + 写入需确认 | smart 模式 |
| 开发调试环境 | L3(全开) | 独立开发容器 | 隔离但允许手动操作 | off 模式(需显式开启 YOLO) |
作者的结论:最安全的 Agent 不是“一个漏洞都没有”的 Agent,而是 “即使出现意外行为,影响也能被沙箱限制、被审批拦截、被审计追溯” 的 Agent。从架构第一天起,就把“能做什么”和“不能做什么”刻成代码的硬边界,而不是靠提示词里的“请勿删除生产数据”来祈祷 Agent 自律。
在下一章中,我们将从安全转向成本——当 Agent 频繁调用大模型时,Token 的消耗会成为隐藏的系统开销。“Token 预算管理是成本控制的核心战场” 将告诉你,如何在不牺牲能力的前提下,把每一次调用的开销降到可控范围。安全护住了下限,成本护住了可持续性——两者缺一不可。
Hermes Agent 系统设计与工程落地
关于 LearnKu