Claude Agent SDK 详解

Claude Agent SDK 把 Claude Code 背后的 Agent 循环做成了可以编程的 SDK,让 AI 不只会回答,还能真正动手完成任务

先分清三个容易混淆的名字

大家口中的「Claude SDK」可能指三个完全不同的东西

名称 解决什么问题 谁负责 Agent 循环 适合场景
Anthropic Client SDK 更方便地调用 Messages API 你的程序 普通聊天、摘要、分类、自己设计工作流
Claude Agent SDK 把 Claude Code 的 Agent 能力嵌入自己的进程 SDK 内部工具、研究助手、代码 Agent、批处理任务
Claude Managed Agents 在 Anthropic 托管环境中运行长时间 Agent Anthropic 不想自己管理会话、沙箱和运行基础设施

本文重点讲的是 Claude Agent SDK,它目前提供 TypeScript 和 Python 两种 SDK

官方文档入口

Claude Agent SDK 到底做了什么

普通的 Messages API 调用大致是这样

1
用户问题 -> 调用模型 -> 得到回答

如果模型需要查数据库,你就要自己实现完整循环

1
2
3
4
5
6
7
调用模型
-> 判断是否返回工具调用
-> 校验工具参数
-> 执行工具
-> 把结果放回消息历史
-> 再次调用模型
-> 重复到任务完成

Claude Agent SDK 则把这套循环、上下文管理和工具执行能力放进了 SDK

1
2
3
4
5
6
7
你的系统
-> 把目标交给 query()
-> Claude 规划下一步
-> SDK 执行获得授权的工具
-> Claude 阅读工具结果并继续判断
-> SDK 持续返回事件
-> Claude 完成任务并返回最终结果

通俗来说,Client SDK 给你的是一位坐在聊天窗口里的顾问,而 Agent SDK 给你的是一位配有电脑、文件和工具箱的执行者

它可以直接复用 Claude Code 中的很多能力

  • 使用 Read、Glob、Grep 读取和搜索文件
  • 使用 Write、Edit 修改文件
  • 使用 Bash 执行命令
  • 使用 WebSearch 搜索网络
  • 通过 MCP 连接数据库、浏览器和第三方系统
  • 使用 Session 保留并恢复上下文
  • 使用 Hooks 记录、拦截或修改工具调用
  • 使用权限规则决定哪些操作自动执行,哪些操作必须确认

最小可运行示例

下面使用 TypeScript 搭建一个最小 Agent

1 安装依赖

1
2
3
4
npm init -y
npm pkg set type=module
npm install @anthropic-ai/claude-agent-sdk
npm install --save-dev tsx typescript

TypeScript 和 Python 版本通常会携带运行所需的 Claude Code 原生二进制,因此大多数环境不需要再单独安装 Claude Code

2 配置 API Key

1
export ANTHROPIC_API_KEY="your-api-key"

API Key 必须保存在服务端环境变量或密钥管理系统中,不要写进代码,也不要交给浏览器

SDK 不会自动读取 .env,如果项目使用 .env 文件,需要由应用主动加载

3 创建第一个 Agent

新建 agent.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { query } from "@anthropic-ai/claude-agent-sdk"

for await (const message of query({
prompt: "阅读当前项目的 README,总结项目用途和启动方式",
options: {
allowedTools: ["Read", "Glob", "Grep"],
permissionMode: "dontAsk"
}
})) {
if (message.type === "assistant") {
for (const block of message.message.content) {
if (block.type === "text") {
console.log(block.text)
}
}
}

if (message.type === "result") {
console.log("执行状态:", message.subtype)
console.log("最终结果:", message.result)
}
}

运行它

1
npx tsx agent.ts

query() 返回的不是一段普通字符串,而是一个异步事件流

执行过程中可能依次收到初始化信息、Claude 的文本、工具调用、工具结果和最终结果,因此真实系统应该根据 message.type 分别处理,而不是假定每一条消息都是最终回答

query() 是整个 SDK 的入口

最重要的三个配置是

配置 作用 直观理解
prompt 告诉 Agent 要完成什么任务 本次工单
options 配置模型、工具、权限和运行环境 员工手册和工具箱
异步事件流 持续返回执行过程和结果 实时工作日志

一个更完整的配置可能是

1
2
3
4
5
6
7
8
9
const options = {
model: "CLAUDE_MODEL_ID",
cwd: "/workspace/project",
systemPrompt: "你是一名谨慎的代码审查助手,只分析当前项目",
allowedTools: ["Read", "Glob", "Grep"],
disallowedTools: ["Bash", "Write", "Edit"],
permissionMode: "dontAsk",
maxTurns: 12
}
  • model 选择实际使用的 Claude 模型
  • cwd 决定 Agent 默认在哪个目录工作,也限定了它最自然的文件上下文
  • systemPrompt 放长期稳定的角色、边界和输出要求
  • allowedTools 会预先批准匹配的工具调用
  • disallowedTools 会让 Claude 看不到或无法使用对应工具
  • permissionMode 决定未被规则处理的工具如何申请权限
  • maxTurns 限制 Agent 最多进行多少轮,避免异常任务无限循环

