SpyBara
Go Premium

agent-sdk/python.md 2026-05-13 23:01 UTC to 2026-05-14 17:02 UTC

113 added, 1 removed.

2026
Sun 31 06:39 Sat 30 06:23 Fri 29 06:38 Thu 28 06:37 Wed 27 06:42 Tue 26 06:33 Sun 24 06:25 Sat 23 06:18 Fri 22 06:33 Thu 21 06:36 Wed 20 06:35 Tue 19 06:34 Mon 18 23:59 Sun 17 01:01 Fri 15 22:58 Thu 14 17:02 Wed 13 23:01 Tue 12 22:57 Mon 11 23:00 Sun 10 23:03 Sat 9 04:57 Fri 8 22:00 Thu 7 22:59 Tue 5 23:00 Mon 4 22:58 Sat 2 18:14 Fri 1 18:19

Agent SDK 参考 - Python

Python Agent SDK 的完整 API 参考,包括所有函数、类型和类。

安装

pip install claude-agent-sdk

query()ClaudeSDKClient 之间选择

Python SDK 提供了两种与 Claude Code 交互的方式:

快速比较

功能 query() ClaudeSDKClient
会话 每次创建新会话 重用同一会话
对话 单次交换 同一上下文中的多次交换
连接 自动管理 手动控制
流式输入 ✅ 支持 ✅ 支持
中断 ❌ 不支持 ✅ 支持
hooks ✅ 支持 ✅ 支持
自定义工具 ✅ 支持 ✅ 支持
继续聊天 ❌ 每次新会话 ✅ 保持对话
用例 一次性任务 持续对话

何时使用 query()(每次新会话)

最适合:

  • 不需要对话历史的一次性问题
  • 不需要来自之前交换的上下文的独立任务
  • 简单的自动化脚本
  • 当你想每次都重新开始时

何时使用 ClaudeSDKClient(持续对话)

最适合:

  • 继续对话 - 当你需要 Claude 记住上下文时
  • 后续问题 - 基于之前的响应进行构建
  • 交互式应用程序 - 聊天界面、REPL
  • 响应驱动的逻辑 - 当下一步操作取决于 Claude 的响应时
  • 会话控制 - 显式管理对话生命周期

函数

query()

为每次与 Claude Code 的交互创建一个新会话。返回一个异步迭代器,当消息到达时产生消息。每次调用 query() 都会重新开始,不记得之前的交互。

async def query(
    *,
    prompt: str | AsyncIterable[dict[str, Any]],
    options: ClaudeAgentOptions | None = None,
    transport: Transport | None = None
) -> AsyncIterator[Message]

参数

参数 类型 描述
prompt str | AsyncIterable[dict] 输入提示,可以是字符串或用于流式模式的异步可迭代对象
options ClaudeAgentOptions | None 可选配置对象(如果为 None,默认为 ClaudeAgentOptions()
transport Transport | None 用于与 CLI 进程通信的可选自定义传输

返回

返回一个 AsyncIterator[Message],从对话中产生消息。

示例 - 带选项

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions


async def main():
    options = ClaudeAgentOptions(
        system_prompt="You are an expert Python developer",
        permission_mode="acceptEdits",
        cwd="/home/user/project",
    )

    async for message in query(prompt="Create a Python web server", options=options):
        print(message)


asyncio.run(main())

tool()

用于定义具有类型安全的 MCP 工具的装饰器。

def tool(
    name: str,
    description: str,
    input_schema: type | dict[str, Any],
    annotations: ToolAnnotations | None = None
) -> Callable[[Callable[[Any], Awaitable[dict[str, Any]]]], SdkMcpTool[Any]]

参数

参数 类型 描述
name str 工具的唯一标识符
description str 工具功能的人类可读描述
input_schema type | dict[str, Any] 定义工具输入参数的模式(见下文)
annotations ToolAnnotations | None 可选的 MCP 工具注解,为客户端提供行为提示

输入模式选项

  1. 简单类型映射(推荐):

    {"text": str, "count": int, "enabled": bool}
    
  2. JSON Schema 格式(用于复杂验证):

    {
        "type": "object",
        "properties": {
            "text": {"type": "string"},
            "count": {"type": "integer", "minimum": 0},
        },
        "required": ["text"],
    }
    

返回

一个装饰器函数,包装工具实现并返回一个 SdkMcpTool 实例。

示例

from claude_agent_sdk import tool
from typing import Any


@tool("greet", "Greet a user", {"name": str})
async def greet(args: dict[str, Any]) -> dict[str, Any]:
    return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

ToolAnnotations

mcp.types 重新导出(也可以从 claude_agent_sdk 导入)。所有字段都是可选的提示;客户端不应依赖它们做出安全决策。

字段 类型 默认值 描述
title str | None None 工具的人类可读标题
readOnlyHint bool | None False 如果为 True,工具不修改其环境
destructiveHint bool | None True 如果为 True,工具可能执行破坏性更新(仅当 readOnlyHintFalse 时有意义)
idempotentHint bool | None False 如果为 True,使用相同参数的重复调用没有额外效果(仅当 readOnlyHintFalse 时有意义)
openWorldHint bool | None True 如果为 True,工具与外部实体交互(例如网络搜索)。如果为 False,工具的域是封闭的(例如内存工具)
from claude_agent_sdk import tool, ToolAnnotations
from typing import Any


@tool(
    "search",
    "Search the web",
    {"query": str},
    annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True),
)
async def search(args: dict[str, Any]) -> dict[str, Any]:
    return {"content": [{"type": "text", "text": f"Results for: {args['query']}"}]}

create_sdk_mcp_server()

创建在 Python 应用程序中运行的进程内 MCP 服务器。

def create_sdk_mcp_server(
    name: str,
    version: str = "1.0.0",
    tools: list[SdkMcpTool[Any]] | None = None
) -> McpSdkServerConfig

参数

参数 类型 默认值 描述
name str - 服务器的唯一标识符
version str "1.0.0" 服务器版本字符串
tools list[SdkMcpTool[Any]] | None None 使用 @tool 装饰器创建的工具函数列表

返回

返回一个 McpSdkServerConfig 对象,可以传递给 ClaudeAgentOptions.mcp_servers

示例

from claude_agent_sdk import tool, create_sdk_mcp_server


@tool("add", "Add two numbers", {"a": float, "b": float})
async def add(args):
    return {"content": [{"type": "text", "text": f"Sum: {args['a'] + args['b']}"}]}


@tool("multiply", "Multiply two numbers", {"a": float, "b": float})
async def multiply(args):
    return {"content": [{"type": "text", "text": f"Product: {args['a'] * args['b']}"}]}


calculator = create_sdk_mcp_server(
    name="calculator",
    version="2.0.0",
    tools=[add, multiply],  # Pass decorated functions
)

# Use with Claude
options = ClaudeAgentOptions(
    mcp_servers={"calc": calculator},
    allowed_tools=["mcp__calc__add", "mcp__calc__multiply"],
)

list_sessions()

列出带有元数据的过去会话。按项目目录过滤或列出所有项目中的会话。同步;立即返回。

def list_sessions(
    directory: str | None = None,
    limit: int | None = None,
    include_worktrees: bool = True
) -> list[SDKSessionInfo]

参数

参数 类型 默认值 描述
directory str | None None 列出会话的目录。省略时,返回所有项目中的会话
limit int | None None 返回的最大会话数
include_worktrees bool True directory 在 git 仓库内时,包括所有 worktrees 路径中的会话

返回类型:SDKSessionInfo

