SpyBara
Go Premium

agent-sdk/python.md 2026-06-16 21:57 UTC to 2026-06-17 17:02 UTC

520 added, 179 removed.

2026
Thu 18 22:00 Wed 17 17:02 Tue 16 21:57 Mon 15 23:02 Sat 13 21:59 Fri 12 22:00 Thu 11 23:01 Wed 10 23:57 Tue 9 06:34 Mon 8 06:52 Sat 6 06:24 Fri 5 06:45 Thu 4 06:52 Wed 3 06:53 Tue 2 06:51

Agent SDK 參考 - Python

Python Agent SDK 的完整 API 參考,包括所有函數、類型和類別。

安裝

pip install claude-agent-sdk

在 `query()` 和 `ClaudeSDKClient` 之間選擇

Python SDK 提供了兩種與 Claude Code 互動的方式:

快速比較

功能 query() ClaudeSDKClient
Session 預設情況下建立新 session 重複使用相同 session
Conversation 單一交換 同一上下文中的多個交換
Connection 自動管理 手動控制
Streaming Input ✅ 支援 ✅ 支援
Interrupts ❌ 不支援 ✅ 支援
Hooks ✅ 支援 ✅ 支援
Custom Tools ✅ 支援 ✅ 支援
Continue Chat 透過 continue_conversationresume 手動進行 ✅ 自動進行
Use Case 一次性任務 持續對話

何時使用 `query()`(一次性任務)

最適合:

  • 一次性問題,不需要對話歷史
  • 不需要先前交換上下文的獨立任務
  • 簡單的自動化腳本
  • 當您想每次都重新開始時

何時使用 `ClaudeSDKClient`(持續對話)

最適合:

  • 繼續對話 - 當您需要 Claude 記住上下文時
  • 後續問題 - 基於先前回應進行構建
  • 互動式應用程式 - 聊天介面、REPL
  • 回應驅動邏輯 - 當下一個動作取決於 Claude 的回應時
  • Session 控制 - 明確管理對話生命週期

函數

`query()`

為每次與 Claude Code 的互動建立新 session。返回一個非同步迭代器,在消息到達時產生消息。每次呼叫 query() 都會重新開始,不記得先前的互動,除非您傳遞 continue_conversation=True 或在 ClaudeAgentOptions 中傳遞 resume。請參閱 Sessions

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 tools 的裝飾器。

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 tool 的唯一識別碼
description str tool 功能的人類可讀描述
input_schema type | dict[str, Any] 定義 tool 輸入參數的架構(見下文)
annotations ToolAnnotations | None 可選的 MCP tool 註解,為客戶端提供行為提示

輸入架構選項

  1. 簡單類型對應(推薦):

    {"text": str, "count": int, "enabled": bool}
    
  2. JSON Schema 格式(用於複雜驗證):

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

返回

一個裝飾器函數,包裝 tool 實現並返回 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 tool 的人類可讀標題
readOnlyHint bool | None False 如果為 True,tool 不會修改其環境
destructiveHint bool | None True 如果為 True,tool 可能執行破壞性更新(僅在 readOnlyHintFalse 時有意義)
idempotentHint bool | None False 如果為 True,使用相同參數的重複呼叫沒有額外效果(僅在 readOnlyHintFalse 時有意義)
openWorldHint bool | None True 如果為 True,tool 與外部實體互動(例如網路搜尋)。如果為 False,tool 的域是封閉的(例如記憶體 tool)
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 裝飾器建立的 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()`

列出過去的 sessions 及其中繼資料。按專案目錄篩選或列出所有專案中的 sessions。同步;立即返回。

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

參數

參數 類型 預設 描述
directory str | None None 列出 sessions 的目錄。省略時,返回所有專案中的 sessions
limit int | None None 返回的最大 sessions 數
include_worktrees bool True directory 在 git 儲存庫內時,包括所有 worktrees 路徑中的 sessions

返回類型:`SDKSessionInfo`

屬性 類型 描述
session_id str 唯一 session 識別碼
summary str 顯示標題:自訂標題、自動生成的摘要或第一個提示
last_modified int 上次修改時間(自紀元以來的毫秒數)
file_size int | None Session 檔案大小(以位元組為單位)(遠端儲存後端為 None
custom_title str | None 使用者設定的 session 標題
first_prompt str | None session 中的第一個有意義的使用者提示
git_branch str | None session 結束時的 Git 分支
cwd str | None session 的工作目錄
tag str | None 使用者設定的 session 標籤(見 tag_session()
created_at int | None session 建立時間(自紀元以來的毫秒數)

範例

列印專案的 10 個最近 sessions。結果按 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()`

