Mindket
Claude Code 进阶课第 4 节,共 4 节

Claude Agent SDK 教程:用 TypeScript 或 Python 构建你自己的智能体

黑色横幅,标题是“Claude Code 进阶”,下面一行是“设置、无头运行、CI 与 Agent SDK”。

Claude Agent SDK 就是作为库使用的 Claude Code。TypeScript 安装 @anthropic-ai/claude-agent-sdk,Python 安装 claude-agent-sdk,用提示词和选项调用 query(),再读取消息流,直到结果出现。内置工具、权限、会话和 MCP 支持都随库带来。想把这套智能体循环放进你自己的程序时,就用它。

本节内容

  • query() 返回一个异步流。最后一条消息是结果,它的 subtype 说明运行是成功了还是撞上了某个上限。先检查它,再读 result。
  • allowedTools 预先批准你列出的工具,并不会限制其余工具。搭配 permissionMode: "dontAsk" 就得到一个锁死的智能体,也可以用 disallowedTools 移除某个工具。
  • SDK 默认会加载你的用户、项目和本地设置,所以设置那一课里的拒绝规则对你的智能体同样生效。传入 settingSources: [] 可以关掉这一点。
  • 给每个生产环境的智能体设上 maxTurns 和 maxBudgetUsd。单次调用在出现错误结果后会抛出异常,所以要把循环放进 try 和 catch。
全部课程
本页目录
  1. Agent SDK 和运行 Claude 的其他方式
  2. 安装并运行第一个智能体
  3. 读消息流,然后检查结果
  4. 权限:什么能不经询问就运行
  5. 在你自己的代码里处理批准
  6. 给 Claude 一个你自己的工具
  7. 接入别人写好的 MCP 服务器
  8. 会话:继续、恢复和分叉
  9. SDK 会从磁盘读什么
  10. 第一条消息之前的报错
  11. Boris Cherny 用 Lean 在 Agent SDK 本身里找出了 bug
  12. 动手试试
  13. 下一门课:开放权重模型
  14. 自测一下
  15. 常见问题
  16. 资料来源

Agent SDK 和运行 Claude 的其他方式

Agent SDK 把 Claude Code 背后的循环做成了库:同样的内置工具、权限系统、会话、hooks 和 MCP 支持,由你自己的 Python 或 TypeScript 代码来驱动。GitHub Actions 那一课已经用过它,因为那个 action 就建立在 SDK 之上,而无头运行那一课里的 claude -p 是它的命令行形态。Anthropic 的概览页按“谁来运行智能体”把四种方式分了类。

这个库只支持 Python 和 TypeScript。用其他语言时,把 CLI 当子进程启动,加上 -p 和 --output-format json。脚本里只有一步时,claude -p 是更小的工具。只有当你自己的代码需要回应批准请求、定义在你进程内运行的工具,或者为多个用户保存会话时,才去用 SDK。

两种语言在 GitHub 上各有一个仓库,更新日志和问题反馈都在那里。在 GitHub 上,Python 那个的关注者更多。

GitHub 上的两个 SDK 仓库

8.4k

claude-agent-sdk-python 获得的星标

来源:anthropics/claude-agent-sdk-python on GitHub (2026年11月5日 查阅)

1.4k

Python SDK 的 fork 数

来源:anthropics/claude-agent-sdk-python on GitHub (2026年11月5日 查阅)

1.9k

claude-agent-sdk-typescript 获得的星标

来源:anthropics/claude-agent-sdk-typescript on GitHub (2026年11月5日 查阅)

246

TypeScript SDK 的 fork 数

来源:anthropics/claude-agent-sdk-typescript on GitHub (2026年11月5日 查阅)

该用哪种 Claude 工具,来自 Agent SDK 概览页
你想要用你得到
在你自己运营的进程里,把 Claude Code 的智能体嵌进你的应用Agent SDK一个带有 Claude Code 的工具、权限、会话和 hooks 的库
在终端里交互式工作,或者运行一次性任务Claude Code CLI为日常使用打造的终端界面
从你自己的代码调用 Claude APIClient SDK直接访问 API。工具循环自己写,或者交给测试版的 tool runner
让 Anthropic 托管智能体Managed Agents托管的运行框架,会话在 Anthropic 的云沙箱里,或在你自己托管的沙箱里

