☰
如何让Agent安全地执行危险命令?learn-agent-architecture 的权限模式与沙箱设计完全指南
2026/10/15 17:45:14 网站建设 项目流程

【免费下载链接】learn-agent-architecture

Learn AI agents from scratch.

项目地址:https://gitcode.com/gh_mirrors/aw/learn-agent-architecture
点击查看免费下载

AI Agent 能执行 shell 命令、改写文件,一次错误的工具调用就可能删除文件、泄漏机密。开源项目 learn-agent-architecture 用"权限模式 + 沙箱"这套设计,让每个动作真正影响系统前都必须先通过检查。本文面向新手,完整讲解 Agent 权限门(permission gate)、allow/ask/deny 三态决策与沙箱限制的落地思路。

🛡️ 核心观点:信任不是安全边界,代码检查才是。

为什么只靠"信任模型"防不住危险命令?

大多数 Agent 共享同一套循环:调用模型 → 执行它要求的工具 → 把结果加回对话 → 再次调用模型(见 Agent loop 章节)。如果没有权限门,这个工具运行环境几乎等同于一个没人看管的远程 shell。

风险来自三项能力的组合,社区称之为lethal trifecta(致命三要素):

  1. 📄 能读取私密数据(源码、凭证);
  2. 🌐 会接触不可信内容(网页、issue 留言、仓库文件中暗藏的注入指令);
  3. 📤 能把数据送到外部。

三项同时出现时,恶意内容就可能诱使 Agent 读取机密并外传。持久化 memory 还会放大风险——恶意指令一旦写入 memory,下一次 session 就会把它读回来,让一次注入跨越整个对话延续下去。

所以权限层的目标不是直接砍掉这三种能力(否则 Agent 无法干活),而是两层保护:

  • 会凑齐三要素的调用,前面先摆一道决策门;
  • 已经放行的调用,后面再用沙箱限制影响范围。

权限门机制:decide() 做出 allow / ask / deny 三态决策

整个权限决策由一个纯函数decide()完成:读取工具、当前 mode、所有 allow 规则,返回三个值之一:

决策含义结果
allow直接执行工具产生真实副作用
ask暂停并询问用户用户批准才执行,否则拒绝
deny不执行工具直接返回拒绝消息

关键设计点:

  • ✅纯函数、无 I/O:可以一个 mode 一个 mode 地单元测试,决策逻辑透明可审计。
  • ✅拒绝也是一种结果:deny或未批准的ask会返回tool_result消息,模型"看得到"发生了什么,并能自行调整策略,而不是静默失败。
  • ✅默认拒绝:approver默认为False,也就是说没有人类在场时,ask等价于"否"。

权限门挂在循环的分发环节_dispatch内部,就在真正执行工具之前:

decision = permissions.decide(tool, mode, allow_rules) # 先过门 if decision == "deny": return res(f"{name} not allowed in {mode} mode") if decision == "ask" and not approver(name, block.input): return res(f"{name} denied by user") return res(run_tool(tool, block.input)) # 现在才真正执行

📁 源码位置:

  • 权限决策:permissions.py
  • 循环集成:loop.py
  • 离线测试(无需 API key):test.py
  • 章节完整说明:README.zh-CN.md

四种权限模式:如何改变默认行为

mode 决定了"拿不准时怎么办"。decide()实现了四种 mode,与 Claude Code 的权限类型一一对应:

Mode适用场景只读工具编辑工具Bash 等高危工具
default日常默认允许询问询问(除非在 allow 规则中)
acceptEdits批量改代码允许允许(预先批准的一类工作)询问
plan探索、制定计划允许拒绝(批准前无副作用)拒绝
bypassPermissions用户明确退出检查允许允许允许

几个值得注意的细节:

  • 🔍plan模式下唯一能触发"询问"的是ExitPlanMode——这是与 Planning 章节 的计划批准握手,计划未批准前不产生任何副作用。
  • ⚠️bypass是用户主动退出检查,范围必须保持狭窄,且当前 mode 应始终可见,防止过宽的 allow 规则让后续高风险调用悄悄执行。

