🎯 核心主张(一句话)
Agent SDK 把 Claude Code 的 Harness 内核作为库直接调用——你从「配置一个现成工具」升级为「用代码构建以 Claude 为引擎的产品」,同时必须自己承担安全与工程化责任。
📖 正文
从配置到代码:控制粒度的演进
Claude Code 前面所有机制(CLAUDE.md、Skills、子智能体、Hooks、MCP、Headless)都预设你是使用者:在既定框架内用配置扩展行为。Agent SDK 预设你是构建者:何时启动 Claude、传什么参数、怎么编排中间步骤、怎么管理多轮状态,全由你的代码决定。
书里的类比很准:Headless 是「使用计算器」,SDK 是「为计算器编程」。演进链每深一层,控制粒度越细,工程复杂度也越高——SDK 站在链条末端。

SDK 提供 Python 和 TypeScript 两个功能对等的版本,2025 年末起包名从 claude-code-sdk 改为 claude-agent-sdk(pip install claude-agent-sdk / npm install @anthropic-ai/claude-agent-sdk)。
核心 API:query 函数 + ClaudeAgentOptions
query 是入口,编程层面等价于 claude -p,但返回的不是最终结果,而是异步生成器:Claude 每产出一条消息就即时吐给你。这意味着 Web 应用能把思考过程以 SSE 流式推到前端,CI 场景能边跑边处理输出。
options = ClaudeAgentOptions(
max_turns=5,
allowed_tools=["Read", "Grep", "Glob"],
system_prompt="你是代码架构分析师",
)
async for message in query(prompt="分析 src/auth/ 的架构", options=options):
... # 按 message.type 分流处理
消息流有固定类型序列,处理逻辑照着 type 分流即可:
system/init:会话配置快照(模型、工具集、MCP 状态)。调试第一步:工具没被调用,先查 init 里有没有注册它assistant:Claude 的响应,content 数组混合文本块和工具调用块,一条消息可含多个并发工具调用user:工具执行结果,tool_use_id的对应关系 SDK 自动维护result:终止信号,带 session_id、费用、轮数、耗时;subtype区分正常完成还是撞上轮数/预算上限/结构化输出重试失败
ClaudeAgentOptions 把 Headless 的命令行参数全部变成编程接口:模型选择、max_turns、max_budget_usd、工具黑白名单(支持 Bash(git diff *) 这种模式匹配)、四种权限模式(default / acceptEdits / plan / bypassPermissions)、系统提示定制、cwd/env、resume 会话延续、fork_session 会话分叉、output_format 强制 JSON Schema。编程接口的真正优势是动态性:按用户角色切权限模式、按任务类型换模型、根据上轮结果改写下轮 prompt——这些配置文件做不到。
两个高频用法:resume=session_id 让第二次调用完整继承上一轮的文件读取和分析结论,不用在 prompt 里重复背景;fork_session=True 从同一分析结果分叉出互不干扰的分支,做「方案 A vs 方案 B」的假设性对比。
自定义工具:进程内 MCP
SDK 的自定义工具本质是进程内 MCP 服务器——不起独立进程,直接跑在应用进程里,省掉进程间通信开销。用 @tool 装饰器定义函数,create_sdk_mcp_server 打包,再注册进 options:
@tool(name="query_database", description="只读 SQL 查询", parameters={"query": str, "limit": int})
async def query_database(args):
if not args["query"].strip().upper().startswith("SELECT"):
return {"content": [{"type": "text", "text": "Error: 仅允许 SELECT"}], "isError": True}
...
工具名遵循 mcp__{服务器名}__{工具名} 格式,天然避开与内置工具的命名冲突,日志审计时也自带分类。复杂参数推荐 Pydantic 模型代替字典,进门就完成类型校验。
三条设计铁律:单一职责(一个工具只干一件事)、描述清晰(description 是写给 Claude 看的使用说明,要写明何时可用何时禁用)、零信任验证(Claude 可能传极端参数、短时间连打几十次,工具内部必须自己校验所有输入)。
纵深防御:四道防线
SDK 应用没有终端里那个「人工确认」兜底,安全必须靠代码分层:
- permission_mode 定全局基调(plan 模式最保险,纯只读;bypassPermissions 只配在容器化、无网络的隔离环境里用)
- allowed_tools 白名单剔除多余工具
- canUseTool 运行时回调,对每次调用做「允许/拒绝」的二元裁决,是最轻量的动态访问控制(比如白名单放行了 Bash,但回调里拦掉 curl/wget/ssh)
- PreToolUse Hooks 做最细粒度的参数审查和审计日志
SDK 里的 Hooks 也从 Shell 脚本升级成原生函数:跑在当前进程、原生 async、可打断点调试。判断标准很简单——直接用 Claude Code 就写 Shell Hooks,基于 SDK 构建应用就写函数 Hooks。
典型形态与选型边界
典型应用形态:Web 代码分析服务(query 生成器直接对接 FastAPI 的 StreamingResponse,前端实时渲染思考流)、多轮对话产品(resume 管理上下文)、结构化数据管道(output_format + Pydantic 校验,失败自动重试)。
SDK vs Headless 的分界线,书里给了一条好记的经验法则:逻辑能用一行 Shell 命令描述就用 Headless CLI,需要写 if/else 或循环就用 SDK。具体对照:CI 单步任务、管道脚本 → Headless(零运行时依赖);Web/桌面应用、自定义工具、多轮会话、并发管理、精细消息控制 → SDK。
最后一个清醒剂:SDK 降低了构建门槛,但 demo 到生产之间隔着错误重试、成本追踪、用户隔离、响应超时、熔断机制这五件工程杂活,一件都躲不掉。
🧭 业界视角(书外补充)
- OpenAI 内部的 Harness 构建者路线:2026 年初业界流传的一个说法是,OpenAI 有团队以「3 个人、0 行手写代码」交付了百万行级的产品代码——真实性存疑,但方向信号明确:头部玩家的工程师已从「写代码的人」转向「构建 Harness 的人」,人力投在编排、验证、防线设计上。Agent SDK 正是这条路线的入场券:它让你做的不是补全工具,而是生产系统。
- Anthropic 40 万会话研究(2025.10–2026.04):典型会话里人做大部分规划决策,Claude 做大部分执行决策。对 SDK 应用的启示是别把产品设计成全自动黑箱——在规划节点(plan 模式输出)留人工确认口,执行阶段才放手,这与四道防线是互补的产品层防线。
- Vercel 团队的减法:他们删掉 80% 的 Agent 工具后流程更快、Token 更省。写
allowed_tools白名单时同理:默认给最小集合,缺了再加,而不是先全开再想着拦。 - Shrivu Shankar 的提醒同样适用于自定义工具:工具会「看守」能力边界,每加一个工具都在扩大 Claude 的行为空间和你的验证负担——加之前先问这件事能不能用现有工具组合完成。
🔗 知识网络
- upstream:Claude Code子智能体:上下文隔离与任务委派、ClaudeHeadless 模式与 CI-CD 集成
- downstream:SDD 与工作流框架:Superpowers 与复合工程
- 平行关联:Hooks:给概率模型上确定性缰绳、MCP:把 M×N 变成 M+N、Claude Code 成本与安全工程