Claude Code Agent SDK 从入门到精通,一步到位
上周五晚上11点,我盯着屏幕上的报错信息发呆------团队的项目需要同时处理5个代码仓库的批量重构,手动改?至少一周。用Cursor一个文件一个文件改?也得好几天。
然后我在Claude Code文档里翻到了一个东西:Agent SDK。
说白了,它就是把Claude Code变成了一个你可以用代码调度的"AI员工"。不是在终端里打字聊天的模式,而是写个Python脚本,Claude就自动帮你读文件、改代码、跑测试------全程不需要你盯着。
我花了两天时间把它从安装到跑通生产任务全部搞了一遍,这篇就是我的踩坑实录。
为什么需要Agent SDK?
你可能想问:我直接用Claude Code CLI不就行了?干嘛还要SDK?
区别在于------CLI是你跟Claude对话,SDK是你写程序调度Claude。
举个真实场景:我要给30个微服务统一升级依赖版本。用CLI的话,我得手动进每个目录,告诉Claude该干嘛。用SDK的话,我写个循环脚本,Claude自动遍历所有仓库、改package.json、跑测试、提交代码。
objectivec
CLI模式:你 → 打字 → Claude → 改代码(一次一个项目)
SDK模式:你的脚本 → 循环调用 → Claude → 批量改代码(30个项目同时搞)
这玩意特别适合:
- 批量代码重构(换API、改函数签名)
- 自动化代码审查
- 大规模测试生成
- CI/CD流水线里集成AI能力
环境准备
别急着装,先确认你的环境:
bash
# Python 3.9+ 或者 Node.js 18+
python3 --version # 我是3.11,没问题
# 装SDK
pip install claude-agent-sdk
# 配置API Key
export ANTHROPIC_API_KEY=sk-ant-xxxxx
# 如果你用的是AWS Bedrock
# export CLAUDE_CODE_USE_BEDROCK=1
# 如果你用的是Google Vertex
# export CLAUDE_CODE_USE_VERTEX=1
对了,API Key这块有个坑------Claude的Agent SDK走的是Anthropic原生API,不是Claude.ai的订阅。也就是说你需要去 console.anthropic.com 单独申请API access,Pro订阅用户也得另外搞。我一开始搞混了,浪费了40分钟......
30秒跑通第一个例子
python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="列出当前目录下的所有Python文件,告诉我每个文件有多少行",
options=ClaudeAgentOptions(allowed_tools=["Bash", "Glob"]),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
保存成 test_sdk.py,然后跑:
bash
python test_sdk.py
如果一切正常,你会看到Claude自己调用了Glob工具找文件,然后用Bash统计行数,最后把结果打印出来。
第一次跑的时候我等了大概8秒------因为它要先初始化会话,加载工具列表。后续的调用会快一些。
进阶:让Claude自己改代码
光列文件没意思。来个实际点的------让Claude自动把项目里的print调试语句全换成logging:
python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
prompt = """
扫描当前目录下所有.py文件,把所有的 print() 调试语句替换成 logging.debug()。
规则:
1. 先 import logging(如果文件没有的话)
2. 只替换明显是调试用途的print,比如 print(f"xxx={xxx}") 这种
3. 不要改 print("hello") 这种正常输出的
4. 改完之后跑一下 python -m py_compile 验证语法没问题
"""
async for message in query(
prompt=prompt,
options=ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Edit", "Glob", "Grep", "Bash"],
permission_mode="acceptEdits", # 自动批准文件编辑
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
permission_mode="acceptEdits" 这个参数很关键。没有它的话,每次Claude想改文件都会停下来等你确认------适合手动review,不适合自动化。
说个坑:我一开始把 allowed_tools 写成了 ["Read", "Write"],结果Claude只能读文件和创建文件,不能做精确编辑。它就走了个歪路------把整个文件读出来,全量重写。虽然结果也对,但diff就变得巨难看了。加上 Edit 工具就好了,它会做精确的行级替换。
高级玩法:监控Claude的每一步操作
生产环境用SDK,你肯定想知道Claude到底改了什么。Agent SDK支持Hook机制,每个操作前后都能插回调:
python
import asyncio
from datetime import datetime
from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher
# 记录Claude改了哪些文件的审计日志
async def log_file_change(input_data, tool_use_id, context):
file_path = input_data.get("tool_input", {}).get("file_path", "unknown")
tool_name = input_data.get("tool_name", "unknown")
with open("./audit.log", "a") as f:
f.write(f"{datetime.now()} | {tool_name} | {file_path}\n")
return {} # 返回空字典表示放行
async def main():
async for message in query(
prompt="重构 utils.py,把所有函数加上类型注解",
options=ClaudeAgentOptions(
permission_mode="acceptEdits",
hooks={
"PostToolUse": [
HookMatcher(
matcher="Edit|Write",
hooks=[log_file_change]
)
]
},
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
跑完之后看 audit.log:
javascript
2026-04-29 12:30:15 | Edit | /project/utils.py
2026-04-29 12:30:22 | Edit | /project/utils.py
2026-04-29 12:30:28 | Bash | /bin/bash
清清楚楚,它改了两次utils.py,然后跑了一次bash(应该是做语法检查)。
这个功能我用了之后才发现------Claude有时候会"反复横跳",改了又改回来。不是bug,是它在尝试不同方案。有审计日志就能知道它到底折腾了几个来回。
多Agent协作:主Agent+子Agent
这是我觉得最牛的部分。你可以定义专门的子Agent,比如一个负责代码审查,一个负责写测试:
python
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
options = ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep", "Agent"],
agents={
"code-reviewer": AgentDefinition(
description="Expert code reviewer for quality and security reviews.",
prompt="Analyze code quality and suggest improvements. Focus on security issues.",
tools=["Read", "Glob", "Grep"],
),
"test-writer": AgentDefinition(
description="Unit test generation specialist.",
prompt="Write comprehensive unit tests. Use pytest. Cover edge cases.",
tools=["Read", "Write", "Edit", "Glob", "Grep", "Bash"],
),
},
)
async def main():
async for message in query(
prompt="审查 auth.py 的代码质量,然后为它写完整的单元测试",
options=options,
):
if hasattr(message, "result"):
print(message.result)
实际跑起来你会看到------主Agent先调用 code-reviewer 审查代码,拿到审查结果之后,再调用 test-writer 根据审查意见写测试。整个过程是串行的,有依赖关系。
不过这块有个问题:子Agent之间的上下文共享目前还比较粗糙。code-reviewer发现的问题,test-writer不一定完全理解。Anthropic说后续会优化这块的上下文传递机制。
MCP Server集成
如果你之前用过MCP(Model Context Protocol),那这个功能会让你兴奋------Agent SDK原生支持MCP Server:
python
options = ClaudeAgentOptions(
mcp_servers={
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
)
加上这一段,Claude就多了浏览器控制能力。我测试的时候让它打开一个本地开发的页面,自动填表单、点按钮、验证结果------整个E2E测试流程全自动。
你想想这意味着啥:写个脚本让Claude自己改代码 → 自己跑E2E测试 → 发现问题自己修 → 再测 → 通过了自动commit。闭环了。
会话恢复:多轮对话不丢上下文
普通API调用是无状态的,但Agent SDK支持会话恢复:
python
session_id = None
# 第一轮:先让Claude读代码
async for message in query(
prompt="读一下 auth.py 模块的代码",
options=ClaudeAgentOptions(allowed_tools=["Read", "Glob"]),
):
if isinstance(message, SystemMessage) and message.subtype == "init":
session_id = message.data["session_id"]
# 第二轮:基于之前的上下文继续对话
async for message in query(
prompt="刚才读的那个文件里,找到所有调用它的地方",
options=ClaudeAgentOptions(resume=session_id),
):
if hasattr(message, "result"):
print(message.result)
注意第二轮的prompt------"刚才读的那个文件里"。Claude记得第一轮读过什么。这在做复杂重构的时候特别有用:先让它理解项目结构,再逐步给任务。
常见踩坑FAQ
Q1: 装完SDK跑起来报 ModuleNotFoundError?
检查一下你的Python版本,3.9以下不支持。另外确认pip装到了正确的虚拟环境里------我犯过这个错,装到了系统Python里,结果项目venv里找不到。
bash
which python3 # 确认是你项目的Python
pip install claude-agent-sdk # 在正确的环境里装
Q2: API Key报401但明明是对的?
大概率是你用了Claude.ai的订阅账号密钥,而不是Anthropic API的Key。这俩是不同的东西。去 console.anthropic.com 拿API Key。
Q3: allowed_tools里的工具名大小写有讲究吗?
有!Edit 不是 edit,Glob 不是 glob。写错了不会报错------但Claude就是找不到那个工具,然后会走弯路。正确的大小写参考文档:Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch。
Q4: 跑着跑着突然停了,没有任何输出?
看看是不是token用完了。Anthropic的API是有rate limit的,超了就静默失败。可以在循环里加个try-except捕获异常:
python
try:
async for message in query(...):
...
except Exception as e:
print(f"挂了: {e}")
Q5: 子Agent可以再调用子Agent吗?嵌套层数有限制吗?
目前不建议嵌套超过2层。层数多了之后上下文传递会变得不可靠,而且token消耗是指数级增长的(每层都带着完整上下文)。
最后说几句
Agent SDK目前还是快速迭代阶段,API偶尔会变。我写这篇文章用的版本,可能到你看到的时候已经有些接口不一样了。不过核心概念------query、tools、hooks、agents、session------这些是稳定的。
说实话,用了一周下来,我觉得这玩意最大的价值不是"帮你写代码",而是帮你把重复性的代码任务自动化。一次性改30个仓库的依赖?人工要一周,脚本+Agent SDK大概2小时。这个ROI没法忽略。
如果你也在搞大规模代码维护或者想给CI/CD加AI能力,建议直接上手试试。
如果觉得有帮助,欢迎点赞收藏 ❤️ 更多AI工具实战教程,关注我第一时间获取~