從過去的 session 中檢索消息。同步;立即返回。

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

參數

參數 類型 預設 描述
session_id str 必需 要檢索消息的 session ID
directory str | None None 要查看的專案目錄。省略時,搜尋所有專案
limit int | None None 返回的最大消息數
offset int 0 從開始跳過的消息數

返回類型:`SessionMessage`

屬性 類型 描述
type Literal["user", "assistant"] 消息角色
uuid str 唯一消息識別碼
session_id str session 識別碼
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 讀取單個 session 的中繼資料,無需掃描完整專案目錄。同步;立即返回。

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

參數

參數 類型 預設 描述
session_id str 必需 要查詢的 session 的 UUID
directory str | None None 專案目錄路徑。省略時,搜尋所有專案目錄

返回 SDKSessionInfo,如果找不到 session,則返回 None

範例

查詢單個 session 的中繼資料,無需掃描專案目錄。當您已經從先前的執行中獲得 session 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()`

通過附加自訂標題項來重新命名 session。重複呼叫是安全的;最新的標題獲勝。同步。

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

參數

參數 類型 預設 描述
session_id str 必需 要重新命名的 session 的 UUID
title str 必需 新標題。去除空格後必須非空
directory str | None None 專案目錄路徑。省略時,搜尋所有專案目錄

如果 session_id 不是有效的 UUID 或 title 為空,則引發 ValueError;如果找不到 session,則引發 FileNotFoundError

範例

重新命名最近的 session,以便稍後更容易找到。新標題在後續讀取時出現在 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()`

標記 session。傳遞 None 以清除標籤。重複呼叫是安全的;最新的標籤獲勝。同步。

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

參數

參數 類型 預設 描述
session_id str 必需 要標記的 session 的 UUID
tag str | None 必需 標籤字串,或 None 以清除。儲存前進行 Unicode 清理
directory str | None None 專案目錄路徑。省略時,搜尋所有專案目錄

如果 session_id 不是有效的 UUID 或 tag 在清理後為空,則引發 ValueError;如果找不到 session,則引發 FileNotFoundError

範例

