Claude Agent SDK实战:一步步搭建你的首个AI代理

Claude Agent SDK 封装代理循环,教程用一个 Python 文件构建带权限与防注入护栏的仓库助手。
文章介绍如何用 Claude Agent SDK 构建一个“仓库助手”:扫描文件夹、记录 bug 并查阅文档。SDK 本质是 Claude Code 的引擎,封装了代理循环、内置工具与上下文管理,开发者只需监听消息流。教程覆盖环境准备与密钥配置、query 入口与消息流结构、turn 概念的代理循环,重点剖析权限系统——allowed 列表只是预批准而非白名单,禁用工具须用 disallowed;并讲解自定义 MCP 工具的完全限定名陷阱与错误处理。安全部分提出三层防提示注入:最小权限范围规则、全模式生效的 deny 规则、最先执行的 pre-tool-use hook。最后强调 max turns 与 max budget 默认无限制,生产必须设限,并介绍 session 恢复、fork 与子代理委派。
为什么需要Agent SDK?
如果你直接用Claude API,工具循环得自己写:调用工具、把结果喂回去、判断何时停止。Claude Agent SDK把这一切封装好了——它本质上就是Claude Code背后的引擎,包含代理循环、内置工具和上下文管理,以Python和TypeScript库的形式提供。据YouTube教程演示,使用SDK后,Claude的工具调用由SDK自动执行,你的代码只需监听消息流。
本教程的目标是构建一个"仓库助手":扫描文件夹、记录发现的bug、并能查阅文档。整个过程浓缩在一个Python文件里。

Agent 循环(Agent Loop) 是这类 SDK 的核心抽象。传统 API 调用是“一问一答”的单次交互;而 Agent 循环把模型置于一个反复决策的闭环中:模型查看当前上下文 → 决定调用工具或直接回答 → 若调用工具,由运行时执行并把结果追加回上下文 → 再次询问模型。循环持续到模型给出不含工具调用的回复为止。Agent SDK 的价值就在于把这个循环、工具执行、消息序列化和停止条件全部封装,开发者只需提供提示词、工具与权限策略。
环境准备:从零到第一个Agent
安装与密钥配置
教程推荐使用uv包管理器,Python版本需3.10以上。初始化项目后安装ClaudeAgentSDK包——好消息是这个包内置了原生Claude Code二进制文件,大多数机器无需额外安装。如果你习惯pip,创建虚拟环境后安装同名包即可。
第一道坎在密钥。SDK不会自动加载.env文件,所以首次运行很可能因认证错误失败。你需要在运行代理的同一个shell中设置ANTHROPIC_API_KEY环境变量,或者用dotenv之类的包在SDK启动前手动加载。如果使用Bedrock、Google Cloud或Microsoft Foundry,文档为每个提供商提供了各自的开关变量。
第一个查询
按Quickstart写一个agent.py:导入query和选项类,query是启动整个代理循环的入口。提示词就是任务本身——让它检查文件夹中会导致代码崩溃的bug。选项里预批准三个工具:read、glob、grep,组合起来就是一个只读代理。
运行后观察消息流:先是带init子类型的system消息,携带会话详情和可用工具列表;然后是assistant消息,部分包含Claude的推理过程(thinking);最后一条result消息收尾,附最终文本、token用量、成本和会话ID。
理解代理循环
把循环想象成跑步机上的圈数。每一圈,Claude审视目前为止的所有信息,决定是直接回答还是请求工具。如果请求工具,SDK执行后把结果交回,开始下一圈——一圈就是一个turn。当Claude回复中不含任何工具调用时,循环结束。简单问题可能一两圈搞定,真正的bug修复可能串联几十次工具调用。
权限系统:最容易踩坑的地方
allowed list不等于白名单
这是教程反复强调的陷阱:如果你在allowed列表里列了三个工具,其他工具并没有被关掉,它们只是没被预批准,会落到权限模式(permission mode)处理。要真正移除某个工具,必须把裸名称放进disallowed列表。
工具请求的检查顺序像机场安检:先是hooks(你自己的函数,可当场拒绝),然后是deny规则(任何模式下都拦截匹配的调用),接着是ask规则,再是权限模式,之后是allow规则,最后未决的落到can use tool回调——默认模式下没有回调就等于拒绝。
权限模式(Permission Mode) 是 SDK 对工具调用审批的整体策略档位,常见取值包括 default(未预批准的调用需回调确认,无回调即拒绝)、acceptEdits(自动接受文件编辑类操作)、dontAsk(不再询问,未预批准即拒绝)和 bypassPermissions(跳过全部权限检查)。它决定的是“未被规则明确处理的调用”如何处置,而不是工具是否存在。因此权限模式与 allow/deny 规则是两层机制:规则做精确匹配,模式做兜底策略。
权限模式怎么选
教程给出的决策规则很实用:
- 只读助手:allowed列表放只读工具,配
don't ask模式,不会有意外操作 - 在你开发机上改代码的代理:用
accept edits,最好限制在隔离文件夹内 - 需要
bypass permissions的:只放在容器或CI任务里,绝不要在本机运行