安装并运行第一个智能体

你需要 Node.js 18.14 或更新版本,或者 Python 3.10 或更新版本,还要有一个来自 Claude Console 的 API 密钥。两个包都自带一个原生的 Claude Code 二进制文件,所以多数安装不需要另外装 Claude Code。Anthropic 的快速入门做了一个智能体,修复名为 utils.py 的文件里两个会崩溃的函数。下面就是用 TypeScript 写的那个智能体。

prompt 是任务,options 是配置,query 返回消息流。用哪些工具由 Claude 决定。这里 allowedTools 预先批准了其中三个,acceptEdits 批准文件修改。脚本后面的步骤会带你安装并运行它。

import { query } from "@anthropic-ai/claude-agent-sdk";

// Agentic loop: streams messages as Claude works
for await (const message of query({
  prompt: "Review utils.py for bugs that would cause crashes. Fix any issues you find.",
  options: {
    allowedTools: ["Read", "Edit", "Glob"], // Auto-approve these tools
    permissionMode: "acceptEdits" // Auto-approve file edits
  }
})) {
  // Print human-readable output
  if (message.type === "assistant" && message.message?.content) {
    for (const block of message.message.content) {
      if ("text" in block) {
        console.log(block.text); // Claude's reasoning
      } else if ("name" in block) {
        console.log("Tool: " + block.name); // Tool being called
      }
    }
  } else if (message.type === "result") {
    console.log("Done: " + message.subtype); // Final result
  }
}
  1. 新建一个文件夹并安装:npm init -y、npm pkg set type=module、npm install @anthropic-ai/claude-agent-sdk 和 npm install --save-dev tsx。Python 的话,先建一个虚拟环境再运行 pip install claude-agent-sdk,或者用 uv add claude-agent-sdk。
  2. 在运行智能体的 shell 里导出 ANTHROPIC_API_KEY。SDK 读取的是进程环境,不会自动加载 .env 文件,所以要自己用 dotenv 之类的包把它加载进来。
  3. 把脚本存成 agent.ts,放在一个 utils.py 旁边,里面要有一个遇到空列表就崩溃的函数,然后运行 npx tsx agent.ts。智能体会打印它的推理和调用的每个工具,最后以 Done: success 结束。
两个 SDK 里的选项名
概念TypeScriptPython
选项对象普通对象ClaudeAgentOptions
预先批准的工具allowedToolsallowed_tools
权限模式permissionModepermission_mode
批准回调canUseToolcan_use_tool
回合和花费上限maxTurns、maxBudgetUsdmax_turns、max_budget_usd
要加载的设置settingSourcessetting_sources
分叉会话forkSessionfork_session
识别结果消息message.type === "result"isinstance(message, ResultMessage)

在 Amazon Bedrock、Google Cloud 的 Agent Platform 或 Microsoft Foundry 上,分别设置 CLAUDE_CODE_USE_BEDROCK=1、CLAUDE_CODE_USE_VERTEX=1 或 CLAUDE_CODE_USE_FOUNDRY=1,并配置对应云平台的凭据。Claude Platform on AWS 则设置 CLAUDE_CODE_USE_ANTHROPIC_AWS=1 和 ANTHROPIC_AWS_WORKSPACE_ID,再配好 AWS 凭据。

读消息流,然后检查结果

一次 query() 调用就跑完整个循环。Claude 要么直接回答,要么请求一个工具,SDK 执行它并把输出送回去,如此重复,直到某次回复里不再有工具调用。你会依次收到带初始化数据的 system 消息、每个内容块一条的 assistant 消息、每个工具结果一条的 user 消息,最后是 result。只有打开部分消息,才会再多出流事件。完整的列表见 Anthropic 的智能体循环页。