属性 类型 描述
session_id str 唯一会话标识符
summary str 显示标题:自定义标题、自动生成的摘要或第一个提示
last_modified int 上次修改时间(自纪元以来的毫秒数)
file_size int | None 会话文件大小(字节)(远程存储后端为 None
custom_title str | None 用户设置的会话标题
first_prompt str | None 会话中的第一个有意义的用户提示
git_branch str | None 会话结束时的 Git 分支
cwd str | None 会话的工作目录
tag str | None 用户设置的会话标签(见 tag_session()
created_at int | None 会话创建时间(自纪元以来的毫秒数)

示例

打印项目的 10 个最近会话。结果按 last_modified 降序排序,所以第一项是最新的。省略 directory 以搜索所有项目。

from claude_agent_sdk import list_sessions

for session in list_sessions(directory="/path/to/project", limit=10):
    print(f"{session.summary} ({session.session_id})")

get_session_messages()

从过去的会话中检索消息。同步;立即返回。

def get_session_messages(
    session_id: str,
    directory: str | None = None,
    limit: int | None = None,
    offset: int = 0
) -> list[SessionMessage]

参数

参数 类型 默认值 描述
session_id str 必需 要检索消息的会话 ID
directory str | None None 要查看的项目目录。省略时,搜索所有项目
limit int | None None 返回的最大消息数
offset int 0 从开始跳过的消息数

返回类型:SessionMessage

属性 类型 描述
type Literal["user", "assistant"] 消息角色
uuid str 唯一消息标识符
session_id str 会话标识符
message Any 原始消息内容
parent_tool_use_id None 保留供将来使用

示例

from claude_agent_sdk import list_sessions, get_session_messages

sessions = list_sessions(limit=1)
if sessions:
    messages = get_session_messages(sessions[0].session_id)
    for msg in messages:
        print(f"[{msg.type}] {msg.uuid}")

get_session_info()

按 ID 读取单个会话的元数据,无需扫描完整项目目录。同步;立即返回。

def get_session_info(
    session_id: str,
    directory: str | None = None,
) -> SDKSessionInfo | None

参数

参数 类型 默认值 描述
session_id str 必需 要查找的会话的 UUID
directory str | None None 项目目录路径。省略时,搜索所有项目目录

返回 SDKSessionInfo,如果找不到会话则返回 None

示例

查找单个会话的元数据,无需扫描项目目录。当你已经从之前的运行中获得会话 ID 时很有用。

from claude_agent_sdk import get_session_info

info = get_session_info("550e8400-e29b-41d4-a716-446655440000")
if info:
    print(f"{info.summary} (branch: {info.git_branch}, tag: {info.tag})")

rename_session()

通过追加自定义标题条目来重命名会话。重复调用是安全的;最新的标题获胜。同步。

def rename_session(
    session_id: str,
    title: str,
    directory: str | None = None,
) -> None

参数

参数 类型 默认值 描述
session_id str 必需 要重命名的会话的 UUID
title str 必需 新标题。去除空格后必须非空
directory str | None None 项目目录路径。省略时,搜索所有项目目录

如果 session_id 不是有效的 UUID 或 title 为空,则抛出 ValueError;如果找不到会话,则抛出 FileNotFoundError

示例

重命名最近的会话,使其更容易找到。新标题在后续读取时出现在 SDKSessionInfo.custom_title 中。

from claude_agent_sdk import list_sessions, rename_session

sessions = list_sessions(directory="/path/to/project", limit=1)
if sessions:
    rename_session(sessions[0].session_id, "Refactor auth module")

tag_session()

标记会话。传递 None 以清除标签。重复调用是安全的;最新的标签获胜。同步。

def tag_session(
    session_id: str,
    tag: str | None,
    directory: str | None = None,
) -> None

参数

参数 类型 默认值 描述
session_id str 必需 要标记的会话的 UUID
tag str | None 必需 标签字符串,或 None 以清除。存储前进行 Unicode 清理
directory str | None None 项目目录路径。省略时,搜索所有项目目录

如果 session_id 不是有效的 UUID 或 tag 在清理后为空,则抛出 ValueError;如果找不到会话,则抛出 FileNotFoundError

示例

标记会话,然后在稍后的读取中按该标签过滤。传递 None 以清除现有标签。

from claude_agent_sdk import list_sessions, tag_session

# Tag a session
tag_session("550e8400-e29b-41d4-a716-446655440000", "needs-review")

# Later: find all sessions with that tag
for session in list_sessions(directory="/path/to/project"):
    if session.tag == "needs-review":
        print(session.summary)

ClaudeSDKClient

在多次交换中维持对话会话。 这是 TypeScript SDK 的 query() 函数内部工作方式的 Python 等价物 - 它创建一个可以继续对话的客户端对象。

关键特性

  • 会话连续性:在多个 query() 调用中维持对话上下文
  • 同一对话:会话保留之前的消息
  • 中断支持:可以在任务中途停止执行
  • 显式生命周期:你控制会话何时开始和结束
  • 响应驱动的流程:可以对响应做出反应并发送后续消息
  • 自定义工具和 hooks:支持自定义工具(使用 @tool 装饰器创建)和 hooks
class ClaudeSDKClient:
    def __init__(self, options: ClaudeAgentOptions | None = None, transport: Transport | None = None)
    async def connect(self, prompt: str | AsyncIterable[dict] | None = None) -> None
    async def query(self, prompt: str | AsyncIterable[dict], session_id: str = "default") -> None
    async def receive_messages(self) -> AsyncIterator[Message]
    async def receive_response(self) -> AsyncIterator[Message]
    async def interrupt(self) -> None
    async def set_permission_mode(self, mode: str) -> None
    async def set_model(self, model: str | None = None) -> None
    async def rewind_files(self, user_message_id: str) -> None
    async def get_mcp_status(self) -> McpStatusResponse
    async def reconnect_mcp_server(self, server_name: str) -> None
    async def toggle_mcp_server(self, server_name: str, enabled: bool) -> None
    async def stop_task(self, task_id: str) -> None
    async def get_server_info(self) -> dict[str, Any] | None
    async def disconnect(self) -> None

方法

方法 描述
__init__(options) 使用可选配置初始化客户端
connect(prompt) 连接到 Claude,可选初始提示或消息流
query(prompt, session_id) 以流式模式发送新请求
receive_messages() 以异步迭代器形式接收来自 Claude 的所有消息
receive_response() 接收消息直到并包括 ResultMessage
interrupt() 发送中断信号(仅在流式模式下工作)
set_permission_mode(mode) 更改当前会话的权限模式
set_model(model) 更改当前会话的模型。传递 None 以重置为默认值
rewind_files(user_message_id) 将文件恢复到指定用户消息时的状态。需要 enable_file_checkpointing=True。见 文件检查点
get_mcp_status() 获取所有配置的 MCP 服务器的状态。返回 McpStatusResponse
reconnect_mcp_server(server_name) 重试连接到失败或断开连接的 MCP 服务器
toggle_mcp_server(server_name, enabled) 在会话中启用或禁用 MCP 服务器。禁用会移除其工具
stop_task(task_id) 停止运行的后台任务。一个状态为 "stopped"TaskNotificationMessage 随后在消息流中出现
get_server_info() 获取服务器信息,包括会话 ID 和功能
disconnect() 从 Claude 断开连接

上下文管理器支持

客户端可以用作异步上下文管理器以自动管理连接:

async with ClaudeSDKClient() as client:
    await client.query("Hello Claude")
    async for message in client.receive_response():
        print(message)

重要: 迭代消息时,避免使用 break 提前退出,因为这可能导致 asyncio 清理问题。相反,让迭代自然完成或使用标志来跟踪何时找到了你需要的内容。

示例 - 继续对话

import asyncio
from claude_agent_sdk import ClaudeSDKClient, AssistantMessage, TextBlock, ResultMessage


async def main():
    async with ClaudeSDKClient() as client:
        # First question
        await client.query("What's the capital of France?")

        # Process response
        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, TextBlock):
                        print(f"Claude: {block.text}")

        # Follow-up question - the session retains the previous context
        await client.query("What's the population of that city?")

        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, TextBlock):
                        print(f"Claude: {block.text}")

        # Another follow-up - still in the same conversation
        await client.query("What are some famous landmarks there?")

        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, TextBlock):
                        print(f"Claude: {block.text}")


asyncio.run(main())

示例 - 使用 ClaudeSDKClient 进行流式输入

import asyncio
from claude_agent_sdk import ClaudeSDKClient


async def message_stream():
    """Generate messages dynamically."""
    yield {
        "type": "user",
        "message": {"role": "user", "content": "Analyze the following data:"},
    }
    await asyncio.sleep(0.5)
    yield {
        "type": "user",
        "message": {"role": "user", "content": "Temperature: 25°C, Humidity: 60%"},
    }
    await asyncio.sleep(0.5)
    yield {
        "type": "user",
        "message": {"role": "user", "content": "What patterns do you see?"},
    }


async def main():
    async with ClaudeSDKClient() as client:
        # Stream input to Claude
        await client.query(message_stream())

        # Process response
        async for message in client.receive_response():
            print(message)

        # Follow-up in same session
        await client.query("Should we be concerned about these readings?")

        async for message in client.receive_response():
            print(message)


asyncio.run(main())

示例 - 使用中断

import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, ResultMessage


async def interruptible_task():
    options = ClaudeAgentOptions(allowed_tools=["Bash"], permission_mode="acceptEdits")

    async with ClaudeSDKClient(options=options) as client:
        # Start a long-running task
        await client.query("Count from 1 to 100 slowly, using the bash sleep command")

        # Let it run for a bit
        await asyncio.sleep(2)

        # Interrupt the task
        await client.interrupt()
        print("Task interrupted!")

        # Drain the interrupted task's messages (including its ResultMessage)
        async for message in client.receive_response():
            if isinstance(message, ResultMessage):
                print(f"Interrupted task finished with subtype={message.subtype!r}")
                # subtype is "error_during_execution" for interrupted tasks

        # Send a new command
        await client.query("Just say hello instead")

        # Now receive the new response
        async for message in client.receive_response():
            if isinstance(message, ResultMessage) and message.subtype == "success":
                print(f"New result: {message.result}")


asyncio.run(interruptible_task())

示例 - 高级权限控制

from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
from claude_agent_sdk.types import (
    PermissionResultAllow,
    PermissionResultDeny,
    ToolPermissionContext,
)


async def custom_permission_handler(
    tool_name: str, input_data: dict, context: ToolPermissionContext
) -> PermissionResultAllow | PermissionResultDeny:
    """Custom logic for tool permissions."""

    # Block writes to system directories
    if tool_name == "Write" and input_data.get("file_path", "").startswith("/system/"):
        return PermissionResultDeny(
            message="System directory write not allowed", interrupt=True
        )

    # Redirect sensitive file operations
    if tool_name in ["Write", "Edit"] and "config" in input_data.get("file_path", ""):
        safe_path = f"./sandbox/{input_data['file_path']}"
        return PermissionResultAllow(
            updated_input={**input_data, "file_path": safe_path}
        )

    # Allow everything else
    return PermissionResultAllow(updated_input=input_data)