標記 session,然後在稍後的讀取中按該標籤篩選。傳遞 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`

在多個交換中維持對話 session。 這是 TypeScript SDK 的 query() 函數內部工作方式的 Python 等效物 - 它建立一個可以繼續對話的客戶端物件。

主要功能

  • Session 連續性:在多個 query() 呼叫中維持對話上下文
  • 相同對話:session 保留先前的消息
  • 中斷支援:可以在任務中途停止執行
  • 明確生命週期:您控制 session 何時開始和結束
  • 回應驅動流程:可以對回應做出反應並發送後續消息
  • 自訂 tools 和 hooks:支援自訂 tools(使用 @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) 變更目前 session 的權限模式
set_model(model) 變更目前 session 的模型。傳遞 None 以重設為預設值
rewind_files(user_message_id) 將檔案還原到指定使用者消息時的狀態。需要 enable_file_checkpointing=True。見 檔案 checkpointing
get_mcp_status() 取得所有已配置 MCP 伺服器的狀態。返回 McpStatusResponse
reconnect_mcp_server(server_name) 重試連接到失敗或斷開連接的 MCP 伺服器
toggle_mcp_server(server_name, enabled) 在 session 中途啟用或停用 MCP 伺服器。停用會移除其 tools
stop_task(task_id) 停止執行中的背景任務。TaskNotificationMessage 的狀態為 "stopped" 在消息流中跟隨
get_server_info() 取得伺服器資訊,包括 session 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 tool 的定義。

@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 tool 的唯一識別碼
description str 人類可讀描述
input_schema type[T] | dict[str, Any] 輸入驗證的架構
handler Callable[[T], Awaitable[dict[str, Any]]] 處理 tool 執行的非同步函數
annotations ToolAnnotations | None 可選的 MCP tool 註解(例如 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。

@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: EffortLevel | None = None
    enable_file_checkpointing: bool = False
    session_store: SessionStore | None = None
    session_store_flush: SessionStoreFlushMode = "batched"
屬性 類型 預設 描述
tools list[str] | ToolsPreset | None None Tools 配置。使用 {"type": "preset", "preset": "claude_code"} 以取得 Claude Code 的預設 tools
allowed_tools list[str] [] 自動批准的 tools,無需提示。這不會限制 Claude 僅使用這些 tools;未列出的 tools 會進入 permission_modecan_use_tool。使用 disallowed_tools 來阻止 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 伺服器和 claude.ai 連接器。對應到 CLI --strict-mcp-config 旗標
permission_mode PermissionMode | None None tool 使用的權限模式
continue_conversation bool False 繼續最近的對話
resume str | None None 要繼續的 session ID
max_turns int | None None 最大代理轉數(tool 使用往返)
max_budget_usd float | None None 當客戶端成本估計達到此 USD 值時停止查詢。與 total_cost_usd 的相同估計進行比較;見 追蹤成本和使用情況 以了解準確性注意事項
disallowed_tools list[str] [] 要拒絕的 tools。裸名稱(例如 "Bash")會從 Claude 的上下文中移除該 tool。範圍規則(例如 "Bash(rm *)")會保留該 tool 可用,並在每個權限模式(包括 bypassPermissions)中拒絕匹配的呼叫。見 權限
enable_file_checkpointing bool False 啟用檔案變更追蹤以進行倒帶。見 檔案 checkpointing
model str | None None Claude 模型別名或完整模型名稱。見 接受的值和提供者特定 ID
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 tool 名稱
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 tool 權限回呼函數。見 權限類型 以了解詳情
hooks dict[HookEvent, list[HookMatcher]] | None None 用於攔截事件的 hooks 配置
user str | None None 使用者識別碼
include_partial_messages bool False 包括部分消息串流事件。啟用時,StreamEvent 消息會被產生
include_hook_events bool False 在消息流中包括 hook 生命週期事件作為 HookEventMessage 物件
fork_session bool False 使用 resume 繼續時,分叉到新 session ID 而不是繼續原始 session
agents dict[str, AgentDefinition] | None None 以程式設計方式定義的子代理
plugins list[SdkPluginConfig] [] 從本地路徑載入自訂外掛程式。見 外掛程式 以了解詳情
sandbox SandboxSettings | None None 以程式設計方式配置沙箱行為。見 沙箱設定 以了解詳情
setting_sources list[SettingSource] | None None(CLI 預設值:所有來源) 控制要載入哪些檔案系統設定。傳遞 [] 以停用使用者、專案和本地設定。無論如何都會載入受管原則設定。見 使用 Claude Code 功能
skills list[str] | Literal["all"] | None None 可供 session 使用的 skills。傳遞 "all" 以啟用每個發現的 skill,或傳遞 skill 名稱清單。設定時,SDK 會自動將 Skill tool 新增到 allowed_tools。如果您也傳遞 tools,請在該清單中包括 "Skill"。見 Skills
max_thinking_tokens int | None None 已棄用 - 思考區塊的最大令牌數。改用 thinking
thinking ThinkingConfig | None None 控制擴展思考行為。優先於 max_thinking_tokens
effort EffortLevel | None None 思考深度的努力級別。見 調整努力級別
session_store SessionStore | None None 將 session 記錄鏡像到外部後端,以便任何主機都可以繼續它們。見 將 sessions 持久化到外部儲存
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=1 搭配 CLAUDE_STREAM_IDLE_TIMEOUT_MS:當標頭已到達但回應本體停止串流時中止請求。當 CLAUDE_ENABLE_STREAM_WATCHDOG 未設定時,預設在直接 Anthropic API 上由伺服器控制,在其他提供者上關閉。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 將每個 session 上下文(例如工作目錄、git 狀態和記憶體路徑)從系統提示移到第一個使用者消息。改進跨使用者和機器的提示快取重複使用。見 修改系統提示

`SettingSource`

控制 SDK 從哪些檔案系統配置來源載入設定。

SettingSource = Literal["user", "project", "local"]
描述 位置
"user" 全域使用者設定 ~/.claude/settings.json
"project" 共享專案設定(版本控制) .claude/settings.json
"local" 本地專案設定(未版本控制) .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: EffortLevel | int | None = None
    permissionMode: PermissionMode | None = None
欄位 必需 描述
description 何時使用此代理的自然語言描述
prompt 代理的系統提示
tools 允許的 tool 名稱陣列。如果省略,繼承所有 tools
disallowedTools 要從代理的 tool 集中移除的 tool 名稱陣列。也接受 MCP 伺服器級別的模式:mcp__servermcp__server__* 移除該伺服器的每個 tool,mcp__* 移除任何伺服器的每個 MCP tool
model 此代理的模型覆蓋。接受別名,例如 "sonnet""opus""haiku""inherit",或完整模型 ID。如果省略,使用主模型
skills 此代理可用的 skill 名稱清單
memory 此代理的記憶體來源:"user""project""local"
mcpServers 此代理可用的 MCP 伺服器。每個項目是伺服器名稱或內聯 {name: config} 字典
initialPrompt 當此代理作為主執行緒代理執行時自動提交為第一個使用者轉
maxTurns 代理停止前的最大代理轉數
background 當呼叫時將此代理作為非阻塞背景任務執行
effort 此代理的推理努力級別。接受命名級別或整數。見 EffortLevel
permissionMode 此代理內 tool 執行的權限模式。見 PermissionMode

`PermissionMode`

用於控制 tool 執行的權限模式。

PermissionMode = Literal[
    "default",  # Standard permission behavior
    "acceptEdits",  # Auto-accept file edits
    "plan",  # Planning mode - explore without editing
    "dontAsk",  # Deny anything not pre-approved instead of prompting
    "bypassPermissions",  # Bypass permission checks; explicit ask rules still prompt (use with caution)
]

`EffortLevel`

用於指導思考深度的努力級別。

EffortLevel = Literal[
    "low",  # Minimal thinking, fastest responses
    "medium",  # Moderate thinking
    "high",  # Deep reasoning
    "xhigh",  # Extended reasoning (Opus 4.8 and Opus 4.7; falls back to "high" on other models)
    "max",  # Maximum effort
]

`CanUseTool`

tool 權限回呼函數的類型別名。

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

回呼接收:

  • tool_name:被呼叫的 tool 名稱
  • input_data:tool 的輸入參數
  • context:具有其他資訊的 ToolPermissionContext

返回 PermissionResultPermissionResultAllowPermissionResultDeny)。

`ToolPermissionContext`

傳遞給 tool 權限回呼的上下文資訊。

@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 並在 sessions 中持久化。
blocked_path str | None 觸發權限請求的檔案路徑(如適用)。例如,當 Bash 命令嘗試存取允許目錄外的路徑時
decision_reason str | None 觸發此權限請求的原因。從 PreToolUse hook 的 permissionDecisionReason 轉發,當 hook 返回 "ask"
title str | None 完整權限提示句子,例如 Claude wants to read foo.txt。當存在時用作主要提示文本
display_name str | None tool 操作的簡短名詞短語,例如 Read file,適合按鈕標籤
description str | None 權限 UI 的人類可讀副標題

`PermissionResult`

權限回呼結果的聯合類型。

PermissionResult = PermissionResultAllow | PermissionResultDeny

`PermissionResultAllow`

指示應允許 tool 呼叫的結果。

@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`

