Claude Agent SDK实战指南:Python几行代码搭一个AI Agent

Claude Agent SDK实战指南:Python几行代码搭一个AI Agent
张文保 更新 25 分钟阅读 4,331 阅读
本文目录
  1. Agent SDK到底解决了什么问题?
  2. 5分钟把环境搭起来需要什么?
  3. query()和ClaudeSDKClient到底该用哪个?
  4. 一次性任务,用query()
  5. 多轮对话,用ClaudeSDKClient
  6. 怎么给Agent扩展工具能力?
  7. 路子一:挂外部MCP Server
  8. 路子二:用@tool装饰器写自己的工具
  9. 怎么把Agent关进笼子,不让它乱来?
  10. 一个能跑的代码审查Agent长什么样?
  11. 让Agent再去派活给子Agent
  12. 上生产之前还要顾及什么?
  13. 什么时候反而不该用Agent SDK?
  14. 常见问题解答
  15. 装了Python为什么还要装Node.js?
  16. query()和ClaudeSDKClient怎么选?
  17. permission_mode到底有哪几种?
  18. 自定义工具授权不上是什么原因?
  19. 怎么防止Agent烧钱或者跑飞?
  20. Agent SDK支持Pro/Max订阅额度吗?
  21. 权威参考资料

一句话结论:Claude Agent SDK把Claude Code内置的那套工具(读文件、写文件、跑命令、搜代码……)直接打包成Python接口,让你不用再手写那个折腾人的“调用工具—拿结果—再调用”的循环。一次性任务用query(),几行代码就能起一个会自己读代码、改bug的Agent;要多轮对话、跨轮记忆就用ClaudeSDKClient。安全这块靠三层闸门兜底:工具白名单、权限模式、Hooks运行时拦截,外加沙箱隔离。这篇按官方最新接口,把环境搭建、两种入口的取舍、工具扩展、权限管控、一个能跑的实战项目和上生产的注意事项一次讲透。

如果你试过自己用大模型API搭一个能干活的Agent,大概率被同一件事折磨过:模型说“我要读一下这个文件”,你得接住这个请求、真去把文件读出来、再把内容塞回对话里,然后模型说“我再跑个命令”,你又得接一遍……这个来回的编排循环,写起来琐碎、容易出错,还得自己处理超时、报错、权限。Agent SDK做的事,就是把这套循环连同一整套现成工具,整个替你包好。

它和直接调Claude的消息API不是一回事。消息API给你的是“一次对话”,工具调用的编排得你自己写;Agent SDK给你的是“一个会自己用工具完成任务的智能体”。想从底层理解这个循环到底怎么转,可以先看保哥在手写一个Claude Code那篇里从零拆的版本,再回来看SDK会更透。下面从它到底解决什么问题讲起。

Agent SDK到底解决了什么问题?

核心就一句话:它把Claude Code那套经过实战打磨的内置工具,直接暴露成了可编程接口。你不用再自己定义“读文件工具长什么样、怎么执行、出错怎么办”,这些SDK都内建好了,而且和命令行版Claude Code用的是同一套实现。

内置工具大致这几类,覆盖了日常开发的绝大多数动作:

工具能干什么典型场景
Read读取任意文件代码审查、读配置
Write新建文件生成报告、脚手架
Edit精确改已有文件修bug、重构
Bash执行终端命令跑测试、git操作
Glob按模式找文件找全部.py文件
Grep正则搜内容找TODO、找调用点
WebSearch搜互联网查文档、找最新信息
WebFetch抓网页内容读在线API文档

有了这些,你给一句目标,Agent就能自己规划:先Glob找到相关文件,再Read读进来,分析完用Edit改掉,最后Bash跑测试验证。整个过程不用你插手编排,这正是它比裸用消息API省事的地方。

5分钟把环境搭起来需要什么?

前置条件不多,但有一个容易被忽略:除了Python,你还得装Node.js。原因后面会讲。

  • Python 3.10以上(建议3.12,更稳);
  • Node.js 18以上
  • 一个Anthropic API Key

安装包名是claude-agent-sdk,用pip或uv都行:

pip install claude-agent-sdk
# 或者用 uv
uv add claude-agent-sdk

然后把API Key配成环境变量:

export ANTHROPIC_API_KEY=你的key

如果公司走云厂商的账单,SDK也支持三家企业云认证,各自一个环境变量切过去即可——走AWS Bedrock用CLAUDE_CODE_USE_BEDROCK=1、走Google Vertex用CLAUDE_CODE_USE_VERTEX=1、走Azure用CLAUDE_CODE_USE_FOUNDRY=1。对有合规要求、必须让数据走自家云的出海团队,这点很实用。