async def main():
    options = ClaudeAgentOptions(
        can_use_tool=custom_permission_handler, allowed_tools=["Read", "Write", "Edit"]
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("Update the system config file")

        async for message in client.receive_response():
            # Will use sandbox path instead
            print(message)


asyncio.run(main())

类型

SdkMcpTool

使用 @tool 装饰器创建的 SDK MCP 工具的定义。

@dataclass
class SdkMcpTool(Generic[T]):
    name: str
    description: str
    input_schema: type[T] | dict[str, Any]
    handler: Callable[[T], Awaitable[dict[str, Any]]]
    annotations: ToolAnnotations | None = None
属性 类型 描述
name str 工具的唯一标识符
description str 人类可读的描述
input_schema type[T] | dict[str, Any] 输入验证的模式
handler Callable[[T], Awaitable[dict[str, Any]]] 处理工具执行的异步函数
annotations ToolAnnotations | None 可选的 MCP 工具注解(例如 readOnlyHintdestructiveHintopenWorldHint)。来自 mcp.types

Transport

自定义传输实现的抽象基类。使用此类通过自定义通道与 Claude 进程通信(例如,远程连接而不是本地子进程)。

from abc import ABC, abstractmethod
from collections.abc import AsyncIterator
from typing import Any


class Transport(ABC):
    @abstractmethod
    async def connect(self) -> None: ...

    @abstractmethod
    async def write(self, data: str) -> None: ...

    @abstractmethod
    def read_messages(self) -> AsyncIterator[dict[str, Any]]: ...

    @abstractmethod
    async def close(self) -> None: ...

    @abstractmethod
    def is_ready(self) -> bool: ...

    @abstractmethod
    async def end_input(self) -> None: ...
方法 描述
connect() 连接传输并准备通信
write(data) 将原始数据(JSON + 换行符)写入传输
read_messages() 异步迭代器,产生解析的 JSON 消息
close() 关闭连接并清理资源
is_ready() 如果传输可以发送和接收,返回 True
end_input() 关闭输入流(例如,为子进程传输关闭 stdin)

导入:from claude_agent_sdk import Transport

ClaudeAgentOptions

Claude Code 查询的配置数据类。

@dataclass
class ClaudeAgentOptions:
    tools: list[str] | ToolsPreset | None = None
    allowed_tools: list[str] = field(default_factory=list)
    system_prompt: str | SystemPromptPreset | None = None
    mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
    strict_mcp_config: bool = False
    permission_mode: PermissionMode | None = None
    continue_conversation: bool = False
    resume: str | None = None
    max_turns: int | None = None
    max_budget_usd: float | None = None
    disallowed_tools: list[str] = field(default_factory=list)
    model: str | None = None
    fallback_model: str | None = None
    betas: list[SdkBeta] = field(default_factory=list)
    output_format: dict[str, Any] | None = None
    permission_prompt_tool_name: str | None = None
    cwd: str | Path | None = None
    cli_path: str | Path | None = None
    settings: str | None = None
    add_dirs: list[str | Path] = field(default_factory=list)
    env: dict[str, str] = field(default_factory=dict)
    extra_args: dict[str, str | None] = field(default_factory=dict)
    max_buffer_size: int | None = None
    debug_stderr: Any = sys.stderr  # Deprecated
    stderr: Callable[[str], None] | None = None
    can_use_tool: CanUseTool | None = None
    hooks: dict[HookEvent, list[HookMatcher]] | None = None
    user: str | None = None
    include_partial_messages: bool = False
    include_hook_events: bool = False
    fork_session: bool = False
    agents: dict[str, AgentDefinition] | None = None
    setting_sources: list[SettingSource] | None = None
    sandbox: SandboxSettings | None = None
    plugins: list[SdkPluginConfig] = field(default_factory=list)
    max_thinking_tokens: int | None = None  # Deprecated: use thinking instead
    thinking: ThinkingConfig | None = None
    effort: Literal["low", "medium", "high", "xhigh", "max"] | None = None
    enable_file_checkpointing: bool = False
    session_store: SessionStore | None = None
    session_store_flush: SessionStoreFlushMode = "batched"
属性 类型 默认值 描述
tools list[str] | ToolsPreset | None None 工具配置。使用 {"type": "preset", "preset": "claude_code"} 获取 Claude Code 的默认工具
allowed_tools list[str] [] 无需提示即可自动批准的工具。这不会限制 Claude 仅使用这些工具;未列出的工具会通过 permission_modecan_use_tool 处理。使用 disallowed_tools 阻止工具。见 权限
system_prompt str | SystemPromptPreset | None None 系统提示配置。传递字符串以获取自定义提示,或使用 {"type": "preset", "preset": "claude_code"} 获取 Claude Code 的系统提示。添加 "append" 以扩展预设
mcp_servers dict[str, McpServerConfig] | str | Path {} MCP 服务器配置或配置文件路径
strict_mcp_config bool False 当为 True 时,仅使用在 mcp_servers 中传递的服务器,忽略项目 .mcp.json、用户设置和插件提供的 MCP 服务器。映射到 CLI --strict-mcp-config 标志
permission_mode PermissionMode | None None 工具使用的权限模式
continue_conversation bool False 继续最近的对话
resume str | None None 要恢复的会话 ID
max_turns int | None None 最大代理轮次(工具使用往返)
max_budget_usd float | None None 当客户端成本估计达到此 USD 值时停止查询。与 total_cost_usd 的相同估计进行比较;见 跟踪成本和使用 了解准确性注意事项
disallowed_tools list[str] [] 始终拒绝的工具。拒绝规则首先检查并覆盖 allowed_toolspermission_mode(包括 bypassPermissions
enable_file_checkpointing bool False 启用文件更改跟踪以进行回滚。见 文件检查点
model str | None None 要使用的 Claude 模型
fallback_model str | None None 主模型失败时使用的备用模型
betas list[SdkBeta] [] 要启用的测试功能。见 SdkBeta 了解可用选项
output_format dict[str, Any] | None None 结构化响应的输出格式(例如 {"type": "json_schema", "schema": {...}})。见 结构化输出 了解详情
permission_prompt_tool_name str | None None 权限提示的 MCP 工具名称
cwd str | Path | None None 当前工作目录
cli_path str | Path | None None Claude Code CLI 可执行文件的自定义路径
settings str | None None 设置文件的路径
add_dirs list[str | Path] [] Claude 可以访问的其他目录
env dict[str, str] {} 环境变量合并到继承的进程环境之上。见 环境变量 了解底层 CLI 读取的变量,以及 处理缓慢或停滞的 API 响应 了解超时相关变量
extra_args dict[str, str | None] {} 直接传递给 CLI 的其他 CLI 参数
max_buffer_size int | None None 缓冲 CLI stdout 时的最大字节数
debug_stderr Any sys.stderr 已弃用 - 用于调试输出的类文件对象。改用 stderr 回调
stderr Callable[[str], None] | None None CLI 中 stderr 输出的回调函数
can_use_tool CanUseTool | None None 工具权限回调函数。见 权限类型 了解详情
hooks dict[HookEvent, list[HookMatcher]] | None None 用于拦截事件的 hooks 配置
user str | None None 用户标识符
include_partial_messages bool False 包括部分消息流式事件。启用时,会产生 StreamEvent 消息
include_hook_events bool False 在消息流中包括 hooks 生命周期事件作为 HookEventMessage 对象
fork_session bool False 使用 resume 恢复时,分叉到新会话 ID 而不是继续原始会话
agents dict[str, AgentDefinition] | None None 以编程方式定义的子代理
plugins list[SdkPluginConfig] [] 从本地路径加载自定义插件。见 Plugins 了解详情
sandbox SandboxSettings | None None 以编程方式配置沙箱行为。见 沙箱设置 了解详情
setting_sources list[SettingSource] | None None(CLI 默认值:所有源) 控制加载哪些文件系统设置。传递 [] 以禁用用户、项目和本地设置。无论如何都会加载托管策略设置。见 使用 Claude Code 功能
skills list[str] | Literal["all"] | None None 会话可用的技能。传递 "all" 以启用每个发现的技能,或传递技能名称列表。设置时,SDK 会自动启用 Skill 工具,无需在 allowed_tools 中列出。见 Skills
max_thinking_tokens int | None None 已弃用 - 思考块的最大令牌数。改用 thinking
thinking ThinkingConfig | None None 控制扩展思考行为。优先于 max_thinking_tokens
effort Literal["low", "medium", "high", "xhigh", "max"] | None None 思考深度的努力级别
session_store SessionStore | None None 将会话记录镜像到外部后端,以便任何主机都可以恢复它们。见 将会话持久化到外部存储
session_store_flush Literal["batched", "eager"] "batched" 何时将镜像的记录条目刷新到 session_store"batched" 每轮刷新一次或当缓冲区填满时;"eager" 在每帧后触发后台刷新。当 session_storeNone 时忽略

处理缓慢或停滞的 API 响应

CLI 子进程读取多个环境变量,这些变量控制 API 超时和停滞检测。通过 ClaudeAgentOptions.env 传递它们:

options = ClaudeAgentOptions(
    env={
        "API_TIMEOUT_MS": "120000",
        "CLAUDE_CODE_MAX_RETRIES": "2",
        "CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS": "120000",
    },
)
  • API_TIMEOUT_MS:Anthropic 客户端上的每个请求超时,以毫秒为单位。默认 600000。适用于主循环和所有子代理。
  • CLAUDE_CODE_MAX_RETRIES:最大 API 重试次数。默认 10。每次重试都有自己的 API_TIMEOUT_MS 窗口,因此最坏情况下的实际时间大约是 API_TIMEOUT_MS × (CLAUDE_CODE_MAX_RETRIES + 1) 加上退避。
  • CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS:使用 run_in_background 启动的子代理的停滞监视器。默认 600000。在每个流事件时重置;停滞时中止子代理,将任务标记为失败,并将错误与任何部分结果一起呈现给父代理。不适用于同步子代理。
  • CLAUDE_ENABLE_STREAM_WATCHDOG=1CLAUDE_STREAM_IDLE_TIMEOUT_MS:当标头已到达但响应体停止流式传输时中止请求。默认关闭。CLAUDE_STREAM_IDLE_TIMEOUT_MS 默认为 300000 并被限制为该最小值。中止的请求通过正常重试路径进行。

OutputFormat

结构化输出验证的配置。将其作为 dict 传递给 ClaudeAgentOptions 上的 output_format 字段:

# Expected dict shape for output_format
{
    "type": "json_schema",
    "schema": {...},  # Your JSON Schema definition
}
字段 必需 描述
type 必须是 "json_schema" 用于 JSON Schema 验证
schema 用于输出验证的 JSON Schema 定义

SystemPromptPreset

使用 Claude Code 的预设系统提示和可选添加的配置。

class SystemPromptPreset(TypedDict):
    type: Literal["preset"]
    preset: Literal["claude_code"]
    append: NotRequired[str]
    exclude_dynamic_sections: NotRequired[bool]
字段 必需 描述
type 必须是 "preset" 以使用预设系统提示
preset 必须是 "claude_code" 以使用 Claude Code 的系统提示
append 要追加到预设系统提示的其他说明
exclude_dynamic_sections 将每个会话的上下文(如工作目录、git 状态和内存路径)从系统提示移到第一条用户消息。改进跨用户和机器的提示缓存重用。见 修改系统提示

SettingSource

控制 SDK 从哪些基于文件系统的配置源加载设置。

SettingSource = Literal["user", "project", "local"]
描述 位置
"user" 全局用户设置 ~/.claude/settings.json
"project" 共享项目设置(版本控制) .claude/settings.json
"local" 本地项目设置(gitignored) .claude/settings.local.json

默认行为

setting_sources 被省略或为 None 时,query() 加载与 Claude Code CLI 相同的文件系统设置:用户、项目和本地。无论如何都会加载托管策略设置。见 settingSources 不控制什么 了解无论此选项如何都会读取的输入,以及如何禁用它们。

为什么使用 setting_sources

禁用文件系统设置:

# Do not load user, project, or local settings from disk
from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="Analyze this code",
    options=ClaudeAgentOptions(
        setting_sources=[]
    ),
):
    print(message)

显式加载所有文件系统设置:

from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="Analyze this code",
    options=ClaudeAgentOptions(
        setting_sources=["user", "project", "local"]
    ),
):
    print(message)

仅加载特定设置源:

# Load only project settings, ignore user and local
async for message in query(
    prompt="Run CI checks",
    options=ClaudeAgentOptions(
        setting_sources=["project"]  # Only .claude/settings.json
    ),
):
    print(message)

测试和 CI 环境:

# Ensure consistent behavior in CI by excluding local settings
async for message in query(
    prompt="Run tests",
    options=ClaudeAgentOptions(
        setting_sources=["project"],  # Only team-shared settings
        permission_mode="bypassPermissions",
    ),
):
    print(message)

仅 SDK 应用程序:

# Define everything programmatically.
# Pass [] to opt out of filesystem setting sources.
async for message in query(
    prompt="Review this PR",
    options=ClaudeAgentOptions(
        setting_sources=[],
        agents={...},
        mcp_servers={...},
        allowed_tools=["Read", "Grep", "Glob"],
    ),
):
    print(message)

加载 CLAUDE.md 项目说明:

# Load project settings to include CLAUDE.md files
async for message in query(
    prompt="Add a new feature following project conventions",
    options=ClaudeAgentOptions(
        system_prompt={
            "type": "preset",
            "preset": "claude_code",  # Use Claude Code's system prompt
        },
        setting_sources=["project"],  # Loads CLAUDE.md from project
        allowed_tools=["Read", "Write", "Edit"],
    ),
):
    print(message)

设置优先级

