תיעוד 195
הפניה ל-Agent SDK - Python
הפניה מלאה ל-API של Agent SDK בפייתון, כולל כל הפונקציות, הטיפוסים והמחלקות.
#התקנה
התקינו את החבילה בסביבה וירטואלית. בהתקנות Python עדכניות של Debian, Ubuntu ו-Homebrew, הרצה של pip install מול Python של המערכת נכשלת עם error: externally-managed-environment.
python3 -m venv .venv
source .venv/bin/activate
pip install claude-agent-sdkלגבי uv, Windows PowerShell והגדרת מפתח API, ראו הגדרה במדריך המהיר של Agent SDK.
#בחירה בין query() לבין ClaudeSDKClient
ה-SDK של Python מספק שתי דרכים לקיים אינטראקציה עם Claude Code:
| מאפיין | query() | ClaudeSDKClient |
|---|---|---|
| סשן | יוצר סשן חדש כברירת מחדל | עושה שימוש חוזר באותו סשן |
| שיחה | חילוף יחיד | כמה חילופים באותו הקשר |
| חיבור | מנוהל אוטומטית | שליטה ידנית |
| קלט בזרימה | ✅ נתמך | ✅ נתמך |
| פסיקות | ❌ לא נתמך | ✅ נתמך |
| Hooks | ✅ נתמך | ✅ נתמך |
| כלים מותאמים | ✅ נתמך | ✅ נתמך |
| המשך צ'אט | ידני דרך continue_conversation או resume | ✅ אוטומטי |
| תרחיש שימוש | משימות חד-פעמיות | שיחות מתמשכות |
השתמשו ב-ClaudeSDKClient ליישומים אינטראקטיביים כמו ממשקי צ'אט, או כשהפעולה הבאה תלויה בתשובה של Claude.
#פונקציות
[!NOTE]
בלוקי חתימה וקטעים חשופים של
async forאוasync withבדף הזה הם להמחשה. כדי להריץ אותם, עטפו את הגוף ב-async def main(): ...וקראו ל-asyncio.run(main()).
#query()
יוצר סשן חדש לכל אינטראקציה עם Claude Code כברירת מחדל. מחזיר איטרטור אסינכרוני שמניב הודעות כשהן מגיעות. כל קריאה ל-query() מתחילה מחדש בלי זיכרון של אינטראקציות קודמות, אלא אם מעבירים continue_conversation=True או resume ב-ClaudeAgentOptions. ראו סשנים.
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 | אובייקט הגדרות אופציונלי (ברירת המחדל היא ClaudeAgentOptions() אם הערך הוא None) |
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",
)
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 אופציונליות שמספקות רמזים התנהגותיים ללקוחות |
#אפשרויות לסכמת קלט
מיפוי טיפוסים פשוט (מומלץ):
{"text": str, "count": int, "enabled": bool}פורמט JSON Schema (לאימות מורכב):
{ "type": "object", "properties": { "text": {"type": "string"}, "count": {"type": "integer", "minimum": 0}, }, "required": ["text"], }מחלקת TypedDict: סכמה מטיפוס, שמפתחות
NotRequiredשלה נשארים מחוץ ל-required.- Python 3.11 ואילך: ייבאו את
TypedDictואתNotRequiredמ-typing. - Python 3.10: ב-
typingאיןNotRequired. ייבאו אתTypedDictואתNotRequiredמ-typing_extensions, שה-SDK מתקין ב-Python 3.10.
from typing import Annotated, Any, NotRequired, TypedDict from claude_agent_sdk import tool class ForecastArgs(TypedDict): latitude: Annotated[float, "Latitude coordinate"] hours: NotRequired[Annotated[int, "How many hours of forecast to return"]] @tool("get_forecast", "Get the hourly forecast for a location", ForecastArgs) async def get_forecast(args: dict[str, Any]) -> dict[str, Any]: hours = args.get("hours", 12) return {"content": [{"type": "text", "text": f"{hours}-hour forecast for {args['latitude']}"}]}- Python 3.11 ואילך: ייבאו את
בצורות של מיפוי פשוט ושל TypedDict, עטפו טיפוס ב-Annotated[type, "description"] כדי לקבוע את תיאור השדה.
#ערך מוחזר
פונקציית דקורטור שעוטפת את מימוש הכלי ומחזירה מופע 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
רמזים התנהגותיים לכלי, שמועברים כארגומנט annotations של tool(). ToolAnnotations מרחיב את mcp.types.ToolAnnotations של MCP SDK בשדה maxResultSizeChars, ואפשר לכתוב כל רמז ב-camelCase או ב-snake_case: ToolAnnotations(readOnlyHint=True) ו-ToolAnnotations(read_only_hint=True) שקולים. כדי לקרוא רמז בחזרה מהאובייקט, השתמשו באיות שמצהירה עליו חבילת mcp המותקנת: .readOnlyHint ב-mcp 1.x ו-.read_only_hint ב-2.x, בעוד .maxResultSizeChars עובד בשניהם. אפשר גם להעביר mcp.types.ToolAnnotations רגיל בכל מקום שה-SDK מקבל בו annotations.
שמות snake_case והשדה המטיפוס maxResultSizeChars דורשים Python Agent SDK 0.2.140 ואילך. גרסאות 0.1.31 עד 0.2.139 מייצאות מחדש את mcp.types.ToolAnnotations בלי שינוי. בגרסאות 0.1.55 עד 0.2.139 עדיין אפשר להעביר את maxResultSizeChars כארגומנט מילת מפתח: מחלקת MCP מקבלת שדות נוספים, וה-SDK מעביר את הערך אל Claude Code.
כל השדות אופציונליים. לקוחות לא אמורים להסתמך על הרמזים להחלטות אבטחה.
| שדה | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
title | str | None | None | כותרת קריאה לבני אדם לכלי |
readOnlyHint | bool | None | False | אם True, הכלי לא משנה את הסביבה שלו |
destructiveHint | bool | None | True | אם True, הכלי עשוי לבצע עדכונים הרסניים (משמעותי רק כש-readOnlyHint הוא False) |
idempotentHint | bool | None | False | אם True, לקריאות חוזרות עם אותם ארגומנטים אין השפעה נוספת (משמעותי רק כש-readOnlyHint הוא False) |
openWorldHint | bool | None | True | אם True, הכלי מקיים אינטראקציה עם ישויות חיצוניות (לדוגמה, חיפוש באינטרנט). אם False, התחום של הכלי סגור (לדוגמה, כלי זיכרון) |
maxResultSizeChars | int | None | None | מספר התווים שעד אליו Claude Code שומר את תוצאת הטקסט של הכלי הזה בתוך השיחה, במקום לשמור אותה בקובץ, עד 500,000. תוצאות שמכילות תמונות לא מושפעות. זו הגדרה של Claude Code ולא רמז MCP: ה-SDK שולח אותה ב-_meta של הכלי בתור anthropic/maxResultSizeChars. ראו העלאת המגבלה לכלי מסוים |
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()
יוצר שרת MCP בתוך התהליך, שרץ בתוך יישום Python שלכם.
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, ClaudeAgentOptions
@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,
offset: int = 0,
include_worktrees: bool = True
) -> list[SDKSessionInfo]#פרמטרים
| פרמטר | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
directory | str | None | None | ספרייה שעבורה מציגים סשנים. כשמשמיטים, מחזיר סשנים מכל הפרויקטים |
limit | int | None | None | המספר המרבי של סשנים להחזרה |
offset | int | 0 | מספר הסשנים לדילוג מתחילת התוצאות הממוינות. השתמשו יחד עם limit לעימוד |
include_worktrees | bool | True | כש-directory נמצא בתוך מאגר git, כלול סשנים מכל נתיבי ה-worktree |
#טיפוס החזרה: SDKSessionInfo
| מאפיין | טיפוס | תיאור |
|---|---|---|
session_id | str | מזהה סשן ייחודי |
summary | str | כותרת תצוגה: כותרת מותאמת, הפרומפט האחרון, סיכום שנוצר אוטומטית, או הפרומפט הראשון |
last_modified | int | זמן השינוי האחרון באלפיות שנייה מאז epoch |
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 | זמן יצירת הסשן באלפיות שנייה מאז epoch |
#דוגמה
הדפיסו את 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 | חובה | מזהה הסשן שעבורו מאחזרים הודעות |
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 | str | None | בהודעות של subagent, המזהה של בלוק השימוש בכלי Agent שיצר אותו. None להודעות של הסשן הראשי ולסשנים ישנים יותר |
parent_agent_id | str | None | להודעות מ-subagent מקונן, מזהה הסוכן של ה-subagent ההורה. None להודעות של הסשן הראשי, להודעות של subagent ברמה העליונה, ולסשנים ישנים יותר. דורש Python Agent SDK 0.2.140 ואילך |
#דוגמה
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()
קורא מטא-נתונים של סשן יחיד לפי מזהה, בלי לסרוק את כל ספריית הפרויקט. סינכרוני. חוזר מיד.
def get_session_info(
session_id: str,
directory: str | None = None,
) -> SDKSessionInfo | None#פרמטרים
| פרמטר | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
session_id | str | חובה | UUID של הסשן לחיפוש |
directory | str | None | None | נתיב ספריית הפרויקט. כשמשמיטים, מחפש בכל ספריות הפרויקטים |
מחזיר SDKSessionInfo, או None אם הסשן לא נמצא.
#דוגמה
חפשו מטא-נתונים של סשן יחיד בלי לסרוק את ספריית הפרויקט. שימושי כשכבר יש לכם מזהה סשן מהרצה קודמת.
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 | נתיב ספריית הפרויקט. כשמשמיטים, מחפש בכל ספריות הפרויקטים |
מעלה ValueError אם session_id אינו UUID תקין או אם title ריק. מעלה 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 | נתיב ספריית הפרויקט. כשמשמיטים, מחפש בכל ספריות הפרויקטים |
מעלה ValueError אם session_id אינו UUID תקין או אם tag ריק אחרי הניקוי. מעלה FileNotFoundError אם אי אפשר למצוא את הסשן.
#דוגמה
תייגו סשן, ואחר כך סננו לפי התג הזה בקריאה מאוחרת יותר. העבירו None כדי לנקות תג קיים.
from claude_agent_sdk import list_sessions, tag_session
# Tag the most recent session
sessions = list_sessions(directory="/path/to/project", limit=1)
if sessions:
tag_session(sessions[0].session_id, "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)#fork_session()
מעתיק את תמליל השיחה של סשן לתוך סשן חדש, כדי שאפשר יהיה לקחת את השיחה לכיוון אחר בזמן שהמקור נשאר ללא שינוי. כדי להסתעף מנקודה מוקדמת יותר בשיחה, מעבירים את up_to_message_id. סינכרוני.
def fork_session(
session_id: str,
directory: str | None = None,
up_to_message_id: str | None = None,
title: str | None = None,
) -> ForkSessionResult#פרמטרים
| פרמטר | סוג | ברירת מחדל | תיאור |
|---|---|---|---|
session_id | str | חובה | UUID של הסשן לפיצול |
directory | str | None | None | נתיב ספריית הפרויקט. כשמושמט, החיפוש מתבצע בכל ספריות הפרויקט |
up_to_message_id | str | None | None | מעתיק את התמליל עד וכולל ההודעה עם UUID זה, כגון uuid מ-get_session_messages(). כשמושמט, מעתיק את כל התמליל |
title | str | None | None | כותרת לפיצול. כשמושמט, ה-SDK גוזר כותרת מהסשן המקורי, ואחריה (fork) |
מחזיר ForkSessionResult שה-session_id שלו הוא ה-UUID של הסשן החדש. מעבירים אותו כ-resume כדי להמשיך את הפיצול. הפיצול לא כולל את נקודות הביקורת של הקבצים של הסשן המקורי, ולכן אי אפשר להחזיר אותו לאחור לנקודת ביקורת שנלכדה לפני הפיצול.
fork_session() מעלה:
ValueError:session_idאוup_to_message_idאינו UUID תקיןValueError: בסשן אין הודעות, או ש-up_to_message_idלא תואם לאף הודעה בתמלילFileNotFoundError: לא ניתן למצוא את הסשן
#דוגמה
מפצל את הסשן האחרון תחת כותרת חדשה, ואז ממשיך את הפיצול. הסשן המקורי שומר על ההיסטוריה שלו.
from claude_agent_sdk import fork_session, list_sessions
sessions = list_sessions(directory="/path/to/project", limit=1)
if sessions:
forked = fork_session(sessions[0].session_id, title="Try the OAuth approach")
print(forked.session_id) # pass as ClaudeAgentOptions(resume=...) to continue the fork#מחלקות
#ClaudeSDKClient
שומר על סשן שיחה לאורך כמה חילופים. זה המקבילה ב-Python לאופן שבו הפונקציה query() של ה-SDK של TypeScript עובדת באופן פנימי: הוא יוצר אובייקט לקוח שיכול להמשיך שיחות. ראו את ההשוואה עם query().
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: PermissionMode) -> 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 get_context_usage(self) -> ContextUsageResponse
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 כדי לאפס למודל ברירת המחדל של Claude Code. סשן במצב auto משתנה למצב default אם המודל החדש לא תומך במצב auto |
rewind_files(user_message_id) | משחזר קבצים למצבם בהודעת המשתמש שצוינה. דורש enable_file_checkpointing=True. ראו נקודות ביקורת של קבצים |
get_mcp_status() | מקבל את הסטטוס של כל שרתי ה-MCP המוגדרים. מחזיר McpStatusResponse |
get_context_usage() | מקבל פירוט של שימוש בחלון ההקשר לפי קטגוריה, skill וכלי. כולל את הנתונים ש-/context מציג בסשן אינטראקטיבי. מחזיר ContextUsageResponse. כדי לחשב את הפירוט, Claude Code מבצע כמה בקשות API לספירת טוקנים שלא מופיעות בזרם ההודעות. ראו איך הבקשות האלה מטופלות |
reconnect_mcp_server(server_name) | מנסה מחדש להתחבר לשרת MCP שנכשל או נותק |
toggle_mcp_server(server_name, enabled) | מפעיל או משבית שרת MCP באמצע הסשן. השבתת שרת stdio, SSE או HTTP מסירה את הכלים שלו |
stop_task(task_id) | עוצר משימת רקע שרצה. TaskNotificationMessage עם סטטוס "stopped" מגיע אחרי כן בזרם ההודעות |
get_server_info() | מקבל את פרטי האתחול של השרת, כולל פקודות זמינות וסגנונות פלט |
disconnect() | מתנתק מ-Claude |
#תמיכה במנהל הקשר
אפשר להשתמש בלקוח כמנהל הקשר אסינכרוני לניהול חיבור אוטומטי:
import asyncio
from claude_agent_sdk import ClaudeSDKClient
async def main():
async with ClaudeSDKClient() as client:
await client.query("Hello Claude")
async for message in client.receive_response():
print(message)
asyncio.run(main())חשוב: בזמן מעבר על הודעות, יש להימנע משימוש ב-
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
query() מקבל גם איטרבל אסינכרוני של מילוני הודעות משתמש, כך שאפשר להרכיב את ההנחיה בזמן השליחה או לכלול בלוקי תוכן כגון תמונות. Claude Code מתחיל להגיב להודעה הראשונה שמונבת ברגע שהיא מגיעה, בלי להמתין שהאיטרבל יסתיים, ו-receive_response() נעצר ב-ResultMessage שמסיים את התשובה הזו. שמים את כל מה ש-Claude צריך לקרוא לפני המענה בתוך הודעה אחת, כמו שהגנרטור הזה עושה, ומצמידים לכל קריאה ל-query() לולאת receive_response() משלה.
import asyncio
from claude_agent_sdk import ClaudeSDKClient
async def message_stream():
"""Assemble the prompt at send time and yield it as one user message."""
readings = {"Temperature": "25°C", "Humidity": "60%"}
data = ", ".join(f"{name}: {value}" for name, value in readings.items())
yield {
"type": "user",
"message": {
"role": "user",
"content": f"Analyze the following sensor data and describe any patterns you see: {data}",
},
}
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: terminal_reason={message.terminal_reason!r}")
# terminal_reason is "aborted_streaming" or "aborted_tools"
# for interrupted turns
# 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())הערה
התנהגות המאגר אחרי פסיקה:
interrupt()שולח אות עצירה אבל לא מנקה את מאגר ההודעות. הודעות שכבר הופקו על ידי המשימה שנקטעה, כולל ה-ResultMessageשלה, נשארות בזרם. חובה לרוקן אותן עםreceive_response()לפני קריאת התשובה לבקשה חדשה. אם שולחים בקשה חדשה מיד אחריinterrupt()וקוראים ל-receive_response()רק פעם אחת, מתקבלות הודעות המשימה שנקטעה, ולא התשובה של הבקשה החדשה.
#דוגמה: בקרת הרשאות מתקדמת
import asyncio
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():
# Don't also list the gated tools in allowed_tools: allow rules approve calls before can_use_tool runs
options = ClaudeAgentOptions(can_use_tool=custom_permission_handler)
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())#טיפוסים
הערה
@dataclassמולTypedDict: ה-SDK הזה משתמש בשני סוגים של טיפוסים. מחלקות שמעוטרות ב-@dataclass(כגוןResultMessage,AgentDefinition,TextBlock) הן מופעי אובייקט בזמן ריצה ותומכות בגישה למאפיינים:msg.result. מחלקות שמוגדרות עםTypedDict(כגוןThinkingConfigEnabled,McpStdioServerConfig,SyncHookJSONOutput) הן מילונים רגילים בזמן ריצה ודורשות גישה לפי מפתח:config["budget_tokens"], ולאconfig.budget_tokens. תחביר הקריאהClassName(field=value)עובד לשניהם, אבל רק dataclasses מייצרים אובייקטים עם מאפיינים.
#SdkMcpTool
הגדרה לכלי MCP של ה-SDK שנוצר עם הדקורטור @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 | מזהה ייחודי לכלי |
description | str | תיאור קריא לאדם |
input_schema | type[T] | dict[str, Any] | סכמה לאימות הקלט |
handler | Callable[[T], Awaitable[dict[str, Any]]] | פונקציה אסינכרונית שמטפלת בהרצת הכלי |
annotations | ToolAnnotations | None | הערות כלי אופציונליות (לדוגמה readOnlyHint, destructiveHint, openWorldHint, maxResultSizeChars) |
#Transport
מחלקת בסיס מופשטת למימושי תעבורה מותאמים. משתמשים בזה כדי לתקשר עם תהליך Claude בערוץ מותאם (לדוגמה, חיבור מרוחק במקום subprocess מקומי).
אזהרה
זה API פנימי ברמה נמוכה. הממשק עשוי להשתנות במהדורות עתידיות. מימושים מותאמים חייבים להתעדכן כדי להתאים לכל שינוי בממשק.
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 + newline) לתעבורה |
read_messages() | איטרטור אסינכרוני שמניב הודעות JSON מפוענחות |
close() | סוגר את החיבור ומנקה משאבים |
is_ready() | מחזיר True אם התעבורה יכולה לשלוח ולקבל |
end_input() | סוגר את זרם הקלט (לדוגמה, סוגר את stdin בתעבורות subprocess) |
ייבוא: from claude_agent_sdk import Transport
#ClaudeAgentOptions
מחלקת נתונים (dataclass) להגדרת שאילתות של Claude Code.
@dataclass
class ClaudeAgentOptions:
tools: list[str] | ToolsPreset | None = None
allowed_tools: list[str] = field(default_factory=list)
system_prompt: str | SystemPromptPreset | SystemPromptCustom | SystemPromptFile | 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
session_id: 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
forward_subagent_text: bool = False
verbatim_prompts: bool = False
fork_session: bool = False
resume_session_at: str | None = None
resume_drops_turn: str | None = None
agents: dict[str, AgentDefinition] | None = None
setting_sources: list[SettingSource] | None = None
skills: list[str] | Literal["all"] | 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"
load_timeout_ms: int = 60_000
task_budget: TaskBudget | None = None| תכונה | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
tools | list[str] | ToolsPreset | None | None | תצורת כלים. השתמש ב-{"type": "preset", "preset": "claude_code"} לכלים ברירת המחדל של Claude Code |
allowed_tools | list[str] | [] | כלים לאישור אוטומטי בלי הנחיה, מלבד קריאות מנתיבי רשת. זה לא מגביל את Claude רק לכלים האלה. אם אתה מציין כאן אחד מכלי מעקב המשימות, Claude Code גם מפעיל את ההצטרפות עבור הסשן. כלים אחרים שלא ברשימה עוברים אל permission_mode ו-can_use_tool. השתמש ב-disallowed_tools כדי לחסום כלים. ראה הרשאות |
system_prompt | str | SystemPromptPreset | SystemPromptCustom | SystemPromptFile | None | None | תצורת הנחיית מערכת. העבר מחרוזת להנחיה מותאמת, {"type": "preset", "preset": "claude_code"} להנחיית המערכת של Claude Code עם "append" אופציונלי, {"type": "custom", "prompt": "..."} להנחיה מותאמת שיכולה גם להגדיר "snapshot", או {"type": "file", "path": "..."} כדי לטעון הנחיה גדולה מהדיסק. ראה SystemPromptPreset, SystemPromptCustom, ו-SystemPromptFile |
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 | מצב הרשאה לשימוש בכלים |
continue_conversation | bool | False | המשך את השיחה האחרונה |
resume | str | None | None | מזהה סשן לחידוש |
session_id | str | None | None | השתמש במזהה סשן מסוים במקום מזהה שנוצר אוטומטית. חייב להיות UUID תקין. אי אפשר לשלב עם continue_conversation או resume אלא אם גם fork_session מוגדר |
max_turns | int | None | None | מספר מרבי של תורות סוכניות |
max_budget_usd | float | None | None | עצור את השאילתה כאשר אומדן העלות בצד הלקוח מגיע לערך זה בדולר ארה"ב. האומדן יכול לעבור את הערך הזה, לכן השאר מרווח. נספרת רק ההוצאה של הקריאה עצמה. סכומים ששוחזרו מסשן שחודש לא נספרים. להסתייגויות דיוק ולהתנהגות איפוס, ראה מעקב עלות ושימוש |
disallowed_tools | list[str] | [] | כלים לדחייה. שם חשוף כגון "Bash" מסיר את הכלי מההקשר של Claude. כלל ממוקד כגון "Bash(rm *)" משאיר את הכלי זמין ודוחה קריאות תואמות בכל מצב הרשאה, כולל 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 | נתיב לקובץ הגדרות או מחרוזת JSON מוטמעת |
add_dirs | list[str | Path] | [] | ספריות נוספות ש-Claude יכול לגשת אליהן. ה-SDK מעביר כל רשומה ל-Claude Code בתור --add-dir, ולכן עם מקור ההגדרות project Claude Code גם טוען את הכישורים, הפקודות ותתי הסוכנים של הספרייה |
env | dict[str, str] | {} | משתני סביבה שממוזגים מעל סביבת התהליך שעוברת בירושה. ראה משתני סביבה למשתנים שה-CLI הבסיסי קורא, וטיפול בתגובות API איטיות או תקועות למשתנים שקשורים לפסק זמן. הגדר CLAUDE_AGENT_SDK_CLIENT_APP כדי לזהות את האפליקציה שלך בכותרת User-Agent |
extra_args | dict[str, str | None] | {} | ארגומנטים נוספים של CLI להעברה ישירה ל-CLI |
max_buffer_size | int | None | None | מספר בתים מרבי בעת אגירת stdout של ה-CLI |
debug_stderr | Any | sys.stderr | מיושן: ה-SDK מתעלם מהערך הזה. השתמש בקריאת ה-callback של stderr לפלט stderr של ה-CLI |
stderr | Callable[[str], None] | None | None | פונקציית callback לפלט stderr מה-CLI |
can_use_tool | CanUseTool | None | None | קריאת callback להרשאת כלים, שמופעלת רק כאשר זרימת ההרשאות מגיעה להנחיה. לא מופעלת לקריאות שאושרו אוטומטית על ידי allowed_tools, כללי allow, או permission_mode. כלל allow לא מאשר מראש את הפעולות שאף מצב לא מאשר אוטומטית. ראה CanUseTool לפרטים |
hooks | dict[HookEvent, list[HookMatcher]] | None | None | תצורות hook ליירוט אירועים |
user | str | None | None | בפלטפורמות POSIX, חשבון המשתמש של מערכת ההפעלה שתחתיו רץ תהליך המשנה של Claude Code. Claude Code שומר את סביבת תהליך האב, כולל HOME, ורץ ב-cwd |
include_partial_messages | bool | False | כלול אירועי הזרמה של הודעות חלקיות. כאשר מופעל, הודעות StreamEvent מוחזרות (yield) |
include_hook_events | bool | False | כלול אירועי מחזור חיים של hook בזרם ההודעות כאובייקטי HookEventMessage |
forward_subagent_text | bool | False | העבר בלוקי טקסט וחשיבה של תת סוכן בזרם ההודעות. בלי אפשרות זו, Claude Code משמיט את בלוקי הטקסט והחשיבה של תת סוכן שרץ בחזית. לתתי סוכנים מקוננים, לכישורים עם context: fork, ולגרסת Claude Code שכל אחד מהם דורש, ראה מעקב אחרי הודעות תת סוכן. דורש Python Agent SDK 0.2.140 או חדש יותר |
verbatim_prompts | bool | False | מסור כל הנחיה כפי שנכתבה. ה-SDK שולח כל הודעת משתמש עם client_composed שמוגדר ל-True. ראה client_composed למה ש-Claude Code מדלג בהודעות האלה. השתמש באפשרות זו כאשר טקסט ההנחיה שלך כולל תוכן שמשתמש הקצה לא הקליד. לשליטה לפי תור, השאר אותה כבויה והגדר "client_composed": True על הודעות מוזרמות בודדות. כל עוד האפשרות פועלת, ה-SDK דורס כל ערך client_composed שהגדרת. דורש Python Agent SDK 0.2.158 או חדש יותר ו-Claude Code v2.1.248 או חדש יותר. ה-CLI שמצורף לגרסאות SDK אלה מספק את דרישת Claude Code |
fork_session | bool | False | בעת חידוש עם resume, פצל למזהה סשן חדש במקום להמשיך את הסשן המקורי |
resume_session_at | str | None | None | בעת חידוש, טען את השיחה רק עד וכולל ההודעה עם UUID זה. השתמש יחד עם resume, ובדרך כלל fork_session, כדי להסתעף מנקודה מוקדמת יותר. דורש Python Agent SDK 0.2.137 או חדש יותר |
resume_drops_turn | str | None | None | UUID של הנחיית המשתמש שהתור שלה נזרק בקיצור של resume_session_at. כאשר מוגדר, ה-CLI מסרב לחידוש אם הטווח שנזרק מכיל רשומות שלא מיוחסות לתור הזה. דורש Python Agent SDK 0.2.137 או חדש יותר ו-Claude Code v2.1.223 או חדש יותר. ה-CLI שמצורף לגרסאות SDK אלה מספק את דרישת Claude Code |
agents | dict[str, AgentDefinition] | None | None | תתי סוכנים שמוגדרים באופן תכנותי |
plugins | list[SdkPluginConfig] | [] | טען תוספים מותאמים מנתיבים מקומיים. ראה תוספים לפרטים |
sandbox | SandboxSettings | None | None | הגדר התנהגות sandbox באופן תכנותי. ראה הגדרות sandbox לפרטים |
setting_sources | list[SettingSource] | None | None (ברירות מחדל של CLI: כל המקורות) | שלוט באילו הגדרות מערכת קבצים לטעון. העבר [] כדי להשבית הגדרות משתמש, פרויקט ומקומיות. כאשר skills מוגדר והשדה הזה לא מוגדר, נטענים רק מקורות משתמש ופרויקט. הגדר setting_sources במפורש כדי לשמור הגדרות מקומיות. מדיניות שמנוהלת בנקודת הקצה נטענת בכל מקרה. הגדרות שמנוהלות בשרת נמשכות כאשר הסשן מאמת עם אישור ארגון בתצורה זכאית. לקלטים שנקראים בלי קשר לאפשרות זו, ראה מה settingSources לא שולט |
skills | list[str] | Literal["all"] | None | None | כישורים שזמינים לסשן. העבר "all" כדי להפעיל כל כישור שהתגלה, או רשימת שמות כישורים. העבר שמות מדויקים בלבד. ה-SDK דוחה שמות פגומים ושמות בצורת תו כללי עם ValueError לפני הפעלת תהליך Claude Code. הבדיקה הזו דורשת Python Agent SDK 0.2.129 או חדש יותר. כאשר מוגדר, ה-SDK מוסיף את כלי Skill ל-allowed_tools אוטומטית. אם אתה גם מעביר tools, כלול "Skill" ברשימה הזו. ראה כישורים |
max_thinking_tokens | int | None | None | מיושן: מספר אסימונים מרבי לבלוקי חשיבה. השתמש ב-thinking במקום |
thinking | ThinkingConfig | None | None | שולט בהתנהגות חשיבה מורחבת. מקבל עדיפות על פני max_thinking_tokens |
effort | EffortLevel | None | None | רמת מאמץ לעומק החשיבה. ראה התאמת רמת המאמץ |
session_store | SessionStore | None | None | שכפל תמלילי סשן למערכת אחורית חיצונית כדי שמארח אחר יוכל לחדש אותם. ראה שמירת סשנים באחסון חיצוני |
session_store_flush | Literal["batched", "eager"] | "batched" | מתי לרוקן רשומות תמליל משוכפלות אל session_store. "batched" מרוקן פעם אחת לכל תור או כאשר המאגר מתמלא. "eager" מפעיל ריקון ברקע אחרי כל מסגרת. מתעלמים כאשר session_store הוא None |
load_timeout_ms | int | 60000 | פסק זמן לכל קריאה עבור session_store.load() ו-list_subkeys() במהלך מימוש החידוש, באלפיות שנייה |
task_budget | TaskBudget | None | None | תקציב אסימונים בצד ה-API. נשלח בתור output_config.task_budget עם כותרת הבטא task-budgets-2026-03-13. העבר {"total": <int>}. |
#טיפול בתגובות API איטיות או תקועות
תהליך המשנה של ה-CLI קורא כמה משתני סביבה ששולטים בפסקי זמן של API ובזיהוי תקיעה. העבר אותם דרך ClaudeAgentOptions.env:
from claude_agent_sdk import ClaudeAgentOptions
options = ClaudeAgentOptions(
env={
"API_TIMEOUT_MS": "120000",
"CLAUDE_CODE_MAX_RETRIES": "2",
"CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS": "120000",
},
)API_TIMEOUT_MS: כמה זמן כל ניסיון בקשה יכול להמתין לכותרות התגובה, באלפיות שנייה. זה לא מגביל כמה זמן תגובת הזרמה רצה אחרי שהכותרות מגיעות. ברירת מחדל600000. חל על הלולאה הראשית ועל כל תתי הסוכנים.CLAUDE_CODE_MAX_RETRIES: מספר מרבי של ניסיונות חוזרים ל-API. ברירת מחדל10, עם תקרה של15. כל ניסיון חוזר מקבל חלוןAPI_TIMEOUT_MSמשלו.להרצות בלי השגחה שצריכות להמתין לאורך תקלות ארוכות יותר, הגדר
CLAUDE_CODE_RETRY_WATCHDOG=1: זה מנסה שוב שגיאות קיבולת חולפות בלי הגבלה, וב-Claude Code v2.1.199 או חדש יותר מעלה את ברירת המחדל לשגיאות חולפות אחרות ל-300ומסיר את התקרה על המשתנה הזה.CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS: שומר תקיעה לתתי סוכנים. כאשר שומר הזרם פועל, ברירת המחדל היאCLAUDE_STREAM_IDLE_TIMEOUT_MSועוד 5 דקות, שמגיע ל-600000אלא אם אתה מעלה את המשתנה הזה. כאשר שומר הזרם כבוי, ברירת המחדל היא600000. לפני v2.1.257, ברירת המחדל הייתה תמיד600000.הטיימר מתאפס בכל אירוע זרם. בתקיעה, Claude Code מבטל את תת הסוכן ומדווח על התקיעה להורה. עבור תת סוכן ברקע, הוא גם מסמן את המשימה כנכשלת ומצרף כל תוצאה חלקית.
CLAUDE_ENABLE_STREAM_WATCHDOGעםCLAUDE_STREAM_IDLE_TIMEOUT_MS: שומר זרם שמבטל את הבקשה כאשר הכותרות הגיעו אבל גוף התגובה מפסיק לזרום. השומר פועל כברירת מחדל לכל הספקים. הגדרCLAUDE_ENABLE_STREAM_WATCHDOG=0כדי להשבית אותו.CLAUDE_STREAM_IDLE_TIMEOUT_MSברירת המחדל היא300000והוא מהודק למינימום הזה. אחרי הביטול, ניסיונות חוזרים אוטומטיים מכסים את מה ש-Claude Code עושה, לפי כמה רחוק התגובה התקדמה.בזמן שהשומר ממתין לתגובה ששער מאחורי
ANTHROPIC_BASE_URLמחזיק פתוחה עם ping של keep-alive, מארח שמגדירinclude_partial_messagesממשיך לקבל הודעותpingמסוגStreamEvent. קרא את המסגרות האלה כסימן חיים, במקום לסיים את הסשן בפסק זמן בגלל שקט. לפני v2.1.257, המסגרות נעצרו 5 דקות אחרי אירוע הזרם האמיתי האחרון.
#OutputFormat
תצורה לאימות פלט מובנה. העבר זאת כ-dict לשדה output_format ב-ClaudeAgentOptions:
# 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]
snapshot: NotRequired[bool]| שדה | חובה | תיאור |
|---|---|---|
type | כן | חייב להיות "preset" כדי להשתמש בהנחיית מערכת מוגדרת מראש |
preset | כן | חייב להיות "claude_code" כדי להשתמש בהנחיית המערכת של Claude Code |
append | לא | הוראות נוספות לצירוף להנחיית המערכת המוגדרת מראש |
exclude_dynamic_sections | לא | מעביר הקשר לפי משתמש, כגון מיקום הזיכרון האוטומטי, מהנחיית המערכת אל הודעת המשתמש הראשונה. משפר שימוש חוזר במטמון ההנחיות בין משתמשים ומכונות. ראה שינוי הנחיות מערכת |
snapshot | לא | הגדר ל-False כדי לבנות מחדש את הנחיית המערכת בכל בקשה במקום שימוש חוזר בהנחיה שההפעלה תיעדה בבקשה הראשונה שלה. דורש claude-agent-sdk בגרסה v0.2.153 או חדשה יותר |
#SystemPromptCustom
הנחיית מערכת מותאמת בצורת אובייקט, שקולה להעברת מחרוזת כ-system_prompt, ויכולה גם להגדיר snapshot. דורש claude-agent-sdk בגרסה v0.2.153 או חדשה יותר.
class SystemPromptCustom(TypedDict):
type: Literal["custom"]
prompt: str
snapshot: NotRequired[bool]| שדה | חובה | תיאור |
|---|---|---|
type | כן | חייב להיות "custom" |
prompt | כן | טקסט הנחיית המערכת. מועבר ל-CLI כארגומנט של שורת פקודה, ולכן חלות מגבלות אורך שורת הפקודה |
snapshot | לא | זהה ל-SystemPromptPreset.snapshot, ומוחל על prompt |
#SystemPromptFile
תצורה לטעינת הנחיית מערכת מותאמת מקובץ במקום להעביר אותה כמחרוזת. ה-SDK ממפה זאת לדגל ה-CLI --system-prompt-file. השתמש בצורת הקובץ כשההנחיה גדולה: ה-SDK מעביר מחרוזת system_prompt ב-argv של תהליך המשנה של ה-CLI, והיא כפופה למגבלות אורך שורת הפקודה של מערכת ההפעלה לפני שה-SDK שולח בקשת API כלשהי. ב-Linux ארגומנט יחיד שארוך מכ-128 KB נכשל ביצירת התהליך עם Argument list too long. ב-Windows כל שורת הפקודה מוגבלת לכ-32 KB, ולכן צורת המחרוזת נכשלת בסף נמוך יותר.
class SystemPromptFile(TypedDict):
type: Literal["file"]
path: str| שדה | חובה | תיאור |
|---|---|---|
type | כן | חייב להיות "file" כדי לטעון את ההנחיה מהדיסק |
path | כן | נתיב לקובץ שמכיל את הנחיית המערכת |
#SettingSource
שולט מאילו מקורות תצורה מבוססי מערכת קבצים ה-SDK טוען הגדרות.
SettingSource = Literal["user", "project", "local"]| ערך | תיאור | מיקום |
|---|---|---|
"user" | הגדרות משתמש גלובליות | ~/.claude/settings.json |
"project" | הגדרות פרויקט משותפות (בבקרת גרסאות) | .claude/settings.json |
"local" | הגדרות פרויקט מקומיות, שנכנסות ל-gitignore כש-Claude Code שומר אליהן הגדרה | .claude/settings.local.json |
#התנהגות ברירת מחדל
כש-setting_sources מושמט או None ו-skills לא מוגדר, query() טוען את אותן הגדרות מערכת קבצים כמו ה-CLI של Claude Code: user, project ו-local. כש-skills מוגדר, שורת setting_sources מתארת את ברירת המחדל הנוכחית. מדיניות שמנוהלת בנקודת הקצה נטענת בכל המקרים. הגדרות שמנוהלות בשרת נשלפות כשההפעלה מבצעת אימות עם אישור ארגון בתצורה זכאית. למידע נוסף, ראה במה settingSources לא שולט.
#למה להשתמש ב-setting_sources
השבתת הגדרות מערכת קבצים:
# Do not load user, project, or local settings from disk
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Analyze this code",
options=ClaudeAgentOptions(
setting_sources=[]
),
):
print(message)
asyncio.run(main())[!NOTE]
ב-Python SDK 0.1.59 ומוקדם יותר, רשימה ריקה טופלה כמו השמטת האפשרות, ולכן
setting_sources=[]לא השבית הגדרות מערכת קבצים. שדרג למהדורה חדשה יותר אם צריך שרשימה ריקה תיכנס לתוקף. ה-TypeScript SDK לא מושפע.
טעינה של מקורות הגדרות ספציפיים בלבד:
# Load only project settings, ignore user and local
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Run CI checks",
options=ClaudeAgentOptions(
setting_sources=["project"] # Only .claude/settings.json
),
):
print(message)
asyncio.run(main())יישומים של SDK בלבד:
# Define everything programmatically.
# Pass [] to opt out of filesystem setting sources.
import asyncio
from claude_agent_sdk import AgentDefinition, ClaudeAgentOptions, query
async def main():
async for message in query(
prompt="Review this PR",
options=ClaudeAgentOptions(
setting_sources=[],
agents={
"code-reviewer": AgentDefinition(
description="Reviews code changes",
prompt="You are a code reviewer. Report issues in the diff.",
),
},
allowed_tools=["Read", "Grep", "Glob"],
),
):
print(message)
asyncio.run(main())כדי לטעון הוראות פרויקט של CLAUDE.md, כלול "project" ב-setting_sources. ראה שינוי הנחיות מערכת לאופן שבו טעינת CLAUDE.md פועלת יחד עם אפשרויות הנחיית המערכת.
#קדימות הגדרות
כשנטענים כמה מקורות, ההגדרות ממוזגות לפי הקדימות הזו (מהגבוהה לנמוכה):
- הגדרות מקומיות (
.claude/settings.local.json) - הגדרות פרויקט (
.claude/settings.json) - הגדרות משתמש (
~/.claude/settings.json)
אפשרויות תכנותיות כגון agents, allowed_tools ו-settings דורסות הגדרות מערכת קבצים של משתמש, פרויקט ומקומי. הגדרות מדיניות מנוהלת מקבלות קדימות על פני אפשרויות תכנותיות.
#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 | לא | מערך של שמות כלים מותרים. אם מושמט, יורש כל כלי שזמין לסוכני משנה |
disallowedTools | לא | מערך של שמות כלים להסרה מערכת הכלים של הסוכן. מתקבלות גם תבניות ברמת שרת MCP: mcp__server או mcp__server__* מסיר כל כלי מהשרת הזה, ו-mcp__* מסיר כל כלי MCP מכל שרת |
model | לא | דריסת מודל לסוכן הזה. מקבל כינוי כגון "sonnet", "opus", "haiku" או "inherit", או מזהה מודל מלא. כשמשמיטים אותו, Claude Code בוחר את המודל בסדר המודל של סוכן משנה |
skills | לא | רשימת שמות skill לטעינה מראש להקשר של הסוכן בהפעלה. skills שלא ברשימה נשארים ניתנים להפעלה דרך כלי ה-Skill |
memory | לא | מקור זיכרון לסוכן הזה: "user", "project" או "local" |
mcpServers | לא | שרתי MCP שזמינים לסוכן הזה. כל רשומה היא שם שרת או מילון {name: config} מוטמע |
initialPrompt | לא | נשלח אוטומטית כתור המשתמש הראשון כשהסוכן הזה רץ כסוכן של השרשור הראשי |
maxTurns | לא | מספר מרבי של תורות agentic לפני שהסוכן עוצר |
background | לא | הרץ את הסוכן הזה כמשימת רקע לא חוסמת כשהוא מופעל |
effort | לא | רמת מאמץ החשיבה לסוכן הזה. מקבל רמה בעלת שם או מספר שלם. ראה EffortLevel |
permissionMode | לא | מצב הרשאה לביצוע כלים בתוך הסוכן הזה. כללי הירושה של סוכן משנה קובעים מתי הוא חל. ראה PermissionMode |
[!NOTE]
שמות השדות של
AgentDefinitionמשתמשים ב-camelCase, כגוןdisallowedTools,permissionModeו-maxTurns. השמות האלה ממופים ישירות לפורמט ה-wire המשותף עם TypeScript SDK. זה שונה מ-ClaudeAgentOptions, שמשתמש ב-snake_case של Python לשדות המקבילים ברמה העליונה, כגוןdisallowed_toolsו-permission_mode. מכיוון ש-AgentDefinitionהוא dataclass, העברת מילת מפתח ב-snake_case מעלהTypeErrorבזמן הבנייה.
#PermissionMode
מצבי הרשאה לשליטה בביצוע כלים.
PermissionMode = Literal[
"default", # Standard permission behavior
"acceptEdits", # Auto-accept file edits
"plan", # Planning mode - Claude explores and plans
"dontAsk", # Deny anything not pre-approved instead of prompting
"bypassPermissions", # Bypass permission checks; explicit ask rules still prompt (use with caution)
"auto", # A model classifier reviews actions such as shell commands and network requests
]#EffortLevel
רמות מאמץ להנחיית עומק החשיבה.
EffortLevel = Literal[
"low", # Minimal thinking, fastest responses
"medium", # Moderate thinking
"high", # Deep reasoning
"xhigh", # Extended reasoning; falls back to "high" on models that don't support it
"max", # Maximum effort
]#CanUseTool
כינוי טיפוס לפונקציות callback של הרשאת כלים.
CanUseTool = Callable[
[str, dict[str, Any], ToolPermissionContext], Awaitable[PermissionResult]
]ה-callback מקבל:
tool_name: שם הכלי שנקראinput_data: פרמטרי הקלט של הכליcontext:ToolPermissionContextעם מידע נוסף
מחזיר PermissionResult (PermissionResultAllow או PermissionResultDeny).
ה-callback מחליף את בקשת ההרשאה האינטראקטיבית. ה-SDK קורא ל-can_use_tool כשזרימת הערכת ההרשאות מגיעה לבקשה. קריאות שאושרו באחת מהדרכים האלה רצות בלי קריאה ל-can_use_tool:
- קריאה שרשומה ב-
allowed_toolsאו כלל allow בהגדרות מאשר - קריאה שמצב ההרשאה מאשר, כגון עריכת קובץ במצב
acceptEdits
כדי לבדוק את הקריאות האלה, השתמש ב-hook של PreToolUse, שרץ גם עבורן.
כלל allow לא מאשר מראש את הפעולות שאף מצב לא מאשר אוטומטית. ראה איך הרשאות מוערכות לגבי אילו מהן מגיעות ל-callback ומה קורה במצב dontAsk ובמצב auto.
#ToolPermissionContext
מידע הקשר שמועבר ל-callbacks של הרשאת כלים.
@dataclass
class ToolPermissionContext:
signal: Any | None = None # Future: abort signal support
suggestions: list[PermissionUpdate] = field(default_factory=list)
tool_use_id: str | None = None
agent_id: str | None = None
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 ושומרת אותו בין הפעלות. |
tool_use_id | str | None | מזהה של קריאת הכלי הספציפית שהבקשה הזו מיועדת לה. תמיד מאוכלס כשהוא מועבר ל-can_use_tool |
agent_id | str | None | מזהה סוכן משנה כשהקריאה מגיעה מסוכן משנה. None עבור הסוכן הראשי |
blocked_path | str | None | נתיב קובץ שהפעיל את בקשת ההרשאה, כשרלוונטי. לדוגמה, כשפקודת Bash מנסה לגשת לנתיב מחוץ לספריות המותרות |
decision_reason | str | None | הסיבה שבקשת ההרשאה הזו הופעלה. מועבר מ-permissionDecisionReason של hook מסוג PreToolUse כשה-hook החזיר "ask" |
title | str | None | משפט מלא של בקשת ההרשאה, כגון Claude wants to read foo.txt. השתמש בו כטקסט הבקשה העיקרי כשהוא קיים |
display_name | str | None | צירוף שמות עצם קצר לפעולת הכלי, כגון Read file, שמתאים לתוויות כפתורים |
description | str | None | כותרת משנה קריאה לאדם עבור ממשק ההרשאות |
#PermissionResult
טיפוס איחוד לתוצאות של callback הרשאה.
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 | עדכוני הרשאה להחלה |
אם מחזירים PermissionResultAllow עם יותר מ-4,096 פריטים ב-updated_permissions, Claude Code מתייחס לתוצאה כלא תקינה ודוחה את קריאת הכלי. כל PermissionUpdate נספר כפריט אחד, וכך גם כל רשומה ברשימת rules או directories שלו. הודעת הדחייה מסתיימת ב-updatedPermissions may hold at most 4096 updates, rules and directories in all. כדי להימנע מהדחייה, החזר 4,096 פריטים או פחות.
#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
שולט בהתנהגות החשיבה המורחבת. איחוד של שלוש תצורות:
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. Claude Code לא מעביר את ערך display שלך לחלק מהספקים, כמו Amazon Bedrock ו-Agent Platform של Google Cloud. אצל ספקים אלה, Opus 4.7 ואילך מחזירים פלטי ThinkingBlock ריקים גם כשמגדירים את display ל-"summarized".
מכיוון שאלה מחלקות 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#TaskBudget
תקציב משימה בטוקנים בצד ה-API, בשימוש עם השדה task_budget ב-ClaudeAgentOptions.
class TaskBudget(TypedDict):
total: int| שדה | טיפוס | תיאור |
|---|---|---|
total | int | תקציב הטוקנים הכולל למשימה |
מכיוון שזה TypedDict, מעבירים אותו כמילון רגיל, למשל ClaudeAgentOptions(task_budget={"total": 50000}).
#SdkBeta
טיפוס ליטרל לתכונות בטא של ה-SDK.
SdkBeta = Literal["context-1m-2025-08-07"]משתמשים בו עם השדה betas ב-ClaudeAgentOptions כדי להפעיל תכונות בטא.
[!WARNING]
ב-Claude API, הבטא
context-1m-2025-08-07הוצאה משימוש עבור Claude Sonnet 4.5 ו-Claude Sonnet 4. אם עדיין מעבירים אותה עם אחד מהמודלים האלה, בקשות שחורגות מחלון ההקשר הרגיל של 200 אלף טוקנים מחזירות שגיאה, ולכן יש להסיר אותה מ-betas. כדי להריץ סשן עם חלון הקשר של מיליון טוקנים, מגדירים אתmodelלמודל שרץ עם חלון של מיליון כברירת מחדל, כמוclaude-sonnet-5-5אוclaude-opus-5-5. עבור מודל שמגיע למיליון רק דרך וריאנט[1m]שלו, מוסיפים את הסיומת למזהה המודל, כמו ב-claude-opus-4-6[1m].
#McpSdkServerConfig
תצורה לשרתי MCP של ה-SDK שנוצרים עם create_sdk_mcp_server().
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, ובנוסף וריאנט claudeai-proxy לפלט בלבד עבור שרתים שמתווכים דרך claude.ai.
McpServerStatusConfig = (
McpStdioServerConfig
| McpSSEServerConfig
| McpHttpServerConfig
| McpSdkServerConfigStatus
| McpClaudeAIProxyServerConfig
)McpSdkServerConfigStatus הוא הצורה הניתנת לסריאליזציה של McpSdkServerConfig, עם השדות type ("sdk") ו-name (str) בלבד. ה-instance שבתוך התהליך מושמט. ל-McpClaudeAIProxyServerConfig יש את השדות type ("claudeai-proxy"), url (str) ו-id (str).
#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), ובנוסף וריאנט claudeai-proxy לשרתים שמחוברים דרך claude.ai |
scope | str (אופציונלי) | היקף התצורה |
tools | list (אופציונלי) | כלים שמספק השרת, לכל אחד השדות name, description ו-annotations |
#ContextUsageResponse
תשובה מ-ClaudeSDKClient.get_context_usage(). התשובה כוללת את המטען ש-Claude Code מציג עבור הפקודה /context בסשן אינטראקטיבי. לצד ספירות הטוקנים, המטען הזה נושא שדות תצוגה כמו color ו-gridRows, ש-Claude Code משתמש בהם כדי לצייר את רשת השימוש של /context.
Claude Code בונה את המטען הזה על ידי שליחת כמה בקשות ל-API של ספירת טוקנים. הבקשות האלה לא מופיעות בזרם ההודעות, ולכן מעקב עלות שקורא את הזרם לא יראה אותן. ב-Anthropic API, ספירת טוקנים לא מחויבת.
class ContextUsageResponse(TypedDict):
categories: list[ContextUsageCategory]
totalTokens: int
maxTokens: int
rawMaxTokens: int
percentage: float
model: str
isAutoCompactEnabled: bool
memoryFiles: list[dict[str, Any]]
mcpTools: list[dict[str, Any]]
agents: list[dict[str, Any]]
gridRows: list[list[dict[str, Any]]]
autoCompactThreshold: NotRequired[int]
deferredBuiltinTools: NotRequired[list[dict[str, Any]]]
systemTools: NotRequired[list[dict[str, Any]]]
systemPromptSections: NotRequired[list[dict[str, Any]]]
slashCommands: NotRequired[dict[str, Any]]
skills: NotRequired[dict[str, Any]] # skill usage with frontmatter breakdown
messageBreakdown: NotRequired[dict[str, Any]] # message tokens by type
apiUsage: NotRequired[dict[str, Any] | None]כל רשומת ContextUsageCategory נושאת את name, tokens, color ודגל אופציונלי isDeferred. totalTokens הוא שימוש ההקשר הנוכחי של הסשן, ו-maxTokens הוא החלון שלפיו נמדד השימוש. החלון הזה הוא חלון ההקשר של המודל, או חלון הדחיסה האוטומטית הנמוך יותר כשאחד כזה חל, ו-rawMaxTokens נושא את אותו ערך כמו maxTokens. apiUsage מחזיק את השימוש מתשובת ה-API האחרונה, ולא סכום מצטבר לסשן. Claude Code משאיר את המפתחות האופציונליים deferredBuiltinTools, systemTools ו-systemPromptSections לא מוגדרים, ולכן צפוי שהם ייעדרו גם אם הטיפוס מצהיר עליהם.
#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
| ConversationResetMessage
)#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
origin: MessageOrigin | None = None| שדה | טיפוס | תיאור |
|---|---|---|
content | str | list[ContentBlock] | תוכן ההודעה כטקסט או כבלוקי תוכן |
uuid | str | None | מזהה ייחודי של ההודעה |
parent_tool_use_id | str | None | מזהה שימוש בכלי אם ההודעה היא תשובת תוצאת כלי |
tool_use_result | dict[str, Any] | None | נתוני תוצאת הכלי, אם רלוונטי |
origin | MessageOrigin | None | מקור ההודעה, מאוכלס בתורות שהוזרקו כמו התראות משימה והודעות עמיתים. None כשה-CLI לא ייחס אותה. דורש Python Agent SDK 0.2.137 או מאוחר יותר |
ה-SDK מעביר את tool_use_result מה-CLI בלי שינוי. עבור כלי בשרת MCP חיצוני שהתוצאה שלו מכילה בלוקי resource_link, למילון יש מפתח resourceLinks שמחזיק רשימת מילונים עם המפתחות של טיפוס TypeScript SDKMcpResourceLink. Claude מקבל כל קישור כשורת טקסט בתוצאת הכלי. כדי להציג את הקבצים שהשרת החזיר, קוראים את resourceLinks במקום לנתח את הטקסט הזה. המפתח resourceLinks דורש Python Agent SDK 0.2.150 או מאוחר יותר ו-Claude Code v2.1.257 או מאוחר יותר. ה-CLI שמצורף לגרסת ה-SDK הזו עומד בדרישת Claude Code.
ה-CLI משמיט את המפתח כשאין קישורים בתוצאה, וגם בתוצאות מסוכני משנה. ה-CLI שומר לכל היותר 50 קישורים לכל תוצאה, ומפסיק להוסיף קישורים ברגע שהרשימה מגיעה ל-64 KiB של JSON מסוּריאל. כלי שמוגדר בתוך התהליך עם tool() אף פעם לא מייצר את המפתח, כי ה-SDK משטח את בלוקי resource_link שלו לטקסט לפני שה-CLI רואה את התוצאה.
#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
stop_reason: str | None = None
session_id: str | None = None
uuid: str | None = None| שדה | טיפוס | תיאור |
|---|---|---|
content | list[ContentBlock] | רשימת בלוקי התוכן בתשובה |
model | str | המודל שיצר את התשובה |
parent_tool_use_id | str | None | מזהה שימוש בכלי אם זו תשובה מקוננת |
error | AssistantMessageError | None | סוג השגיאה אם התשובה נתקלה בשגיאה |
usage | dict[str, Any] | None | שימוש בטוקנים לכל הודעה (אותם מפתחות כמו ResultMessage.usage) |
message_id | str | None | מזהה הודעת API. כמה הודעות מאותה תור חולקות את אותו מזהה |
stop_reason | str | None | סיבת העצירה מה-API (למשל end_turn, tool_use) |
session_id | str | None | המזהה של הסשן שההודעה שייכת אליו |
uuid | str | None | מזהה ייחודי של ההודעה בתוך תמליל הסשן |
#AssistantMessageError
סוגי שגיאה אפשריים להודעות עוזר.
AssistantMessageError = Literal[
"authentication_failed",
"billing_error",
"rate_limit",
"invalid_request",
"server_error",
"unknown",
]תהליך ה-CLI שמתחת יכול לפלוט סוגי שגיאה שה-Literal הזה לא מפרט, כמו max_output_tokens. ה-SDK מעביר את הערך בלי שינוי, ולכן יש להתייחס למחרוזות מחוץ לרשימה הזו כמו שמתייחסים ל-unknown. טיפוס TypeScript SDKAssistantMessageError מפרט את קבוצת הערכים המלאה שה-CLI יכול לפלוט.
#SystemMessage
הודעת מערכת עם מטא נתונים.
@dataclass
class SystemMessage:
subtype: str
data: dict[str, Any]תת סוגים שאין להם dataclass משלהם מגיעים כ-SystemMessage. כדי לעקוב אחרי הסשן בין תורות, מגדירים CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS=1 וקוראים את message.data["state"] בכל הודעה שה-subtype שלה הוא session_state_changed. SDKSessionStateChangedMessage מפרט את המצבים שהוא יכול לשאת. עוברים עליהם עם receive_messages() כדי לקרוא אותם: receive_response() נעצר ב-ResultMessage, והודעת session_state_changed יכולה לבוא אחרי התוצאה הזו.
#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, ModelUsage] | 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
terminal_reason: str | None = None
origin: MessageOrigin | None = Noneהשדה subtype קובע אילו שדות אחרים מאוכלסים. הוא אחד מהערכים "success", "error_during_execution", "error_max_turns", "error_max_budget_usd", או "error_max_structured_output_retries". ה-dataclass של Python משטח את כל הוריאנטים לצורה אחת, כך ששדות שלא חלים על ה-subtype שהוחזר הם None.
כמה שדות נושאים פירוט אבחוני על האופן שבו השיחה הסתיימה:
is_error:Trueכשהשיחה הסתיימה במצב שגיאה. תמידTrueבתת-הסוגיםerror_*. ב-subtype="success"הואTrueבשלושה מקרים. בדקו אתstop_reasonכדי להבדיל ביניהם:"refusal": המודל סירב להגיב. קראו את טקסט הסירוב ב-result, או ב-AssistantMessageהקודם כש-resultריק."tool_deferred_unavailable": הכלי שנדחה כבר לא היה זמין כשחידשתם את הסשן, למשל כי שרת ה-MCP שלו לא היה מחובר. בשני המקרים שלהלן, פרומפט שאתם שולחים אחרי חידוש נספר כמו פרומפט שהועבר עם ה-resume:- בלי פרומפט: הקריאה עדיין ממתינה. הפכו את הכלי לזמין וחדשו שוב בלי פרומפט, והקריאה תרוץ קודם.
- פרומפט: Claude Code עונה עליו בלי תוצאת הכלי, והקריאה שנדחתה נעלמת. שלחו פרומפט חדש אם עדיין צריך לקרוא לכלי.
- כל ערך אחר: התור הסתיים בשגיאה ש-Claude Code דיווח עליה במקום תשובת מודל, כמו שגיאת API. קראו את
terminal_reasonלסיבה, אתresultלהודעה, ואתapi_error_statusלסטטוס ה-HTTP כשה-API החזיר אחד.
api_error_status: קוד סטטוס ה-HTTP של שגיאת ה-API המסיימת.Noneכשהתור הסתיים בלי שגיאה כזו. מאוכלס רק ב-subtype="success".result: הטקסט של הודעת העוזר הסופית ב-subtype="success", אוNoneבתת-הסוגיםerror_*. כש-subtype="success"ו-is_error=True, זה מחזיק את מחרוזת שגיאת ה-API אם אחת זמינה, אבל יכול להיות ריק, אז בדקו אתapi_error_statusואת תוכן ה-AssistantMessageהקודם לפירוט.errors: מחרוזות שגיאה ברמת הלולאה, כמו הודעת מקסימום התורות. מאוכלס רק בתת-הסוגיםerror_*.terminal_reason: למה לולאת השאילתה הסתיימה, למשל"completed","max_turns","api_error","aborted_streaming", או"aborted_tools". ערך"aborted_streaming"או"aborted_tools"אומר שהתור בוטל לפני שהושלם. סיבות נפוצות הןinterrupt()וקריאת callback של הרשאה שמחזירהPermissionResultDenyעםinterrupt=True.Noneבגרסאות CLI שקדמו לשדה, בתוצאות מפקודות מקומיות כמו/voiceאו/usage, שעוקפות את לולאת השאילתה, או בתוצאות שגיאה מסונתזות שנפלטות כשהסשן נכשל באופן קטלני. משקף אתSDKResultMessage.terminal_reasonשל ה-SDK של TypeScript, שמפרט את קבוצת הערכים המלאה.origin: המקור של הודעת המשתמש שהפעילה את התור הזה. במצב קלט בזרימה, בדקו את זה כדי להבדיל בין התוצאה של הפרומפט שלכם, שבוoriginהואNoneאו{"kind": "human"}, לבין התוצאה של תור שהוזרק, כמו התראת משימת רקע. דורש Python Agent SDK 0.2.137 או חדש יותר.
כשכמה משימות רקע מסתיימות קרוב זו לזו, Claude Code יכול לענות על ההתראות שלהן בתור אחד במקום בתור לכל אחת. עדיין מקבלים ResultMessage אחד לכל התראה, לפי הסדר, כל אחד עם origin ש-kind שלו הוא "task-notification". לכולם חוץ מהאחרון יש num_turns שמוגדר ל-0 ו-result ריק, והאחרון נושא את התור שעונה על כולן.
מילון usage מכסה רק את לולאת הסוכן הראשית ואינו כולל קריאות מודל של תת-סוכן וקריאות מודל מקוננות או עזר אחרות. במצב קלט בזרימה, הערכים הם לפי תור. העדיפו את model_usage לחשבונאות של טוקנים ועלות. מילון usage מכיל את המפתחות הבאים כשהם נוכחים:
| מפתח | טיפוס | תיאור |
|---|---|---|
input_tokens | int | טוקני קלט שנצרכו על ידי לולאת הסוכן ברמה העליונה. טוקני תת-סוכן אינם כלולים; השתמשו ב-model_usage לחשבונאות של כל העץ. |
output_tokens | int | טוקני פלט שנוצרו על ידי לולאת הסוכן ברמה העליונה. טוקני תת-סוכן אינם כלולים. |
cache_creation_input_tokens | int | טוקנים ששימשו ליצירת רשומות מטמון חדשות. |
cache_read_input_tokens | int | טוקנים שנקראו מרשומות מטמון קיימות. |
מילון model_usage ממפה שמות מודלים לשימוש לפי מודל. הוא מכסה כל קריאת מודל שנעשתה דרך צינור השאילתה: הלולאה הראשית, תת-סוכנים, וקריאות פנימיות כמו דחיסה וסוכני Workflow. קריאות עזר מחוץ לצינור הזה, כמו מסווג ההרשאות ובקשות ספירת טוקנים, מוחרגות מ-model_usage. התייחסו ל-model_usage כהערכה, לא כהצהרת חיוב.
במצב קלט בזרימה, model_usage ו-total_cost_usd מצטברים לאורך התורות, אז קראו את התוצאה האחרונה במקום לסכם בין תוצאות. קריאה שמחדשת סשן סופרת גם את הסכומים ששוחזרו מקריאות קודמות של הסשן. ראו מעקב עלויות במצב קלט בזרימה לאיפוסים ושחזור סכומים אחרי קריסת סשן לתוצאות שאופסו.
כל ערך ב-model_usage הוא TypedDict מסוג ModelUsage, שמיובא באמצעות from claude_agent_sdk.types import ModelUsage. המפתחות שלו ב-camelCase כי ה-SDK מעביר את הערך כמו שהוא מתהליך ה-CLI שמתחת, בהתאמה לטיפוס ModelUsage של TypeScript:
| מפתח | טיפוס | תיאור |
|---|---|---|
inputTokens | int | טוקני קלט למודל הזה. |
outputTokens | int | טוקני פלט למודל הזה. |
cacheReadInputTokens | int | טוקני קריאה ממטמון למודל הזה. |
cacheCreationInputTokens | int | טוקני יצירת מטמון למודל הזה. |
webSearchRequests | int | בקשות חיפוש באינטרנט שנעשו על ידי המודל הזה. |
thinkingTokens | int | טוקני חשיבה שנוצרו על ידי המודל הזה, כבר נספרים בתוך outputTokens. נעדר עד שתור רץ על גרסת Claude Code שרושמת אותו, ולא מוצהר ב-TypedDict, אז קראו אותו עם .get(). דורש Python Agent SDK 0.2.150 או חדש יותר, שה-CLI הארוז איתו רושם אותו. |
costUSD | float | עלות משוערת בדולר ארה"ב למודל הזה, מחושבת בצד הלקוח. ראו מעקב עלות ושימוש להסתייגויות חיוב. |
contextWindow | int | גודל חלון ההקשר למודל הזה. |
maxOutputTokens | int | מגבלת טוקני הפלט המרבית למודל הזה. |
canonicalModel | str | מזהה המודל הקנוני ששימש לחיפוש התמחור. עשוי להיות שונה ממחרוזת המודל הגולמית שלפיה הרשומה ממופתחת, כמו מזהה או כינוי ספציפי לספק. לא תמיד נוכח. |
provider | str | ספק ה-API ששירת את המודל הזה, למשל firstParty, bedrock, vertex, foundry, anthropicAws, mantle, או gateway. לא תמיד נוכח. |
costBasis | str | טבלת המחירים שתמחרה את הבקשה האחרונה של המודל הזה: list למחיר מחירון, managed לטבלת modelPricing, או unknown כשאף אחד מהם לא התאים למזהה המודל. לא תמיד נוכח, ולא מוצהר ב-TypedDict, אז קראו אותו עם .get(). דורש Claude Code v2.1.246 או חדש יותר. |
#StreamEvent
אירוע זרם לעדכוני הודעה חלקיים בזמן זרימה. מתקבל רק כש-include_partial_messages=True ב-ClaudeAgentOptions. ייבוא באמצעות 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] | נתוני אירוע זרם ה-API הגולמיים של Claude |
parent_tool_use_id | str | None | תמיד None. אירועי זרם נפלטים רק לסשן הראשי. לשיוך לתת-סוכן, השתמשו בהודעות שלמות כמו AssistantMessage |
#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", "allowed_warning", או "rejected". "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, כולל שדות שלא ממודלים למעלה |
#ConversationResetMessage
נפלט כשהשיחה מוחלפת בלי לסיים את החיבור, למשל אחרי /clear. ראו מעקב עלויות במצב קלט בזרימה לאופן שבו איפוס משפיע על הסכומים הרצים באובייקטי ResultMessage מאוחרים יותר. דורש Python Agent SDK 0.2.137 או חדש יותר.
@dataclass
class ConversationResetMessage:
new_conversation_id: str
uuid: str
session_id: str| שדה | טיפוס | תיאור |
|---|---|---|
new_conversation_id | str | מזהה אטום לשיחה החדשה. זה לא ה-session_id של ההודעות הבאות; קראו אותו מההודעה הבאה |
uuid | str | מזהה הודעה ייחודי |
session_id | str | המזהה של הסשן שאופס. הודעות אחרי האיפוס נושאות session_id חדש |
#TaskStartedMessage
נפלט כשמשימת רקע מתחילה. משימת רקע היא כל דבר שעוקבים אחריו מחוץ לתור הראשי: פקודת Bash שהועברה לרקע, מעקב Monitor, תת-סוכן שהופעל דרך כלי Agent, או סוכן מרוחק. השדה task_type אומר איזה. השם הזה אינו קשור לשינוי השם של הכלי מ-Task ל-Agent.
@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 | מזהה שימוש בכלי המשויך |
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 | מזהה שימוש בכלי המשויך |
last_tool_name | str | None | שם הכלי האחרון שהמשימה השתמשה בו |
#TaskNotificationMessage
נפלט כשמשימת רקע מסתיימת, נכשלת, או נעצרת. משימות רקע כוללות פקודות Bash עם run_in_background, מעקבי 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 | מזהה שימוש בכלי המשויך |
usage | TaskUsage | None | שימוש סופי בטוקנים למשימה |
כשה-CLI מעביר קריאת כלי MCP ארוכה לרקע, תוצאת הכלי לקריאה הזו מחזיקה רק מציין מקום, והתוצאה האמיתית של הקריאה מגיעה בהודעה הזו. בהתראת "completed" לקריאה כזו, ה-CLI מוסיף מפתח resource_links שמפרט את הקבצים שהכלי החזיר לפי הפניה, עם אותן רשומות ומגבלות כמו מפתח resourceLinks ב-UserMessage.tool_use_result. המפתח resource_links דורש Python Agent SDK 0.2.150 או חדש יותר ו-Claude Code v2.1.257 או חדש יותר; ה-CLI הארוז עם גרסת ה-SDK הזו עומד בדרישת Claude Code.
ל-dataclass אין שדה עבור resource_links. קראו אותו ממילון data שההודעה יורשת מ-SystemMessage: message.data.get("resource_links"). התאימו את ההתראה לקריאה באמצעות tool_use_id. ה-CLI משמיט את המפתח כשלתוצאה לא היו קישורים ובהתראות למשימות שאינן קריאות כלי MCP.
#טיפוסי בלוקי תוכן
#ContentBlock
טיפוס איחוד של כל בלוקי התוכן.
ContentBlock = (
TextBlock
| ThinkingBlock
| ToolUseBlock
| ToolResultBlock
| ServerToolUseBlock
| ServerToolResultBlock
)#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#סוגי שגיאות
הטיפוסים להלן מגדירים מה הקוד תופס. לרשומות שממופות להודעות השגיאה שהטיפוסים האלה מעלים, עם הסיבה והתיקון לכל אחת, ראו Troubleshooting.
#ClaudeSDKError
מחלקת חריגה בסיסית לכל שגיאות ה-SDK.
class ClaudeSDKError(Exception):
"""Base error for Claude SDK."""כאשר query() בזריקה אחת מסתיים בתוצאת שגיאה, למשל שגיאת מגבלת תורות, ה-SDK מעלה ResultError.
#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#ResultError
מועלה כאשר תהליך Claude Code יוצא כי הריצה הסתיימה בהודעת תוצאה של שגיאה, כגון שגיאת מגבלת תורות או שגיאת API. ResultError יורש מ-ProcessError, כך שמטפל קיים של except ProcessError תופס גם אותו. המאפיינים שלו נושאים את השדות של הודעת התוצאה הזו, כך שאפשר להסתעף לפי הסיבה שהריצה נכשלה בלי לפרסר את טקסט ההודעה. דורש Python Agent SDK 0.2.140 או גרסה מאוחרת יותר.
class ResultError(ProcessError):
subtype: str | None # "error_max_turns", "error_during_execution", ...; "success" when the run ended on a failed request
errors: list[str] # an empty list when the result message reported none
result: str | None
api_error_status: int | None
terminal_reason: str | None # "max_turns", "api_error", ...; check after data["stop_reason"], before subtype
session_id: str | None
data: dict[str, Any] # the raw result message payloadכדי להבדיל בין כשלים, בדקו קודם את data["stop_reason"], אחר כך את terminal_reason, ואחר כך את subtype. לתגובה שנדחתה יש stop_reason עם הערך "refusal", בדרך כלל עם subtype "success". ה-terminal_reason שלה לא מבדיל אותה בפני עצמו, ויכול לקרוא "completed" או "api_error". לבקשה סופית שנכשלה יש subtype "success" והסיבה שלה ב-terminal_reason, למשל "api_error" עבור שגיאת API. כאשר הריצה מגיעה למגבלה שהגדרתם, כגון max_turns או max_budget_usd, מתקבל subtype מסוג error_*.
#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 a prompt is submitted
"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
][!NOTE]
ה-SDK של TypeScript תומך באירועי hook נוספים שעדיין אינם זמינים ב-Python. ראו את טבלת זמינות ה-hooks לתמיכה לפי SDK.
#HookCallback
הגדרת טיפוס לפונקציות callback של hook.
HookCallback = Callable[[HookInput, str | None, HookContext], Awaitable[HookJSONOutput]]פרמטרים:
input: קלט hook עם טיפוס חזק, עם union מובחן לפיhook_event_name(ראוHookInput)tool_use_id: מזהה שימוש בכלי אופציונלי (ל-hooks שקשורים לכלים)context: הקשר ה-hook עם מידע נוסף
מחזיר HookJSONOutput.
#HookContext
מידע הקשר שמועבר ל-callback של 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. When omitted, the per-event default applies:
# 600 for most events, 30 for UserPromptSubmit
)
on_failure: Literal["continue", "block"] | None = (
None # "block" blocks the action when a callback fails
)כדי להחליט מה on_failure מכסה, ראו חסימת הפעולה כאשר callback נכשל.
#HookInput
טיפוס union של כל סוגי קלט ה-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
נתוני קלט לאירועי hook מסוג PreToolUse.
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
נתוני קלט לאירועי hook מסוג PostToolUse.
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
נתוני קלט לאירועי hook מסוג PostToolUseFailure. נקרא כאשר ביצוע כלי נכשל.
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 (אופציונלי) | True כאשר הכשל הגיע אל Claude Code כ-abort ולא כשגיאה שהכלי דיווח. ביטול כלי שרץ באמצעות interrupt() לא מפעיל את ה-hook הזה. תוצאת הכלי נושאת את הודעת ההפרעה במקום זאת |
agent_id | str (אופציונלי) | מזהה סוכן המשנה, נוכח כאשר ה-hook מופעל בתוך סוכן משנה |
agent_type | str (אופציונלי) | סוג סוכן המשנה, נוכח כאשר ה-hook מופעל בתוך סוכן משנה |
#UserPromptSubmitHookInput
נתוני קלט לאירועי hook מסוג UserPromptSubmit.
class UserPromptSubmitHookInput(BaseHookInput):
hook_event_name: Literal["UserPromptSubmit"]
prompt: str| שדה | טיפוס | תיאור |
|---|---|---|
hook_event_name | Literal["UserPromptSubmit"] | תמיד "UserPromptSubmit" |
prompt | str | הפרומפט שנשלח |
#StopHookInput
נתוני קלט לאירועי hook מסוג Stop.
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
נתוני קלט לאירועי hook מסוג SubagentStop.
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
נתוני קלט לאירועי hook מסוג PreCompact.
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
נתוני קלט לאירועי hook מסוג Notification.
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
נתוני קלט לאירועי hook מסוג SubagentStart.
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
נתוני קלט לאירועי hook מסוג PermissionRequest. מאפשר ל-hooks לטפל בהחלטות הרשאה באופן תכנותי.
class PermissionRequestHookInput(BaseHookInput):
hook_event_name: Literal["PermissionRequest"]
tool_name: str
tool_input: dict[str, Any]
permission_suggestions: NotRequired[list[Any]]
agent_id: NotRequired[str]
agent_type: NotRequired[str]| שדה | טיפוס | תיאור |
|---|---|---|
hook_event_name | Literal["PermissionRequest"] | תמיד "PermissionRequest" |
tool_name | str | שם הכלי שמבקש הרשאה |
tool_input | dict[str, Any] | פרמטרי הקלט של הכלי |
permission_suggestions | list[Any] (אופציונלי) | עדכוני הרשאה מוצעים מה-CLI |
agent_id | str (אופציונלי) | מזהה סוכן המשנה, נוכח כאשר ה-hook מופעל בתוך סוכן משנה |
agent_type | str (אופציונלי) | סוג סוכן המשנה, נוכח כאשר ה-hook מופעל בתוך סוכן משנה |
#HookJSONOutput
טיפוס union לערכי החזרה של callback של 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][!NOTE]
השתמשו ב-
continue_(עם קו תחתון) בקוד Python. הוא מומר אוטומטית ל-continueכאשר הוא נשלח ל-CLI.
#HookSpecificOutput
union מובחן של טיפוסי פלט TypedDict שספציפיים לאירוע. השדה hookEventName קובע אילו שדות תקפים. לפרטים מלאים על השדות הזמינים לכל אירוע hook, ראו שליטה בביצוע עם hooks.
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] # MCP tools only. Prefer 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[!NOTE]
השתמשו ב-
async_(עם קו תחתון) בקוד Python. הוא מומר אוטומטית ל-asyncכאשר הוא נשלח ל-CLI.
#דוגמה לשימוש ב-Hook
הדוגמה הזו רושמת שני hooks: אחד שחוסם פקודות Bash מסוכנות כמו rm -rf /, ואחר שמתעד את כל השימוש בכלים לצורכי ביקורת. ה-hook של האבטחה רץ רק על פקודות Bash (דרך ה-matcher), בעוד שה-hook של התיעוד רץ על כל הכלים.
import asyncio
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 (per-event default timeout)
],
"PostToolUse": [HookMatcher(hooks=[log_tool_use])],
}
)
async def main():
async for message in query(prompt="Analyze this codebase", options=options):
print(message)
asyncio.run(main())#טיפוסי קלט ופלט של כלים
תיעוד של סכמות קלט ופלט לכלים המובנים של Claude Code. ה-SDK של Python לא מייצא אותם כטיפוסים, אבל הם מייצגים את המבנה של קלטי כלים ופלטי כלים בהודעות.
כל פלט שמוצג הוא הערך שקוראים מ-UserMessage.tool_use_result עבור הכלי הזה. שמות המפתחות מופיעים בדיוק כפי ש-Claude Code פולט אותם. מפתח שמסומן | None עם הערת "present when" או "optional" מושמט כאשר הוא לא חל.
#Agent
שם הכלי: Agent. השם הקודם Task עדיין מתקבל ככינוי כאשר הכלי הזה זמין לסשן.
רשימת tools ב-SystemMessage של האתחול מדווחת על הכלי הזה כ-Task לצורך תאימות לאחור.
קלט:
{
"description": str, # A short (3-5 word) description of the task
"prompt": str, # The task for the agent to perform
"subagent_type": str | None, # The type of specialized agent to use
"model": "sonnet" | "opus" | "haiku" | "fable" | None, # Model override for this agent
"effort": "low" | "medium" | "high" | "xhigh" | "max" | None, # Reasoning effort for this agent
"run_in_background": bool | None, # Default when omitted: your main agent's call runs the new agent in the background, and a subagent's call waits for it
"name": str | None, # Name for the spawned agent
"team_name": str | None, # Deprecated; ignored
"mode": "acceptEdits" | "auto" | "bypassPermissions" | "default" | "dontAsk" | "plan" | None, # Deprecated; ignored. The subagent inheritance rules decide a subagent's permission mode
"isolation": "worktree" | "remote" | None, # Isolation mode for the agent's changes
}מפעיל סוכן חדש לטיפול במשימות מורכבות ורב שלביות באופן אוטונומי.
כאשר Claude משמיט את run_in_background מקריאה ל-Agent, כברירת מחדל הסוכן הראשי שלך לא ממתין לסוכן החדש, ותת סוכן ממתין:
- מהסוכן הראשי שלך: הסוכן החדש רץ ברקע, ולתוצאה יש
status: "async_launched". כדי שהסוכן הראשי שלך ימתין לסוכן החדש, ראה בחירה אם Claude ממתין לתת סוכנים. - מאחד מתת הסוכנים שלך: תת הסוכן הקורא ממתין לסוכן החדש. הסוכן החדש רץ ברקע כאשר ההגדרה שלו מגדירה את
backgroundל-True, או כאשר מכבים את מצב הפיצול על ידי הגדרתCLAUDE_CODE_FORK_SUBAGENTל-0.
לפני Python SDK v0.2.169, גם סוכנים שתת הסוכנים שלך הפעילו רצו ברקע כברירת מחדל. הגרסה הזו היא הראשונה שמצרפת את Claude Code v2.1.302 או מאוחר יותר.
פלט (status: "completed"):
{
"status": "completed",
"agentId": str, # ID of the agent that ran
"agentType": str | None, # The subagent type that handled the task
"content": [ # Result content blocks
{
"type": "text",
"text": str,
"citations": list | None,
}
],
"resolvedModel": str | None, # Model the subagent started on
"modelsUsed": list[str] | None, # Models used in order, with consecutive repeats collapsed
"totalToolUseCount": int, # Number of tool calls the agent made
"totalDurationMs": int, # Execution duration in milliseconds
"totalTokens": int, # Token count from the final API request, not the whole run
"usage": { # Token usage statistics
"input_tokens": int,
"output_tokens": int,
"cache_creation_input_tokens": int | None,
"cache_read_input_tokens": int | None,
"server_tool_use": {"web_search_requests": int, "web_fetch_requests": int} | None,
"service_tier": str | None,
"cache_creation": {"ephemeral_1h_input_tokens": int, "ephemeral_5m_input_tokens": int} | None,
"inference_geo": str | None,
"speed": str | None,
"iterations": Any | None,
"output_tokens_details": {"thinking_tokens": int | None} | None,
"fallback_credit": Any | None,
},
"toolStats": { # Aggregate tool activity for the run
"readCount": int,
"searchCount": int,
"bashCount": int,
"editFileCount": int,
"linesAdded": int,
"linesRemoved": int,
"otherToolCount": int,
"frameCount": int | None,
} | None,
"prompt": str, # The prompt the agent ran
"worktreePath": str | None, # Present when Claude Code kept the subagent's worktree
"worktreeBranch": str | None, # Present when Claude Code created that worktree with git
}פלט (status: "async_launched"):
{
"status": "async_launched",
"isAsync": bool | None, # True on background launches
"agentId": str, # ID of the launched agent
"description": str, # The task description
"resolvedModel": str | None, # Model in use at the backgrounding transition
"modelsUsed": list[str] | None, # Models used before backgrounding, in order, with consecutive repeats collapsed
"prompt": str, # The prompt the agent runs
"outputFile": str, # File path where the agent's output is written
"canReadOutputFile": bool | None, # Whether the output file can be read directly
}פלט (status: "remote_launched"):
{
"status": "remote_launched",
"taskId": str, # ID of the dispatched task
"sessionUrl": str, # Link to the cloud session
"description": str, # The task description
"prompt": str, # The prompt the agent runs
"outputFile": str, # File path where the agent's output is written
}מחזיר את התוצאה מתת הסוכן. הפלט מובחן לפי שדה status: "completed" למשימות שהסתיימו, "async_launched" למשימות רקע, ו-"remote_launched" למשימות ש-Claude Code שיגר לסשן ענן, שבו sessionUrl מקשר לסשן הזה ו-taskId מזהה אותו. אם Claude Code שמר את עץ העבודה המבודד של תת הסוכן, worktreePath בווריאנט completed הוא המקום שבו למצוא אותו, ו-worktreeBranch הוא הענף שלו כאשר Claude Code יצר את עץ העבודה עם git.
בווריאנט completed, resolvedModel מציין את המודל שעליו תת הסוכן התחיל, והוא יכול להיות שונה מקלט model המבוקש כאשר availableModels או דריסה אחרת חלים. השדה הזה דורש Claude Code v2.1.174 או מאוחר יותר. בווריאנט async_launched, resolvedModel מציין את המודל שבשימוש כאשר הסוכן עבר לרקע, כך שהחלפה שהתרחשה לפני המעבר לרקע משתקפת שם. השדה modelsUsed בשני הווריאנטים מפרט את המודלים ששימשו לפי הסדר, עם כיווץ של חזרות רצופות. הוא מוגדר רק כאשר המודל הוחלף באמצע הריצה. modelsUsed והתנהגות resolvedModel בזמן המעבר לרקע דורשים Claude Code v2.1.212 או מאוחר יותר.
Claude Code ממלא את usage ואת totalTokens מבקשת ה-API הסופית של תת הסוכן, לא מכל הריצה. כאשר הוא נוכח, thinking_tokens תחת output_tokens_details ב-usage הוא מספר אסימוני הפלט של הבקשה הזו שהיו אסימוני חשיבה. המפתח output_tokens_details דורש Python SDK v0.2.136 או מאוחר יותר, שמצרף את Claude Code v2.1.228. המפתח fallback_credit דורש Python SDK v0.2.162 או מאוחר יותר, שמצרף את Claude Code v2.1.285.
#AskUserQuestion
שם הכלי: AskUserQuestion
שואל את המשתמש שאלות הבהרה במהלך הביצוע. ראה טיפול באישורים ובקלט משתמש לפרטי שימוש.
קלט:
{
"questions": [ # Questions to ask the user (1-4 questions)
{
"question": str, # The complete question to ask the user
"header": str, # Very short label displayed as a chip/tag (max 12 chars)
"options": [ # The available choices (2-4 options)
{
"label": str, # Display text for this option (1-5 words)
"description": str, # Explanation of what this option means
"preview": str | None, # Preview content rendered when the option is focused
}
],
"multiSelect": bool, # Set to true to allow multiple selections
}
],
"answers": dict[str, str] | None,
# User answers populated by the permission system. Multi-select
# answers are a comma-joined string of the selected labels; a
# list of labels is accepted on input and coerced to that form
"annotations": dict[str, dict] | None,
# Per-question annotations from the user, keyed by question text.
# Each value can carry "preview" (the selected option's preview
# content) and "notes" (free-text notes on the selection)
"metadata": dict | None, # Analytics metadata, such as {"source": "remember"}; not displayed to the user
}פלט:
{
"questions": [ # The questions that were asked
{
"question": str,
"header": str,
"options": [{"label": str, "description": str, "preview": str | None}],
"multiSelect": bool,
}
],
"answers": dict[str, str], # Maps question text to answer string
# Multi-select answers are comma-separated
"response": str | None,
# Freeform reply typed instead of answering the questions; when set,
# Claude receives "The user responded: ..." in place of the answer list
"annotations": dict[str, dict] | None, # Per-question "preview" and "notes" from the user's selections
"afkTimeoutMs": int | None, # Set when the dialog auto-resolved after this many milliseconds of user inactivity; absent when the user answered
}#Bash
שם הכלי: Bash
למה שקובע את תקרת החזית, ראה מגבלות זמן ופלט. למגבלת הזמן ברקע, ראה מגבלת זמן לפקודות רקע.
קלט:
{
"command": str, # The command to execute
"timeout": int | None, # Milliseconds. Foreground: capped at 600000 by default, higher values are clamped. With run_in_background (Claude Code v2.1.285 or later): the background time limit, 1800000 when omitted, capped at 7200000 unless raised
"description": str | None, # Clear, concise description (5-10 words)
"run_in_background": bool | None, # Set to true to run in background
}פלט:
{
"stdout": str, # The command's output; stdout and stderr arrive merged into this one interleaved stream
"stderr": str, # Notices the tool itself adds, not the command's stderr
"interrupted": bool, # Whether the command was interrupted
"isImage": bool | None, # Whether stdout contains image data
"backgroundTaskId": str | None, # ID of the background task if command is running in background
}#Monitor
שם הכלי: Monitor
מריץ מקור רקע ומעביר כל אירוע ל-Claude כדי שיוכל להגיב בלי polling: command מריץ סקריפט ופולט אירוע אחד לכל שורת stdout, ו-ws פותח WebSocket ופולט אירוע אחד לכל מסגרת טקסט. יש לספק בדיוק אחד מבין command או ws.
כאשר Monitor מריץ פקודה, הוא פועל לפי אותם כללי הרשאה כמו Bash. מעקב WebSocket מבקש אישור בנפרד. מקור ws דורש Claude Code v2.1.195 או מאוחר יותר. ראה את הפניה לכלי Monitor להתנהגות ולזמינות ספקים.
קלט:
{
"command": str | None, # Shell script; each stdout line is an event, exit ends the watch
"ws": dict | None, # WebSocket source: {"url": str, "protocols": list[str] | None}; each text frame is an event
"description": str, # Short description shown in notifications
"timeout_ms": int | None, # Deadline in milliseconds (default 300000, max 3600000; the effective deadline is at most 1800000)
}פלט:
{
"taskId": str, # ID of the background monitor task
"timeoutMs": int, # The watch's effective deadline in milliseconds
"persistent": bool | None, # False: every watch has a deadline
}#Edit
שם הכלי: Edit
קלט:
{
"file_path": str, # The absolute path to the file to modify
"old_string": str, # The text to replace
"new_string": str, # The text to replace it with
"replace_all": bool | None, # Replace all occurrences (default False)
}פלט:
{
"filePath": str, # The file that was edited
"oldString": str, # The text that was replaced
"newString": str, # The text that replaced it
"originalFile": str | None, # File contents before the edit
"structuredPatch": [ # Diff hunks for the change
{
"oldStart": int,
"oldLines": int,
"newStart": int,
"newLines": int,
"lines": list[str],
}
],
"userModified": bool, # Whether the user changed the proposed edit before accepting it
"replaceAll": bool, # Whether all occurrences were replaced
"gitDiff": { # Optional git diff summary for the file
"filename": str,
"status": "modified" | "added",
"additions": int,
"deletions": int,
"changes": int,
"patch": str,
"repository": str | None, # GitHub owner/repo when available
} | None,
}#Read
שם הכלי: Read
קלט:
{
"file_path": str, # The absolute path to the file to read
"offset": int | None, # The line number to start reading from
"limit": int | None, # The number of lines to read
}הפלט מקבל אחת מהצורות הבאות לפי מה ש-Claude קרא. בדוק את המפתח type כדי להבדיל ביניהן.
פלט (type: "text"):
{
"type": "text",
"file": {
"filePath": str, # The file that was read
"content": str, # The returned content
"numLines": int, # Number of lines in the returned content
"startLine": int, # Line number the content starts at
"totalLines": int, # Total number of lines in the file
"truncatedByTokenCap": bool | None, # Present and True when a whole-file read exceeded the token cap and content is the first page
},
}פלט (type: "image"):
{
"type": "image",
"file": {
"base64": str, # Base64-encoded image data
"type": "image/jpeg" | "image/png" | "image/gif" | "image/webp", # Image MIME type
"originalSize": int, # Original file size in bytes
"dimensions": { # Optional sizing info for coordinate mapping
"originalWidth": int | None, # Optional; original width in pixels
"originalHeight": int | None, # Optional; original height in pixels
"displayWidth": int | None, # Optional; width after resizing
"displayHeight": int | None, # Optional; height after resizing
} | None,
},
}פלט (type: "notebook"):
{
"type": "notebook",
"file": {
"filePath": str, # The notebook that was read
"cells": list, # Notebook cells
},
}פלט (type: "pdf"):
{
"type": "pdf",
"file": {
"filePath": str, # The PDF that was read
"base64": str, # Base64-encoded PDF data
"originalSize": int, # File size in bytes
},
}פלט (type: "parts"):
{
"type": "parts",
"file": {
"filePath": str, # The PDF that was read
"originalSize": int, # File size in bytes
"count": int, # Number of pages extracted as images
"outputDir": str, # Directory containing the extracted page images
},
"firstPage": int | None, # Optional document page number of the first extracted page
}פלט (type: "file_unchanged"):
{
"type": "file_unchanged", # The file is unchanged since Claude last read it in this session, so the content isn't repeated
"file": {
"filePath": str,
},
"source": "seeded" | None, # Present when the earlier copy came from a CLAUDE.md or memory file loaded at startup rather than a Read call
}#Write
שם הכלי: Write
קלט:
{
"file_path": str, # The absolute path to the file to write
"content": str, # The content to write to the file
}פלט:
{
"type": "create" | "update", # Whether the write created a new file or overwrote an existing one
"filePath": str, # The file that was written
"content": str, # The content that was written
"structuredPatch": [ # Diff hunks; empty for a new file, when nothing changed, or when Claude Code skipped the diff
{
"oldStart": int,
"oldLines": int,
"newStart": int,
"newLines": int,
"lines": list[str],
}
],
"originalFile": str | None, # Previous content; None for a new file or when the previous content was too large to include
"gitDiff": { # Optional git diff summary for the file
"filename": str,
"status": "modified" | "added",
"additions": int,
"deletions": int,
"changes": int,
"patch": str,
"repository": str | None, # GitHub owner/repo when available
} | None,
"userModified": bool | None, # Optional; whether the user edited the proposed content before accepting it
}#Glob
שם הכלי: Glob
קלט:
{
"pattern": str, # The glob pattern to match files against
"path": str | None, # The directory to search in (defaults to cwd)
}פלט:
{
"durationMs": int, # Time taken to run the search, in milliseconds
"numFiles": int, # Number of paths returned, after any truncation
"filenames": list[str], # Matching file paths
"truncated": bool, # Whether the results were truncated at the 100-file limit
"totalMatches": int | None, # Optional total number of matching files before truncation; a lower bound when countIsComplete is False
"countIsComplete": bool | None, # Optional; whether totalMatches is exact
}totalMatches ו-countIsComplete דורשים Claude Code בגרסה v2.1.191 או מאוחרת יותר.
#Grep
שם הכלי: Grep
קלט:
{
"pattern": str, # The regular expression pattern
"path": str | None, # File or directory to search in
"glob": str | None, # Glob pattern to filter files
"type": str | None, # File type to search
"output_mode": str | None, # "content", "files_with_matches", or "count"
"-i": bool | None, # Case insensitive search
"-n": bool | None, # Show line numbers
"-B": int | None, # Lines to show before each match
"-A": int | None, # Lines to show after each match
"-C": int | None, # Lines to show before and after
"context": int | None, # Lines to show before and after; -C is an alias
"-o": bool | None, # Print only the matched parts of each line
"head_limit": int | None, # Limit output to first N lines/entries
"offset": int | None, # Skip first N lines/entries before applying head_limit
"multiline": bool | None, # Enable multiline mode
}פלט:
{
"mode": "content" | "files_with_matches" | "count" | None, # The output mode that was used
"numFiles": int, # Number of files in the result; always 0 in content mode
"filenames": list[str], # Matching files in files_with_matches mode; empty in the other modes
"content": str | None, # Matching lines in content mode, or per-file counts in count mode
"numLines": int | None, # Number of lines in content, present in content mode
"numMatches": int | None, # Total match count, present in count mode
"totalFiles": int | None, # Optional total before head_limit and offset, in files_with_matches mode
"totalLines": int | None, # Optional total before head_limit and offset, in content mode
"appliedLimit": int | None, # Present when head_limit truncated the result
"appliedOffset": int | None, # Present when an offset was applied
}Grep מחזיר את צורת ה-dict הזו בכל מצב פלט. אילו מפתחות אופציונליים מופיעים תלוי ב-output_mode.
totalFiles דורש Claude Code בגרסה v2.1.208 או מאוחרת יותר. totalLines דורש Claude Code בגרסה v2.1.210 או מאוחרת יותר.
#NotebookEdit
שם הכלי: NotebookEdit
קלט:
{
"notebook_path": str, # Absolute path to the Jupyter notebook
"cell_id": str | None, # The ID of the cell to edit
"new_source": str, # The new source for the cell
"cell_type": "code" | "markdown" | None, # The type of the cell
"edit_mode": "replace" | "insert" | "delete" | None, # Edit operation type
}פלט:
{
"new_source": str, # The source written to the cell
"old_source": str | None, # Previous cell source, present for replace and delete
"cell_id": str | None, # ID of the edited cell, when available
"cell_type": "code" | "markdown", # The cell type
"language": str, # The notebook's programming language
"edit_mode": str, # The edit mode that was used
"error": str | None, # Error message when the operation failed
"notebook_path": str, # The notebook file
"original_file": str, # Notebook content before the edit
"updated_file": str, # Notebook content after the edit
}#WebFetch
שם הכלי: WebFetch
קלט:
{
"url": str, # The URL to fetch content from
"prompt": str, # The prompt to run on the fetched content
"offset": int | None, # Number of characters to skip from the start of the page. Requires Python Agent SDK 0.2.164 or later
}פלט:
{
"bytes": int, # Size of the fetched content in bytes
"code": int, # HTTP response code
"codeText": str, # HTTP response code text
"result": str, # Processed result from applying the prompt to the content
"durationMs": int, # Time to fetch and process the content, in milliseconds
"url": str, # URL that was fetched
}#WebSearch
שם הכלי: WebSearch
קלט:
{
"query": str, # The search query to use
"allowed_domains": list[str] | None, # Only include results from these domains
"blocked_domains": list[str] | None, # Never include results from these domains
}פלט:
{
"query": str, # The search query
"results": list[str | {"tool_use_id": str, "content": list[{"title": str, "url": str}]}],
"durationSeconds": float, # Search duration in seconds
}#TodoWrite
שם הכלי: TodoWrite
[!NOTE]
הכלים הבאים זמינים כברירת מחדל רק ב-Claude Opus 4.7, Claude Sonnet 4.6, Claude Haiku 4.5, ובמודלים מוקדמים יותר. בכל מודל אחר, כולל מזהי מודל ש-Claude Code לא מזהה, הם אינם זמינים אלא אם בוחרים להצטרף:
TodoWriteTaskCreateTaskGetTaskUpdateTaskListבכל מקום שבו הכלים זמינים, Claude Code מספק את ארבעת כלי ה-Task, או את
TodoWriteבמקומם כאשר מגדיריםCLAUDE_CODE_ENABLE_TASKS=0.קבוצת ברירת המחדל הזו חלה ב-Claude Code v2.1.268 ומאוחר יותר, ש-TypeScript Agent SDK אורז מ-v0.3.268.
ראו זמינות מודלים כדי להצטרף.
קלט:
{
"todos": [
{
"content": str, # The task description
"status": "pending" | "in_progress" | "completed", # Task status
"activeForm": str, # Active form of the description
}
]
}פלט:
{
"oldTodos": [ # The todo list before the update
{
"content": str,
"status": "pending" | "in_progress" | "completed",
"activeForm": str,
}
],
"newTodos": [ # The todo list after the update
{
"content": str,
"status": "pending" | "in_progress" | "completed",
"activeForm": str,
}
],
}#TaskCreate
שם הכלי: TaskCreate
קלט:
{
"subject": str, # Short task title
"description": str, # Detailed task body
"activeForm": str | None, # Present-tense label shown while in progress
"metadata": dict | None, # Arbitrary caller metadata
}פלט:
{
"task": {"id": str, "subject": str}, # Created task with assigned ID
}#TaskUpdate
שם הכלי: TaskUpdate
קלט:
{
"taskId": str, # ID of the task to patch
"status": Literal["pending", "in_progress", "completed", "deleted"] | None,
"subject": str | None,
"description": str | None,
"activeForm": str | None,
"addBlocks": list[str] | None, # Task IDs this task now blocks
"addBlockedBy": list[str] | None, # Task IDs that now block this task
"owner": str | None,
"metadata": dict | None,
}פלט:
{
"success": bool,
"taskId": str,
"updatedFields": list[str], # Names of fields that changed
"error": str | None,
"statusChange": {"from": str, "to": str} | None,
}#TaskGet
שם הכלי: TaskGet
קלט:
{
"taskId": str, # ID of the task to read
}פלט:
{
"task": {
"id": str,
"subject": str,
"description": str,
"status": Literal["pending", "in_progress", "completed"],
"blocks": list[str],
"blockedBy": list[str],
} | None, # None when the ID is not found
}#TaskList
שם הכלי: TaskList
קלט:
{}פלט:
{
"tasks": [
{
"id": str,
"subject": str,
"status": Literal["pending", "in_progress", "completed"],
"owner": str | None,
"blockedBy": list[str],
}
],
}#TaskOutput
הוסר ב-Claude Code v2.1.277. בעבר אחזר פלט ממשימה ברקע שרצה או שהושלמה, כאשר BashOutput התקבל ככינוי. Claude קורא את קובץ הפלט של משימת רקע באמצעות Read במקום זאת.
רשומת disallowed_tools או כלל דחייה שעדיין מציינים אחד משני השמות מתעלמים מהם בלי אזהרה.
#TaskStop
שם הכלי: TaskStop. עדיין אפשר להשתמש בשמות הקודמים KillShell ו-KillBash בכללי הרשאה, במתאמי hook, ובאפשרויות tools, allowed_tools ו-disallowed_tools.
קלט:
{
"task_id": str | None, # The ID of the background task to stop
"shell_id": str | None, # Deprecated: use task_id instead
}פלט:
{
"message": str, # Status message about the operation
"task_id": str, # The ID of the task that was stopped
"task_type": str, # The type of the task that was stopped
"command": str | None, # The command or description of the stopped task
}#ExitPlanMode
שם הכלי: ExitPlanMode
קלט:
{
"plan": str # The plan to run by the user for approval
}פלט:
{
"plan": str | None, # The plan that was presented to the user
"isAgent": bool, # True when a subagent called the tool
"filePath": str | None, # Present when the plan was saved to a file
"hasTaskTool": bool | None, # Optional; whether the Agent tool is available in the current context
"planWasEdited": bool | None, # Present and True when the user edited the plan before approving
"awaitingLeaderApproval": bool | None, # Present and True when a teammate sent the plan to the team lead for approval
"requestId": str | None, # Optional ID of that approval request
}#ListMcpResources
שם הכלי: ListMcpResourcesTool
קלט:
{
"server": str | None # Optional server name to filter resources by
}התוצאה היא רשימה ולא dict, ולכן tool_use_result מחזיק list עבור הכלי הזה.
פלט:
[ # One entry per resource
{
"uri": str, # Resource URI
"name": str, # Resource name
"mimeType": str | None, # Optional MIME type
"description": str | None, # Optional description
"server": str, # Server that provides this resource
}
]#ReadMcpResource
שם הכלי: ReadMcpResourceTool
קלט:
{
"server": str, # The MCP server name
"uri": str, # The resource URI to read
}פלט:
{
"contents": [
{
"uri": str, # Resource URI
"mimeType": str | None, # Optional MIME type
"text": str | None, # Text content, or a note about the binary content
"blobSavedTo": str | None, # Present when Claude Code saved binary content to disk; path of the saved file
}
],
"error": str | None, # Present when the server couldn't read the resource
}#בניית ממשק שיחה רציפה
הדוגמה הבאה משאירה ClaudeSDKClient אחד מחובר לאורך התורות, כך ש-Claude זוכר הודעות קודמות. הקלידו new כדי להתנתק ולהתחבר מחדש לסשן חדש, או exit כדי לסיים את השיחה.
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())#טיפול בשגיאות
הדוגמה הבאה עוטפת קריאה ל-query() במטפלים לארבעה מתוך סוגי השגיאות שה-SDK מעלה.
הדוגמה הזו תופסת ResultError, שדורש Python Agent SDK 0.2.140 או מאוחר יותר.
import asyncio
from claude_agent_sdk import (
query,
CLINotFoundError,
ProcessError,
ResultError,
CLIJSONDecodeError,
)
async def main():
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"
)
# Catch ResultError before ProcessError, which it subclasses. Its message
# carries the error text. A refusal and a failed final request both usually
# arrive with subtype "success", so check stop_reason, then terminal_reason.
except ResultError as e:
if e.data.get("stop_reason") == "refusal":
print(f"Model declined to respond: {e}")
elif e.terminal_reason == "api_error":
print(f"API request failed: {e}")
else:
print(f"Query ended with an error result ({e.terminal_reason or e.subtype}): {e}")
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}")
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 *"]. אלה רצות מחוץ לארגז החול באופן אוטומטי בלי מעורבות של המודל. sandbox.excludedCommands מכסה מתי רשומה חלה |
allowUnsandboxedCommands | bool | True | לאפשר למודל לבקש הרצת פקודות מחוץ לארגז החול. כש-True, המודל יכול להגדיר dangerouslyDisableSandbox בקלט הכלי, וזה נופל חזרה למערכת ההרשאות |
network | SandboxNetworkConfig | None | הגדרת ארגז חול ספציפית לרשת |
ignoreViolations | SandboxIgnoreViolations | None | הגדרה אילו הפרות של ארגז החול להתעלם מהן |
enableWeakerNestedSandbox | bool | False | הפעלת ארגז חול מקונן חלש יותר לצורך תאימות |
[!NOTE]
ארגז החול תלוי בתמיכת הפלטפורמה, וב-Linux בכלים כמו
bubblewrapו-socat. כברירת מחדל, כש-enabledהואTrueאבל ארגז החול לא יכול להתחיל, הפקודות רצות מחוץ לארגז החול עם אזהרה ב-stderr. ברירת המחדל הזו שונה מ-SDK של TypeScript, שבוfailIfUnavailableברירת המחדל היאtrue.הגדירו
"failIfUnavailable": Trueבהגדרות ארגז החול כדי לעצור במקום זאת. ה-SDK מעביר אתfailIfUnavailableאל Claude Code יחד עם שדותSandboxSettingsהמוצהרים.query()מדווח אז עלResultMessageעםsubtype="error_during_execution"והסיבה ב-errors. מכיוון שזו קריאתquery()חד-פעמית, ה-SDK מעלה חריגה אחרי שהוא מניב את תוצאת השגיאה, ולכן עטפו את הלולאה בבלוק try כדי להמשיך מעבר לה. ראו טיפול בתוצאה לחוזה השגיאה.
כדי למנוע מפקודות בארגז החול לכתוב לקובץ, רשמו את הנתיב המוחלט שלו תחת denyWrite בהגדרות ארגז החול, כגון "filesystem": {"denyWrite": ["/home/user/project/.env"]}. ה-SDK מעביר את filesystem אל Claude Code יחד עם שדות SandboxSettings המוצהרים. אחרי שארגז החול מתחיל, הוא חוסם כתיבה לכל נתיב מוחלט שרשמתם.
#דוגמה לשימוש
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
sandbox_settings = {
"enabled": True,
"autoAllowBashIfSandboxed": True,
"failIfUnavailable": True,
"network": {"allowLocalBinding": True},
}
async def main():
try:
async for message in query(
prompt="Build and test my project",
options=ClaudeAgentOptions(sandbox=sandbox_settings),
):
print(message)
except Exception as error:
# A single-shot query() raises after yielding an error result,
# such as when failIfUnavailable is set and the sandbox can't start.
print(f"Session ended with an error: {error}")
asyncio.run(main())[!WARNING]
אבטחת שקעי Unix: האפשרות
allowUnixSocketsיכולה להעניק גישה לשירותי מערכת שמגיעים מחוץ לארגז החול. לדוגמה, התרת/var/run/docker.sockמעניקה למעשה גישה מלאה למערכת המארחת דרך ה-API של Docker, ועוקפת את בידוד ארגז החול. התירו רק שקעי Unix שהם הכרחיים בהחלט, והבינו את השלכות האבטחה של כל אחד.
#SandboxNetworkConfig
הגדרה ספציפית לרשת עבור מצב ארגז חול. ההגדרות האלה חלות על פקודות Bash בארגז החול כש-enabled הוא True ב-SandboxSettings ההורה. הן אינן מגבילות את כלי 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 ומכללי היתר WebFetch(domain:...) ממקורות הגדרות שאינם מנוהלים. אין השפעה כשמוגדר דרך אפשרויות ה-SDK |
allowUnixSockets | list[str] | [] | רק ב-macOS: נתיבי שקעי Unix שתהליכים יכולים לגשת אליהם, כגון שקע Docker. מתעלמים מזה ב-Linux |
allowAllUnixSockets | bool | False | התרת גישה לכל שקעי Unix, וב-Linux גם לשקעי VM (AF_VSOCK) |
allowLocalBinding | bool | False | התרת לתהליכים להיקשר לפורטים מקומיים (לדוגמה, לשרתי פיתוח) |
allowMachLookup | list[str] | [] | רק ב-macOS: שמות שירותי XPC/Mach להתיר. תומך בתו כללי בסוף |
httpProxyPort | int | None | פורט פרוקסי HTTP לבקשות רשת |
socksProxyPort | int | None | פורט פרוקסי SOCKS לבקשות רשת |
[!NOTE]
פרוקסי ארגז החול המובנה אוכף את רשימת ההיתרים של הרשת לפי שם המארח המבוקש. כברירת מחדל, הפרוקסי לא מסיים ולא בודק תעבורת TLS, ולכן טכניקות כמו domain fronting יכולות לעקוף את רשימת ההיתרים. ראו מגבלות האבטחה של ארגז החול לפרטים ופריסה מאובטחת להגדרת פרוקסי שמסיים TLS.
#SandboxIgnoreViolations
הגדרה להתעלמות מהפרות ספציפיות של ארגז החול.
class SandboxIgnoreViolations(TypedDict, total=False):
file: list[str]
network: list[str]| מאפיין | סוג | ברירת מחדל | תיאור |
|---|---|---|---|
file | list[str] | [] | תבניות נתיבי קבצים שעבורן מתעלמים מהפרות |
network | list[str] | [] | תבניות רשת שעבורן מתעלמים מהפרות |
#נפילה חזרה להרשאות לפקודות מחוץ לארגז החול
כש-allowUnsandboxedCommands מופעל, המודל יכול לבקש להריץ פקודות מחוץ לארגז החול על ידי הגדרת dangerouslyDisableSandbox: True בקלט הכלי. בקשות אלה נופלות חזרה למערכת ההרשאות הקיימת, כלומר ה-handler של can_use_tool שלכם מופעל, וזה מאפשר לכם לממש לוגיקת הרשאה מותאמת אישית.
רשומות excludedCommands שלכם, לעומת זאת, מוציאות קריאה מארגז החול בלי מעורבות של המודל. sandbox.excludedCommands מכסה מתי רשומה חלה.
הדוגמה הבאה רושמת כל בקשה מחוץ לארגז החול ודוחה אותה, אלא אם לוגיקת ההרשאה שלכם מתירה אותה:
import asyncio
from claude_agent_sdk import (
query,
ClaudeAgentOptions,
HookMatcher,
PermissionResultAllow,
PermissionResultDeny,
ToolPermissionContext,
)
def is_command_authorized(command: str | None) -> bool:
# Replace with your own authorization logic
return False
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)
asyncio.run(main())[!WARNING]
לפקודות שרצות עם
dangerouslyDisableSandbox: Trueיש גישה מלאה למערכת. ודאו שה-handler שלcan_use_toolמאמת את הבקשות האלה בקפידה.אם
permission_modeמוגדר ל-bypassPermissionsו-allowUnsandboxedCommandsמופעל, המודל יכול להריץ באופן אוטונומי פקודות מחוץ לארגז החול בלי בקשות אישור, מלבד הפעולות שאף מצב לא מאשר אוטומטית. השילוב הזה למעשה מאפשר למודל לצאת מבידוד ארגז החול בשקט.
#ראו גם
- סקירת SDK - מושגים כלליים של ה-SDK
- מדריך SDK של TypeScript - תיעוד SDK של TypeScript
- כלים מותאמים אישית - הגדרת כלי MCP בתוך התהליך ש-Claude יכול לקרוא להם
- מדריך CLI - ממשק שורת הפקודה
- תהליכי עבודה נפוצים - מדריכים צעד אחר צעד