这里要注意一个常见误区:为什么装了Python还非要Node.js?因为Agent SDK底层其实是去驱动Claude Code的命令行程序(那是个Node.js应用),Python这层是个封装。Node没装好,运行时会直接抛CLINotFoundError。这也是新手第一次跑不通最常见的原因。

query()和ClaudeSDKClient到底该用哪个?

SDK给了两个入口,选错了会很别扭,先把区别讲清楚。

一次性任务,用query()

query()适合“给个目标,让它跑完就完事”的场景。它返回一个异步迭代器,你边跑边收到一条条消息。最精简的版本就三行:

from claude_agent_sdk import query

async for message in query(prompt="找出并修复 auth.py 里的 bug"):
    print(message)

真实用的时候,一般会配上ClaudeAgentOptions来限定它能用哪些工具、用什么权限模式,并区分处理“助手消息”和“最终结果”:

from claude_agent_sdk import (
    query, ClaudeAgentOptions, AssistantMessage, ResultMessage,
)

async for message in query(
    prompt="审查 utils.py,找出潜在 bug 并修复",
    options=ClaudeAgentOptions(
        allowed_tools=["Read", "Edit", "Glob"],
        permission_mode="acceptEdits",
    ),
):
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if hasattr(block, "text"):
                print(block.text)
    elif isinstance(message, ResultMessage):
        print(f"耗时 {message.duration_ms}ms,成本 {message.total_cost_usd} 美元")

query()的局限也很明确:它是无状态的,每次调用都开一个新会话,跑完不记得上次干了什么。要让它续上,得显式传continue_conversation=True或者resume一个会话ID。

多轮对话,用ClaudeSDKClient

如果你要做的是“先让它读模块,再基于读到的内容追问下一步”,这种跨轮依赖的活儿就该用ClaudeSDKClient。它维持同一个会话,第二轮能自然用上第一轮的上下文,还支持中途打断:

from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions

async with ClaudeSDKClient(options=options) as client:
    await client.query("读一下认证模块,告诉我它怎么校验 token")
    async for message in client.receive_response():
        ...  # 处理第一轮

    await client.query("现在找出所有调用它的地方")
    async for message in client.receive_response():
        ...  # 第二轮能用上第一轮读到的信息

一个简单的判断口诀:单次跑完即走,用query();要连续对话、跨轮记上下文,用ClaudeSDKClient。下面这张表把差异摆清楚:

特性query()ClaudeSDKClient
会话每次新建复用同一个
对话轮次单次多次
连接管理自动手动控制
中途打断不支持支持
续接上下文需手动传参天然支持

怎么给Agent扩展工具能力?

内置工具够用一大半,但碰到“调我们内部的运维接口”“开浏览器截个图”这类需求,就得自己加工具了。有两条路。

路子一:挂外部MCP Server

MCP(模型上下文协议)是连接外部工具的标准。社区已经有几百个现成的MCP Server,挂上就能用。比如要做浏览器自动化,挂个Playwright的MCP:

async for message in query(
    prompt="打开 zhangwenbao.com 并截一张图",
    options=ClaudeAgentOptions(
        mcp_servers={
            "playwright": {
                "command": "npx",
                "args": ["@playwright/mcp@latest"],
            }
        }
    ),
):
    ...

MCP怎么配、有哪些坑,保哥在Claude Code MCP配置指南里专门讲过,要接外部服务的可以对照着配。

路子二:用@tool装饰器写自己的工具

如果只是三五个小工具,不必单独起一个MCP Server,用@tool装饰器在Python里直接定义更省事。定义完用create_sdk_mcp_server()打个包就能挂上:

from claude_agent_sdk import tool, create_sdk_mcp_server

@tool("check_service_health", "检查某个服务是否在运行", {"service_name": str})
async def check_health(args):
    service = args["service_name"]
    return {"content": [{"type": "text", "text": f"服务 {service} 运行正常"}]}

ops_server = create_sdk_mcp_server(
    name="ops-tools",
    version="1.0.0",
    tools=[check_health],
)

options = ClaudeAgentOptions(
    mcp_servers={"ops": ops_server},
    allowed_tools=["mcp__ops__check_service_health"],
)

注意自定义工具在白名单里的名字有固定格式:mcp__服务名__工具名,中间是双下划线。这个命名规则写错了,工具就授权不上,是个高频踩坑点。选哪条路?三五个工具用@tool,工具多到十几个、或者要跨项目复用,就单独起MCP Server。

怎么把Agent关进笼子,不让它乱来?

让Agent自己跑命令、改文件,最让人心里没底的就是“它会不会手一抖把不该删的删了”。SDK的安全设计是三层防御,逐层收紧。

第一层,allowed_tools工具白名单。只把它该用的工具放进来。做代码审查就只给只读的Read、Glob、Grep,根本不给它Write和Bash,从源头上断了它乱写乱跑的可能。

