
SDK 内置 11 种工具(Read/Write/Edit/Bash/Glob/Grep/WebSearch 等),搭配 allowed_tools、disallowed_tools 两个过滤器和 5 种 permission_mode,构成一套完整的工具权限体系。本篇完整拆解 11 种工具的能力范围、两个过滤器的本质区别、权限评估的 5 步顺序,附三种典型配置代码示例和选型建议。
node_modules 删了;给太少,它跑两步就卡住。query() 调用时 Agent 可以碰什么、不能碰什么。本篇把这套机制从头到尾拆一遍。| 工具 | 做什么 |
|---|---|
Read | 读取工作目录下的任意文件 |
Write | 创建新文件 |
Edit | 对已有文件做精准修改(非整体覆盖) |
Bash | 执行终端命令、脚本、git 操作 |
Monitor | 监听后台脚本,把每行输出当事件处理 |
Glob | 按模式匹配查找文件,如 **/*.ts |
Grep | 用正则搜索文件内容 |
WebSearch | 搜索网络获取实时信息 |
WebFetch | 抓取并解析指定网页 |
AskUserQuestion | 向用户提出澄清问题(支持多选) |
Agent | 调用子代理,需显式加入 allowed_tools |
Agent 工具要单独关注:它允许 Claude 生成子代理来处理子任务,但只有你把 Agent 写进 allowed_tools 才会激活。多 Agent 编排的话题后面会单独一期讲,这里先记住它需要显式开启2。
allowed_tools vs disallowed_tools:两个过滤器的本质区别allowed_tools:预批准清单permission_mode 和 canUseTool 流程。from claude_agent_sdk import query, ClaudeAgentOptions
async for message in query(
prompt="分析这个仓库里的所有 Python 文件,找出潜在的安全问题",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep"], # 这三个直接放行,不追问
),
):
if hasattr(message, "result"):
print(message.result)disallowed_tools:硬屏蔽规则"Bash")会直接把这个工具从 Claude 的上下文里移除——Claude 根本看不见它,更无法调用。"Bash(rm *)")更细粒度:Bash 工具本身还在,但凡调用里包含 rm * 的请求,即使在 bypassPermissions 模式下也会被拦截。options = ClaudeAgentOptions(
disallowed_tools=["Write", "Edit", "Bash(rm *)"],
)permission_mode:从最严格到最宽松allowed_tools 和 disallowed_tools 是条目级的控制,permission_mode 是全局基调。两者叠加使用。| 模式 | 行为 | 典型场景 |
|---|---|---|
default | 未匹配规则的工具触发 canUseTool 回调 | 交互式开发,需要人工确认 |
dontAsk | 未预批准的工具直接拒绝,不问用户 | 无人值守脚本,固定工具范围 |
acceptEdits | 自动批准文件读写操作,其他工具走正常流程 | 快速原型开发,信任 Claude 编辑 |
plan | 只允许只读工具,Claude 仅分析不修改 | 代码评审、修改前先出方案 |
bypassPermissions | 跳过所有权限检查,全部放行 | 完全受控的沙盒环境 |
auto 模式,让模型分类器对每次工具调用做批准/拒绝判断,Python SDK 目前没有。
dontAsk + allowed_tools 的锁定组合是生产环境最常用的模式之一:# TypeScript 示例
const options = {
allowedTools: ["Read", "Glob", "Grep"],
permissionMode: "dontAsk",
};
// 效果:只有这三个工具能跑,其他所有工具调用直接拒绝,不发起询问bypassPermissions 有一个容易踩的坑:allowed_tools 管不住它。没有被 disallowed_tools 拦截的工具,在 bypassPermissions 模式下都会被放行——即使那个工具没在 allowed_tools 里。如果你想在 bypassPermissions 下禁止某个工具,必须用 disallowed_tools,不能只靠 allowed_tools 的「不列出」来限制2。disallowed_tools 匹配则立即拦截,bypassPermissions 也不例外bypassPermissions 放行一切,acceptEdits 放行文件操作allowed_tools 匹配则批准canUseTool 回调:dontAsk 模式在此步直接拒绝bypassPermissions 之前执行。这意味着如果你想在完全开放的沙盒里保留一条底线(比如任何情况下都不允许 rm -rf),用 disallowed_tools=["Bash(rm -rf *)"] 就够了。import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def analyze_codebase():
async for message in query(
prompt="找出所有 TODO 注释并生成汇总报告",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep"],
permission_mode="dontAsk", # 固定工具范围,不询问
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(analyze_codebase())options = ClaudeAgentOptions(
allowed_tools=["Read", "Edit", "Write", "Bash"],
disallowed_tools=["Bash(rm *)", "Bash(rmdir *)"], # 显式拦截删除命令
permission_mode="acceptEdits",
)options = ClaudeAgentOptions(
disallowed_tools=["WebSearch", "WebFetch"], # 断网,但代码工具全开
permission_mode="bypassPermissions",
)bypassPermissions、acceptEdits 或 auto 时,所有子代理自动继承该模式,无法在子代理层级单独覆盖。子代理会拿到和父代理完全一样的系统级权限。disallowed_tools 显式屏蔽敏感工具。allowed_tools 白名单,不需要的工具不要加。Bash 特别危险,只有真正需要执行命令时才加入Bash 用作用域写法精细化限制,比如 allowed_tools=["Bash(git log *)"] 只允许 git 只读命令dontAsk,防止 Claude 在执行过程中等待用户输入而卡死bypassPermissions 只在沙盒或测试环境中用,生产代码里出现它需要在代码审查时重点关注disallowed_tools 而非依赖「不加进 allowed_tools」,两者的覆盖范围不同stream-json 模式下如何解析消息流、处理长任务的实时输出,以及如何在流式场景下复用 session。docs.anthropic.com
docs.anthropic.com
docs.anthropic.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.