用自定义工具连接自己的业务系统

内置工具解决的是文件、命令和搜索问题,真正搭建自己的系统时,还要让 Agent 访问订单、知识库、工单或内部 API

Claude Agent SDK 使用进程内 MCP Server 注册自定义工具

下面定义一个查询订单的工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import {
createSdkMcpServer,
query,
tool
} from "@anthropic-ai/claude-agent-sdk"
import { z } from "zod"

const getOrder = tool(
"get_order",
"根据订单号查询订单状态,只用于读取订单信息",
{
orderId: z.string().min(1).describe("订单号")
},
async ({ orderId }) => {
const response = await fetch(`https://internal.example.com/orders/${orderId}`, {
headers: {
Authorization: `Bearer ${process.env.INTERNAL_API_TOKEN}`
}
})

if (!response.ok) {
return {
content: [{ type: "text", text: "订单查询失败" }],
isError: true
}
}

const order = await response.json()

return {
content: [{ type: "text", text: JSON.stringify(order) }],
structuredContent: order
}
},
{
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: true
}
}
)

const businessServer = createSdkMcpServer({
name: "business",
version: "1.0.0",
tools: [getOrder]
})

for await (const message of query({
prompt: "查询订单 A20260905001,并用一句话告诉用户当前进度",
options: {
mcpServers: {
business: businessServer
},
allowedTools: ["mcp__business__get_order"],
permissionMode: "dontAsk"
}
})) {
if (message.type === "result") {
console.log(message.result)
}
}

这里有四个关键点

  1. tool() 使用名称、描述、Zod Schema 和处理函数定义工具
  2. createSdkMcpServer() 把工具包装成进程内 MCP Server,不需要另起一个服务
  3. 工具完整名称遵循 mcp__服务名__工具名
  4. Claude 只负责决定何时调用,真正的鉴权、参数校验和业务操作仍由你的程序完成

工具描述并不是普通注释,它会直接影响 Claude 是否正确选择工具

「查询订单」不如「根据订单号读取订单状态,不会修改订单」清楚,参数的 describe() 也应该写明格式、单位和业务含义

搭建一个真正可用的系统

下面以「内部工单助手」为例,把 Agent SDK 放进一套完整架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
浏览器或企业聊天工具
|
v
业务后端 / API Gateway
- 用户认证
- 权限校验
- 限流与配额
- 会话映射
|
v
Agent Worker
- Claude Agent SDK
- System Prompt
- Permission Rules
- Hooks
|
+----> 工单 MCP / 自定义工具
+----> 企业知识库
+----> 日志与监控
+----> 隔离的文件系统或容器

第一层 接口层

接口层负责接收用户请求和输出事件,不应该把浏览器直接连接到 Agent SDK

一个简化后的服务函数可以这样写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { query } from "@anthropic-ai/claude-agent-sdk"

export async function* runSupportAgent(input: {
userId: string
prompt: string
}) {
if (!input.userId) {
throw new Error("用户未登录")
}

for await (const message of query({
prompt: input.prompt,
options: {
systemPrompt: [
"你是内部工单助手",
"先读取资料再回答,不确定时明确说明",
"任何修改和发送操作都必须获得用户确认"
].join("\n"),
mcpServers: {
business: businessServer
},
allowedTools: [
"mcp__business__get_order"
],
disallowedTools: [
"Bash",
"Write",
"Edit"
],
permissionMode: "dontAsk",
maxTurns: 10
}
})) {
yield message
}
}

HTTP 层可以把这些事件转换成 SSE 或 WebSocket 消息,前端就能实时展示「正在查询订单」「正在阅读文档」和最终回答

第二层 Agent 层

Agent 层不要只写一句「你是一个有用的助手」,至少应该明确

  • 它的职责是什么
  • 哪些数据是可信来源
  • 什么情况下必须拒绝或升级人工
  • 哪些操作只能读取
  • 哪些操作会产生副作用
  • 最终结果应该是什么格式

任务目标越明确,Agent 越容易知道什么时候应该停止

第三层 工具层

工具应该保持小而清晰

1
2
不推荐:manage_order
推荐:get_order、calculate_refund、submit_refund

把读取、计算和写入拆开后,可以只自动批准只读工具,让退款提交之类的高风险工具进入人工确认

所有工具都应该在服务端重新检查用户身份和资源权限,不能因为 Claude 传入了某个 orderId 就默认用户有权读取它

第四层 数据与状态层

短任务可以一次调用 query() 完成,连续对话则需要保存 Session ID

1
2
3
4
用户第一次提问 -> 创建 Session -> 保存 sessionId
用户继续提问 -> 使用 sessionId 恢复上下文
用户另开分支 -> Fork Session
任务结束 -> 记录结果、成本和审计日志

