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

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

Mindket 编辑部 · 发布于 2026-11-04 · 更新于 2026-11-05 · https://mindket.com/cn/learn/claude-code-advanced/claude-agent-sdk

## 要点

- `query()` 返回一个异步流。最后一条消息是结果，它的 `subtype` 说明运行是成功了还是撞上了某个上限。先检查它，再读 `result`。
- `allowedTools` 预先批准你列出的工具，并不会限制其余工具。搭配 `permissionMode: "dontAsk"` 就得到一个锁死的智能体，也可以用 `disallowedTools` 移除某个工具。
- SDK 默认会加载你的用户、项目和本地设置，所以设置那一课里的拒绝规则对你的智能体同样生效。传入 `settingSources: []` 可以关掉这一点。
- 给每个生产环境的智能体设上 `maxTurns` 和 `maxBudgetUsd`。单次调用在出现错误结果后会抛出异常，所以要把循环放进 try 和 catch。

## Agent SDK 和运行 Claude 的其他方式

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

这个库只支持 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](https://github.com/anthropics/claude-agent-sdk-python), 2026-11-05 查阅)
- **1.4k** Python SDK 的 fork 数 (来源：[anthropics/claude-agent-sdk-python on GitHub](https://github.com/anthropics/claude-agent-sdk-python), 2026-11-05 查阅)
- **1.9k** claude-agent-sdk-typescript 获得的星标 (来源：[anthropics/claude-agent-sdk-typescript on GitHub](https://github.com/anthropics/claude-agent-sdk-typescript), 2026-11-05 查阅)
- **246** TypeScript SDK 的 fork 数 (来源：[anthropics/claude-agent-sdk-typescript on GitHub](https://github.com/anthropics/claude-agent-sdk-typescript), 2026-11-05 查阅)

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

## 安装并运行第一个智能体

你需要 Node.js 18.14 或更新版本，或者 Python 3.10 或更新版本，还要有一个来自 [Claude Console](https://platform.claude.com/settings/keys) 的 API 密钥。两个包都自带一个原生的 Claude Code 二进制文件，所以多数安装不需要另外装 Claude Code。Anthropic 的[快速入门](https://code.claude.com/docs/en/agent-sdk/quickstart)做了一个智能体，修复名为 `utils.py` 的文件里两个会崩溃的函数。下面就是用 TypeScript 写的那个智能体。

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

````typescript
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` 结束。

| 概念 | TypeScript | Python |
| --- | --- | --- |
| 选项对象 | 普通对象 | `ClaudeAgentOptions` |
| 预先批准的工具 | `allowedTools` | `allowed_tools` |
| 权限模式 | `permissionMode` | `permission_mode` |
| 批准回调 | `canUseTool` | `can_use_tool` |
| 回合和花费上限 | `maxTurns`、`maxBudgetUsd` | `max_turns`、`max_budget_usd` |
| 要加载的设置 | `settingSources` | `setting_sources` |
| 分叉会话 | `forkSession` | `fork_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 的[智能体循环页](https://code.claude.com/docs/en/agent-sdk/agent-loop)。

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

````typescript
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 | 发生了什么 | 有 `result` |
| --- | --- | --- |
| `success` | Claude 完成了任务 | 有 |
| `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`，这样每个本来会弹出确认的调用都会被拒绝。两个选项的背后是同一套固定顺序，[权限页](https://code.claude.com/docs/en/agent-sdk/permissions)列出了它，下面的步骤再复述一遍。

````typescript
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 会把这条消息当作工具结果读到。你回复之前，执行会一直等着。完整的约定见[用户输入页](https://code.claude.com/docs/en/agent-sdk/user-input)。

> 自动批准的工具永远不会到达 canUseTool。
>
> Anthropic, Agent SDK 文档（此处为中文译文）, [Agent SDK 文档：配置权限](https://code.claude.com/docs/en/agent-sdk/permissions) (2026-11-04 查阅)

````typescript
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 的写法见[自定义工具页](https://code.claude.com/docs/en/agent-sdk/custom-tools)。

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

````typescript
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 页](https://code.claude.com/docs/en/agent-sdk/mcp)。

````typescript
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()` 调用里，智能体已经能按需要走任意多个回合，批准请求也在循环里处理。只有当多次独立的提示词应当共享上下文时，才需要会话，[会话页](https://code.claude.com/docs/en/agent-sdk/sessions)有详细说明。

````typescript
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` 都会生效，这正是[设置那一课](https://mindket.com/cn/learn/claude-code-advanced/claude-code-settings)在这里重要的原因。来源里包含 `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 上](https://x.com/bcherny/status/2102543349102338309)说，他用 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](https://x.com/bcherny/status/2102543349102338309) (2026-11-05 查阅)

[![Boris Cherny（@bcherny）2026 年 9 月 22 日在 X 上说，他用 Opus 5.5 和 Lean 对 Claude Agent SDK 做了形式化验证，几条简短的提示词带来 16 个修复 bug 和竞态条件的 PR，TLA+ 也很好用。](https://mindket.com/blog/shots/x-bcherny-agent-sdk-lean.webp?v=05d5ce1672af)](https://x.com/bcherny/status/2102543349102338309)

Boris Cherny 在 X 上，2026 年 9 月 22 日

[Claude Agent SDK [Full Workshop] — Thariq Shihipar, Anthropic](https://www.youtube.com/watch?v=TqC1qOfiVcQ)

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 上运行。下一门课[开放权重模型](https://mindket.com/cn/learn/open-weight-models/what-are-open-weight-models)讲你可以自己下载和运行的模型，之后的“本地 AI”课程再用 [Ollama](https://mindket.com/cn/learn/local-ai/ollama-tutorial) 把一个模型跑起来。MCP 课程排在后面，“用 Python 构建 MCP 服务器”一课会写出一个任何智能体都能连接的服务器，包括你用这个 SDK 运行的智能体。

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

## 自测一下

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

   A. 只有 Read
   B. Read 和其他只读工具
   C. 所有工具，包括 Bash 和 Edit

   答案：C。 allowedTools 只预先批准它列出的工具，而 bypassPermissions 会批准走到权限模式这一步的每次调用，所以它约束不了这个模式。

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

   A. 它的 subtype 是否为 success
   B. 它的 session_id 是否已设置
   C. 它的 total_cost_usd 是否大于零

   答案：A。 只有 success 这一类才带有 result。error_max_turns 之类的错误 subtype 没有它。

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

   A. 把 permission_mode 改成 acceptEdits
   B. 把回调加进 allowed_tools
   C. 把 setting_sources 设为空列表
   D. 把提示词写成异步生成器，再加一个让流保持打开的 PreToolUse hook

   答案：D。 文档把这种流式提示词加上一个占位的 PreToolUse hook，称为 Python 里使用 can_use_tool 的必需变通办法。

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

   A. get_temperature
   B. mcp__weather__get_temperature
   C. weather.get_temperature

   答案：B。 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 自带循环，所以你的时间花在工具和权限上。

## 资料来源

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

[浏览技能](https://mindket.com/cn/skills)
