在构建 AI Agent 时,权限控制 (Permissions) 是连接“智能”与“安全”的护城河。你肯定不希望你的 Agent 在未经允许的情况下删除了生产环境的数据库,或者在调试时因为频繁的“请求批准”弹窗而打断心流。
Anthropic 的 Claude Agent SDK 提供了一套类似“洋葱圈”的层级权限管理机制。本文将带你深入理解其评估流程,并实战配置 Permission Modes,教你如何根据场景灵活切换 Agent 的“安全等级”。
🔍 原理揭秘:权限是如何被评估的?(Evaluation Flow)
当 Agent 试图调用一个工具(比如写文件 write_file、运行终端命令 bash)时,SDK 不会立即执行,而是会像过安检一样,严格按照以下 4 个步骤 的顺序进行检查。
一旦在某一步骤被明确“允许 (Allow)”或“拒绝 (Deny)”,流程就会终止,不再继续检查后续步骤。
1. Hooks (钩子函数) - 最优先
这是第一道关卡。你可以编写自定义 Python 代码,在最早期拦截特定请求。
- 场景:比如你写了一个钩子,禁止 Agent 在周五下午 5 点后运行任何部署命令。
2. Permission Rules (规则配置) - 声明式
SDK 会检查 settings.json 中的静态规则。
- 优先级:
Deny(黑名单) >Allow(白名单) >Ask(询问)。 - 场景:在团队共享配置中,强制禁止
rm -rf等高危命令,无论代码怎么写都无法绕过。
3. Permission Mode (权限模式) - 全局设定
这是我们本文实战的重点。它决定了 Agent 的默认行为倾向。
4. canUseTool Callback (回调兜底) - 最终裁判
如果以上所有步骤都无法决定(例如:模式是 default,且没有匹配任何规则),SDK 会调用此回调,通常表现为在终端弹出一个 (Y/N) 的交互式提示,等待用户人工确认。
🚦 核心概念:4 种权限模式 (Permission Modes)
Claude Agent SDK 提供了四种预设的权限模式,适用于从“完全受控”到“完全自动”的不同场景:
| 模式 (Mode) | 读权限 | 写文件/文件操作 | 终端命令 | 适用场景 |
|---|---|---|---|---|
default | ✅ | ❓ 询问 | ❓ 询问 | 生产环境、敏感操作、安全第一 |
acceptEdits | ✅ | ✅ 自动 | ❓ 询问 | 开发辅助、代码重构、原型开发 (推荐) |
plan | ✅ | ❌ 禁止 | ❌ 禁止 | Code Review、方案设计、只读分析 |
bypassPermissions | ✅ | ✅ 自动 | ✅ 自动 | CI/CD、无人值守脚本 (慎用!) |
注:acceptEdits 会自动批准 mkdir, rm, mv, cp 以及文件编辑工具,但不会批准 curl 或非文件系统的 bash 命令。
💻 Python 实战指南
在开始之前,请确保你已经安装了 SDK 环境。
实战一:在查询初始化时设置权限 (Query Time)
这是最基础的用法。当你启动一个 Agent 会话时,可以通过 options 字典直接指定权限模式。
场景:创建一个自动重构代码的 Agent,我们希望它能直接修改文件,不需要每改一行都问我。
Python
import asyncio
from anthropic.agent import Agent # 假设的导入路径,请根据实际 SDK 包名调整
async def refactor_code_session():
print("🤖 Agent 启动中... (模式: acceptEdits)")
agent = Agent()
user_prompt = "请扫描当前目录下的 main.py,将所有的 print 语句替换为 logging 模块的调用。"
try:
# 调用 query 接口
# 🔑 关键点:options 参数中的 permission_mode
stream = await agent.query(
prompt=user_prompt,
options={
"permission_mode": "acceptEdits", # ✅ 自动允许文件修改,无需弹窗
"verbose": True
}
)
async for message in stream:
print(message)
except Exception as e:
print(f"❌ 发生错误: {e}")
if __name__ == "__main__":
asyncio.run(refactor_code_session())
实战二:在流式对话中动态升级权限 (Dynamic Switching)
有时候,你希望 Agent 先处于“安全模式” (plan) 给你提出方案,等你确认方案无误后,再赋予它“自动执行”的权限。
场景:先询问计划,满意后再自动执行。
Python
import asyncio
from anthropic.agent import Agent
async def interactive_session():
agent = Agent()
print("🔒 初始模式: PLAN (只读)")
# 1. 初始查询:使用 'plan' 模式,确保 Agent 只能看不能改
# Agent 会分析代码并告诉你它打算做什么,但如果它尝试修改文件,会被拦截
initial_prompt = "请帮我规划一下如何将当前项目的 Flask 迁移到 FastAPI。"
stream = await agent.query(
prompt=initial_prompt,
options={
"permission_mode": "plan" # ✅ 初始为只读模式
}
)
async for message in stream:
# 这里处理 Agent 返回的计划文本...
print(message)
# --- 假设这里是用户交互环节 ---
user_approval = input("\n👤 计划看起来如何?是否批准执行?(y/n): ")
if user_approval.lower() == 'y':
print("\n🚀 用户已确认,正在提升权限为 'acceptEdits' 并执行...")
# 2. 后续查询:用户批准后,发送执行指令并升级权限
execute_prompt = "计划通过,请开始执行文件修改。"
exec_stream = await agent.query(
prompt=execute_prompt,
options={
"permission_mode": "acceptEdits" # ⚡️ 动态升级权限!
}
)
async for msg in exec_stream:
print(msg)
else:
print("❌ 操作已取消")
if __name__ == "__main__":
asyncio.run(interactive_session())
⚙️ 进阶配置:持久化规则 (settings.json)
除了在代码中动态控制,你也应该了解如何配置静态规则。在项目根目录下的 .claude/settings.json 中,你可以定义团队共享的安全规范。
JSON
{
"commands": {
"allow": ["ls", "git status", "pytest"],
"deny": ["rm -rf /", "format c:"]
},
"filesystem": {
"deny": ["/etc/*", "C:\Windows\*", "*.env"]
}
}
最佳实践建议:
- 开发阶段:默认使用
acceptEdits模式,既能快速迭代代码,又能防止误触非文件系统的敏感操作。 - 生产/CI环境:如果必须自动化,使用
bypassPermissions但配合严格的Deny Rules(在settings.json中配置) 来兜底。 - 敏感操作:对于涉及支付、删除数据库等操作,尽量不要使用
bypassPermissions,应当保留canUseTool的人工确认环节。
希望这篇教程能帮助你更好地驾驭 Claude Agent!如果你觉得有用,别忘了点赞收藏 👍