要一直迭代到流结束,而不是在看到结果时就跳出,因为结果之后还可能到达几条收尾的系统事件。然后根据 subtype 分支处理。下面的循环会打印文本和工具调用,并说明是什么让运行停了下来。

import { query } from "@anthropic-ai/claude-agent-sdk";

try {
  for await (const message of query({ prompt: "Summarize this project" })) {
    if (message.type === "assistant") {
      // Each assistant message carries one content block
      for (const block of message.message.content) {
        if (block.type === "text") {
          console.log("Claude: " + block.text);
        } else if (block.type === "tool_use") {
          console.log("Tool call: " + block.name);
        }
      }
    }
    if (message.type === "result") {
      if (message.subtype === "success") {
        console.log(message.result);
      } else {
        console.log("Stopped: " + message.subtype);
      }
    }
  }
} catch (error) {
  // A single-shot query() throws after yielding an error result.
  console.log("Session ended with an error: " + error);
}
  • 每个结果都带有 total_cost_usd、usage、num_turns 和 session_id,错误结果也不例外,所以你可以记录花费并恢复会话。usage 只覆盖主循环,modelUsage 则覆盖整棵调用树,子智能体也在内。
  • maxTurns 把每个调用了工具的回合都算上,再加上最后只含文本的那次回复。上限设为 2 的话,Anthropic 示例里那个四个回合的修测试任务会在编辑之前就停下。
  • maxBudgetUsd 是在每次响应到达之后才检查的,所以花费可能超出上限一次响应的量,再加上仍在运行的子智能体。子智能体的花费也计入其中,超出上限后再生成子智能体会失败,报 Budget limit reached。这些上限行为需要 Claude Code v2.1.217 或更新版本。
  • 单次的 query() 会先给出错误结果,然后抛出异常,所以上面那种 try 和 catch 就是常规写法。想捕捉拒答,就检查 stop_reason 是否为 refusal。
结果的 subtype,来自智能体循环页
Subtype发生了什么有 result
successClaude 完成了任务有
error_max_turns先撞上了 maxTurns 上限没有
error_max_budget_usd先撞上了 maxBudgetUsd 上限没有
error_during_execution一个错误打断了循环,比如请求被取消没有
error_max_structured_output_retries在重试上限内没有得到有效的结构化输出没有

权限:什么能不经询问就运行

在 Claude Code v2.1.302 或更新版本上,SDK 应用从 default 模式启动,除非你设置了模式,或者它的设置文件设置了。在 default 模式下,需要批准的调用会被拒绝,除非有允许规则、hook 或你的回调批准它。无头运行里工具调用被拒绝,通常就该先查这里。

有两个选项承担大部分工作。allowedTools 预先批准你列出的工具,并不会限制其余工具:没列出的工具依然存在,会落到权限模式去处理。disallowedTools 才是封锁。裸名字比如 Bash 会把这个工具从 Claude 的上下文里移除,而 Bash(rm *) 让它继续可用,只按字面写法在每种模式下拒绝匹配的调用,所以 /bin/rm 能溜过去。像 Bash(npm test *) 这样带范围的允许条目反过来也一样,只批准匹配的调用。

要得到一个锁死的智能体,就列出只读工具并设为 dontAsk,这样每个本来会弹出确认的调用都会被拒绝。两个选项的背后是同一套固定顺序,权限页列出了它,下面的步骤再复述一遍。

const options = {
  allowedTools: ["Read", "Glob", "Grep"],
  permissionMode: "dontAsk"
};
  1. hooks 最先运行。hook 可以拒绝一次调用,而允许调用的 hook 不会跳过它后面的拒绝规则和询问规则。
  2. 拒绝规则,来自 disallowedTools 或设置文件。匹配就会在每种模式下拒绝调用,bypassPermissions 也不例外。
  3. 来自设置文件的询问规则。匹配就把调用交给你的回调,同样连 bypassPermissions 也不例外。
  4. 权限模式。acceptEdits 批准工作目录内的文件修改和 mkdir、mv、cp 之类的文件系统命令,bypassPermissions 批准走到这一步的一切。
  5. 允许规则,来自 allowedTools 和设置文件。匹配就批准这次调用。
  6. 剩下的由你的 canUseTool 回调决定。在 dontAsk 模式下这一步会被跳过,调用直接被拒绝。