加载多个源时,设置按此优先级合并(从高到低):

  1. 本地设置(.claude/settings.local.json
  2. 项目设置(.claude/settings.json
  3. 用户设置(~/.claude/settings.json

编程选项(如 agentsallowed_tools)覆盖用户、项目和本地文件系统设置。托管策略设置优先于编程选项。

AgentDefinition

以编程方式定义的子代理的配置。

@dataclass
class AgentDefinition:
    description: str
    prompt: str
    tools: list[str] | None = None
    disallowedTools: list[str] | None = None
    model: str | None = None
    skills: list[str] | None = None
    memory: Literal["user", "project", "local"] | None = None
    mcpServers: list[str | dict[str, Any]] | None = None
    initialPrompt: str | None = None
    maxTurns: int | None = None
    background: bool | None = None
    effort: Literal["low", "medium", "high", "xhigh", "max"] | int | None = None
    permissionMode: PermissionMode | None = None
字段 必需 描述
description 何时使用此代理的自然语言描述
prompt 代理的系统提示
tools 允许的工具名称数组。如果省略,继承所有工具
disallowedTools 要从代理的工具集中移除的工具名称数组
model 此代理的模型覆盖。接受别名如 "sonnet""opus""haiku""inherit",或完整模型 ID。如果省略,使用主模型
skills 此代理可用的技能名称列表
memory 此代理的内存源:"user""project""local"
mcpServers 此代理可用的 MCP 服务器。每个条目是服务器名称或内联 {name: config} 字典
initialPrompt 当此代理作为主线程代理运行时自动提交为第一个用户轮次
maxTurns 代理停止前的最大代理轮次数
background 调用时将此代理作为非阻塞后台任务运行
effort 此代理的推理努力级别。接受命名级别或整数
permissionMode 此代理内工具执行的权限模式。见 PermissionMode

PermissionMode

用于控制工具执行的权限模式。

PermissionMode = Literal[
    "default",  # Standard permission behavior
    "acceptEdits",  # Auto-accept file edits
    "plan",  # Planning mode - read-only tools only
    "dontAsk",  # Deny anything not pre-approved instead of prompting
    "bypassPermissions",  # Bypass all permission checks (use with caution)
]

CanUseTool

工具权限回调函数的类型别名。

CanUseTool = Callable[
    [str, dict[str, Any], ToolPermissionContext], Awaitable[PermissionResult]
]

回调接收:

  • tool_name:被调用的工具的名称
  • input_data:工具的输入参数
  • context:带有附加信息的 ToolPermissionContext

返回 PermissionResultPermissionResultAllowPermissionResultDeny)。

ToolPermissionContext

传递给工具权限回调的上下文信息。

@dataclass
class ToolPermissionContext:
    signal: Any | None = None  # Future: abort signal support
    suggestions: list[PermissionUpdate] = field(default_factory=list)
    blocked_path: str | None = None
    decision_reason: str | None = None
    title: str | None = None
    display_name: str | None = None
    description: str | None = None
字段 类型 描述
signal Any | None 保留供将来中止信号支持
suggestions list[PermissionUpdate] 来自 CLI 的权限更新建议。Bash 提示包括带有 localSettings 目标的建议,因此在 updated_permissions 中返回它会将规则写入 .claude/settings.local.json 并在会话间持久化。
blocked_path str | None 触发权限请求的文件路径(如适用)。例如,当 Bash 命令尝试访问允许目录外的路径时
decision_reason str | None 触发此权限请求的原因。从 PreToolUse hooks 的 permissionDecisionReason 转发,当 hooks 返回 "ask"
title str | None 完整权限提示句子,如 Claude wants to read foo.txt。存在时用作主要提示文本
display_name str | None 工具操作的短名词短语,如 Read file,适合按钮标签
description str | None 权限 UI 的人类可读副标题

PermissionResult

权限回调结果的联合类型。

PermissionResult = PermissionResultAllow | PermissionResultDeny

PermissionResultAllow

指示应允许工具调用的结果。

@dataclass
class PermissionResultAllow:
    behavior: Literal["allow"] = "allow"
    updated_input: dict[str, Any] | None = None
    updated_permissions: list[PermissionUpdate] | None = None
字段 类型 默认值 描述
behavior Literal["allow"] "allow" 必须是 "allow"
updated_input dict[str, Any] | None None 要使用的修改后的输入而不是原始输入
updated_permissions list[PermissionUpdate] | None None 要应用的权限更新

PermissionResultDeny

指示应拒绝工具调用的结果。

@dataclass
class PermissionResultDeny:
    behavior: Literal["deny"] = "deny"
    message: str = ""
    interrupt: bool = False
字段 类型 默认值 描述
behavior Literal["deny"] "deny" 必须是 "deny"
message str "" 解释为什么拒绝工具的消息
interrupt bool False 是否中断当前执行

PermissionUpdate

用于以编程方式更新权限的配置。

@dataclass
class PermissionUpdate:
    type: Literal[
        "addRules",
        "replaceRules",
        "removeRules",
        "setMode",
        "addDirectories",
        "removeDirectories",
    ]
    rules: list[PermissionRuleValue] | None = None
    behavior: Literal["allow", "deny", "ask"] | None = None
    mode: PermissionMode | None = None
    directories: list[str] | None = None
    destination: (
        Literal["userSettings", "projectSettings", "localSettings", "session"] | None
    ) = None
字段 类型 描述
type Literal[...] 权限更新操作的类型
rules list[PermissionRuleValue] | None 用于添加/替换/移除操作的规则
behavior Literal["allow", "deny", "ask"] | None 基于规则的操作的行为
mode PermissionMode | None setMode 操作的模式
directories list[str] | None 用于添加/移除目录操作的目录
destination Literal[...] | None 应用权限更新的位置

PermissionRuleValue

要在权限更新中添加、替换或移除的规则。

@dataclass
class PermissionRuleValue:
    tool_name: str
    rule_content: str | None = None

ToolsPreset

使用 Claude Code 的默认工具集的预设工具配置。

class ToolsPreset(TypedDict):
    type: Literal["preset"]
    preset: Literal["claude_code"]

ThinkingConfig

控制扩展思考行为。三种配置的联合:

class ThinkingConfigAdaptive(TypedDict):
    type: Literal["adaptive"]


class ThinkingConfigEnabled(TypedDict):
    type: Literal["enabled"]
    budget_tokens: int


class ThinkingConfigDisabled(TypedDict):
    type: Literal["disabled"]


ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
变体 字段 描述
adaptive type Claude 自适应决定何时思考
enabled type, budget_tokens 启用具有特定令牌预算的思考
disabled type 禁用思考

因为这些是 TypedDict 类,它们在运行时是普通字典。要么将它们构造为字典字面量,要么调用类作为构造函数;两者都产生 dict。使用 config["budget_tokens"] 访问字段,而不是 config.budget_tokens

from claude_agent_sdk import ClaudeAgentOptions, ThinkingConfigEnabled

# Option 1: dict literal (recommended, no import needed)
options = ClaudeAgentOptions(thinking={"type": "enabled", "budget_tokens": 20000})

# Option 2: constructor-style (returns a plain dict)
config = ThinkingConfigEnabled(type="enabled", budget_tokens=20000)
print(config["budget_tokens"])  # 20000
# config.budget_tokens would raise AttributeError

SdkBeta

SDK 测试功能的字面类型。

SdkBeta = Literal["context-1m-2025-08-07"]

ClaudeAgentOptions 中的 betas 字段一起使用以启用测试功能。

McpSdkServerConfig

使用 create_sdk_mcp_server() 创建的 SDK MCP 服务器的配置。

class McpSdkServerConfig(TypedDict):
    type: Literal["sdk"]
    name: str
    instance: Any  # MCP Server instance

McpServerConfig

MCP 服务器配置的联合类型。

McpServerConfig = (
    McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig
)

McpStdioServerConfig

class McpStdioServerConfig(TypedDict):
    type: NotRequired[Literal["stdio"]]  # Optional for backwards compatibility
    command: str
    args: NotRequired[list[str]]
    env: NotRequired[dict[str, str]]

McpSSEServerConfig

class McpSSEServerConfig(TypedDict):
    type: Literal["sse"]
    url: str
    headers: NotRequired[dict[str, str]]

McpHttpServerConfig

class McpHttpServerConfig(TypedDict):
    type: Literal["http"]
    url: str
    headers: NotRequired[dict[str, str]]

McpServerStatusConfig

get_mcp_status() 报告的 MCP 服务器的配置。这是所有 McpServerConfig 传输变体加上用于通过 claude.ai 代理的服务器的仅输出 claudeai-proxy 变体的联合。

McpServerStatusConfig = (
    McpStdioServerConfig
    | McpSSEServerConfig
    | McpHttpServerConfig
    | McpSdkServerConfigStatus
    | McpClaudeAIProxyServerConfig
)

McpSdkServerConfigStatusMcpSdkServerConfig 的可序列化形式,仅包含 type"sdk")和 namestr)字段;进程内 instance 被省略。McpClaudeAIProxyServerConfig 具有 type"claudeai-proxy")、urlstr)和 idstr)字段。

McpStatusResponse

来自 ClaudeSDKClient.get_mcp_status() 的响应。在 mcpServers 键下包装服务器状态列表。

class McpStatusResponse(TypedDict):
    mcpServers: list[McpServerStatus]

McpServerStatus

连接的 MCP 服务器的状态,包含在 McpStatusResponse 中。

class McpServerStatus(TypedDict):
    name: str
    status: McpServerConnectionStatus  # "connected" | "failed" | "needs-auth" | "pending" | "disabled"
    serverInfo: NotRequired[McpServerInfo]
    error: NotRequired[str]
    config: NotRequired[McpServerStatusConfig]
    scope: NotRequired[str]
    tools: NotRequired[list[McpToolInfo]]