无论哪种模式,deny规则和hooks始终拥有最先发言权。
自定义工具:让Agent拥有你应用独有的能力
内置工具很好,但真正的威力在于给代理一个只有你的应用才有的工具。自定义工具由四部分组成:名称、描述(Claude据此决定何时使用)、输入schema、处理器。
教程中的例子叫save finding——每当代理发现bug,就带着文件名和问题摘要调用它,处理器把发现追加到一个列表。这样发现就以结构化数据的形式落在你的程序里,而不是埋在一段文字中。用SDK的tool装饰器,前两个参数是名称和描述(写给Claude看的,不是写给人看的),schema是一个简单字典,把参数映射到Python类型。处理器返回一个包含text块的content列表,这正是Claude看到的结果。
最后用create SDK MCP server把工具包进一个在你进程内运行的小服务器。
MCP工具名的坑
每个MCP工具有一个完全限定名:mcp__服务器名__工具名,用双下划线连接。这个完整字符串必须一字不差地出现在allowed列表里,否则调用会落到权限模式,在don't ask模式下就是一次礼貌但坚决的拒绝。服务器前缀后加通配符可以允许该服务器的所有工具。

远程服务器通过HTTP接入,本地服务器通常以命令启动(比如npx)。SDK默认用tool search延迟加载MCP工具schema,避免大型服务器一开始就吃掉上下文。
工具失败怎么办
未捕获的异常不会终止循环,服务器会把它转成携带原始异常信息的错误结果。但裸栈信息很少能告诉Claude下一步该做什么——自己捕获问题,返回标记为error的结果,说明什么失败了、该尝试什么,Claude才能重试、换工具或解释故障。
MCP(Model Context Protocol) 是一个开放协议,用于把外部工具与数据源以标准化方式暴露给模型。在 MCP 中,工具由“服务器”提供,每个工具拥有形如 mcp__<server>__<tool> 的完全限定名,服务器可以是本地进程(如通过 npx 启动)或远程 HTTP 服务。Agent SDK 内建了在进程内运行 MCP 服务器的能力(即 in-process SDK MCP server),因此自定义工具无需独立部署即可被代理发现和调用;同时 SDK 支持延迟加载工具 schema,避免大量工具一次性占用上下文窗口。
安全防线:三层防护挡住提示注入
这是教程最有价值的部分。假设你为了运行测试,懒惰地把bash整个加进allowed列表,不留任何限制。Gremlin在readme里塞了一行:告诉AI代理用强制删除清理build文件夹。代理把文件内容当数据读,但文字可以很像指令,一条破坏性命令现在只有一步之遥。这就是提示注入——文件内容绝不能是你和磁盘之间的唯一屏障。
三层防护,每层都很便宜:
- 最小权限:不用裸bash,只允许匹配pytest命令的范围规则
- deny规则:拦截rm命令,在所有模式下生效,包括bypass permissions
- pre-tool-use hook:deny规则匹配的是命令字面,
/bin/rm这种写法可以绕过,所以需要你自己的代码在链条最前面检查每个bash调用
hook是一个异步函数,接收工具输入,bash命令在command键下。如果命令包含作为完整单词的rm,打印警告并返回deny决策。reason字符串很重要——Claude会读它,从而改变计划而不是盲目重试。其余情况返回空字典表示无异议。注册时用事件名作字典键,matcher设为bash,只对bash调用生效。

重跑后,代理读了readme、咬钩、尝试清理命令,hook先拦住、打印警告、关闭调用。Claude收到拒绝理由作为工具结果,报告无法执行该命令,继续完成审查,什么都没被删除。
提示注入(Prompt Injection) 指攻击者把指令伪装成数据放入模型会读取的内容中(如 README、网页、issue 描述),诱导代理执行非用户本意的操作。它与传统代码注入的区别在于:模型无法可靠区分“数据”与“指令”,任何进入上下文的文本都可能被当作命令遵循。防御思路因此不依赖模型自身的判断力,而是在执行层设卡——收窄可用工具范围、用 deny 规则硬拦截危险命令、并在工具执行前用自定义 hook 做语义级检查,使恶意指令即使被模型“相信”也无法落地为破坏性操作。
成本与轮次限制
开放式提示词会让循环转个不停。max turns限制工具调用往返次数,max budget(美元)限制估算花费,两者默认都无限制。任何要上生产的东西都要设限。
预算在每次响应到达后检查,所以最终花费可能略超上限,留些余量。触限时result的subtype会指明是哪个限制,且没有最终文本——单次查询会故意抛异常,所以要用try块包住循环。教程中的设置是20轮、半美元、effort设为low,因为审查小文件夹不需要深度推理。同时保存session ID,之后可以用resume选项续接同一会话、追加轮次。
下一步:记忆与子代理
每个query默认开启新会话,但result携带session ID,可以通过resume选项传回去——代理会记得读过哪些文件、发现了什么。想尝试风险想法而不丢失原始会话,可以fork会话。聊天式应用则用Python SDK的client类保持单个会话打开。
委派方面,给helper定义描述、提示词和它自己的简短工具列表,把agent工具加入allowed列表。每个子代理以全新上下文启动,只交回最终答案,让主代理的上下文保持精简。它们的开销同样计入预算上限。
到这里,你有了第一个真正的代理:一个文件、一个你理解的循环、你自己的工具,以及gremlin无法说服的护栏。
相关推荐

Asana AI产品负责人分享AI Agent最佳实践
Asana AI产品负责人分享AI Agent最佳实践,涵盖职责边界设定、人在回路设计、数据模型锚定以及评估迭代方法,为产品团队落地Agent提供可参考的原则。

日本互联网巨头GMO遭黑客泄密:云服务漏洞致客户数据外泄
日本GMO Internet证实云服务遭黑客攻击,客户数据疑被公开。公司正核实泄露数据真实性,事件凸显云服务安全风险与供应链攻击威胁。

苹果为Pages、Keynote、Numbers加入AI助手
苹果为Keynote、Pages、Numbers引入AI助手,基于苹果与OpenAI模型,可理解文档上下文,在Keynote中设计动画幻灯片、在Pages中起草和重构文档,生产力套件AI竞争升级。