agent-sdk-python
npx skills add https://github.com/dawiddutoit/custom-claude --skill agent-sdk-python
Agent 安装分布
Skill 文档
Agent SDK Integration
Purpose
Build production-ready AI agents using the Agent SDK for Python. This skill provides hands-on workflows for implementing agent features including simple queries, interactive conversations, custom MCP tools, permission control, context loading, and error handling.
Quick Start
Simple one-shot query:
from claude_agent_sdk import query
async for message in query(prompt="What is the capital of France?"):
print(message)
Interactive conversation:
from claude_agent_sdk import ClaudeSDKClient
async with ClaudeSDKClient() as client:
await client.query("Hello!")
async for msg in client.receive_response():
print(msg)
When to Use This Skill
Explicit Triggers:
- “build agent with SDK”
- “use query() function”
- “create ClaudeSDKClient”
- “implement agent workflows”
- “add custom MCP tools”
- “configure agent permissions”
- “load CLAUDE.md context”
- “implement agent hooks”
Implicit Triggers:
- Implementing autonomous agent behavior
- Creating interactive chat agents
- Building batch processing workflows
- Adding custom tools to agents
- Managing agent permissions
- Integrating project context into agents
Debugging Scenarios:
- Agent not connecting to CLI
- Tools not available to agent
- Permission denied errors
- Context not loading correctly
- Hooks not executing
Instructions
Step 1: Choose the Right API Mode
Use query() for:
- Simple one-shot questions
- Batch processing of independent tasks
- Stateless operations
- When all inputs are known upfront
- CI/CD automation scripts
Use ClaudeSDKClient for:
- Interactive conversations with follow-ups
- Chat applications or REPL interfaces
- When you need to send messages based on responses
- Long-running sessions with state management
- Interrupt capabilities
Step 2: Build Simple Agent (query() Function)
Basic implementation:
from claude_agent_sdk import query, ClaudeAgentOptions
async for message in query(
prompt="Analyze this code for security issues",
options=ClaudeAgentOptions(
system_prompt="You are a security expert",
cwd="/path/to/project",
permission_mode="default"
)
):
if hasattr(message, 'content'):
print(message.content)
Key configuration options:
system_prompt: Define agent expertisecwd: Set working directorypermission_mode: Control tool execution (“default”, “acceptEdits”, “bypassPermissions”)model: Choose model (“claude-sonnet-4”, “claude-opus-4”)
Step 3: Build Interactive Agent (ClaudeSDKClient)
Full conversation example:
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
async with ClaudeSDKClient(
options=ClaudeAgentOptions(
system_prompt="You are a helpful coding assistant",
permission_mode="acceptEdits"
)
) as client:
# Send initial message
await client.query("Help me write a Python web server")
# Process response
async for msg in client.receive_response():
print(msg)
# Follow-up question
await client.query("Can you add error handling?")
async for msg in client.receive_response():
print(msg)
See references/implementation-guide.md for detailed patterns.
Step 4: Create Custom MCP Tools
Define tools with @tool decorator:
from claude_agent_sdk import tool, create_sdk_mcp_server
@tool("greet", "Greet a user by name", {"name": str})
async def greet(args):
return {
"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]
}
# Create MCP server
calculator = create_sdk_mcp_server(
name="calculator",
version="1.0.0",
tools=[greet]
)
# Use with agent
options = ClaudeAgentOptions(
mcp_servers={"calc": calculator},
allowed_tools=["greet"]
)
See references/implementation-guide.md for error handling and advanced patterns.
Step 5: Configure Permissions and Tool Access
Fine-grained tool restrictions:
options = ClaudeAgentOptions(
# Allow only specific tools
allowed_tools=["Read", "Grep", "search_code"],
# Block dangerous tools
disallowed_tools=["Bash", "Write"],
# Permission mode
permission_mode="default"
)
Dynamic permission callback:
from claude_agent_sdk import PermissionResultAllow, PermissionResultDeny
async def can_use_tool(tool_name, tool_input, context):
if tool_name in ["Read", "Grep", "Glob"]:
return PermissionResultAllow()
if tool_name == "Bash" and "rm" in str(tool_input):
return PermissionResultDeny(
message="Destructive bash commands are not allowed",
interrupt=True
)
return PermissionResultAllow()
options = ClaudeAgentOptions(can_use_tool=can_use_tool)
See references/implementation-guide.md for complete examples.
Step 6: Load CLAUDE.md Context (setting_sources)
Load project and user instructions:
options = ClaudeAgentOptions(
# Load CLAUDE.md files
setting_sources=["user", "project"],
# user: ~/.claude/CLAUDE.md (user-level instructions)
# project: ./CLAUDE.md or ./.claude/CLAUDE.md (project-level)
cwd="/path/to/project"
)
async for message in query(
prompt="Review this code following project standards",
options=options
):
print(message)
When to use which source:
- “user”: Personal preferences, global workflows
- “project”: Team standards, project architecture
- “local”: Machine-specific settings
- Best practice: Use
["user", "project"]for most workflows
Step 7: Implement Error Handling
Try/catch with specific exceptions:
from claude_agent_sdk import (
ClaudeSDKError,
CLIConnectionError,
CLINotFoundError,
ProcessError
)
try:
async for message in query(prompt="Hello"):
print(message)
except CLINotFoundError:
print("Install CLI: npm install -g claude-code")
except CLIConnectionError as e:
print(f"Connection failed: {e}")
except ProcessError as e:
print(f"Process error (exit {e.exit_code}): {e.stderr}")
See references/implementation-guide.md for retry patterns.
Step 8: Add Hooks for Event-Driven Automation
PreToolUse hook:
from claude_agent_sdk import HookMatcher
async def log_tool_use(input_data, tool_use_id, context):
tool_name = input_data.get("tool", {}).get("name")
print(f"About to use tool: {tool_name}")
return {} # Empty = allow
options = ClaudeAgentOptions(
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash|Write", hooks=[log_tool_use])
]
}
)
See references/implementation-guide.md for PostToolUse and blocking patterns.
Step 9: Implement Agent Delegation
Define custom agents:
from claude_agent_sdk import AgentDefinition
options = ClaudeAgentOptions(
agents={
"python-expert": AgentDefinition(
description="Python code expert",
prompt="Expert Python developer",
tools=["Read", "Write"],
model="opus"
)
}
)
async for message in query(
prompt="@python-expert Review this code",
options=options
):
print(message)
See references/implementation-guide.md for multi-agent patterns.
Supporting Files
References
- api-reference.md – Complete API documentation including all classes, functions, and types
- implementation-guide.md – Detailed patterns for all steps including production examples
Scripts
- verify_sdk.py – Verify Agent SDK installation and configuration
- claude_agent_examples.py – 9 comprehensive examples for claude_agent module
- hook_integration_example.py – Hook patterns and workflows
Expected Outcomes
Successful Agent Implementation:
â
Agent created with proper configuration
â
Tools accessible and executing correctly
â
Permissions enforced as expected
â
Context loaded from CLAUDE.md files
â
Error handling captures all exceptions
â
Hooks executing at correct lifecycle points
Common Issues:
- CLI not found: Install with
npm install -g claude-code - Permission denied: Check
permission_modeandallowed_tools - Tools unavailable: Verify
mcp_serversconfiguration - Context not loading: Check
setting_sourcesandcwdpath
Requirements
Python Dependencies:
pip install claude-agent-sdk
# or
uv pip install claude-agent-sdk
System Requirements:
# Claude CLI
npm install -g claude-code
# Verify installation
claude-code --version
Environment Variables:
# API Key (default)
export ANTHROPIC_API_KEY=your_key
# OR Amazon Bedrock
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
export AWS_REGION=us-east-1
# OR Google Vertex AI
export CLAUDE_CODE_USE_VERTEX=1
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
Integration Points
With Project Patterns
ServiceResult Pattern:
from domain.value_objects import ServiceResult
async def agent_query_service(prompt: str) -> ServiceResult[list]:
try:
messages = []
async for message in query(prompt=prompt):
messages.append(message)
return ServiceResult.success(messages)
except ClaudeSDKError as e:
return ServiceResult.failure(f"Agent query failed: {e}")
Fail-Fast Imports:
# â
CORRECT - Fail fast
from claude_agent_sdk import query, ClaudeAgentOptions
# â WRONG - Optional dependency
try:
from claude_agent_sdk import query
except ImportError:
query = None
See references/implementation-guide.md for dependency injection patterns.
Common Patterns
Code Review Agent
async def code_review_agent(file_path: str):
async for message in query(
prompt=f"Review {file_path} for code quality",
options=ClaudeAgentOptions(
system_prompt="Senior code reviewer",
setting_sources=["project"],
allowed_tools=["Read", "Grep"]
)
):
yield message
Batch Processing
async def batch_analyze(files: list[str]):
results = {}
for file_path in files:
messages = []
async for msg in query(
prompt=f"Analyze {file_path}",
options=ClaudeAgentOptions(allowed_tools=["Read"])
):
messages.append(msg)
results[file_path] = messages
return results
See references/implementation-guide.md for interactive debugging and production patterns.
Red Flags to Avoid
- Using optional imports instead of fail-fast (violates project standards)
- Not handling CLINotFoundError (users get cryptic errors)
- Skipping permission configuration (security risk)
- Not loading project context with setting_sources (ignores team standards)
- Using bypassPermissions in production (dangerous)
- Not implementing error handling (unreliable agents)
- Hardcoding paths instead of using cwd parameter
- Not testing hooks before deployment
- Mixing query() and ClaudeSDKClient in same workflow (confusion)
- Not cleaning up client connections (resource leaks)
Notes
- API Mode Choice: Use
query()for one-shot,ClaudeSDKClientfor interactive - Permission Modes: “default” = ask user, “acceptEdits” = auto-accept, “bypassPermissions” = no checks
- Context Loading: Always use
["user", "project"]for team workflows - Error Handling: Always catch CLINotFoundError and CLIConnectionError
- Hook Matchers: Use regex patterns or None for all tools
- Tool Restrictions: Prefer
allowed_toolsoverdisallowed_toolsfor security - Agent Delegation: Use @agent-name syntax in prompts
- Production: Always implement permission callbacks and logging hooks
See Also
- API Reference – Complete API documentation
- Implementation Guide – Detailed patterns and examples
- Official SDK Documentation – Anthropic’s official docs