字段 类型 描述
name str 服务器名称
status str "connected""failed""needs-auth""pending""disabled" 之一
serverInfo dict(可选) 服务器名称和版本({"name": str, "version": str}
error str(可选) 服务器连接失败时的错误消息
config McpServerStatusConfig(可选) 服务器配置。与 McpServerConfig 形状相同(stdio、SSE、HTTP 或 SDK),加上通过 claude.ai 连接的服务器的 claudeai-proxy 变体
scope str(可选) 配置范围
tools list(可选) 此服务器提供的工具,每个都有 namedescriptionannotations 字段

SdkPluginConfig

SDK 中加载插件的配置。

class SdkPluginConfig(TypedDict):
    type: Literal["local"]
    path: str
字段 类型 描述
type Literal["local"] 必须是 "local"(目前仅支持本地插件)
path str 插件目录的绝对或相对路径

示例:

plugins = [
    {"type": "local", "path": "./my-plugin"},
    {"type": "local", "path": "/absolute/path/to/plugin"},
]

有关创建和使用插件的完整信息,见 Plugins

消息类型

Message

所有可能消息的联合类型。

Message = (
    UserMessage
    | AssistantMessage
    | SystemMessage
    | ResultMessage
    | StreamEvent
    | RateLimitEvent
)

UserMessage

用户输入消息。

@dataclass
class UserMessage:
    content: str | list[ContentBlock]
    uuid: str | None = None
    parent_tool_use_id: str | None = None
    tool_use_result: dict[str, Any] | None = None
字段 类型 描述
content str | list[ContentBlock] 消息内容为文本或内容块
uuid str | None 唯一消息标识符
parent_tool_use_id str | None 如果此消息是工具结果响应,则为工具使用 ID
tool_use_result dict[str, Any] | None 工具结果数据(如果适用)

AssistantMessage

带有内容块的助手响应消息。

@dataclass
class AssistantMessage:
    content: list[ContentBlock]
    model: str
    parent_tool_use_id: str | None = None
    error: AssistantMessageError | None = None
    usage: dict[str, Any] | None = None
    message_id: str | None = None
字段 类型 描述
content list[ContentBlock] 响应中的内容块列表
model str 生成响应的模型
parent_tool_use_id str | None 如果这是嵌套响应,则为工具使用 ID
error AssistantMessageError | None 如果响应遇到错误,则为错误类型
usage dict[str, Any] | None 每条消息的令牌使用情况(与 ResultMessage.usage 相同的键)
message_id str | None API 消息 ID。来自一个轮次的多条消息共享相同的 ID

AssistantMessageError

助手消息的可能错误类型。

AssistantMessageError = Literal[
    "authentication_failed",
    "billing_error",
    "rate_limit",
    "invalid_request",
    "server_error",
    "max_output_tokens",
    "unknown",
]

SystemMessage

带有元数据的系统消息。

@dataclass
class SystemMessage:
    subtype: str
    data: dict[str, Any]

ResultMessage

带有成本和使用信息的最终结果消息。

@dataclass
class ResultMessage:
    subtype: str
    duration_ms: int
    duration_api_ms: int
    is_error: bool
    num_turns: int
    session_id: str
    stop_reason: str | None = None
    total_cost_usd: float | None = None
    usage: dict[str, Any] | None = None
    result: str | None = None
    structured_output: Any = None
    model_usage: dict[str, Any] | None = None
    permission_denials: list[Any] | None = None
    deferred_tool_use: DeferredToolUse | None = None
    errors: list[str] | None = None
    api_error_status: int | None = None
    uuid: str | None = None

usage 字典在存在时包含以下键:

类型 描述
input_tokens int 消耗的总输入令牌。
output_tokens int 生成的总输出令牌。
cache_creation_input_tokens int 用于创建新缓存条目的令牌。
cache_read_input_tokens int 从现有缓存条目读取的令牌。

model_usage 字典将模型名称映射到每个模型的使用情况。内部字典键使用 camelCase,因为该值从底层 CLI 进程未修改地传递,匹配 TypeScript ModelUsage 类型:

类型 描述
inputTokens int 此模型的输入令牌。
outputTokens int 此模型的输出令牌。
cacheReadInputTokens int 此模型的缓存读取令牌。
cacheCreationInputTokens int 此模型的缓存创建令牌。
webSearchRequests int 此模型进行的网络搜索请求。
costUSD float 此模型的估计成本(美元),客户端计算。见 跟踪成本和使用 了解计费注意事项。
contextWindow int 此模型的上下文窗口大小。
maxOutputTokens int 此模型的最大输出令牌限制。

StreamEvent

流式事件,用于流式传输期间的部分消息更新。仅在 ClaudeAgentOptionsinclude_partial_messages=True 时接收。通过 from claude_agent_sdk.types import StreamEvent 导入。

@dataclass
class StreamEvent:
    uuid: str
    session_id: str
    event: dict[str, Any]  # The raw Claude API stream event
    parent_tool_use_id: str | None = None
字段 类型 描述
uuid str 此事件的唯一标识符
session_id str 会话标识符
event dict[str, Any] 原始 Claude API 流事件数据
parent_tool_use_id str | None 如果此事件来自子代理,则为父工具使用 ID

RateLimitEvent

当速率限制状态更改时发出(例如,从 "allowed""allowed_warning")。使用此来在用户达到硬限制之前警告他们,或在状态为 "rejected" 时退避。

@dataclass
class RateLimitEvent:
    rate_limit_info: RateLimitInfo
    uuid: str
    session_id: str
字段 类型 描述
rate_limit_info RateLimitInfo 当前速率限制状态
uuid str 唯一事件标识符
session_id str 会话标识符

RateLimitInfo

RateLimitEvent 携带的速率限制状态。

RateLimitStatus = Literal["allowed", "allowed_warning", "rejected"]
RateLimitType = Literal[
    "five_hour", "seven_day", "seven_day_opus", "seven_day_sonnet", "overage"
]


@dataclass
class RateLimitInfo:
    status: RateLimitStatus
    resets_at: int | None = None
    rate_limit_type: RateLimitType | None = None
    utilization: float | None = None
    overage_status: RateLimitStatus | None = None
    overage_resets_at: int | None = None
    overage_disabled_reason: str | None = None
    raw: dict[str, Any] = field(default_factory=dict)
字段 类型 描述
status RateLimitStatus 当前状态。"allowed_warning" 表示接近限制;"rejected" 表示达到限制
resets_at int | None 速率限制窗口重置的 Unix 时间戳
rate_limit_type RateLimitType | None 哪个速率限制窗口适用
utilization float | None 消耗的速率限制的分数(0.0 到 1.0)
overage_status RateLimitStatus | None 按需付费超额使用的状态(如果适用)
overage_resets_at int | None 超额窗口重置的 Unix 时间戳
overage_disabled_reason str | None 为什么超额不可用,如果状态为 "rejected"
raw dict[str, Any] 来自 CLI 的完整原始字典,包括上面未建模的字段

TaskStartedMessage

当后台任务启动时发出。后台任务是在主轮次之外跟踪的任何内容:后台 Bash 命令、Monitor 监视、通过 Agent 工具生成的子代理或远程代理。task_type 字段告诉你是哪一个。此命名与 TaskAgent 工具重命名无关。

@dataclass
class TaskStartedMessage(SystemMessage):
    task_id: str
    description: str
    uuid: str
    session_id: str
    tool_use_id: str | None = None
    task_type: str | None = None
字段 类型 描述
task_id str 任务的唯一标识符
description str 任务的描述
uuid str 唯一消息标识符
session_id str 会话标识符
tool_use_id str | None 关联的工具使用 ID
task_type str | None 哪种后台任务:"local_bash" 用于后台 Bash 和 Monitor 监视,"local_agent""remote_agent"

TaskUsage

后台任务的令牌和计时数据。

class TaskUsage(TypedDict):
    total_tokens: int
    tool_uses: int
    duration_ms: int

TaskProgressMessage

定期为运行的后台任务发出进度更新。

@dataclass
class TaskProgressMessage(SystemMessage):
    task_id: str
    description: str
    usage: TaskUsage
    uuid: str
    session_id: str
    tool_use_id: str | None = None
    last_tool_name: str | None = None
字段 类型 描述
task_id str 任务的唯一标识符
description str 当前状态描述
usage TaskUsage 此任务迄今为止的令牌使用情况
uuid str 唯一消息标识符
session_id str 会话标识符
tool_use_id str | None 关联的工具使用 ID
last_tool_name str | None 任务使用的最后一个工具的名称

TaskNotificationMessage

当后台任务完成、失败或停止时发出。后台任务包括 run_in_background Bash 命令、Monitor 监视和后台子代理。

@dataclass
class TaskNotificationMessage(SystemMessage):
    task_id: str
    status: TaskNotificationStatus  # "completed" | "failed" | "stopped"
    output_file: str
    summary: str
    uuid: str
    session_id: str
    tool_use_id: str | None = None
    usage: TaskUsage | None = None
字段 类型 描述
task_id str 任务的唯一标识符
status TaskNotificationStatus "completed""failed""stopped" 之一
output_file str 任务输出文件的路径
summary str 任务结果的摘要
uuid str 唯一消息标识符
session_id str 会话标识符
tool_use_id str | None 关联的工具使用 ID
usage TaskUsage | None 任务的最终令牌使用情况

内容块类型

ContentBlock

所有内容块的联合类型。

ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock

TextBlock

文本内容块。

@dataclass
class TextBlock:
    text: str

ThinkingBlock

思考内容块(用于具有思考能力的模型)。

@dataclass
class ThinkingBlock:
    thinking: str
    signature: str

ToolUseBlock

工具使用请求块。

@dataclass
class ToolUseBlock:
    id: str
    name: str
    input: dict[str, Any]

ToolResultBlock

工具执行结果块。

@dataclass
class ToolResultBlock:
    tool_use_id: str
    content: str | list[dict[str, Any]] | None = None
    is_error: bool | None = None

错误类型

ClaudeSDKError

所有 SDK 错误的基础异常类。

class ClaudeSDKError(Exception):
    """Base error for Claude SDK."""

CLINotFoundError

当 Claude Code CLI 未安装或找不到时引发。

class CLINotFoundError(CLIConnectionError):
    def __init__(
        self, message: str = "Claude Code not found", cli_path: str | None = None
    ):
        """
        Args:
            message: Error message (default: "Claude Code not found")
            cli_path: Optional path to the CLI that was not found
        """

CLIConnectionError

当连接到 Claude Code 失败时引发。

class CLIConnectionError(ClaudeSDKError):
    """Failed to connect to Claude Code."""

ProcessError

当 Claude Code 进程失败时引发。

class ProcessError(ClaudeSDKError):
    def __init__(
        self, message: str, exit_code: int | None = None, stderr: str | None = None
    ):
        self.exit_code = exit_code
        self.stderr = stderr

CLIJSONDecodeError

当 JSON 解析失败时引发。

class CLIJSONDecodeError(ClaudeSDKError):
    def __init__(self, line: str, original_error: Exception):
        """
        Args:
            line: The line that failed to parse
            original_error: The original JSON decode exception
        """
        self.line = line
        self.original_error = original_error

Hook 类型

有关使用 hooks 的综合指南,包括示例和常见模式,见 Hooks 指南

HookEvent

支持的 hook 事件类型。

HookEvent = Literal[
    "PreToolUse",  # Called before tool execution
    "PostToolUse",  # Called after tool execution
    "PostToolUseFailure",  # Called when a tool execution fails
    "UserPromptSubmit",  # Called when user submits a prompt
    "Stop",  # Called when stopping execution
    "SubagentStop",  # Called when a subagent stops
    "PreCompact",  # Called before message compaction
    "Notification",  # Called for notification events
    "SubagentStart",  # Called when a subagent starts
    "PermissionRequest",  # Called when a permission decision is needed
]

HookCallback

hook 回调函数的类型定义。

HookCallback = Callable[[HookInput, str | None, HookContext], Awaitable[HookJSONOutput]]

参数:

  • input:强类型 hook 输入,具有基于 hook_event_name 的判别联合(见 HookInput
  • tool_use_id:可选工具使用标识符(用于工具相关的 hooks)
  • context:带有附加信息的 hook 上下文

返回可能包含以下内容的 HookJSONOutput

  • decision"block" 以阻止操作
  • systemMessage:显示给用户的警告消息
  • hookSpecificOutput:hook 特定的输出数据

HookContext

传递给 hook 回调的上下文信息。

class HookContext(TypedDict):
    signal: Any | None  # Future: abort signal support

HookMatcher

用于将 hooks 匹配到特定事件或工具的配置。

@dataclass
class HookMatcher:
    matcher: str | None = (
        None  # Tool name or pattern to match (e.g., "Bash", "Write|Edit")
    )
    hooks: list[HookCallback] = field(
        default_factory=list
    )  # List of callbacks to execute
    timeout: float | None = (
        None  # Timeout in seconds for all hooks in this matcher (default: 60)
    )

HookInput

所有 hook 输入类型的联合类型。实际类型取决于 hook_event_name 字段。

HookInput = (
    PreToolUseHookInput
    | PostToolUseHookInput
    | PostToolUseFailureHookInput
    | UserPromptSubmitHookInput
    | StopHookInput
    | SubagentStopHookInput
    | PreCompactHookInput
    | NotificationHookInput
    | SubagentStartHookInput
    | PermissionRequestHookInput
)

BaseHookInput

所有 hook 输入类型中存在的基础字段。

class BaseHookInput(TypedDict):
    session_id: str
    transcript_path: str
    cwd: str
    permission_mode: NotRequired[str]
字段 类型 描述
session_id str 当前会话标识符
transcript_path str 会话记录文件的路径
cwd str 当前工作目录
permission_mode str(可选) 当前权限模式

PreToolUseHookInput

PreToolUse hook 事件的输入数据。

class PreToolUseHookInput(BaseHookInput):
    hook_event_name: Literal["PreToolUse"]
    tool_name: str
    tool_input: dict[str, Any]
    tool_use_id: str
    agent_id: NotRequired[str]
    agent_type: NotRequired[str]
字段 类型 描述
hook_event_name Literal["PreToolUse"] 始终为 "PreToolUse"
tool_name str 即将执行的工具的名称
tool_input dict[str, Any] 工具的输入参数
tool_use_id str 此工具使用的唯一标识符
agent_id str(可选) 子代理标识符,当 hook 在子代理内触发时存在
agent_type str(可选) 子代理类型,当 hook 在子代理内触发时存在

PostToolUseHookInput

PostToolUse hook 事件的输入数据。

class PostToolUseHookInput(BaseHookInput):
    hook_event_name: Literal["PostToolUse"]
    tool_name: str
    tool_input: dict[str, Any]
    tool_response: Any
    tool_use_id: str
    agent_id: NotRequired[str]
    agent_type: NotRequired[str]
字段 类型 描述
hook_event_name Literal["PostToolUse"] 始终为 "PostToolUse"
tool_name str 已执行的工具的名称
tool_input dict[str, Any] 使用的输入参数
tool_response Any 工具执行的响应
tool_use_id str 此工具使用的唯一标识符
agent_id str(可选) 子代理标识符,当 hook 在子代理内触发时存在
agent_type str(可选) 子代理类型,当 hook 在子代理内触发时存在

PostToolUseFailureHookInput

PostToolUseFailure hook 事件的输入数据。当工具执行失败时调用。

class PostToolUseFailureHookInput(BaseHookInput):
    hook_event_name: Literal["PostToolUseFailure"]
    tool_name: str
    tool_input: dict[str, Any]
    tool_use_id: str
    error: str
    is_interrupt: NotRequired[bool]
    agent_id: NotRequired[str]
    agent_type: NotRequired[str]
字段 类型 描述
hook_event_name Literal["PostToolUseFailure"] 始终为 "PostToolUseFailure"
tool_name str 失败的工具的名称
tool_input dict[str, Any] 使用的输入参数
tool_use_id str 此工具使用的唯一标识符
error str 失败执行的错误消息
is_interrupt bool(可选) 失败是否由中断引起
agent_id str(可选) 子代理标识符,当 hook 在子代理内触发时存在
agent_type str(可选) 子代理类型,当 hook 在子代理内触发时存在

UserPromptSubmitHookInput

UserPromptSubmit hook 事件的输入数据。

class UserPromptSubmitHookInput(BaseHookInput):
    hook_event_name: Literal["UserPromptSubmit"]
    prompt: str
字段 类型 描述
hook_event_name Literal["UserPromptSubmit"] 始终为 "UserPromptSubmit"
prompt str 用户提交的提示

StopHookInput

Stop hook 事件的输入数据。

class StopHookInput(BaseHookInput):
    hook_event_name: Literal["Stop"]
    stop_hook_active: bool
字段 类型 描述
hook_event_name Literal["Stop"] 始终为 "Stop"
stop_hook_active bool stop hook 是否活跃

SubagentStopHookInput

SubagentStop hook 事件的输入数据。

class SubagentStopHookInput(BaseHookInput):
    hook_event_name: Literal["SubagentStop"]
    stop_hook_active: bool
    agent_id: str
    agent_transcript_path: str
    agent_type: str
字段 类型 描述
hook_event_name Literal["SubagentStop"] 始终为 "SubagentStop"
stop_hook_active bool stop hook 是否活跃
agent_id str 子代理的唯一标识符
agent_transcript_path str 子代理的记录文件路径
agent_type str 子代理的类型

PreCompactHookInput

PreCompact hook 事件的输入数据。

class PreCompactHookInput(BaseHookInput):
    hook_event_name: Literal["PreCompact"]
    trigger: Literal["manual", "auto"]
    custom_instructions: str | None
字段 类型 描述
hook_event_name Literal["PreCompact"] 始终为 "PreCompact"
trigger Literal["manual", "auto"] 什么触发了压缩
custom_instructions str | None 压缩的自定义说明

NotificationHookInput

Notification hook 事件的输入数据。

class NotificationHookInput(BaseHookInput):
    hook_event_name: Literal["Notification"]
    message: str
    title: NotRequired[str]
    notification_type: str
字段 类型 描述
hook_event_name Literal["Notification"] 始终为 "Notification"
message str 通知消息内容
title str(可选) 通知标题
notification_type str 通知类型

SubagentStartHookInput

SubagentStart hook 事件的输入数据。

class SubagentStartHookInput(BaseHookInput):
    hook_event_name: Literal["SubagentStart"]
    agent_id: str
    agent_type: str
字段 类型 描述
hook_event_name Literal["SubagentStart"] 始终为 "SubagentStart"
agent_id str 子代理的唯一标识符
agent_type str 子代理的类型

PermissionRequestHookInput

PermissionRequest hook 事件的输入数据。允许 hooks 以编程方式处理权限决策。

class PermissionRequestHookInput(BaseHookInput):
    hook_event_name: Literal["PermissionRequest"]
    tool_name: str
    tool_input: dict[str, Any]
    permission_suggestions: NotRequired[list[Any]]
字段 类型 描述
hook_event_name Literal["PermissionRequest"] 始终为 "PermissionRequest"
tool_name str 请求权限的工具的名称
tool_input dict[str, Any] 工具的输入参数
permission_suggestions list[Any](可选) 来自 CLI 的建议权限更新

HookJSONOutput

hook 回调返回值的联合类型。

HookJSONOutput = AsyncHookJSONOutput | SyncHookJSONOutput

SyncHookJSONOutput

具有控制和决策字段的同步 hook 输出。

class SyncHookJSONOutput(TypedDict):
    # Control fields
    continue_: NotRequired[bool]  # Whether to proceed (default: True)
    suppressOutput: NotRequired[bool]  # Hide stdout from transcript
    stopReason: NotRequired[str]  # Message when continue is False

    # Decision fields
    decision: NotRequired[Literal["block"]]
    systemMessage: NotRequired[str]  # Warning message for user
    reason: NotRequired[str]  # Feedback for Claude

    # Hook-specific output
    hookSpecificOutput: NotRequired[HookSpecificOutput]

HookSpecificOutput

包含 hook 事件名称和事件特定字段的 TypedDict。形状取决于 hookEventName 值。有关每个 hook 事件的可用字段的完整详情,见 使用 hooks 控制执行

事件特定输出类型的判别联合。hookEventName 字段确定哪些字段有效。

class PreToolUseHookSpecificOutput(TypedDict):
    hookEventName: Literal["PreToolUse"]
    permissionDecision: NotRequired[Literal["allow", "deny", "ask", "defer"]]
    permissionDecisionReason: NotRequired[str]
    updatedInput: NotRequired[dict[str, Any]]
    additionalContext: NotRequired[str]


class PostToolUseHookSpecificOutput(TypedDict):
    hookEventName: Literal["PostToolUse"]
    additionalContext: NotRequired[str]
    updatedToolOutput: NotRequired[Any]
    updatedMCPToolOutput: NotRequired[Any]


class PostToolUseFailureHookSpecificOutput(TypedDict):
    hookEventName: Literal["PostToolUseFailure"]
    additionalContext: NotRequired[str]


class UserPromptSubmitHookSpecificOutput(TypedDict):
    hookEventName: Literal["UserPromptSubmit"]
    additionalContext: NotRequired[str]


class NotificationHookSpecificOutput(TypedDict):
    hookEventName: Literal["Notification"]
    additionalContext: NotRequired[str]


class SubagentStartHookSpecificOutput(TypedDict):
    hookEventName: Literal["SubagentStart"]
    additionalContext: NotRequired[str]


class PermissionRequestHookSpecificOutput(TypedDict):
    hookEventName: Literal["PermissionRequest"]
    decision: dict[str, Any]


HookSpecificOutput = (
    PreToolUseHookSpecificOutput
    | PostToolUseHookSpecificOutput
    | PostToolUseFailureHookSpecificOutput
    | UserPromptSubmitHookSpecificOutput
    | NotificationHookSpecificOutput
    | SubagentStartHookSpecificOutput
    | PermissionRequestHookSpecificOutput
)

AsyncHookJSONOutput

延迟 hook 执行的异步 hook 输出。

class AsyncHookJSONOutput(TypedDict):
    async_: Literal[True]  # Set to True to defer execution
    asyncTimeout: NotRequired[int]  # Timeout in milliseconds

Hook 使用示例

此示例注册两个 hooks:一个阻止危险的 bash 命令(如 rm -rf /),另一个记录所有工具使用以进行审计。安全 hook 仅在 Bash 命令上运行(通过 matcher),而日志 hook 在所有工具上运行。

from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, HookContext
from typing import Any


async def validate_bash_command(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Validate and potentially block dangerous bash commands."""
    if input_data["tool_name"] == "Bash":
        command = input_data["tool_input"].get("command", "")
        if "rm -rf /" in command:
            return {
                "hookSpecificOutput": {
                    "hookEventName": "PreToolUse",
                    "permissionDecision": "deny",
                    "permissionDecisionReason": "Dangerous command blocked",
                }
            }
    return {}


async def log_tool_use(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Log all tool usage for auditing."""
    print(f"Tool used: {input_data.get('tool_name')}")
    return {}


options = ClaudeAgentOptions(
    hooks={
        "PreToolUse": [
            HookMatcher(
                matcher="Bash", hooks=[validate_bash_command], timeout=120
            ),  # 2 min for validation
            HookMatcher(
                hooks=[log_tool_use]
            ),  # Applies to all tools (default 60s timeout)
        ],
        "PostToolUse": [HookMatcher(hooks=[log_tool_use])],
    }
)

async for message in query(prompt="Analyze this codebase", options=options):
    print(message)

工具输入/输出类型

所有内置 Claude Code 工具的输入/输出模式文档。虽然 Python SDK 不将这些导出为类型,但它们代表消息中工具输入和输出的结构。

Agent

工具名称: Agent(之前为 Task,仍然接受作为别名)

输入:

{
    "description": str,  # 任务的简短描述(3-5 个单词)
    "prompt": str,  # 代理要执行的任务
    "subagent_type": str,  # 要使用的专门代理的类型
}

输出:

{
    "result": str,  # 来自子代理的最终结果
    "usage": dict | None,  # 令牌使用统计
    "total_cost_usd": float | None,  # 以美元计的估计总成本
    "duration_ms": int | None,  # 执行持续时间(毫秒)
}

AskUserQuestion

工具名称: AskUserQuestion

在执行期间向用户提出澄清问题。见 处理批准和用户输入 了解使用详情。

输入:

{
    "questions": [  # 要向用户提出的问题(1-4 个问题)
        {
            "question": str,  # 要向用户提出的完整问题
            "header": str,  # 显示为芯片/标签的非常简短的标签(最多 12 个字符)
            "options": [  # 可用的选择(2-4 个选项)
                {
                    "label": str,  # 此选项的显示文本(1-5 个单词)
                    "description": str,  # 此选项含义的说明
                }
            ],
            "multiSelect": bool,  # 设置为 true 以允许多个选择
        }
    ],
    "answers": dict[str, str | list[str]] | None,
    # 由权限系统填充的用户答案。多选
    # 答案可能是标签列表或逗号连接的字符串
}

输出:

{
    "questions": [  # 被提出的问题
        {
            "question": str,
            "header": str,
            "options": [{"label": str, "description": str}],
            "multiSelect": bool,
        }
    ],
    "answers": dict[str, str],  # 将问题文本映射到答案字符串
    # 多选答案以逗号分隔
}

Bash

工具名称: Bash

输入:

{
    "command": str,  # 要执行的命令
    "timeout": int | None,  # 可选的超时时间(毫秒)(最大 600000)
    "description": str | None,  # 清晰、简洁的描述(5-10 个单词)
    "run_in_background": bool | None,  # 设置为 true 以在后台运行
}

输出:

{
    "output": str,  # 合并的 stdout 和 stderr 输出
    "exitCode": int,  # 命令的退出代码
    "killed": bool | None,  # 命令是否因超时而被杀死
    "shellId": str | None,  # 后台进程的 Shell ID
}

Monitor

工具名称: Monitor

运行后台脚本并将每个 stdout 行作为事件传递给 Claude,以便它可以做出反应而无需轮询。Monitor 遵循与 Bash 相同的权限规则。见 Monitor 工具参考 了解行为和提供商可用性。

输入:

{
    "command": str,  # Shell 脚本;每个 stdout 行是一个事件,退出结束监视
    "description": str,  # 在通知中显示的简短描述
    "timeout_ms": int | None,  # 在此截止时间后杀死(默认 300000,最大 3600000)
    "persistent": bool | None,  # 在会话的生命周期内运行;使用 TaskStop 停止
}

输出:

{
    "taskId": str,  # 后台监视任务的 ID
    "timeoutMs": int,  # 超时截止时间(毫秒)(持久时为 0)
    "persistent": bool | None,  # 当运行到 TaskStop 或会话结束时为 True
}

Edit

工具名称: Edit

输入:

{
    "file_path": str,  # 要修改的文件的绝对路径
    "old_string": str,  # 要替换的文本
    "new_string": str,  # 替换为的文本
    "replace_all": bool | None,  # 替换所有出现(默认 False)
}

输出:

{
    "message": str,  # 确认消息
    "replacements": int,  # 进行的替换次数
    "file_path": str,  # 被编辑的文件路径
}

Read

工具名称: Read

输入:

{
    "file_path": str,  # 要读取的文件的绝对路径
    "offset": int | None,  # 开始读取的行号
    "limit": int | None,  # 要读取的行数
}

输出(文本文件):

{
    "content": str,  # 带行号的文件内容
    "total_lines": int,  # 文件中的总行数
    "lines_returned": int,  # 实际返回的行数
}

输出(图像):

{
    "image": str,  # Base64 编码的图像数据
    "mime_type": str,  # 图像 MIME 类型
    "file_size": int,  # 文件大小(字节)
}

Write

工具名称: Write

输入:

{
    "file_path": str,  # 要写入的文件的绝对路径
    "content": str,  # 要写入文件的内容
}

输出:

{
    "message": str,  # 成功消息
    "bytes_written": int,  # 写入的字节数
    "file_path": str,  # 被写入的文件路径
}

Glob

工具名称: Glob

输入:

{
    "pattern": str,  # 用于匹配文件的 glob 模式
    "path": str | None,  # 要搜索的目录(默认为 cwd)
}

输出:

{
    "matches": list[str],  # 匹配的文件路径数组
    "count": int,  # 找到的匹配数
    "search_path": str,  # 使用的搜索目录
}

Grep

工具名称: Grep

输入:

{
    "pattern": str,  # 正则表达式模式
    "path": str | None,  # 要搜索的文件或目录
    "glob": str | None,  # 用于过滤文件的 glob 模式
    "type": str | None,  # 要搜索的文件类型
    "output_mode": str | None,  # "content"、"files_with_matches" 或 "count"
    "-i": bool | None,  # 不区分大小写的搜索
    "-n": bool | None,  # 显示行号
    "-B": int | None,  # 每个匹配前显示的行数
    "-A": int | None,  # 每个匹配后显示的行数
    "-C": int | None,  # 每个匹配前后显示的行数
    "head_limit": int | None,  # 将输出限制为前 N 行/条目
    "multiline": bool | None,  # 启用多行模式
}

输出(content 模式):

{
    "matches": [
        {
            "file": str,
            "line_number": int | None,
            "line": str,
            "before_context": list[str] | None,
            "after_context": list[str] | None,
        }
    ],
    "total_matches": int,
}

输出(files_with_matches 模式):

{
    "files": list[str],  # 包含匹配的文件
    "count": int,  # 包含匹配的文件数
}

NotebookEdit

工具名称: NotebookEdit

输入:

{
    "notebook_path": str,  # Jupyter 笔记本的绝对路径
    "cell_id": str | None,  # 要编辑的单元格的 ID
    "new_source": str,  # 单元格的新源代码
    "cell_type": "code" | "markdown" | None,  # 单元格的类型
    "edit_mode": "replace" | "insert" | "delete" | None,  # 编辑操作类型
}

输出:

{
    "message": str,  # 成功消息
    "edit_type": "replaced" | "inserted" | "deleted",  # 执行的编辑类型
    "cell_id": str | None,  # 受影响的单元格 ID
    "total_cells": int,  # 编辑后笔记本中的总单元格数
}

WebFetch

工具名称: WebFetch

输入:

{
    "url": str,  # 要从中获取内容的 URL
    "prompt": str,  # 在获取的内容上运行的提示
}

输出:

{
    "bytes": int,  # 获取的内容大小(字节)
    "code": int,  # HTTP 响应代码
    "codeText": str,  # HTTP 响应代码文本
    "result": str,  # 通过将提示应用于内容得到的处理结果
    "durationMs": int,  # 获取和处理内容的时间(毫秒)
    "url": str,  # 被获取的 URL
}

工具名称: WebSearch

输入:

{
    "query": str,  # 要使用的搜索查询
    "allowed_domains": list[str] | None,  # 仅包含来自这些域的结果
    "blocked_domains": list[str] | None,  # 永远不包含来自这些域的结果
}

输出:

{
    "query": str,  # 搜索查询
    "results": list[str | {"tool_use_id": str, "content": list[{"title": str, "url": str}]}],
    "durationSeconds": float,  # 搜索持续时间(秒)
}

TodoWrite

工具名称: TodoWrite

输入:

{
    "todos": [
        {
            "content": str,  # 任务描述
            "status": "pending" | "in_progress" | "completed",  # 任务状态
            "activeForm": str,  # 描述的活跃形式
        }
    ]
}

输出:

{
    "message": str,  # 成功消息
    "stats": {"total": int, "pending": int, "in_progress": int, "completed": int},
}

TaskCreate

工具名称: TaskCreate

输入:

{
    "subject": str,  # 简短的任务标题
    "description": str,  # 详细的任务正文
    "activeForm": str | None,  # 进行中时显示的现在时标签
    "metadata": dict | None,  # 任意调用者元数据
}

输出:

{
    "task": {"id": str, "subject": str},  # 创建的任务及其分配的 ID
}

TaskUpdate

工具名称: TaskUpdate

输入:

{
    "taskId": str,  # 要修补的任务的 ID
    "status": Literal["pending", "in_progress", "completed", "deleted"] | None,
    "subject": str | None,
    "description": str | None,
    "activeForm": str | None,
    "addBlocks": list[str] | None,  # 此任务现在阻止的任务 ID
    "addBlockedBy": list[str] | None,  # 现在阻止此任务的任务 ID
    "owner": str | None,
    "metadata": dict | None,
}

输出:

{
    "success": bool,
    "taskId": str,
    "updatedFields": list[str],  # 更改的字段名称
    "error": str | None,
    "statusChange": {"from": str, "to": str} | None,
}

TaskGet

工具名称: TaskGet

输入:

{
    "taskId": str,  # 要读取的任务的 ID
}

输出:

{
    "task": {
        "id": str,
        "subject": str,
        "description": str,
        "status": Literal["pending", "in_progress", "completed"],
        "blocks": list[str],
        "blockedBy": list[str],
    } | None,  # 当 ID 未找到时为 None
}

TaskList

工具名称: TaskList

输入:

{}

输出:

{
    "tasks": [
        {
            "id": str,
            "subject": str,
            "status": Literal["pending", "in_progress", "completed"],
            "owner": str | None,
            "blockedBy": list[str],
        }
    ],
}

BashOutput

工具名称: BashOutput

输入:

{
    "bash_id": str,  # 后台 shell 的 ID
    "filter": str | None,  # 用于过滤输出行的可选正则表达式
}

输出:

{
    "output": str,  # 自上次检查以来的新输出
    "status": "running" | "completed" | "failed",  # 当前 shell 状态
    "exitCode": int | None,  # 完成时的退出代码
}

KillBash

工具名称: KillBash

输入:

{
    "shell_id": str  # 要杀死的后台 shell 的 ID
}

输出:

{
    "message": str,  # 成功消息
    "shell_id": str,  # 被杀死的 shell 的 ID
}

ExitPlanMode

工具名称: ExitPlanMode

输入:

{
    "plan": str  # 用户要运行以获得批准的计划
}

输出:

{
    "message": str,  # 确认消息
    "approved": bool | None,  # 用户是否批准了计划
}

ListMcpResources

工具名称: ListMcpResources

输入:

{
    "server": str | None  # 可选的服务器名称以按其过滤资源
}

输出:

{
    "resources": [
        {
            "uri": str,
            "name": str,
            "description": str | None,
            "mimeType": str | None,
            "server": str,
        }
    ],
    "total": int,
}

ReadMcpResource

工具名称: ReadMcpResource

输入:

{
    "server": str,  # MCP 服务器名称
    "uri": str,  # 要读取的资源 URI
}

输出:

{
    "contents": [
        {"uri": str, "mimeType": str | None, "text": str | None, "blob": str | None}
    ],
    "server": str,
}

ClaudeSDKClient 的高级功能

构建持续对话界面

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    AssistantMessage,
    TextBlock,
)
import asyncio


class ConversationSession:
    """Maintains a single conversation session with Claude."""

    def __init__(self, options: ClaudeAgentOptions | None = None):
        self.client = ClaudeSDKClient(options)
        self.turn_count = 0

    async def start(self):
        await self.client.connect()
        print("Starting conversation session. Claude will remember context.")
        print(
            "Commands: 'exit' to quit, 'interrupt' to stop current task, 'new' for new session"
        )

        while True:
            user_input = input(f"\n[Turn {self.turn_count + 1}] You: ")

            if user_input.lower() == "exit":
                break
            elif user_input.lower() == "interrupt":
                await self.client.interrupt()
                print("Task interrupted!")
                continue
            elif user_input.lower() == "new":
                # Disconnect and reconnect for a fresh session
                await self.client.disconnect()
                await self.client.connect()
                self.turn_count = 0
                print("Started new conversation session (previous context cleared)")
                continue

            # Send message - the session retains all previous messages
            await self.client.query(user_input)
            self.turn_count += 1

            # Process response
            print(f"[Turn {self.turn_count}] Claude: ", end="")
            async for message in self.client.receive_response():
                if isinstance(message, AssistantMessage):
                    for block in message.content:
                        if isinstance(block, TextBlock):
                            print(block.text, end="")
            print()  # New line after response

        await self.client.disconnect()
        print(f"Conversation ended after {self.turn_count} turns.")


async def main():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Write", "Bash"], permission_mode="acceptEdits"
    )
    session = ConversationSession(options)
    await session.start()


# Example conversation:
# Turn 1 - You: "Create a file called hello.py"
# Turn 1 - Claude: "I'll create a hello.py file for you..."
# Turn 2 - You: "What's in that file?"
# Turn 2 - Claude: "The hello.py file I just created contains..." (remembers!)
# Turn 3 -You: "Add a main function to it"
# Turn 3 - Claude: "I'll add a main function to hello.py..." (knows which file!)

asyncio.run(main())

使用 Hooks 进行行为修改

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    HookMatcher,
    HookContext,
)
import asyncio
from typing import Any