allowedTools 约束不了 bypassPermissions。设为 allowedTools: ["Read"] 再加上这个模式,所有工具都会被批准,Bash 也在内。TypeScript 里这个模式还需要 allowDangerouslySkipPermissions: true,在 Linux 和 macOS 上,以 root 身份运行时,除非处在已认可的沙箱里,否则它不会启动。

在你自己的代码里处理批准

当前面没有任何一步裁决这次调用时,你的回调会被触发,Claude 用 AskUserQuestion 工具向用户提问时也会触发。它收到工具名和工具的输入,返回允许(可以附带改过的输入),或者拒绝并附上一条消息,Claude 会把这条消息当作工具结果读到。你回复之前,执行会一直等着。完整的约定见用户输入页。

自动批准的工具永远不会到达 canUseTool。

Anthropic, Agent SDK 文档(此处为中文译文) · Agent SDK 文档:配置权限 (2026年11月4日 查阅)
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Create a test file in /tmp and then delete it",
  options: {
    canUseTool: async (toolName, input) => {
      // Display the tool request
      console.log("Tool: " + toolName, input);

      // Ask the user with your own prompt helper
      const response = await prompt("Allow this action? (y/n): ");

      if (response.toLowerCase() === "y") {
        // Allow: the tool runs with the original (or modified) input
        return { behavior: "allow", updatedInput: input };
      }
      // Deny: the tool does not run, and Claude sees the message
      return { behavior: "deny", message: "User denied this action" };
    }
  }
})) {
  if ("result" in message) console.log(message.result);
}
  • 必须看到每一次调用的检查,请放进 PreToolUse hook。hooks 在其他所有步骤之前运行,而 hook 的拒绝即使在 bypassPermissions 下也有效。
  • 回调可以无限期地挂起。如果用户的回复可能比你的进程能活的时间更久,就从 PreToolUse hook 返回 defer 决定,让进程退出,之后再恢复保存下来的会话。
  • 在 Python 里,这个回调有个陷阱,文档称之为必需的变通办法。要把提示词写成产出用户消息的异步生成器,再加一个返回 {"continue_": True} 的 PreToolUse hook,让流保持打开。
  • 当 canUseTool 和 bypassPermissions,或和 allowedTools 里的裸工具名同时出现时,TypeScript SDK 会在每次查询里打印一次代码为 CLAUDE_SDK_CAN_USE_TOOL_SHADOWED 的进程警告,因为回调看不到这些调用。

给 Claude 一个你自己的工具

自定义工具有四个部分:唯一的名字、Claude 据以决定何时调用的描述、输入模式,以及一个异步的处理函数。模式在 TypeScript 里是 Zod 模式,在 Python 里是类型字典。处理函数返回一个由结果块组成的 content 数组。你把工具包进一个进程内的 MCP 服务器,所以不会有单独的进程。Python 的写法见自定义工具页。

把服务器传给 mcpServers,再用完整名字把每个工具列进 allowedTools,这里就是 mcp__weather__get_temperature。这个名字用双下划线连接服务器的键和工具名。

import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";

// Define a tool: name, description, input schema, handler
const getTemperature = tool(
  "get_temperature",
  "Get the current temperature at a location",
  {
    latitude: z.number().describe("Latitude coordinate"),
    longitude: z.number().describe("Longitude coordinate")
  },
  async (args) => {
    const response = await fetch(
      "https://api.open-meteo.com/v1/forecast?latitude=" + args.latitude +
        "&longitude=" + args.longitude +
        "&current=temperature_2m&temperature_unit=fahrenheit"
    );
    const data: any = await response.json();

    // Return a content array: Claude sees this as the tool result
    return {
      content: [{ type: "text", text: "Temperature: " + data.current.temperature_2m + " F" }]
    };
  }
);