指示應拒絕 tool 呼叫的結果。

@dataclass
class PermissionResultDeny:
    behavior: Literal["deny"] = "deny"
    message: str = ""
    interrupt: bool = False
欄位 類型 預設 描述
behavior Literal["deny"] "deny" 必須是 "deny"
message str "" 解釋為什麼拒絕 tool 的消息
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 預設 tool 集的預設 tools 配置。

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

`ThinkingConfig`

控制擴展思考行為。三個配置的聯合:

ThinkingDisplay = Literal["summarized", "omitted"]


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


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


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


ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
變體 欄位 描述
adaptive type, display Claude 自適應決定何時思考
enabled type, budget_tokens, display 啟用具有特定令牌預算的思考
disabled type 停用思考

可選的 display 欄位控制思考文本是否返回為 "summarized""omitted"。在 Claude Opus 4.7 及更新版本上,API 預設為 "omitted",因此設定 "summarized" 以在 ThinkingBlock 輸出中接收思考內容。

因為這些是 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`

MCP 伺服器的配置,如 get_mcp_status() 所報告。這是所有 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(可選) 此伺服器提供的 tools,每個都具有 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"},
]

如需建立和使用外掛程式的完整資訊,見 外掛程式

消息類型

`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 如果此消息是 tool 結果回應,則為 tool 使用 ID
tool_use_result dict[str, Any] | None tool 結果資料(如適用)