Session 解决的是 Agent 上下文连续性,不应该替代业务数据库

订单状态、用户权限和任务进度仍应保存在自己的数据库中,Session 只保存模型理解对话所需的上下文

权限设计比 Prompt 更重要

Prompt 中写「不要删除文件」只是语言要求,权限规则才是工程边界

可以按风险把工具分成三层

风险等级 例子 推荐策略
只读 搜索文档、读取订单、查询数据库 可在完成鉴权后自动批准
可恢复写入 创建草稿、修改临时文件 限定目录并记录变更,必要时确认
高风险操作 删除数据、转账、发布、发送消息 必须由用户明确确认

需要特别注意,allowedTools 不是工具白名单

它表示这些工具可以自动批准,其他未被列出的工具仍可能进入权限模式或回调流程;如果希望 Claude 完全不能看到某个工具,应该使用 disallowedTools 或只把必要工具放进上下文

生产环境不要为了省事使用 bypassPermissions,尤其不要让面向外部用户的 Agent 拥有不受限制的 Bash、文件写入和网络访问能力

Session、记忆和业务状态不是一回事

这三个概念很容易混在一起

概念 保存什么 例子
Session 当前对话和工具调用上下文 用户追问「那第二个方案呢」时知道第二个指什么
Memory 跨会话仍然有效的偏好和知识 用户偏好中文回答
业务状态 系统真实数据 订单已退款、工单已关闭

Session 可以恢复或 Fork,适合做多轮助手和任务分支

Memory 应该可查看、可修改、可删除,并避免保存不必要的敏感信息

业务状态必须由数据库或真实系统负责,Claude 的上下文不能成为事实来源

如何控制成本和失控风险

Agent 的成本不只来自最终回答,还包括规划、工具调用后的再次推理、失败重试和长上下文

建议至少设置以下边界

  1. 使用 maxTurns 限制最大循环次数
  2. 为单次任务设置超时和取消机制
  3. 限制工具返回内容大小,不要把整张数据库表塞回上下文
  4. 对搜索、查询和写入工具分别设置调用次数
  5. 记录模型、Session、耗时、Token、工具调用和最终状态
  6. 对外部 API 增加超时、重试上限和幂等键
  7. 超出预算时中止任务并返回可恢复状态

如果一个 Agent 连续三次调用同一个工具却没有获得新信息,通常应该停止并暴露问题,而不是继续烧 Token

Hooks 适合做什么

Hooks 可以在 Agent 生命周期的关键位置执行代码

常见用途包括

  • 在工具执行前检查参数
  • 阻止访问敏感路径
  • 给所有外部请求增加审计信息
  • 在工具执行后记录耗时和结果摘要
  • 对输出进行脱敏
  • 将执行轨迹发送到可观测平台

Hooks 适合做确定性的工程控制,System Prompt 适合描述行为目标,两者不要互相替代

什么时候不应该使用 Agent SDK

Agent SDK 很强,但并不是每次调用 AI 都需要 Agent

下面这些场景使用普通 Client SDK 往往更简单

  • 输入一段文本,输出一次摘要
  • 固定格式的信息抽取
  • 明确的单次分类任务
  • 所有执行步骤都能提前写成确定流程
  • 对延迟和成本非常敏感的高并发接口

判断标准很简单

如果程序员可以提前准确写出每一步,就使用普通代码编排;如果下一步取决于上一步观察到的结果,并且路径无法完全提前确定,Agent 才真正有价值

一套推荐的落地顺序

不要第一天就给 Agent 接上整个生产系统

阶段一 只读原型

  • 只启用 Read、Glob、Grep 或只读业务工具
  • 准备 20 到 50 个真实任务作为评测集
  • 记录每次执行路径、答案和成本

阶段二 受控写入

  • 增加创建草稿、修改临时文件等可恢复操作
  • 对每次写入展示预览或 Diff
  • 为工具增加鉴权、参数校验和幂等保护

阶段三 有审批的生产操作

  • 高风险操作必须人工确认
  • 使用隔离容器、最小权限凭据和网络白名单
  • 建立超时、取消、重试、告警和审计链路

阶段四 持续评测

  • 模型或 Prompt 更新前运行固定评测集
  • 比较任务成功率、工具调用次数、Token 和延迟
  • 对失败轨迹分类,而不是只看最终回答好不好

最后总结

Claude Agent SDK 的价值,不是少写一次 API 请求,而是直接获得一套已经成形的 Agent Runtime

它负责让 Claude 在「思考、调用工具、读取结果、继续行动」之间循环,你负责定义业务目标、工具、权限、数据边界和运行环境

真正可靠的 Agent 系统通常遵循同一个原则

1
2
3
4
让模型负责判断
让代码负责约束
让权限负责兜底
让日志负责还原现场

从一个只读工具和十几条真实任务开始,比一开始就打造一个无所不能的超级 Agent 更容易成功

参考资料