# 三行速读

  1. 安全是管道,不是开关:deny -> mode -> allow -> ask。
  2. 能力越强,越要把 “意图到执行” 这段路径做透明。
  3. 这章给后续所有新能力(后台、团队、MCP)统一上安全闸。

# 先修知识

  • 已掌握 s02 的工具路由思想。
  • 知道读写操作风险不同,需要差异化处理。

# 读完后你应该能做到(可检验清单)

# 本篇要解决什么

到这一步,Agent 已经具备真实执行力:读写文件、跑命令、改代码。执行力越强,风险越高。s07 的任务是建立 “意图到执行之间的安全闸门”。

# 用一个类比先理解

像机场安检:

  • 不是看一眼就放行;
  • 要按固定流程过几道检查;
  • 风险级别不同,处理方式不同。

权限系统也是同样逻辑:deny、mode、allow、ask 逐层决策。

# 为什么这一步必须现在做

因为后续还会接入后台任务、多智能体和外部能力。如果现在不建立统一权限管道,后面每增加一个能力都是新的风险入口。

# 关键代码怎么读

# 1) 模式分层

1
2
3
MODES = ("default", "plan", "auto")
READ_ONLY_TOOLS = {"read_file", "bash_readonly"}
WRITE_TOOLS = {"write_file", "edit_file", "bash"}

先定义模式和读写边界,是后续决策可解释的前提。

# 2) Bash 风险校验器

1
2
3
4
5
6
7
class BashSecurityValidator:
VALIDATORS = [
("shell_metachar", r"[;&|`$]"),
("sudo", r"\bsudo\b"),
("rm_rf", r"\brm\s+(-[a-zA-Z]*)?r"),
...
]

这里不是追求完美防护,而是先把高风险模式前置识别出来。

# 3) 固定顺序的决策流水线

1
2
3
4
5
6
def check(self, tool_name: str, tool_input: dict) -> dict:
# 0) bash validator
# 1) deny rules
# 2) mode check
# 3) allow rules
# 4) ask user

顺序固定非常重要,尤其是 deny 优先级必须高于 allow。

# 4) Plan 模式硬限制

1
2
3
4
if self.mode == "plan":
if tool_name in WRITE_TOOLS:
return {"behavior": "deny", ...}
return {"behavior": "allow", ...}

这对 “先勘探、后执行” 的工作流很实用,也方便团队协作时降低误操作。

# 你可以怎么复现

  1. 分别用 default/plan/auto 模式执行同一批工具调用。
  2. 记录每次 behaviorreason
  3. 检查是否符合预期策略。

# 常见误区

  • 误区 1:把权限看成单个 if,而不是多层决策链。
  • 误区 2:让高风险能力绕过 ask。
  • 误区 3:规则优先级不清,导致行为不稳定。

# 一句话总结

s07 让 Agent 从 “会执行” 升级到 “可控执行”,这是走向生产可用的分水岭。

# 补充解读:s07 的决策链为什么可扩展

权限系统做不好时,最常见问题不是 “挡不住危险操作”,而是 “规则越来越多但没人说得清为什么这次被放行 / 拦截”。

# A. DEFAULT_RULES 体现了 deny-first 思想

1
2
3
4
5
DEFAULT_RULES = [
{"tool": "bash", "content": "rm -rf /", "behavior": "deny"},
{"tool": "bash", "content": "sudo *", "behavior": "deny"},
{"tool": "read_file", "path": "*", "behavior": "allow"},
]

先写最明确的 deny,再写 allow。这个顺序能减少规则冲突。

# B. check() 的四层管线

  1. bash validator
  2. deny rules
  3. mode rules
  4. allow rules / ask

你可以把它看成 “逐层收敛” 的决策树:先快速拦高风险,再处理上下文模式,再看细粒度规则。

# C. ask_user 的价值不只是交互

1
2
if answer == "always":
self.rules.append({"tool": tool_name, "path": "*", "behavior": "allow"})

这段说明 ask 还能沉淀为长期规则,系统会越用越贴近团队习惯。

# D. 连续拒绝计数是人机协作提示

1
2
3
self.consecutive_denials += 1
if self.consecutive_denials >= self.max_consecutive_denials:
print("... consider switching to plan mode")

当模型持续请求被拒动作时,系统会提示换模式,这其实是在做 “协作状态纠偏”。

# 进阶练习

  1. 增加一条 “特定目录只读” 的规则,验证路径匹配。
  2. auto 模式下测试读写混合请求,确认 ask 行为。
  3. 记录每次 permission reason,做一份 “本周拒绝原因排行”。

# 本章再总结一次

权限系统不是为了限制能力,而是为了让能力可控、可解释、可迭代。

# 统一术语口径(本章)

  • Permission Pipeline :deny -> mode -> allow -> ask 的决策链。
  • Plan Mode :只允许读,不允许改写的保守模式。
  • Ask :风险动作需要人工确认的决策结果。

# 章节衔接(从易到难)

  • 本章解决 “执行可控性”。
  • 下一章 s08 解决 “不改主循环如何增量扩展行为”。