anthropics/claude-agent-sdk-python

GitHub: anthropics/claude-agent-sdk-python

Anthropic 官方 Python SDK,支持以编程方式调用 Claude Code 的完整工具链、自定义进程内 MCP 工具和 Hook 拦截机制,用于构建代码自动化和 AI 辅助开发工作流。

Stars: 5964 | Forks: 804

# Claude Agent SDK for Python Claude Agent 的 Python SDK。更多信息请参阅 [Claude Agent SDK 文档](https://platform.claude.com/docs/en/agent-sdk/python)。 ## 安装 ``` pip install claude-agent-sdk ``` **前置条件:** - Python 3.10+ **注意:** Claude Code CLI 会自动与此包捆绑在一起 —— 无需单独安装!SDK 将默认使用捆绑的 CLI。如果您更喜欢使用系统范围的安装或特定版本,您可以: - 单独安装 Claude Code:`curl -fsSL https://claude.ai/install.sh | bash` - 指定自定义路径:`ClaudeAgentOptions(cli_path="/path/to/claude")` ## 快速开始 ``` import anyio from claude_agent_sdk import query async def main(): async for message in query(prompt="What is 2 + 2?"): print(message) anyio.run(main) ``` ## 基本用法:query() `query()` 是一个用于查询 Claude code 的异步函数。它返回一个响应消息的 `AsyncIterator`。参见 [src/claude_agent_sdk/query.py](src/claude_agent_sdk/query.py)。 ``` from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock # Simple query async for message in query(prompt="Hello Claude"): if isinstance(message, AssistantMessage): for block in message.content: if isinstance(block, TextBlock): print(block.text) # With options options = ClaudeAgentOptions( system_prompt="You are a helpful assistant", max_turns=1 ) async for message in query(prompt="Tell me a joke", options=options): print(message) ``` ### 使用工具 默认情况下,Claude 可以访问完整的 [Claude Code 工具集](https://code.claude.com/docs/en/settings#tools-available-to-claude)(Read、Write、Edit、Bash 等)。`allowed_tools` 是一个权限允许列表:列出的工具会自动批准,未列出的工具则根据 `permission_mode` 和 `can_use_tool` 进行决策。它不会从 Claude 的工具集中移除工具。要阻止特定工具,请使用 `disallowed_tools`。有关完整的评估顺序,请参阅 [权限指南](https://platform.claude.com/docs/en/agent-sdk/permissions)。 ``` options = ClaudeAgentOptions( allowed_tools=["Read", "Write", "Bash"], # auto-approve these tools permission_mode='acceptEdits' # auto-accept file edits ) async for message in query( prompt="Create a hello.py file", options=options ): # Process tool use and results pass ``` ### 工作目录 ``` from pathlib import Path options = ClaudeAgentOptions( cwd="/path/to/project" # or Path("/path/to/project") ) ``` ## ClaudeSDKClient `ClaudeSDKClient` 支持与 Claude Code 进行双向、交互式对话。参见 [src/claude_agent_sdk/client.py](src/claude_agent_sdk/client.py)。 与 `query()` 不同,`ClaudeSDKClient` 额外支持**自定义工具**和 **hooks**,这两者都可以定义为 Python 函数。 ### 自定义工具(作为进程内 SDK MCP 服务器) **自定义工具**是一个 Python 函数,您可以将其提供给 Claude,供 Claude 根据需要调用。 自定义工具是在 Python 应用程序中直接运行的进程内 MCP 服务器,无需像常规 MCP 服务器那样使用单独的进程。 有关端到端示例,请参阅 [MCP Calculator](examples/mcp_calculator.py)。 #### 创建简单工具 ``` from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions, ClaudeSDKClient # Define a tool using the @tool decorator @tool("greet", "Greet a user", {"name": str}) async def greet_user(args): return { "content": [ {"type": "text", "text": f"Hello, {args['name']}!"} ] } # Create an SDK MCP server server = create_sdk_mcp_server( name="my-tools", version="1.0.0", tools=[greet_user] ) # Use it with Claude. allowed_tools pre-approves the tool so it runs # without a permission prompt; it does not control tool availability. options = ClaudeAgentOptions( mcp_servers={"tools": server}, allowed_tools=["mcp__tools__greet"] ) async with ClaudeSDKClient(options=options) as client: await client.query("Greet Alice") # Extract and print response async for msg in client.receive_response(): print(msg) ``` #### 相比外部 MCP 服务器的优势 - **无子进程管理** —— 在与应用程序相同的进程中运行 - **更好的性能** —— 工具调用无 IPC 开销 - **更简单的部署** —— 单个 Python 进程而非多个 - **更轻松的调试** —— 所有代码在同一进程中运行 - **类型安全** —— 带有类型提示的直接 Python 函数调用 #### 从外部服务器迁移 ``` # BEFORE: External MCP server (separate process) options = ClaudeAgentOptions( mcp_servers={ "calculator": { "type": "stdio", "command": "python", "args": ["-m", "calculator_server"] } } ) # AFTER: SDK MCP server (in-process) from my_tools import add, subtract # Your tool functions calculator = create_sdk_mcp_server( name="calculator", tools=[add, subtract] ) options = ClaudeAgentOptions( mcp_servers={"calculator": calculator} ) ``` #### 混合服务器支持 您可以同时使用 SDK 和外部 MCP 服务器: ``` options = ClaudeAgentOptions( mcp_servers={ "internal": sdk_server, # In-process SDK server "external": { # External subprocess server "type": "stdio", "command": "external-server" } } ) ``` ### Hooks **Hook** 是一个 Python 函数,Claude Code _应用程序_(而非 Claude)在 Claude agent 循环的特定点调用。Hooks 可以为 Claude 提供确定性处理和自动化反馈。在 [使用 hooks 拦截和控制 agent 行为](https://platform.claude.com/docs/en/agent-sdk/hooks) 中了解更多信息。 更多示例请参见 examples/hooks.py。 #### 示例 ``` from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, HookMatcher async def check_bash_command(input_data, tool_use_id, context): tool_name = input_data["tool_name"] tool_input = input_data["tool_input"] if tool_name != "Bash": return {} command = tool_input.get("command", "") block_patterns = ["foo.sh"] for pattern in block_patterns: if pattern in command: return { "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": f"Command contains invalid pattern: {pattern}", } } return {} options = ClaudeAgentOptions( allowed_tools=["Bash"], hooks={ "PreToolUse": [ HookMatcher(matcher="Bash", hooks=[check_bash_command]), ], } ) async with ClaudeSDKClient(options=options) as client: # Test 1: Command with forbidden pattern (will be blocked) await client.query("Run the bash command: ./foo.sh --help") async for msg in client.receive_response(): print(msg) print("\n" + "=" * 50 + "\n") # Test 2: Safe command that should work await client.query("Run the bash command: echo 'Hello from hooks example!'") async for msg in client.receive_response(): print(msg) ``` ## 类型 完整类型定义请参见 [src/claude_agent_sdk/types.py](src/claude_agent_sdk/types.py): - `ClaudeAgentOptions` - 配置选项 - `AssistantMessage`, `UserMessage`, `SystemMessage`, `ResultMessage` - 消息类型 - `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - 内容块 ## 错误处理 ``` from claude_agent_sdk import ( ClaudeSDKError, # Base error CLINotFoundError, # Claude Code not installed CLIConnectionError, # Connection issues ProcessError, # Process failed CLIJSONDecodeError, # JSON parsing issues ) try: async for message in query(prompt="Hello"): pass except CLINotFoundError: print("Please install Claude Code") 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}") ``` 所有错误类型请参见 [src/claude_agent_sdk/_errors.py](src/claude_agent_sdk/_errors.py)。 ## 可用工具 完整可用工具列表请参见 [Claude Code 文档](https://code.claude.com/docs/en/settings#tools-available-to-claude)。 ## 示例 完整工作示例请参见 [examples/quick_start.py](examples/quick_start.py)。 有关涉及 `ClaudeSDKClient` 的综合示例,请参见 [examples/streaming_mode.py](examples/streaming_mode.py)。您甚至可以在 IPython 中运行 [examples/streaming_mode_ipython.py](examples/streaming_mode_ipython.py) 的交互式示例。 ## 从 Claude Code SDK 迁移 如果您正在从 Claude Code SDK(版本 < 0.1.0)升级,请参阅 [CHANGELOG.md](CHANGELOG.md#010) 了解破坏性更改和新功能的详细信息,包括: - `ClaudeCodeOptions` → `ClaudeAgentOptions` 重命名 - 合并的 system prompt 配置 - 设置隔离和显式控制 - 新的编程式 subagents 和 session forking 功能 ## 开发 如果您要为此项目做出贡献,请运行初始设置脚本来安装 git hooks: ``` ./scripts/initial-setup.sh ``` 这将安装一个 pre-push hook,在推送前运行 lint 检查,与 CI 工作流保持一致。要临时跳过该 hook,请使用 `git push --no-verify`。 ### 本地构建 Wheels 要使用捆绑的 Claude Code CLI 构建 wheels: ``` # Install build dependencies pip install build twine # Build wheel with bundled CLI python scripts/build_wheel.py # Build with specific version python scripts/build_wheel.py --version 0.1.4 # Build with specific CLI version python scripts/build_wheel.py --cli-version 2.0.0 # Clean bundled CLI after building python scripts/build_wheel.py --clean # Skip CLI download (use existing) python scripts/build_wheel.py --skip-download ``` 构建脚本将: 1. 下载适用于您平台的 Claude Code CLI 2. 将其捆绑在 wheel 中 3. 构建 wheel 和源分发包 4. 使用 twine 检查包 所有选项请参见 `python scripts/build_wheel.py --help`。 ### 发布工作流 该包通过 `.github/workflows/publish.yml` 中的 GitHub Actions 工作流发布到 PyPI。要创建新版本: 1. **触发工作流**:在 Actions 选项卡中手动触发,并提供两个输入参数: - `version`:要发布的包版本(例如 `0.1.5`) - `claude_code_version`:要捆绑的 Claude Code CLI 版本(例如 `2.0.0` 或 `latest`) 2. **工作流将**: - 为 macOS、Linux 和 Windows 构建特定平台的 wheels - 在每个 wheel 中捆绑指定的 Claude Code CLI 版本 - 构建源分发包 - 将所有构件发布到 PyPI - 创建带有版本更新的发布分支 - 向 main 分支开启一个 PR,包含: - 更新的 `pyproject.toml` 版本 - 更新的 `src/claude_agent_sdk/_version.py` - 更新的 `src/claude_agent_sdk/_cli_version.py`(包含捆绑的 CLI 版本) - 自动生成的 `CHANGELOG.md` 条目 3. **审查并合并**发布 PR,以使用新版本信息更新 main 该工作流分别跟踪包版本和捆绑的 CLI 版本,允许您在无需代码更改的情况下发布带有更新 CLI 的新包版本。 ## 许可证和条款 本 SDK 的使用受 Anthropic 的 [商业服务条款](https://www.anthropic.com/legal/commercial-terms) 管辖,包括当您使用它为您自己的客户和最终用户提供产品和服务时,除非特定组件或依赖项由该组件的 LICENSE 文件中指示的不同许可证覆盖。
标签:Agent SDK, AI 编程, Anthropic, Apex, API 封装, CIS基准, Claude, Claude Code, CLI 工具, CVE检测, DLL 劫持, Function Calling, LLM 开发工具, NLP, pip, Python 3.10+, Python SDK, RPA, 代码生成, 大语言模型, 工具调用, 开发工具包, 异步编程, 数字取证, 文档结构分析, 机器人流程自动化, 机器学习, 深度学习, 渗透测试工具, 自动化脚本, 逆向工具