async def pre_tool_logger(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Log all tool usage before execution."""
    tool_name = input_data.get("tool_name", "unknown")
    print(f"[PRE-TOOL] About to use: {tool_name}")

    # You can modify or block the tool execution here
    if tool_name == "Bash" and "rm -rf" in str(input_data.get("tool_input", {})):
        return {
            "hookSpecificOutput": {
                "hookEventName": "PreToolUse",
                "permissionDecision": "deny",
                "permissionDecisionReason": "Dangerous command blocked",
            }
        }
    return {}


async def post_tool_logger(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Log results after tool execution."""
    tool_name = input_data.get("tool_name", "unknown")
    print(f"[POST-TOOL] Completed: {tool_name}")
    return {}


async def user_prompt_modifier(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Add context to user prompts."""
    original_prompt = input_data.get("prompt", "")

    # Add a timestamp as additional context for Claude to see
    from datetime import datetime

    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    return {
        "hookSpecificOutput": {
            "hookEventName": "UserPromptSubmit",
            "additionalContext": f"[Submitted at {timestamp}] Original prompt: {original_prompt}",
        }
    }


async def main():
    options = ClaudeAgentOptions(
        hooks={
            "PreToolUse": [
                HookMatcher(hooks=[pre_tool_logger]),
                HookMatcher(matcher="Bash", hooks=[pre_tool_logger]),
            ],
            "PostToolUse": [HookMatcher(hooks=[post_tool_logger])],
            "UserPromptSubmit": [HookMatcher(hooks=[user_prompt_modifier])],
        },
        allowed_tools=["Read", "Write", "Bash"],
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("List files in current directory")

        async for message in client.receive_response():
            # Hooks will automatically log tool usage
            pass


asyncio.run(main())

实时进度监控

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    AssistantMessage,
    ToolUseBlock,
    ToolResultBlock,
    TextBlock,
)
import asyncio


async def monitor_progress():
    options = ClaudeAgentOptions(
        allowed_tools=["Write", "Bash"], permission_mode="acceptEdits"
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("Create 5 Python files with different sorting algorithms")

        # Monitor progress in real-time
        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, ToolUseBlock):
                        if block.name == "Write":
                            file_path = block.input.get("file_path", "")
                            print(f"Creating: {file_path}")
                    elif isinstance(block, ToolResultBlock):
                        print("Completed tool execution")
                    elif isinstance(block, TextBlock):
                        print(f"Claude says: {block.text[:100]}...")

        print("Task completed!")


asyncio.run(monitor_progress())

示例用法

基本文件操作(使用 query)

from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ToolUseBlock
import asyncio


async def create_project():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Write", "Bash"],
        permission_mode="acceptEdits",
        cwd="/home/user/project",
    )

    async for message in query(
        prompt="Create a Python project structure with setup.py", options=options
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, ToolUseBlock):
                    print(f"Using tool: {block.name}")


asyncio.run(create_project())

错误处理

from claude_agent_sdk import query, CLINotFoundError, ProcessError, CLIJSONDecodeError

try:
    async for message in query(prompt="Hello"):
        print(message)
except CLINotFoundError:
    print(
        "Claude Code CLI not found. Try reinstalling: pip install --force-reinstall claude-agent-sdk"
    )
except ProcessError as e:
    print(f"Process failed with exit code: {e.exit_code}")
except CLIJSONDecodeError as e:
    print(f"Failed to parse response: {e}")

使用客户端的流式模式

from claude_agent_sdk import ClaudeSDKClient
import asyncio


async def interactive_session():
    async with ClaudeSDKClient() as client:
        # Send initial message
        await client.query("What's the weather like?")

        # Process responses
        async for msg in client.receive_response():
            print(msg)

        # Send follow-up
        await client.query("Tell me more about that")

        # Process follow-up response
        async for msg in client.receive_response():
            print(msg)


asyncio.run(interactive_session())

使用 ClaudeSDKClient 的自定义工具

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    tool,
    create_sdk_mcp_server,
    AssistantMessage,
    TextBlock,
)
import asyncio
from typing import Any


# Define custom tools with @tool decorator
@tool("calculate", "Perform mathematical calculations", {"expression": str})
async def calculate(args: dict[str, Any]) -> dict[str, Any]:
    try:
        result = eval(args["expression"], {"__builtins__": {}})
        return {"content": [{"type": "text", "text": f"Result: {result}"}]}
    except Exception as e:
        return {
            "content": [{"type": "text", "text": f"Error: {str(e)}"}],
            "is_error": True,
        }


@tool("get_time", "Get current time", {})
async def get_time(args: dict[str, Any]) -> dict[str, Any]:
    from datetime import datetime

    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    return {"content": [{"type": "text", "text": f"Current time: {current_time}"}]}


async def main():
    # Create SDK MCP server with custom tools
    my_server = create_sdk_mcp_server(
        name="utilities", version="1.0.0", tools=[calculate, get_time]
    )

    # Configure options with the server
    options = ClaudeAgentOptions(
        mcp_servers={"utils": my_server},
        allowed_tools=["mcp__utils__calculate", "mcp__utils__get_time"],
    )

    # Use ClaudeSDKClient for interactive tool usage
    async with ClaudeSDKClient(options=options) as client:
        await client.query("What's 123 * 456?")

        # Process calculation response
        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, TextBlock):
                        print(f"Calculation: {block.text}")

        # Follow up with time query
        await client.query("What time is it now?")

        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, TextBlock):
                        print(f"Time: {block.text}")


asyncio.run(main())

沙箱配置

SandboxSettings

沙箱行为的配置。使用此来启用命令沙箱和以编程方式配置网络限制。

class SandboxSettings(TypedDict, total=False):
    enabled: bool
    autoAllowBashIfSandboxed: bool
    excludedCommands: list[str]
    allowUnsandboxedCommands: bool
    network: SandboxNetworkConfig
    ignoreViolations: SandboxIgnoreViolations
    enableWeakerNestedSandbox: bool
属性 类型 默认值 描述
enabled bool False 为命令执行启用沙箱模式
autoAllowBashIfSandboxed bool True 启用沙箱时自动批准 bash 命令
excludedCommands list[str] [] 始终绕过沙箱限制的命令(例如 ["docker"])。这些自动运行沙箱外,无需模型参与
allowUnsandboxedCommands bool True 允许模型请求在沙箱外运行命令。当为 True 时,模型可以在工具输入中设置 dangerouslyDisableSandbox,这会回退到 权限系统
network SandboxNetworkConfig None 网络特定的沙箱配置
ignoreViolations SandboxIgnoreViolations None 配置要忽略的沙箱违规
enableWeakerNestedSandbox bool False 启用较弱的嵌套沙箱以实现兼容性

示例用法

from claude_agent_sdk import query, ClaudeAgentOptions, SandboxSettings

sandbox_settings: SandboxSettings = {
    "enabled": True,
    "autoAllowBashIfSandboxed": True,
    "network": {"allowLocalBinding": True},
}

async for message in query(
    prompt="Build and test my project",
    options=ClaudeAgentOptions(sandbox=sandbox_settings),
):
    print(message)

SandboxNetworkConfig

沙箱模式的网络特定配置。

class SandboxNetworkConfig(TypedDict, total=False):
    allowedDomains: list[str]
    deniedDomains: list[str]
    allowManagedDomainsOnly: bool
    allowUnixSockets: list[str]
    allowAllUnixSockets: bool
    allowLocalBinding: bool
    allowMachLookup: list[str]
    httpProxyPort: int
    socksProxyPort: int
属性 类型 默认值 描述
allowedDomains list[str] [] 沙箱化进程可以访问的域名
deniedDomains list[str] [] 沙箱化进程无法访问的域名。优先于 allowedDomains
allowManagedDomainsOnly bool False 仅限托管设置:在托管设置中设置时,忽略来自非托管设置源的 allowedDomains。通过 SDK 选项设置时无效
allowUnixSockets list[str] [] 进程可以访问的 Unix socket 路径(例如 Docker socket)
allowAllUnixSockets bool False 允许访问所有 Unix sockets
allowLocalBinding bool False 允许进程绑定到本地端口(例如开发服务器)
allowMachLookup list[str] [] 仅限 macOS:允许的 XPC/Mach 服务名称。支持尾部通配符
httpProxyPort int None 网络请求的 HTTP 代理端口
socksProxyPort int None 网络请求的 SOCKS 代理端口

SandboxIgnoreViolations

用于忽略特定沙箱违规的配置。

class SandboxIgnoreViolations(TypedDict, total=False):
    file: list[str]
    network: list[str]
属性 类型 默认值 描述
file list[str] [] 要忽略违规的文件路径模式
network list[str] [] 要忽略违规的网络模式

沙箱外命令的权限回退

allowUnsandboxedCommands 启用时,模型可以通过在工具输入中设置 dangerouslyDisableSandbox: True 来请求在沙箱外运行命令。这些请求回退到现有权限系统,意味着你的 can_use_tool 处理程序将被调用,允许你实现自定义授权逻辑。

from claude_agent_sdk import (
    query,
    ClaudeAgentOptions,
    HookMatcher,
    PermissionResultAllow,
    PermissionResultDeny,
    ToolPermissionContext,
)


async def can_use_tool(
    tool: str, input: dict, context: ToolPermissionContext
) -> PermissionResultAllow | PermissionResultDeny:
    # Check if the model is requesting to bypass the sandbox
    if tool == "Bash" and input.get("dangerouslyDisableSandbox"):
        # The model is requesting to run this command outside the sandbox
        print(f"Unsandboxed command requested: {input.get('command')}")

        if is_command_authorized(input.get("command")):
            return PermissionResultAllow()
        return PermissionResultDeny(
            message="Command not authorized for unsandboxed execution"
        )
    return PermissionResultAllow()


# Required: dummy hook keeps the stream open for can_use_tool
async def dummy_hook(input_data, tool_use_id, context):
    return {"continue_": True}


async def prompt_stream():
    yield {
        "type": "user",
        "message": {"role": "user", "content": "Deploy my application"},
    }


async def main():
    async for message in query(
        prompt=prompt_stream(),
        options=ClaudeAgentOptions(
            sandbox={
                "enabled": True,
                "allowUnsandboxedCommands": True,  # Model can request unsandboxed execution
            },
            permission_mode="default",
            can_use_tool=can_use_tool,
            hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[dummy_hook])]},
        ),
    ):
        print(message)

此模式使你能够:

  • 审计模型请求:记录模型何时请求沙箱外执行
  • 实现允许列表:仅允许特定命令在沙箱外运行
  • 添加批准工作流:需要显式授权以进行特权操作

另见