沙箱设计:三道限制挡住"判断错的那次 allow"

权限门也会判断错。沙箱的作用,就是让误放行不要付出太大代价。三个限制就能挡掉大部分风险:

1. Egress:网络默认挡掉

放行的流量走一个握有 host 允许列表的 proxy。三要素中"对外通讯"这一项被直接切掉——Agent 照样读代码、写文件,但哪里都送不出去。

2. Mount:只给该给的文件

源代码用只读挂载,凭证文件一个都不挂,只给一个可写的工作目录。Agent 打不开的文件,就外泄不出去。

3. Quota:资源上限 + 可读取的错误

CPU、内存、磁盘、wall clock 时间都设上限。踩到上限时,回一个错误当 tool result,而不是悄悄杀掉进程——模型读得到 timeout,就知道换一条更短的指令;悄悄杀掉,它什么都学不到。

两个容易踩的坑:字符串匹配与批准疲劳

🚫 坑一:deny 列表比对字符串必然被绕过

rm -rf /很好抓,但这些变体会溜过去:

  • find . -exec rm {} \;—— 删除动作藏在 flag 里;
  • $(echo rm) -rf /—— shell 运行时才拼出rm;
  • curl -o /etc/crontab—— 没用到任何"写入指令"却写了一个文件。

解法是解析指令结构而不是比对字面:把指令拆成程序和参数,判断每个程序实际会做什么(-exec自带的指令要连带检查,-o指向的路径按一次写入检查)。解析器不认识的程序就读不懂,所以沙箱必须挡在它后面兜底。

🙅 坑二:每次调用都询问会训练用户盲点"批准"

正确做法是预先批准低风险类别(如只读工具、编辑类工作),让破坏性动作维持明确询问;真正的高风险调用才停下来问人。如果连询问前的检查本身很慢,还可以做"推测式检查":检查丢到后台先跑,画面先显示一行不改系统的进度;检查若已回allow,提示框根本不出现。提前跑的只有检查,工具本身仍要等检查给答案,安全性不受影响。

动手跑跑看:两条命令验证权限门

python sections/03-permission-sandbox/src/test.py # 离线检查,无需 API key uv run python sections/03-permission-sandbox/src/demo.py # 实时演示,需要 ANTHROPIC_API_KEY

test.py会逐项验证:plan模式拒绝编辑、acceptEdits放行编辑、default下Bash走ask且无人批准即被拒——全部断言通过即打印03 permissions: ok。

从第 3 章出发:完整的 Agent 架构学习路径

权限门只是整个 harness 的一层。learn-agent-architecture 共 24 章,逐层搭建从最小 loop 到可自运转系统的完整架构,每一章都附带可运行的src/代码,对比相邻章节的 diff 就能看到新增机制。

与权限沙箱最相关的前后章节:

章节解决的问题与权限的关系
04 · Hooks扩展功能怎么挂进 loopPreToolUse在权限门之前执行,可挡下或改写调用
05 · Planning & todos大工作怎么拆解plan mode 与编辑批准握手
06 · Subagents子问题怎么被隔离子 Agent 无终端可问,提示应上抛给父 Agent 代问
15 · Worktree isolation并行工作怎么避免冲突用 git worktree 做文件系统级隔离

📚 更多设计细节(推测式检查、管路径不只管结果等)见 第 3 章延伸阅读。


一句话总结:让 Agent 安全执行危险命令的答案不是"更信任模型",而是在每个副作用前面摆一道可测试的权限门(allow/ask/deny),再用 Egress、Mount、Quota 三道沙箱限制兜底——这正是 learn-agent-architecture 第 3 章的完整设计。

【免费下载链接】learn-agent-architecture

Learn AI agents from scratch.

项目地址:https://gitcode.com/gh_mirrors/aw/learn-agent-architecture
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询