权限
权限检查发生在工具执行前,由运行工具的 harness 负责。策略可以允许、拒绝,或请求人工批准。本例的优先级为 deny > ask > allow。ask 只开始等待,收到肯定答复后才能调用工具。
假设智能体需要读取项目笔记并更新文件:普通读取可直接执行,受保护文件不能读取,写入要先审核。检查必须放在操作前;读取之后才检查,内容早已被访问。
权限如何在执行前拦截调用
模型提出工具名和参数,harness 收到后先检查规则。每条规则包含效果、工具名、目标。目标可以是精确文件名,或匹配该工具所有目标的 *。
分发器收集匹配效果,再按 deny、ask、allow 的顺序选择,与画面的规则排列无关。广泛 allow 和指定文件的 deny 同时命中时,deny 胜出是因为效果优先级,并非窄匹配天然优先。本例没有匹配规则时默认拒绝。
- deny:调用工具前返回阻止状态,不请求人工答复。
- ask:为这一次调用请求答复。肯定则继续,拒绝则阻止,未答复则等待。
- allow:直接继续到工具调用,不弹批准提示。
这些是策略决定,最终状态则是 executed、blocked、waiting。allow 只允许尝试调用,不证明已经执行,也不保证成功。
Python 分发器把执行边界放在 run_tool(call)。所有阻止分支都在它上方返回。批准适配器返回 True、False、None,最后一个代表尚无答复。生产异步实现应保存待处理调用,在答复到达后恢复,而不是等待时编造一个工具错误发给模型。
权限逐步演示
默认写入规则为 ask,模拟答复为 approve,内存文件 notes.txt 初始为 draft。每次重放使用相同的三个请求和初始数据。
| 规则 | 效果 | 工具 | 目标 |
|---|---|---|---|
| r1 | allow | Read | * |
| r2 | deny | Read | secrets.txt |
| r3 | ask | Write | notes.txt |
1. 读取普通文件。 c1 为 Read("readme.txt"),只有 r1 匹配。分发器选择 allow,越过 deny、ask 分支并执行 Read,返回 Project notes。工具执行 1 次,批准提示 0 次,notes.txt 不变。
2. 读取受保护示例文件。 c2 为 Read("secrets.txt"),r1、r2 同时匹配,选择 deny。分发器以 Denied by policy 返回 blocked,从未调用 Read。c2 执行数为 0,总数仍为 1。harness 可向调用方报告拒绝,无需伪造工具结果。
3. 请求写入。 c3 为 Write("notes.txt", "reviewed"),r3 选择 ask。批准卡片标出 c3 和目标,调用停在执行边界前。提示数为 1,执行数仍为 1,文件仍为 draft。
4. 收到批准,再执行。 模拟答复批准 c3。答复出现的那一步,文件仍未变化;分发器还要进入调用行。下一步 Write 才把 draft 改为 reviewed,总执行数变为 2,再返回工具结果。
最终账本记录:c1 为 allow → executed,c2 为 deny → blocked,c3 为 ask → approve → executed。共三个请求、两次执行、一个阻止。顶部计数累计所有调用,当前世界面板只计正在展示的这一次调用。
时间与空间复杂度
有 R 条规则时,在本课固定长度工具名和目标字符串的条件下,匹配为 O(R)。效果只有三种,解析优先级为 O(1)。不同效果集合最多三个元素,因此显示的分发器辅助空间为 O(1),不计输入规则和工具自身工作。
教学轨迹还保存匹配规则 ID 与快照,以便回看;这是可视化的存储成本,不是权限分发的必要开销。人工答复延迟也不属于计算复杂度:策略检查很快,请求仍可能一直等待。
边界情况
没有答复。 选择 ask 与 Unanswered,写入保持 waiting,文件保持 draft,整次运行只执行前面的普通读取。播放器到末帧不代表请求获批;等待与拒绝是不同结果。
拒绝写入。 选择 ask 与 Decline,适配器返回否定答复,分发器返回 blocked。账本有两个阻止:受保护读取和被拒写入;只执行一次普通读取。
授权范围超出预期。 选择 allow 与 Decline,系统根本不请求写入批准,因此不读取这个假设答复。Write 仍执行,文件变为 reviewed。想让人决定,策略必须走 ask;仅选择答复不会创建提示。
deny 配上肯定答复。 选择 deny 与 Approve,分发器在调用批准适配器前就返回,答复无法覆盖规则,文件保持 draft。
没有匹配规则。 本分发器默认拒绝,其他产品可有不同模式,应按实际契约配置。这里只做精确文件名或 * 匹配,notes.txt 不匹配 notes.txt.bak。
常见错误
- 先执行再检查。 阻止返回无法撤回已经暴露的读取内容;调用点必须在权限检查之后。
- 让第一条显示规则胜出。 显示顺序与效果优先级不同。若先处理 allow,r1 就可能放行受保护文件。
- 把提示当成授权。 提示开始等待,不是答复。本例 ask 只有收到肯定答复才继续。
- 把请求数当成执行数。 三个请求都到达 harness,默认只有两个到达工具。
- 把获准当成成功。 权限决定能否尝试,获准工具仍可能失败。工具调用 解释错误如何返回循环。
模型的简化
这是确定性权限分发器的说明,不是生产安全实现或安全培训替代品。请求预先编写,文件仅在浏览器内存中,没有真实凭据、文件系统写入、外部操作或模型录制。每组输入的匹配、决定和效果由分发器计算。
生产系统还需处理路径规范化、权限模式、hooks、记忆或限定范围的授权、取消,以及所有资源访问入口。拒绝一个 Read 工具不代表其他工具无法打开同一文件。应用权限与 OS 沙箱控制不同边界。本课省略这些机制,集中观察提前返回与唯一调用点。
参考与后续课程
Claude Code 权限文档 描述 deny/ask/allow 及优先级,完整引擎还包含模式和 hooks。Agent SDK 人工批准指南 解释答复处理;本课同步返回值是更小的教学接口。
回到智能体循环,可把检查放在模型提出动作与 harness 调用工具之间。任务系统 则解释另一项运行时职责:进程重启后保留已完成工作。