`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 如果這是嵌套回應,則為 tool 使用 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

subtype 欄位決定了其他哪些欄位會被填入。它是 "success""error_during_execution""error_max_turns""error_max_budget_usd""error_max_structured_output_retries" 之一。Python dataclass 將所有變體扁平化為一個形狀,因此不適用於返回的 subtype 的欄位為 None

當對話在錯誤時結束時,多個欄位會帶有診斷詳細資訊:

  • is_error:當對話以錯誤狀態結束時為 True。在 error_* subtypes 上始終為 True。在 subtype="success" 上,當最終模型請求失敗時為 True,表示代理迴圈已完成但最後一個 API 呼叫返回了錯誤。
  • api_error_status:終止 API 錯誤的 HTTP 狀態碼。當轉在沒有錯誤的情況下結束時為 None。僅在 subtype="success" 上填入。
  • result:在 subtype="success" 上為最終助手消息的文字,或在 error_* subtypes 上為 None。當 subtype="success"is_error=True 時,如果可用,此欄位會保存 API 錯誤字串,但可能為空,因此請檢查 api_error_status 和前面的 AssistantMessage 內容以獲取詳細資訊。
  • errors:迴圈級別的錯誤字串,例如最大轉數消息。僅在 error_* subtypes 上填入。

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 此模型的估計成本(以 USD 為單位),在客戶端計算。見 追蹤成本和使用情況 以了解計費注意事項。
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 session 識別碼
event dict[str, Any] 原始 Claude API 串流事件資料
parent_tool_use_id str | None 如果此事件來自子代理,則為父 tool 使用 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 session 識別碼

`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 tool 生成的子代理或遠端代理。task_type 欄位告訴您是哪一個。此命名與 TaskAgent tool 重新命名無關。

@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 session 識別碼
tool_use_id str | None 相關聯的 tool 使用 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 session 識別碼
tool_use_id str | None 相關聯的 tool 使用 ID
last_tool_name str | None 任務最後使用的 tool 名稱