// Wrap the tool in an in-process MCP server
const weatherServer = createSdkMcpServer({
  name: "weather",
  version: "1.0.0",
  tools: [getTemperature]
});

for await (const message of query({
  prompt: "What's the temperature in San Francisco?",
  options: {
    mcpServers: { weather: weatherServer },
    allowedTools: ["mcp__weather__get_temperature"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
  • 处理函数里未捕获的异常不会让循环停下。服务器会把它变成带着原始消息的错误结果,Claude 可以重试或做出解释。当 Claude 需要一条能据以行动的消息时,比如哪个请求失败了,就自己捕获异常并返回 isError: true。
  • 自定义工具默认一次只运行一个。在工具的 annotations 里设置 readOnlyHint: true,Claude 就能把它和其他只读工具并行调用。

接入别人写好的 MCP 服务器

不是你写的服务器,放进同一个 mcpServers 选项。stdio 服务器带 command 和 args,作为本地进程运行。远程服务器带 type: "http" 和 url,下面的例子连接的就是 Anthropic 的文档服务器。你也可以把列表放在项目根目录的 .mcp.json 里,它会通过 project 这个设置来源加载。认证和报错见MCP 页。

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Use the docs MCP server to explain what hooks are in Claude Code",
  options: {
    mcpServers: {
      "claude-code-docs": {
        type: "http",
        url: "https://code.claude.com/docs/mcp"
      }
    },
    allowedTools: ["mcp__claude-code-docs__*"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
  • MCP 工具需要明确的许可。没有许可,Claude 能看到这些工具,却无法调用。acceptEdits 不覆盖它们,bypassPermissions 虽然覆盖,却同时去掉了大部分其他确认,所以请把工具列进 allowedTools。
  • 通配符只能用在字面的 mcp__ 和服务器名之后。mcp__github__* 批准那个服务器的全部工具,而允许列表里的 ["*"] 或 ["mcp__*"] 会被忽略。
  • stdio 服务器,或者没有缓存工具列表的远程服务器,会拖住第一个回合,直到连上为止,默认最长 30 秒(MCP_TIMEOUT)。工具好像缺失时,去看初始化消息里每个服务器的状态。
  • 服务器键里的点或空格,在工具名里会变成下划线,所以 my.server 对应的是 mcp__my_server__list_issues。

会话:继续、恢复和分叉

会话就是对话历史:提示词、每次工具调用和结果,以及各次回复,SDK 会自动把它写进磁盘。它保存的是对话,不是你的文件,所以需要撤销修改时要用文件检查点。在一次 query() 调用里,智能体已经能按需要走任意多个回合,批准请求也在循环里处理。只有当多次独立的提示词应当共享上下文时,才需要会话,会话页有详细说明。

import { query } from "@anthropic-ai/claude-agent-sdk";

let sessionId: string | undefined;

// First run: read the session ID off the result message
for await (const message of query({
  prompt: "Analyze the auth module and suggest improvements",
  options: { allowedTools: ["Read", "Glob", "Grep"] }
})) {
  if (message.type === "result") sessionId = message.session_id;
}

// Later run: resume it, and the agent keeps the earlier analysis
for await (const message of query({
  prompt: "Now implement the refactoring you suggested",
  options: {
    resume: sessionId,
    allowedTools: ["Read", "Edit", "Write", "Glob", "Grep"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
  • 分叉会把历史复制进一个新会话,原会话保持不变。它不会复制文件,所以分叉出来的智能体所做的修改,对该目录下的每个会话都是真实的。
  • 会话文件只存在写下它的那台机器上,位于 ~/.claude/projects 下一个按工作目录命名的文件夹里。要在另一台主机上恢复,就挂上 sessionStore 适配器,或者把你需要的结果放进一个新会话的提示词。
  • 遇到 error_max_turns 或 error_max_budget_usd 之后,把上限调高再恢复这个会话。
  • 实验性的 TypeScript V2 会话 API,也就是 createSession(),已在 SDK 0.3.142 中移除。用到它的教程,需要改成带 continue 或 resume 的 query()。
哪种会话选项适合哪种应用
你在做的是该用什么
一次性任务只调用一次 query(),不用别的
单进程里的聊天Python 的 ClaudeSDKClient,或 TypeScript 的 continue: true
重启之后接着干continue_conversation=True 或 continue: true,会恢复该目录里最新的会话
每个用户一个会话记下会话 ID,传给 resume
试另一种做法,同时保留原来的用 fork_session 或 forkSession 分叉
不往磁盘写任何东西TypeScript 用 persistSession: false,Python 在 env 里设 CLAUDE_CODE_SKIP_PROMPT_HISTORY

SDK 会从磁盘读什么

SDK 会启动 Claude Code 的二进制文件,所以那些塑造 Claude Code 的文件,也会塑造你的智能体,除非你选择退出。

  • 不传 settingSources 时,query() 会加载用户、项目和本地设置,和 CLI 一样。你的 .claude/settings.json 里的允许、询问和拒绝规则,以及 .mcp.json 都会生效,这正是设置那一课在这里重要的原因。来源里包含 project 时,CLAUDE.md 文件也会加载。在 Python 里,设置了 skills 又没设 setting_sources 时,默认值会收窄为用户和项目。
  • 传入 settingSources: [],智能体就会忽略这三者。托管策略设置仍会加载,因为它不属于你能关掉的来源。
  • 在 TypeScript 里,默认的系统提示词是精简的。把 { type: "preset", preset: "claude_code" } 作为 systemPrompt 传入,Python 里则是 system_prompt,就能用 Claude Code 自己的提示词,还可以附加 append。
  • 在 TypeScript 里,env 选项会替换子进程的环境,所以要传 { ...process.env, YOUR_VAR: "value" } 才能保住 PATH。在 Python 里,它是合并到继承来的环境之上。
  • 一个服务里有多个租户时,给每个租户各自的 settingSources、env 和 cwd。

第一条消息之前的报错

  • Python 里的 CLINotFoundError 表示 SDK 把 CLI 当子进程启动,却没找到它。平台 wheel 包自带它,但源码安装就没有,比如在 ARM64 的 Windows 上。请原生安装 Claude Code,确认在你的应用运行的环境里 claude --version 能用,或者设置 cli_path。在 shell 之外启动的服务,PATH 往往不同。
  • Windows 上的 Refusing to execute batch script 表示 SDK 不会运行 npm 的 claude.cmd 垫片,因为 cmd.exe 会重新解析参数,可能执行被注入的命令。把 cli_path 指向 claude.exe,或者去掉它,让 SDK 用自带的二进制文件。这项检查是在 claude-agent-sdk 0.2.124 加入的。
  • 在 TypeScript 里,如果提示找不到你所在平台的原生 CLI 二进制文件,说明安装跳过了可选依赖,npm ci --omit=optional 就会这样。重新安装且不要跳过它们,或者设置 pathToClaudeCodeExecutable。
  • Python 里单独出现的 ProcessError 会打印 "Error output: Check stderr output for details",这是固定文本。在选项里传入 stderr 回调,才能抓到 CLI 真正写出的内容。
  • 在 ClaudeSDKClient 连接之前调用它的方法,会抛出 Not connected. Call connect() first.。用 async with 打开客户端,进入时就会自动连接。
  • Not logged in 或 Invalid API key 通常表示运行智能体的那个进程的环境里没有设置 ANTHROPIC_API_KEY。要检查的是那个进程,而不是你的 shell 历史。

Boris Cherny 用 Lean 在 Agent SDK 本身里找出了 bug

Boris Cherny 是 Claude Code 的作者。他九月在 X 上说,他用 Opus 5.5 和 Lean 对 Agent SDK 做了形式化验证。Lean 是一种由机器检查证明的语言。

几条简短的提示词,就带来了 16 个修复各种 bug 和竞态条件的拉取请求。他还说 TLA+ 也很好用,他有时把两者结合起来,检查数据流、并发和状态管理。他说这两种语言他都不太熟。

这类修复会随新的 SDK 版本发布,所以要让包保持最新:运行 npm update @anthropic-ai/claude-agent-sdk 或 pip install -U claude-agent-sdk,升级前先读更新日志。另外,这个方法也适用于你自己的代码:让 Claude 为智能体里处理会话或并行工具调用的部分建模,再去找你的测试从未走到的状态。

想看更完整的讲解,Anthropic 的 Thariq Shihipar 做过一场 SDK 工作坊,由 AI Engineer 频道录制。

我用 Opus 5.5 和 Lean 对 Claude Agent SDK 做了形式化验证。几条简短的提示词,换来 16 个修复各种 bug 和竞态条件的 PR。

Boris Cherny, Claude Code 的作者,就职于 Anthropic,引文为译文 · X (2026年11月5日 查阅)
Boris Cherny(@bcherny)2026 年 9 月 22 日在 X 上说,他用 Opus 5.5 和 Lean 对 Claude Agent SDK 做了形式化验证,几条简短的提示词带来 16 个修复 bug 和竞态条件的 PR,TLA+ 也很好用。
Boris Cherny 在 X 上,2026 年 9 月 22 日
Anthropic 的 Thariq Shihipar 主讲的 Claude Agent SDK 完整工作坊,发布在 YouTube 的 AI Engineer 频道。

X 官方嵌入卡片的截图,拍摄于 2026 年 11 月 5 日,时间为 UTC。X 用“Show more”截断了这条帖子。点击截图可到 X 上打开原帖。

动手试试

  • 运行快速入门里的智能体,再把 maxTurns 设成 2,读一读结果的 subtype。调高后再比较。
  • 改成 permissionMode: "dontAsk",只允许 Read,再让它去修改文件。看着拒绝作为工具结果返回,并观察 Claude 接下来怎么做。
  • 加上天气工具,把它的服务器键改名为 my.weather,推算出你现在需要的允许工具名。
  • 从一个结果里取出 session_id,用后续提示词恢复它,再把它分叉,比较两个 ID。

下一门课:开放权重模型

这一课让智能体在云端的 Claude 上运行。下一门课开放权重模型讲你可以自己下载和运行的模型,之后的“本地 AI”课程再用 Ollama 把一个模型跑起来。MCP 课程排在后面,“用 Python 构建 MCP 服务器”一课会写出一个任何智能体都能连接的服务器,包括你用这个 SDK 运行的智能体。

子智能体用的是同一套选项。SDK 有一个 agents 选项,可以在代码里定义它们,什么时候适合这样拆分工作,见子智能体指南。

自测一下

  1. 你把 allowedTools 设为 ["Read"],同时把 permissionMode 设为 "bypassPermissions"。哪些工具不经确认就会运行?

    查看答案

    C. 所有工具,包括 Bash 和 Edit allowedTools 只预先批准它列出的工具,而 bypassPermissions 会批准走到权限模式这一步的每次调用,所以它约束不了这个模式。

  2. 在读取 query() 循环最后一条消息的 result 字段之前,应该先检查什么?

    查看答案

    A. 它的 subtype 是否为 success 只有 success 这一类才带有 result。error_max_turns 之类的错误 subtype 没有它。

  3. 在 Python 里你设置了 can_use_tool,却把一个普通字符串当作提示词传入。文档里的做法要求改成什么?

    查看答案

    D. 把提示词写成异步生成器,再加一个让流保持打开的 PreToolUse hook 文档把这种流式提示词加上一个占位的 PreToolUse hook,称为 Python 里使用 can_use_tool 的必需变通办法。

  4. 一个自定义工具 get_temperature 放在键为 weather 的进程内服务器里。哪个 allowedTools 条目能预先批准它?

    查看答案

    B. mcp__weather__get_temperature MCP 工具名是在 mcp 前缀之后,用双下划线连接服务器的键和工具名。

常见问题

Agent SDK 和 Claude Code SDK 是一回事吗?

Agent SDK 是你要迁移到的那个包。Anthropic 为旧的 Claude Code SDK 包写了迁移指南,所以导入旧包的教程需要先看这份指南。

怎样选择模型?

把 model 选项设为 sonnet、opus 或 haiku 这样的别名,或者完整的模型名。不设的话,用 CLI 的默认值。子智能体可以用它定义里的 model 字段覆盖,inherit 表示沿用主模型。

我的应用能让用户用 Claude 订阅登录吗?

除非 Anthropic 事先批准,第三方开发者不得在自己的产品里提供 claude.ai 登录或它的速率限制,用 Agent SDK 构建的智能体也包括在内。请使用 API 密钥认证,或者 Bedrock、Vertex、Foundry 的凭据。

Python 里的 query() 和 ClaudeSDKClient 有什么区别?

query() 每次调用都开一个新会话,只处理一次交流,也不支持中断。ClaudeSDKClient 在多次交流之间保持同一个会话,并支持中断。这适合聊天界面,以及下一步取决于 Claude 回答的工作。TypeScript 没有客户端对象,用的是 continue: true。

怎样在 Claude 写的同时流式输出文字?

用部分消息。打开之后,消息流里会多出 StreamEvent 消息,携带原始的 API 流事件,比如文本增量。这个选项在 TypeScript 里叫 includePartialMessages,在 Python 里叫 include_partial_messages。

我能把自己的产品叫作 Claude Code 吗?

不能。Anthropic 的品牌指南允许使用“Claude Agent”,或者你自己的智能体名字加上“Powered by Claude”,不允许使用“Claude Code”或“Claude Code Agent”。你的产品要保持自己的品牌。

什么时候 Client SDK 是更好的选择?

当你只需要一次模型调用,或者想自己掌控工具循环时。它直接访问 Claude API,循环由你来写,或者用测试版的 tool runner。Agent SDK 自带循环,所以你的时间花在工具和权限上。

资料来源

  1. Claude Code docs: Agent SDK overview (2026年11月5日 查阅)https://code.claude.com/docs/en/agent-sdk/overview
  2. Claude Code docs: Agent SDK quickstart (2026年11月5日 查阅)https://code.claude.com/docs/en/agent-sdk/quickstart
  3. Claude Code docs: How the agent loop works (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/agent-loop
  4. Claude Code docs: Configure permissions (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/permissions
  5. Claude Code docs: Handle approvals and user input (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/user-input
  6. Claude Code docs: Give Claude custom tools (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/custom-tools
  7. Claude Code docs: Connect to external tools with MCP (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/mcp
  8. Claude Code docs: Work with sessions (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/sessions
  9. Claude Code docs: Agent SDK reference, TypeScript (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/typescript
  10. Claude Code docs: Agent SDK reference, Python (2026年11月4日 查阅)https://code.claude.com/docs/en/agent-sdk/python
  11. anthropics/claude-agent-sdk-python on GitHub (2026年11月5日 查阅)https://github.com/anthropics/claude-agent-sdk-python
  12. anthropics/claude-agent-sdk-typescript on GitHub (2026年11月5日 查阅)https://github.com/anthropics/claude-agent-sdk-typescript
  13. Boris Cherny on X: formally verifying the Claude Agent SDK with Lean (2026年11月5日 查阅)https://x.com/bcherny/status/2102543349102338309
  14. AI Engineer on YouTube: Claude Agent SDK [Full Workshop], Thariq Shihipar (2026年11月5日 查阅)https://www.youtube.com/watch?v=TqC1qOfiVcQ

分享本节课

你的智能体可以加载的技能

用 SDK 构建的智能体,会像 Claude Code 一样从项目的 .claude 文件夹加载技能。来看看 Mindket 上的技能。

浏览技能

本节课的 Markdown 版本 · Claude Code 进阶课 · 全部课程