Agent SDK智能体开发套件1
1 Agent SDK的定位:从工具到组件
- 它预设开发者是应用构建者,旨在将ClaudeCode的核心能力深度嵌入自有应用中
点击查看代码
# Python
pip install claude-agent-sdk
# TypeScript/Node.js
npm install @anthropic-ai/claude-agent-sdk
2 核心API:query函数
- Agent SDK的入口是query函数,异步消息流。
2.1 Python版本
点击查看代码
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def analyze_code():
options = ClaudeAgentOptions(
max_turns=5,
allowed_tools=["Read", "Grep", "Glob"],
system_prompt="你是一名代码架构分析师",
)
async for message in query(
prompt="分析 src/auth/ 目录的实现架构",
options=options,
):
if message.type == "assistant":
for block in message.content:
if hasattr(block, "text"):
print(block.text, end="", flush=True)
elif message.type == "result":
print(f"\n\n完成。费用:${message.total_cost_usd:.4f}")
asyncio.run(analyze_code())
2.2 TypeScript版本
点击查看代码
import { query, ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
const options: ClaudeAgentOptions = {
maxTurns: 5,
allowedTools: ["Read", "Grep", "Glob"],
systemPrompt: "你是一名代码架构分析师。",
};
async function analyzeCode() {
for await (const message of query({
prompt: "分析 src/auth/ 目录的实现架构",
options,
})) {
if (message.type === "assistant") {
for (const block of message.content) {
if ("text" in block) {
process.stdout.write(block.text);
}
}
} else if (message.type === "result") {
console.log(`\n\n完成。费用:$${message.totalCostUsd}`);
}
}
}
analyzeCode();
3 消息类型:解读Claude的输出流
3.1 system/init——会话初始化
点击查看代码
{
"type": "system",
"subtype": "init",
"session_id": "550e8400-...",
"model": "claude-sonnet4-6",
"tools": [
"Read",
"Grep",
"Glob"
],
"mcp_servers": []
}
3.2 assistant——Claude的响应
点击查看代码
{
"type": "assistant",
"message": {
"role": "assistant",
"content": [
{
"type": "text",
"text": "让我先看看目录结构……"
},
{
"type": "tool_use",
"id": "toolu_xxx",
"name": "Glob",
"input": {
"pattern": "src/auth/**/*"
}
}
]
}
}
3.3 user——工具执行结果
点击查看代码
{
"type": "user",
"message": {
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_xxx",
"content": "src/auth/\n├── login.ts\n├── session.ts\n└── middleware.ts"
}
]
}
}
3.4 result——任务完成
- 以下代码展示了任务完成时的终止消息示例。
点击查看代码
{
"type": "result",
"subtype": "success",
"session_id": "550e8400-...",
"num_turns": 5,
"total_cost_usd": 0.0342,
"duration_ms": 12345,
"duration_api_ms": 10000,
"usage": {
"input_tokens": 5000,
"output_tokens": 1500,
"cache_read_input_tokens": 3000
},
"result": "架构分析:src/auth/ 采用分层设计...",
"structured_output": null
}
- 以下代码展示了一个实用的消息处理模式,用于在异步消息流中收集文本输出、记录工具调用详情并存储会话元数据。
点击查看代码
async def process_query(prompt: str, options: ClaudeAgentOptions) -> dict:
"""处理查询流并聚合结果。"""
# 初始化结果容器
result = {
"text": [],
"tools": [],
"metadata": {},
"error": None,
}
# 异步遍历消息流
async for message in query(prompt=prompt, options=options):
if message.type == "assistant":
# 处理助手响应中的内容块
for block in message.content:
if hasattr(block, "text"):
# 收集文本输出(思考或回答)
result["text"].append(block.text)
elif hasattr(block, "name"):
# 记录工具调用(名称与输入参数)
result["tools"].append({
"tool": block.name,
"input": block.input,
})
elif message.type == "result":
# 提取终止消息中的元数据
result["metadata"] = {
"session_id": message.session_id,
"cost": message.total_cost_usd,
"turns": message.num_turns,
"duration_ms": message.duration_ms,
}
# 检查是否因错误终止
if message.is_error:
result["error"] = message.subtype
return result
4 ClaudeAgentOptions:精细的行为控制
点击查看代码
from claude_agent_sdk import ClaudeAgentOptions
options = ClaudeAgentOptions(
# === 模型与执行控制 ===
model="claude-sonnet-4-6", # 指定使用的模型版本
max_turns=10, # 限制最大交互轮数,防止死循环
max_budget_usd=1.0, # 设置单次任务的费用上限(美元),超出即停止
# === 工具权限管理 ===
# 白名单:仅允许使用列出的工具
allowed_tools=["Read", "Grep", "Glob", "Write"],
# 黑名单:明确禁止使用的工具(优先级通常高于白名单或作为补充)
disallowed_tools=["Bash"],
# === 权限模式 ===
# default: 标准模式,需用户确认危险操作
# acceptEdits: 自动接受文件编辑
# plan: 仅规划不执行
# bypassPermissions: 跳过所有确认(高风险,仅限受信任环境)
permission_mode="default",
# === 提示工程 ===
system_prompt="你是一名高级代码审查员", # 设定核心系统指令
append_system_prompt="务必检查SQL注入漏洞", # 在核心指令后追加特定要求
# === 工作环境配置 ===
cwd="path/to/project", # 设置 Agent 的工作目录
env={"PROJECT_NAME": "MyApp"}, # 注入自定义环境变量
# === 会话管理 ===
resume="session-id-to-resume", # 从指定的 session_id 恢复上下文
no_session_persistence=False, # 若为 True,则任务结束后不保存会话历史
# === 结构化输出 ===
# 强制模型输出符合特定 JSON Schema 格式的数据
output_format={
"type": "json_schema",
"schema": my_schema,
},
# === MCP 集成 ===
# 动态启动并连接外部 MCP 服务器
mcp_servers=[
{
"name": "db",
"command": "python",
"args": ["./db_server.py"],
}
],
)
4.1 权限模式详解
- 权限模式是Agent SDK应用安全防线的核心。
4.2 工具权限的模式匹配
- allowed_tools支持与Headless CLI相同的模式匹配语法。
点击查看代码
options = ClaudeAgentOptions(
allowed_tools=[
"Read",
"Grep",
"Glob",
"Bash(git diff *)", # 仅允许执行 git diff 命令
"Bash(npm test *)", # 仅允许执行 npm test 命令
"mcp__database__query", # 仅允许使用 MCP 数据库查询工具
],
)
5 会话管理:跨调用的上下文延续
5.1 基于session_id的会话延续
点击查看代码
# === 第一次调用:分析问题 ===
session_id = None
async for message in query(prompt="分析 src/auth 的安全问题", options=options):
if message.type == "system" and message.subtype == "init":
# 【关键】获取会话 ID,用于后续恢复上下文
session_id = message.session_id
if message.type == "result":
print(message.result)
# === 第二次调用:在上一轮上下文的基础上继续深入 ===
resume_options = ClaudeAgentOptions(**options.__dict__, resume=session_id)
async for message in query(
prompt="重点分析你发现的第一个SQL注入风险",
options=resume_options,
):
if message.type == "result":
print(message.result)
5.2 会话分叉
点击查看代码
# === 基于同一个分析结果,探索不同的方向 ===
# 创建分叉配置:复用原会话状态,但开启新分支
options_fork = ClaudeAgentOptions(
**options.__dict__,
resume=session_id,
fork_session=True,
)
# --- 方向 A:探讨微服务重构方案 ---
async for message in query(
prompt="如果重构为微服务架构,需要修改哪些部分?",
options=options_fork,
):
...
# --- 方向 B:探讨现有架构的安全加固方案 ---
# 基于同一个 session_id 再次分叉,确保两个方向完全独立
async for message in query(
prompt="如果保持现有架构,应如何加固安全性?",
options=options_fork,
):
...
6 自定义工具:扩展Claude的能力边界
- Agent SDK中的自定义工具实质上是进程内MCP服务器。
6.1 使用@tool装饰器定义工具
点击查看代码
import json
from claude_agent_sdk import tool, create_sdk_mcp_server
# === 工具 1:数据库查询(只读) ===
@tool(
name="query_database",
description="Execute a read-only SQL query on the application database",
parameters={
"query": str,
"limit": int,
},
)
async def query_database(args):
sql = args["query"]
limit = args.get("limit", 100)
# 【安全关键】强制校验:仅允许 SELECT 语句
if not sql.strip().upper().startswith("SELECT"):
return {
"content": [{"type": "text", "text": "Error: Only SELECT queries allowed"}],
"isError": True,
}
results = await db.execute(f"{sql} LIMIT {limit}")
return {
"content": [{"type": "text", "text": json.dumps(results, indent=2)}],
}
# === 工具 2:发送通知 ===
@tool(
name="send_notification",
description="Send a notification to the team Slack channel",
parameters={
"channel": str,
"message": str,
},
)
async def send_notification(args):
await slack.post_message(args["channel"], args["message"])
return {
"content": [{"type": "text", "text": f"Notification sent to #{args['channel']}"}],
}
# === 创建 MCP 服务器承载这些工具 ===
tools_server = create_sdk_mcp_server(
name="app-tools",
version="1.0.0",
tools=[query_database, send_notification],
)
6.2 在Agent配置中注册并启用自定义工具
点击查看代码
options = ClaudeAgentOptions(
mcp_servers={
"app-tools": tools_server,
},
allowed_tools=[
# 内置工具
"Read",
"Grep",
"Glob",
# 自定义 MCP 工具
"mcp__app-tools__query_database",
"mcp__app-tools__send_notification",
],
)
6.3 使用Pydantic模型进行参数验证
点击查看代码
from pydantic import BaseModel, Field
from claude_agent_sdk import tool
# === 定义结构化参数模型 ===
class DatabaseQueryParams(BaseModel):
table: str = Field(
...,
description="Table name",
)
columns: list[str] = Field(
default=["*"],
description="Columns to select",
)
where: str | None = Field(
default=None,
description="SQL WHERE clause condition (optional)",
)
limit: int = Field(
default=100,
ge=1,
le=1000,
description="Maximum number of rows to return",
)
# === 将模型直接作为工具参数定义 ===
@tool(
name="safe_query",
description="Execute a safe, parameterized database query",
parameters=DatabaseQueryParams,
)
async def safe_query(args: DatabaseQueryParams):
# args 已经通过 Pydantic 模型验证,类型安全
...

浙公网安备 33010602011771号