`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 session 識別碼
tool_use_id str | None 相關聯的 tool 使用 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:可選 tool 使用識別碼(用於 tool 相關 hooks)
  • context:具有其他資訊的 hook 上下文

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

  • decision"block" 以阻止動作
  • systemMessage:警告消息,顯示給使用者
  • hookSpecificOutput:hook 特定輸出資料

`HookContext`

傳遞給 hook 回呼的上下文資訊。

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

`HookMatcher`

用於將 hooks 符合到特定事件或 tools 的配置。

@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 目前 session 識別碼
transcript_path str session 記錄檔案的路徑
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 名稱
tool_input dict[str, Any] tool 的輸入參數
tool_use_id str 此 tool 使用的唯一識別碼
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 名稱
tool_input dict[str, Any] 使用的輸入參數
tool_response Any tool 執行的回應
tool_use_id str 此 tool 使用的唯一識別碼
agent_id str(可選) 子代理識別碼,當 hook 在子代理內觸發時出現
agent_type str(可選) 子代理類型,當 hook 在子代理內觸發時出現

`PostToolUseFailureHookInput`

PostToolUseFailure hook 事件的輸入資料。在 tool 執行失敗時呼叫。

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 名稱
tool_input dict[str, Any] 使用的輸入參數
tool_use_id str 此 tool 使用的唯一識別碼
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 名稱
tool_input dict[str, Any] tool 的輸入參數
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]  # Deprecated: use updatedToolOutput, which works for all tools


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 /),另一個記錄所有 tool 使用情況以進行審計。安全 hook 僅在 Bash 命令上執行(透過 matcher),而記錄 hook 在所有 tools 上執行。

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)

Tool 輸入/輸出類型

所有內建 Claude Code tools 的輸入/輸出架構文件。雖然 Python SDK 不將這些匯出為類型,但它們代表消息中 tool 輸入和輸出的結構。

Agent

Tool 名稱: Agent(先前為 Task,仍接受作為別名)

輸入:

{
    "description": str,  # 任務的簡短描述(3-5 個單詞)
    "prompt": str,  # agent 要執行的任務
    "subagent_type": str,  # 要使用的專門 agent 類型
}

輸出:

{
    "result": str,  # 來自 subagent 的最終結果
    "usage": dict | None,  # Token 使用統計
    "total_cost_usd": float | None,  # 估計的美元總成本
    "duration_ms": int | None,  # 執行持續時間(毫秒)
}

AskUserQuestion

Tool 名稱: 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

Tool 名稱: 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

Tool 名稱: Monitor

執行背景腳本並將每個 stdout 行作為事件傳遞給 Claude,以便它可以做出反應而無需輪詢。Monitor 遵循與 Bash 相同的權限規則。見 Monitor tool 參考 以了解行為和提供者可用性。

輸入:

{
    "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

Tool 名稱: Edit

輸入:

{
    "file_path": str,  # 要修改的檔案的絕對路徑
    "old_string": str,  # 要替換的文字
    "new_string": str,  # 用來替換的文字
    "replace_all": bool | None,  # 替換所有出現次數(預設 False)
}

輸出:

{
    "message": str,  # 確認訊息
    "replacements": int,  # 進行的替換次數
    "file_path": str,  # 被編輯的檔案路徑
}

Read

Tool 名稱: 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

Tool 名稱: Write

輸入:

{
    "file_path": str,  # 要寫入的檔案的絕對路徑
    "content": str,  # 要寫入檔案的內容
}

輸出:

{
    "message": str,  # 成功訊息
    "bytes_written": int,  # 寫入的位元組數
    "file_path": str,  # 被寫入的檔案路徑
}

Glob

Tool 名稱: Glob

輸入:

{
    "pattern": str,  # 要與檔案匹配的 glob 模式
    "path": str | None,  # 要搜尋的目錄(預設為 cwd)
}

輸出:

{
    "matches": list[str],  # 匹配的檔案路徑陣列
    "count": int,  # 找到的匹配數
    "search_path": str,  # 使用的搜尋目錄
}

Grep

Tool 名稱: 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

Tool 名稱: NotebookEdit

輸入:

{
    "notebook_path": str,  # Jupyter notebook 的絕對路徑
    "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,  # 編輯後 notebook 中的總儲存格數
}

WebFetch

Tool 名稱: WebFetch

輸入:

{
    "url": str,  # 要從中擷取內容的 URL
    "prompt": str,  # 在擷取的內容上執行的提示
}

輸出:

{
    "bytes": int,  # 擷取內容的大小(位元組)
    "code": int,  # HTTP 回應代碼
    "codeText": str,  # HTTP 回應代碼文字
    "result": str,  # 將提示應用於內容的處理結果
    "durationMs": int,  # 擷取和處理內容的時間(毫秒)
    "url": str,  # 被擷取的 URL
}

WebSearch

Tool 名稱: 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

Tool 名稱: TodoWrite

輸入:

{
    "todos": [
        {
            "content": str,  # 任務描述
            "status": "pending" | "in_progress" | "completed",  # 任務狀態
            "activeForm": str,  # 描述的主動形式
        }
    ]
}

輸出:

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

TaskCreate

Tool 名稱: TaskCreate

輸入:

{
    "subject": str,  # 簡短的任務標題
    "description": str,  # 詳細的任務內容
    "activeForm": str | None,  # 進行中時顯示的現在式標籤
    "metadata": dict | None,  # 任意呼叫者中繼資料
}

輸出:

{
    "task": {"id": str, "subject": str},  # 建立的任務及指派的 ID
}

TaskUpdate

Tool 名稱: 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

Tool 名稱: 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

Tool 名稱: TaskList

輸入:

{}

輸出:

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

BashOutput

Tool 名稱: BashOutput

輸入:

{
    "bash_id": str,  # 背景 shell 的 ID
    "filter": str | None,  # 用於篩選輸出行的可選正規表達式
}

輸出:

{
    "output": str,  # 自上次檢查以來的新輸出
    "status": "running" | "completed" | "failed",  # 目前 shell 狀態
    "exitCode": int | None,  # 完成時的結束代碼
}

KillBash

Tool 名稱: KillBash

輸入:

{
    "shell_id": str  # 要終止的背景 shell 的 ID
}

輸出:

{
    "message": str,  # 成功訊息
    "shell_id": str,  # 被終止的 shell 的 ID
}

ExitPlanMode

Tool 名稱: ExitPlanMode

輸入:

{
    "plan": str  # 使用者要執行以供批准的計畫
}

輸出:

{
    "message": str,  # 確認訊息
    "approved": bool | None,  # 使用者是否批准計畫
}

ListMcpResources

Tool 名稱: ListMcpResourcesTool

輸入:

{
    "server": str | None  # 可選的伺服器名稱以篩選資源
}

輸出:

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

ReadMcpResource

Tool 名稱: ReadMcpResourceTool

輸入:

{
    "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 的自訂 tools

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 時,模型可以在 tool 輸入中設定 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`

沙箱模式的網路特定配置。這些設定適用於當父 SandboxSettings 中的 enabledTrue 時的沙箱化 Bash 命令。它們不會限制 WebFetch 工具,該工具改用權限規則

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 proxy 連接埠
socksProxyPort int None 網路請求的 SOCKS proxy 連接埠

`SandboxIgnoreViolations`

用於忽略特定沙箱違規的配置。

class SandboxIgnoreViolations(TypedDict, total=False):
    file: list[str]
    network: list[str]
屬性 類型 預設 描述
file list[str] [] 要忽略違規的檔案路徑模式
network list[str] [] 要忽略違規的網路模式

未沙箱化命令的權限回退

allowUnsandboxedCommands 啟用時,模型可以透過在 tool 輸入中設定 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)

此模式使您能夠:

  • 審計模型請求:記錄模型何時請求未沙箱化執行
  • 實現允許清單:僅允許特定命令在沙箱外執行
  • 新增批准工作流程:需要明確授權以進行特權操作

另見