入口函数

心智模型:Claude Agent SDK 把Agent Session抽象成一个异步生成器

export declare function query(_params: {
  prompt: string | AsyncIterable<SDKUserMessage>;
  options?: Options;
}): Query;   // Query extends AsyncGenerator<SDKMessage, void>

SDKMessage

for await 拿到的每一条消息都是 SDKMessage。它是一个联合类型,常见成员如下:

type 含义 关键字段
'system'subtype:'init' 会话初始化信息,第一条 claude_code_versioncwdtoolsmcp_serversmodelpermissionModeskillspluginscapabilities?
'assistant' 模型一轮回复(含 text / tool_use / thinking 块) message: BetaMessageparent_tool_use_iduuidsession_idaborted?subagent_type?
'user' 用户消息或工具结果回填 message: MessageParamtool_use_result?shouldQuery?priority?〔sdk.d.ts:4583-4605〕
'stream_event'SDKPartialAssistantMessage 流式增量,仅当 includePartialMessages:true 才出现
'result' 终结消息,流到此结束 见下表

联合里还包含 hook_started/hook_responsetask_*rate_limitcompact_boundary 等大量事件类型。普通集成只需关注 system / assistant / user / result,其余按需处理。

终结消息:成功 vs 失败

'result'SDKResultSuccess | SDKResultError〔sdk.d.ts:4290〕。判别字段是 subtype

成功

{
  type: 'result'; subtype: 'success';
  is_error: false;
  num_turns: number;            // 轮数
  result: string;               // 最终文本
  total_cost_usd: number;       // 本次花费
  usage: NonNullableUsage;      // token 用量
  structured_output?: unknown;  // 仅当 outputFormat 设定时存在
  terminal_reason?: TerminalReason;
  session_id: string;
}

失败——subtype 只能是这四种之一,直接告诉你失败的原因类别

subtype: 'error_during_execution'
        | 'error_max_turns'              // 触达 maxTurns
        | 'error_max_budget_usd'         // 触达 maxBudgetUsd
        | 'error_max_structured_output_retries';  // 结构化输出重试耗尽
is_error: true;
errors: string[];              // 具体错误文本数组
permission_denials: SDKPermissionDenial[];

terminal_reason:循环为何终止

终结消息里可选的 terminal_reason 解释了“为什么停”。常用值:

  • 'completed' — 正常完成
  • 'max_turns' — 触达 maxTurns
  • 'budget_exhausted' — 预算耗尽
  • 'aborted_streaming' / 'aborted_tools' — 被中断
  • 'stop_hook_prevented' / 'hook_stopped' — 被 Stop hook 拦下
  • 'tool_deferred' / 'tool_deferred_unavailable' — 工具被延迟/不可用
  • 'prompt_too_long' / 'api_error' / 'model_error' / 'image_error'

边界提示:拿到 result务必先看 subtype/is_error,不要假设流结束即成功。error_max_turns 是最常见的“Agent 跑飞”信号——它意味着模型在 maxTurns 内没收敛,而不是真的完成了任务。

流式输入输出模式

当开发者把 prompt 传成 AsyncIterable<SDKUserMessage>(流式输入)时,下面这些方法才生效;传字符串时调用它们无效:

方法 作用 出处
interrupt() 中断当前执行;返回 {still_queued, cancelled?} 〔sdk.d.ts:2293, 3485-3494〕
setPermissionMode(mode) 运行中切换权限模式 〔sdk.d.ts:2300〕
setMcpPermissionModeOverride(server, mode|null) 针对单台 MCP server 钉住/清除权限覆盖(只能收紧不能放大,仅 'default'|'auto'|null 〔sdk.d.ts:2317〕
setModel(model?) 运行中换模型 〔sdk.d.ts:2327〕
setMaxThinkingTokens(n|null, display?) 已废弃,改用 thinking 选项 〔sdk.d.ts:2350, 2337-2340〕
applyFlagSettings(settings) 运行中合并 flag 层设置 〔sdk.d.ts:2373〕
initializationResult() / reinitialize() 取/重发 init 〔sdk.d.ts:2382, 2399〕
supportedModels() / supportedAgents() / supportedCommands() 列模型/子代理/命令 〔sdk.d.ts:2411, 2417, 2405〕
mcpServerStatus() 各 MCP server 连接状态 〔sdk.d.ts:2423〕
getContextUsage() 上下文用量分类明细 〔sdk.d.ts:2430〕
rewindFiles(userMessageId, {dryRun?}) 回滚文件到某条用户消息的状态(需 enableFileCheckpointing 〔sdk.d.ts:2486〕

Options

进程与环境

env

env?: { [envVar: string]: string | undefined };

一旦传了 env,子进程就只剩用户给的那几个变量——PATHHOME、API Key 全没了,于是命令找不到、鉴权失败。正确做法是显式展开:

env: { ...process.env, CLAUDE_AGENT_SDK_CLIENT_APP: "my-app/1.0" }

在多租户和安全场景下,尽量不直接注入 process.env。

cwd

会话工作目录,默认 process.cwd()。它决定了 Agent 读写文件的基准、以及 settingSources'project' 的查找位置。

settingSources:SDK 隔离模式

settingSources?: SettingSource[];   // 'user' | 'project' | 'local'

“Pass [] to disable filesystem settings (SDK isolation mode). Must include 'project' to load CLAUDE.md files.”〔sdk.d.ts:1907-1908〕

  • 省略 = 加载全部三层(与 CLI 一致)。
  • [] = 彻底不读任何文件系统配置,是 SDK 嵌入到别处时最干净的隔离姿态。
  • 想让 Agent 读到项目里的 CLAUDE.md/AGENTS.md必须显式包含 'project'

工具与权限

tools?: string[] | { type: 'preset'; preset: 'claude_code' };
allowedTools?: string[];
disallowedTools?: string[];
选项 作用 边界
tools 决定哪些内置工具存在['Bash','Read','Edit'] 显式列举;[] 禁用所有内置工具{type:'preset',preset:'claude_code'} 用全套〔sdk.d.ts:1423-1434〕 native 构建可能用 Bash 的 find/grep 代替 Grep/Glob;需要的话要在 toolsallowedTools 里显式列出 Grep/Glob〔sdk.d.ts:1428-1429〕
allowedTools 这些工具自动放行、不弹权限提示〔sdk.d.ts:1369-1371〕 要限制可用工具,用 tools 而不是 allowedTools”〔sdk.d.ts:1371〕;传 'Skill' 已废弃,改用 skills〔sdk.d.ts:1373〕
disallowedTools 从模型上下文中移除这些工具,即便本可使用也用不了〔sdk.d.ts:1391-1395〕

常见误用:想“只允许 Bash”却设了 allowedTools:['Bash']——这只是“Bash 不弹窗”,其它工具照样存在可用。正确做法是 tools:['Bash'](白名单化工具集)。

permissionMode:六种模式

export declare type PermissionMode =
  'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk' | 'auto';

〔sdk.d.ts:2090-2092〕官方释义(逐字):

  • 'default' — 标准行为,危险操作弹窗
  • 'acceptEdits' — 自动接受文件编辑
  • 'bypassPermissions'绕过所有权限检查(需要 allowDangerouslySkipPermissions
  • 'plan' — 规划模式,不实际执行工具
  • 'dontAsk' — 不弹窗,未预批准则直接拒绝
  • 'auto' — 用模型分类器决定放行/拒绝

canUseTool:权限回调(核心,见 §4 详解)

canUseTool?: CanUseTool;   // (toolName, input, options) => Promise<PermissionResult | null>

sandbox:OS 级隔离(见 §5 详解)

sandbox?: SandboxSettings;

模型与推理

model

'claude-sonnet-5'

thinking(推荐)

thinking?: ThinkingConfig;   // adaptive | enabled | disabled
type ThinkingAdaptive  = { type: 'adaptive';  display?: 'summarized' | 'omitted' }; // Claude 自己决定何时/思考多少(Opus 4.6+),支持模型的默认值
type ThinkingEnabled   = { type: 'enabled';   budgetTokens?: number; display?: ... }; // 固定思考预算(旧模型)
type ThinkingDisabled  = { type: 'disabled' };

effort:努力度

effort?: EffortLevel;   // 'low' | 'medium' | 'high' | 'xhigh' | 'max'
级别 语义 支持模型
'low' 最少思考、最快
'medium' 适中
'high' 深度推理(默认
'xhigh' 比 high 更深 Fable 5 / Opus 4.7+ / Sonnet 5
'max' 最大努力 Fable 5 / Opus 4.6+ / Sonnet 4.6+

边界'max' 是会话级的、永不持久化。effort 与 adaptive thinking 协同引导思考深度〔sdk.d.ts:1654〕。

预算与轮数

选项 作用 触发后果
maxTurns?: number 最大对话轮数〔sdk.d.ts:1674-1678〕 超出 → result.subtype === 'error_max_turns'
maxBudgetUsd?: number 最大 USD 预算〔sdk.d.ts:1679-1683〕 超出 → 'error_max_budget_usd'
taskBudget?: { total: number }@alpha API 侧 token 任务预算,模型会感知剩余预算以规划工具使用〔sdk.d.ts:1684-1693〕 task-budgets-2026-03-13 beta header

边界maxTurns 的“一轮”= 一条用户消息 + 一条 assistant 回复〔sdk.d.ts:1676〕。设太小会频繁触发 error_max_turns——这不是崩溃,是策略性截断,要在外层据此决定是否续跑。maxBudgetUsd 是硬墙,超额即停。

会话与恢复

resume?: string;          // 恢复指定 session_id
continue?: boolean;       // 恢复当前目录最近一次会话
sessionId?: string;       // 用指定 UUID 作为新会话 ID
forkSession?: boolean;    // 恢复时分叉到新 session,而不是续写
resumeSessionAt?: string; // 仅恢复到某条消息(含)为止
persistSession?: boolean; // 是否落盘(默认 true)

互斥与组合规则(这是会话管理最容易踩坑的地方):

  1. continueresume 互斥〔sdk.d.ts:1382-1385〕。
  2. sessionId 不能continue/resume 同时用,除非也设了 forkSession(此时 sessionId 给分叉出的新会话指定 UUID)〔sdk.d.ts:1805-1809〕。
  3. resumeSessionAt 只能与 resume 搭配,消息 UUID 应取自 SDKAssistantMessage.uuid〔sdk.d.ts:1810-1815〕。
  4. forkSession:true 时,恢复会分叉出新 session_id,不污染原会话〔sdk.d.ts:1496-1500〕。

persistSessionsessionStore

  • persistSession 默认 true;设 false不落盘~/.claude/projects/,无法 resume〔sdk.d.ts:1580-1586〕。
  • sessionStore@alpha)把 transcript 镜像到外部存储;子进程仍会本地写(可把 CLAUDE_CONFIG_DIR 设到 /tmp 做临时本地副本)并双写到 adapter〔sdk.d.ts:1587-1598〕。
  • 硬约束sessionStore 不能persistSession:false 同用——镜像 hook 在本地写成功后才触发,没有本地写就没有镜像〔sdk.d.ts:1592-1593〕。
  • sessionStoreFlush?: 'batched' | 'eager' 控制刷新激进程度,默认 'batched'〔sdk.d.ts:1599-1606, 4905〕。
  • loadTimeoutMs(默认 60000)兜底 resume 载入超时,否则延迟 spawn 路径无上限地挂起迭代器〔sdk.d.ts:1607-1616〕。

SessionStore 契约要点〔sdk.d.ts:4793-4815〕:

  • append(key, entries):本地写成功调用,~100ms 一批;带 uuid 的条目应作为幂等键(upsert/去重),无 uuid 的(标题/标签)直接追加。
  • 拒绝会重试 3 次;超时(60s)不重试;最终失败则丢批并发出 mirror_error 系统消息,子进程不受影响

输入输出形态

systemPrompt:三种形态

systemPrompt?: string | string[] | {
  type: 'preset'; preset: 'claude_code';
  append?: string; excludeDynamicSections?: boolean;
};
```- `string`:完全替换系统提示。
- `string[]`:可插入**缓存边界标记** `SYSTEM_PROMPT_DYNAMIC_BOUNDARY`(`"__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__"`)〔sdk.d.ts:6855-6863〕。**边界之前**的块获得**跨会话全局缓存**作用域,**之后**的块是会话级、不全局缓存。这让你把“稳定的系统指令”和“每次会话变动的动态指令”分开,吃满 prompt cache。
- `{type:'preset', preset:'claude_code', append?, excludeDynamicSections?}`:保留默认 Claude Code 系统提示,追加 `append`,可选排除动态段落。

#### `outputFormat`:结构化输出

```ts
outputFormat?: OutputFormat;   // = JsonSchemaOutputFormat
type JsonSchemaOutputFormat = { type: 'json_schema'; schema: Record<string, unknown> };

〔sdk.d.ts:1714-1726, 2065, 930-933, 4314〕

设定后,成功结果里会出现 structured_output?: unknown,其内容匹配你给的 schema〔sdk.d.ts:4314〕。若结构化输出反复校验失败,会以 error_max_structured_output_retries 终结〔sdk.d.ts:4271〕。

扩展能力

  • mcpServers?: Record<string, McpServerConfig>:MCP 服务器配置(见 §7)〔sdk.d.ts:1694-1708〕。
  • agents?: Record<string, AgentDefinition>:自定义子代理(见 §8)〔sdk.d.ts:1367〕。
  • hooks?: Partial<Record<HookEvent, HookCallbackMatcher[]>>:钩子(见 §6)〔sdk.d.ts:1508-1521〕。
  • onElicitation?: OnElicitation:MCP elicitation(表单/URL 鉴权)回调;不提供且无 hook 处理时,elicitation 请求会被自动拒绝〔sdk.d.ts:1522-1542〕。
  • onUserDialog:处理 request_user_dialog 控制请求〔sdk.d.ts:1543〕。
  • betas?: SdkBeta[]:如 'context-1m-2025-08-07'(1M 上下文,仅 Sonnet 4/4.5)〔sdk.d.ts:1501-1507〕。