Claude Agent SDK #1:query() 函数全解——三行代码启动一个自主 Agent

整个 Claude Agent SDK 只有一个主入口:query()。本篇完整拆解它的三个核心参数(prompt / ClaudeAgentOptions / 消息流)、五种 permission_mode 的适用场景与安全边界、内置工具组合策略,以及 async for 消息流的正确消费方式——帮你从第一行代码就建立对 SDK 的完整心智模型。

Claude Code SDK 每日技术拆解
May 25, 2026 · 6:17 PM
2 subscriptions · 35 items

Research Brief

用了这么久 Claude Code,你知道它背后的 SDK 怎么用吗?
Anthropic 把驱动 Claude Code 的整个 Agent 引擎开放成了 SDK——Claude Agent SDK。你可以用几行代码,让 Claude 自主读文件、改代码、跑命令,全程不需要你实现工具循环。
今天是新系列第一篇,拆解 SDK 最核心的入口:query() 函数。

🔑 一切从 query() 开始
整个 SDK 只有一个主入口:
from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="找出 auth.py 里会崩溃的 bug 并修复",
    options=ClaudeAgentOptions(
        allowed_tools=["Read", "Edit", "Glob"],
        permission_mode="acceptEdits",
    ),
):
    if hasattr(message, "result"):
        print(message.result)
就这样。Claude 会自己读文件、分析逻辑、调用工具、写回修复——你只负责消费消息流。

⚙️ query() 的三个核心参数
prompt——你想让 Agent 做什么,用自然语言描述即可。Claude 根据任务自己决定调哪些工具、用什么顺序。
optionsClaudeAgentOptions——控制 Agent 行为边界:
  • allowed_tools:预授权工具列表,列在里面的工具 Claude 可以直接调用,不需要每次询问
  • permission_mode:权限模式(见下)
  • system_prompt:给 Claude 的角色定制指令
③ 返回值:async 消息迭代器——query() 是异步生成器,async for 消费每一条消息,Claude 思考、工具调用、工具结果、最终输出都会依次流出

🛡️ permission_mode:五种权限模式
这是 ClaudeAgentOptions 里最容易踩坑的参数:
模式行为适用场景
acceptEdits自动批准文件读写,其他操作询问本地开发
dontAsk只允许 allowed_tools 里的工具,其余全拒锁定式无人值守
bypassPermissions所有工具直接执行,不询问完全隔离的 CI 沙盒
auto(TS 专属)模型分类器自动判断每个工具调用带安全防护的自主 Agent
default需要你提供 canUseTool 回调处理审批自定义审批流程
生产环境建议:配合 allowed_tools + dontAsk 白名单锁死,绝不用 bypassPermissions 跑在你的真实文件系统上。

📦 内置工具一览
allowed_tools 里能填哪些?SDK 内置了一整套:
  • Read / Write / Edit:读写文件,Edit 可精确按行范围替换
  • Bash:执行终端命令、git 操作、跑测试
  • Glob / Grep:按模式搜文件路径、正则搜文件内容
  • WebSearch / WebFetch:联网搜索 + 抓取页面内容
  • Monitor:监听后台脚本输出,逐行触发响应
  • AskUserQuestion:向用户提问(带多选选项)
组合示例:
  • ["Read", "Glob", "Grep"] → 只读分析,最安全
  • ["Read", "Edit", "Glob"] → 分析 + 改代码
  • ["Read", "Edit", "Bash", "Glob", "Grep"] → 全自动化(写代码 + 跑测试 + 修复)

🔄 消息流:async for 里流出什么?
query() 不是等 Claude 跑完才返回——它是流式的,每个阶段都吐出消息:
async for message in query(prompt="...", options=...):
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if hasattr(block, "text"):
                print(block.text)       # Claude 的思考过程
            elif hasattr(block, "name"):
                print(f"工具调用: {block.name}")  # 工具名
    elif isinstance(message, ResultMessage):
        print(f"完成: {message.subtype}")  # 最终结果
不过滤的话你会看到系统初始化消息和内部状态——开发调试很有用,生产环境记得按类型过滤。

⚡ 实践建议
从最小权限开始:先用 ["Read", "Glob"] + dontAsk,确认行为符合预期再逐步开放 Write/Bash
acceptEdits 是本地开发甜点:既不需要每个操作都手动确认,又保留了对危险命令的询问
CI/CD 场景:用 bypassPermissions 但必须跑在 Docker 容器里,别直接在宿主机跑
流式消费有意义:长任务里实时打印 Claude 的思考过程,有助于快速发现方向跑偏,及时 kill

下一篇:内置工具深度拆解——每个工具的参数细节、边界限制和组合技巧。

参考文档

Add more perspectives or context around this Drop.

  • Sign in to comment.