第二层,permission_mode权限模式。这里要专门纠正一个很多教程的疏漏——权限模式其实有五种,不止常说的那几个。官方当前的完整取值是:

模式行为适用场景
default标准权限行为,按需询问常规开发
acceptEdits自动批准文件编辑,其他仍询问信任的开发环境
plan规划模式,只读不动手先让它出方案再决定
dontAsk没预先授权的直接拒绝,不弹问无人值守的CI/CD
bypassPermissions跳过所有权限检查仅限沙箱容器内

很多攻略漏掉了plan这个规划模式,但它其实非常好用:让Agent只读代码、只产出一份改动计划而不真动手,你看过没问题再放它执行。对不敢一上来就放权的场景,这是个稳妥的过渡档。生产环境的无人值守任务,建议用dontAsk;而bypassPermissions这种全放开的模式,只应该在隔离的沙箱里用。

第三层,Hooks运行时拦截。白名单和权限模式是“事前”管控,Hooks是“运行时”的最后一道闸:每次工具真正执行前后插一段你的代码,可以记审计日志,也可以临场拦截危险操作。比如禁止它碰系统目录:

from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher

async def block_system_files(input_data, tool_use_id, context):
    path = input_data.get("tool_input", {}).get("file_path", "")
    if path.startswith("/etc/") or path.startswith("/system/"):
        return {"decision": "deny", "message": "禁止修改系统文件"}
    return {"decision": "allow"}

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Edit", "Glob", "Grep"],
    permission_mode="acceptEdits",
    hooks={
        "PreToolUse": [HookMatcher(matcher="Edit|Write", hooks=[block_system_files])],
    },
)

Hooks这套机制和命令行版Claude Code是同源的,配置思路完全一致,吃不准的可以参考Claude Code Hooks完全指南。三层叠起来用,才算把Agent真正关进了笼子。

一个能跑的代码审查Agent长什么样?

把前面的东西串起来,下面是一个能直接跑的代码审查Agent的骨架。它读指定目录的代码,按一份清单找问题,关键是加了两道硬约束:最多30轮、预算上限2美元,防止它跑飞或烧钱。

import asyncio
import sys
from claude_agent_sdk import (
    query, ClaudeAgentOptions, AssistantMessage,
)

REVIEW_PROMPT = """你是一位资深代码审查员,请按以下清单分析代码:
1. 安全:SQL注入、XSS、命令注入、硬编码密钥
2. 错误处理:未捕获的异常
3. 性能:O(n^2) 循环等
4. 质量:死代码、重复逻辑
把发现写成一份 Markdown 报告。"""

async def main():
    target = sys.argv[1] if len(sys.argv) > 1 else "."
    async for message in query(
        prompt=REVIEW_PROMPT,
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Glob", "Grep", "Write"],
            permission_mode="acceptEdits",
            cwd=target,
            max_turns=30,
            max_budget_usd=2.0,
        ),
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text)

asyncio.run(main())
# 运行: python code_reviewer.py ./src

这个例子里有两个参数值得单拎出来记:max_turns限制它最多自主跑多少轮,max_budget_usd是硬性的成本天花板,到了就停。这俩是上生产前的“安全带”,强烈建议每个Agent都系上。

让Agent再去派活给子Agent

SDK还支持子Agent——主Agent可以把任务拆给专精的子Agent去做,每个子Agent还能有自己独立的工具白名单。比如一个审查任务,派一个专查安全、一个专查代码风格:

from claude_agent_sdk import ClaudeAgentOptions, AgentDefinition

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Glob", "Grep", "Agent"],
    agents={
        "security-auditor": AgentDefinition(
            description="安全审查专家",
            prompt="专找安全问题:注入、XSS、密钥泄露……",
            tools=["Read", "Glob", "Grep"],
        ),
        "style-checker": AgentDefinition(
            description="代码质量审查",
            prompt="检查命名规范、重复逻辑、死代码……",
            tools=["Read", "Glob", "Grep"],
        ),
    },
)

子Agent的好处是职责隔离、各管一摊,复杂任务拆开后更可控,每个子Agent的权限也能单独收紧。

上生产之前还要顾及什么?

能跑通和能上生产是两回事。三件事必须想清楚。

第一,成本控制。除了上面的max_budget_usdmax_turns,模型选择是最大的省钱杠杆——简单任务用Sonnet,比Opus便宜得多;只有需要复杂推理的硬骨头才上Opus。截至2026年中,最新的旗舰是Opus 4.8(源文里写的Opus 4.7已经被它接替),日常活儿真没必要全程顶配。Agent这种会连续自主调用工具的玩法,最容易在不知不觉中烧掉额度,关于用量和限流的账怎么算,可以看Claude速率限制详解

第二,错误处理。生产代码得接住SDK会抛的几类异常:Node没装好的CLINotFoundError、底层进程出错的ProcessError、以及兜底的ClaudeSDKError。该重试的重试,该告警的告警,别让一个异常把整条流水线带崩:

from claude_agent_sdk import (
    query, ClaudeSDKError, CLINotFoundError, ProcessError, ResultMessage,
)

try:
    async for message in query(prompt="修复这个 bug", options=options):
        if isinstance(message, ResultMessage) and message.is_error:
            print(f"Agent 出错:{message.result}")
            break
except CLINotFoundError:
    print("没找到 Claude Code 命令行,请先装好 Node.js 18+")
except ProcessError as e:
    print(f"底层进程失败(exit {e.exit_code}):{e.stderr}")
except ClaudeSDKError as e:
    print(f"SDK 错误:{e}")

第三,沙箱隔离。真要让Agent全放开权限干活,务必把它关进容器里跑。SDK提供了sandbox配置,配合容器,bypassPermissions带来的风险才被锁在隔离环境里——它再怎么折腾,也出不了那个沙箱。生产环境放权的前提,永远是先隔离再放开,顺序不能反。

什么时候反而不该用Agent SDK?

它不是万能锤。下面几种情况,用别的更合适:

  • 纯问答、不需要工具。只是要个文本回答,直接用Anthropic的消息SDK更轻,没必要拉起一整套Agent运行时。
  • 要跨多家模型。Agent SDK只支持Claude。需要在不同厂商模型间切换的,用LangChain、LlamaIndex这类更中立的框架。
  • 极高并发。SDK每个query()底层会拉起一个命令行进程,高并发下开销大,这种场景自己基于消息SDK写tool loop更划算。
  • 订阅计费的个人用户。Agent SDK只认API Key计费,用不上Pro/Max的订阅额度。如果你就是个人交互式开发,直接用命令行版Claude Code更对路。

一句话总结取舍:要的是“一个会自己用工具干活、且基于Claude、走API计费”的智能体,Agent SDK是最省心的选择;偏离这三个条件越多,越该考虑别的方案。

常见问题解答

装了Python为什么还要装Node.js?

因为Agent SDK底层是驱动Claude Code的命令行程序,那是个Node.js应用,Python这层只是封装。Node没装好运行时会抛CLINotFoundError,这是新手最常见的报错。版本要求是Node.js 18以上。

query()和ClaudeSDKClient怎么选?

单次任务、跑完即走用query();需要多轮对话、跨轮记上下文、或者中途要打断,用ClaudeSDKClient。前者无状态每次新建会话,后者复用同一会话天然续接上下文。

permission_mode到底有哪几种?

官方当前是五种:default、acceptEdits、plan、dontAsk、bypassPermissions。很多教程漏掉了plan规划模式(只读出方案不动手)。无人值守用dontAsk,全放开的bypassPermissions只应在沙箱容器内用。

自定义工具授权不上是什么原因?

多半是白名单里的工具名写错了。自定义工具的名字格式固定为mcp__服务名__工具名,中间是双下划线。这个格式写错,工具就挂不上,是高频踩坑点。

怎么防止Agent烧钱或者跑飞?

两道硬约束:max_turns限制最多自主跑多少轮,max_budget_usd设成本上限到了就停。再配合默认用Sonnet、复杂任务才上Opus的模型策略,成本就基本可控了。

Agent SDK支持Pro/Max订阅额度吗?

不支持,它只认API Key计费。个人订阅用户想交互式开发,直接用命令行版Claude Code更合适;要做自动化、可编程的Agent,才用SDK配API Key。

权威参考资料

FAQPage + Article AI 引用友好版

TL;DR · 60–80 字摘要 · 适用 ChatGPT / Perplexity / Gemini / 文心 引用

不想再手写那套调用工具、拿结果、再调用的循环?Claude Agent SDK把Claude Code内置工具直接做成Python接口。本文按官方最新接口讲清query与ClaudeSDKClient取舍、MCP与@tool扩展工具、三层权限与沙箱兜底,附一个能跑的代码审查Agent。

关键实体 · Key Entities

  • AI编程
  • Python
  • Anthropic SDK
  • Agent开发
  • Claude Agent SDK
  • AI编程与工具链

引用元数据 · Citation Metadata

title:       Claude Agent SDK实战指南:Python几行代码搭一个AI Agent
author:      张文保 (Paul Zhang) — PatPat SEO 经理
url:         https://zhangwenbao.com/claude-agent-sdk-guide.html
published:   2026-04-17
modified:    2026-06-03
source-type: First-hand expert commentary
language:    zh-CN
license:     CC BY-NC-SA 4.0 (要求保留原文链接与作者归属)
分享到
标签
版权声明

本文标题:《Claude Agent SDK实战指南:Python几行代码搭一个AI Agent》

本文链接:https://zhangwenbao.com/claude-agent-sdk-guide.html

版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交