claude-agent-sdk

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Claude Agent SDK - Structured Outputs & Error Prevention Guide

Claude Agent SDK - 结构化输出与错误预防指南

Package: @anthropic-ai/claude-agent-sdk@0.2.12 Breaking Changes: v0.1.45 - Structured outputs (Nov 2025), v0.1.0 - No default system prompt, settingSources required

Package: @anthropic-ai/claude-agent-sdk@0.2.12 重大变更: v0.1.45 - 新增结构化输出(2025年11月),v0.1.0 - 无默认系统提示,需指定settingSources

What's New in v0.1.45+ (Nov 2025)

v0.1.45+版本新特性(2025年11月)

1. 结构化输出(v0.1.45,2025年11月14日)

Major Features:
  • JSON schema验证 - 确保响应与指定的精确 schema 匹配
  • outputFormat
    参数
    - 使用JSON schema或Zod定义输出结构
  • 访问验证后的结果 - 通过
    message.structured_output
    获取
  • 需添加Beta头:
    structured-outputs-2025-11-13
  • 类型安全 - 结合Zod schema实现完整TypeScript类型推断
示例:
typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

const schema = z.object({
  summary: z.string(),
  sentiment: z.enum(['positive', 'neutral', 'negative']),
  confidence: z.number().min(0).max(1)
});

const response = query({
  prompt: "Analyze this code review feedback",
  options: {
    model: "claude-sonnet-4-5",
    outputFormat: {
      type: "json_schema",
      json_schema: {
        name: "AnalysisResult",
        strict: true,
        schema: zodToJsonSchema(schema)
      }
    }
  }
});

for await (const message of response) {
  if (message.type === 'result' && message.structured_output) {
    // 保证匹配schema
    const validated = schema.parse(message.structured_output);
    console.log(`Sentiment: ${validated.sentiment}`);
  }
}
Zod兼容性(v0.1.71+): SDK支持Zod v3.24.1+和Zod v4.0.0+作为对等依赖。无论使用哪个版本,导入方式均为
import { z } from "zod"

1. Structured Outputs (v0.1.45, Nov 14, 2025)

2. 插件系统(v0.1.27)

  • JSON schema validation - Guarantees responses match exact schemas
  • outputFormat
    parameter
    - Define output structure with JSON schema or Zod
  • Access validated results - Via
    message.structured_output
  • Beta header required:
    structured-outputs-2025-11-13
  • Type safety - Full TypeScript inference with Zod schemas
Example:
typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

const schema = z.object({
  summary: z.string(),
  sentiment: z.enum(['positive', 'neutral', 'negative']),
  confidence: z.number().min(0).max(1)
});

const response = query({
  prompt: "Analyze this code review feedback",
  options: {
    model: "claude-sonnet-4-5",
    outputFormat: {
      type: "json_schema",
      json_schema: {
        name: "AnalysisResult",
        strict: true,
        schema: zodToJsonSchema(schema)
      }
    }
  }
});

for await (const message of response) {
  if (message.type === 'result' && message.structured_output) {
    // Guaranteed to match schema
    const validated = schema.parse(message.structured_output);
    console.log(`Sentiment: ${validated.sentiment}`);
  }
}
Zod Compatibility (v0.1.71+): SDK supports both Zod v3.24.1+ and Zod v4.0.0+ as peer dependencies. Import remains
import { z } from "zod"
for either version.
  • plugins
    数组
    - 加载本地插件路径
  • 自定义插件支持 - 扩展代理能力

2. Plugins System (v0.1.27)

3. 钩子系统(v0.1.0+)

  • plugins
    array
    - Load local plugin paths
  • Custom plugin support - Extend agent capabilities
全部12种钩子事件:
钩子触发时机适用场景
PreToolUse
工具执行前验证、修改或阻止工具调用
PostToolUse
工具执行后记录结果、触发副作用
Notification
代理发送通知时显示状态更新
UserPromptSubmit
收到用户提示时预处理或验证输入
SubagentStart
子代理启动时跟踪任务委托、记录上下文
SubagentStop
子代理完成时汇总结果、清理资源
PreCompact
上下文压缩前保存截断前的状态
PermissionRequest
需要权限时自定义审批工作流
Stop
代理停止时清理资源、最终日志记录
SessionStart
会话开始时初始化状态
SessionEnd
会话结束时持久化状态、清理资源
Error
发生错误时自定义错误处理
钩子配置:
typescript
const response = query({
  prompt: "...",
  options: {
    hooks: {
      PreToolUse: async (input) => {
        console.log(`Tool: ${input.toolName}`);
        return { allow: true };  // 或 { allow: false, message: "..." }
      },
      PostToolUse: async (input) => {
        await logToolUsage(input.toolName, input.result);
      }
    }
  }
});

3. Hooks System (v0.1.0+)

4. 其他选项

All 12 Hook Events:
HookWhen FiredUse Case
PreToolUse
Before tool executionValidate, modify, or block tool calls
PostToolUse
After tool executionLog results, trigger side effects
Notification
Agent notificationsDisplay status updates
UserPromptSubmit
User prompt receivedPre-process or validate input
SubagentStart
Subagent spawnedTrack delegation, log context
SubagentStop
Subagent completedAggregate results, cleanup
PreCompact
Before context compactionSave state before truncation
PermissionRequest
Permission neededCustom approval workflows
Stop
Agent stoppingCleanup, final logging
SessionStart
Session beginsInitialize state
SessionEnd
Session endsPersist state, cleanup
Error
Error occurredCustom error handling
Hook Configuration:
typescript
const response = query({
  prompt: "...",
  options: {
    hooks: {
      PreToolUse: async (input) => {
        console.log(`Tool: ${input.toolName}`);
        return { allow: true };  // or { allow: false, message: "..." }
      },
      PostToolUse: async (input) => {
        await logToolUsage(input.toolName, input.result);
      }
    }
  }
});
  • fallbackModel
    - 失败时自动切换备用模型
  • maxThinkingTokens
    - 控制扩展思考预算
  • strictMcpConfig
    - 严格的MCP配置验证
  • continue
    - 使用新提示恢复会话(与
    resume
    不同)
  • permissionMode: 'plan'
    - 用于规划工作流的新权限模式

4. Additional Options

Claude Agent SDK完整参考

目录

  • fallbackModel
    - Automatic model fallback on failures
  • maxThinkingTokens
    - Control extended thinking budget
  • strictMcpConfig
    - Strict MCP configuration validation
  • continue
    - Resume with new prompt (differs from
    resume
    )
  • permissionMode: 'plan'
    - New permission mode for planning workflows

The Complete Claude Agent SDK Reference

核心Query API

Table of Contents

关键签名:
typescript
query(prompt: string | AsyncIterable<SDKUserMessage>, options?: Options)
  -> AsyncGenerator<SDKMessage>
重要选项:
  • outputFormat
    - 结构化JSON schema验证(v0.1.45+)
  • settingSources
    - 文件系统设置加载来源('user'|'project'|'local')
  • canUseTool
    - 自定义权限逻辑回调
  • agents
    - 程序化子代理定义
  • mcpServers
    - MCP服务器配置
  • permissionMode
    - 'default'|'acceptEdits'|'bypassPermissions'|'plan'
  • betas
    - 启用Beta功能(如1M上下文窗口)
  • sandbox
    - 用于安全执行的沙箱设置
  • enableFileCheckpointing
    - 启用文件状态快照
  • systemPrompt
    - 系统提示(字符串或预设对象)

Core Query API

扩展上下文(1M令牌)

Key signature:
typescript
query(prompt: string | AsyncIterable<SDKUserMessage>, options?: Options)
  -> AsyncGenerator<SDKMessage>
Critical Options:
  • outputFormat
    - Structured JSON schema validation (v0.1.45+)
  • settingSources
    - Filesystem settings loading ('user'|'project'|'local')
  • canUseTool
    - Custom permission logic callback
  • agents
    - Programmatic subagent definitions
  • mcpServers
    - MCP server configuration
  • permissionMode
    - 'default'|'acceptEdits'|'bypassPermissions'|'plan'
  • betas
    - Enable beta features (e.g., 1M context window)
  • sandbox
    - Sandbox settings for secure execution
  • enableFileCheckpointing
    - Enable file state snapshots
  • systemPrompt
    - System prompt (string or preset object)
启用100万令牌上下文窗口:
typescript
const response = query({
  prompt: "Analyze this large codebase",
  options: {
    betas: ['context-1m-2025-08-07'],  // 启用1M上下文
    model: "claude-sonnet-4-5"
  }
});

Extended Context (1M Tokens)

系统提示配置

Enable 1 million token context window:
typescript
const response = query({
  prompt: "Analyze this large codebase",
  options: {
    betas: ['context-1m-2025-08-07'],  // Enable 1M context
    model: "claude-sonnet-4-5"
  }
});
两种systemPrompt形式:
typescript
// 1. 简单字符串
systemPrompt: "You are a helpful coding assistant."

// 2. 预设形式(保留Claude Code默认行为并添加自定义内容)
systemPrompt: {
  type: 'preset',
  preset: 'claude_code',
  append: "\n\nAdditional context: Focus on security."
}
推荐使用预设形式,这样既能保留Claude Code的默认行为,又能添加自定义内容。

System Prompt Configuration

工具集成(内置+自定义)

Two forms of systemPrompt:
typescript
// 1. Simple string
systemPrompt: "You are a helpful coding assistant."

// 2. Preset with optional append (preserves Claude Code defaults)
systemPrompt: {
  type: 'preset',
  preset: 'claude_code',
  append: "\n\nAdditional context: Focus on security."
}
Use preset form when you want Claude Code's default behaviors plus custom additions.

工具控制:
  • allowedTools
    - 白名单(优先级最高)
  • disallowedTools
    - 黑名单
  • canUseTool
    - 自定义权限回调(见权限控制章节)
内置工具: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, Task, NotebookEdit, BashOutput, KillBash, ListMcpResources, ReadMcpResource, AskUserQuestion

Tool Integration (Built-in + Custom)

AskUserQuestion工具(v0.1.71+)

Tool Control:
  • allowedTools
    - Whitelist (takes precedence)
  • disallowedTools
    - Blacklist
  • canUseTool
    - Custom permission callback (see Permission Control section)
Built-in Tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, Task, NotebookEdit, BashOutput, KillBash, ListMcpResources, ReadMcpResource, AskUserQuestion
允许代理执行过程中与用户交互:
typescript
const response = query({
  prompt: "Review and refactor the codebase",
  options: {
    allowedTools: ["Read", "Write", "Edit", "AskUserQuestion"]
  }
});

// 代理现在可以提出澄清问题
// 问题会以tool_call形式出现在消息流中,名称为"AskUserQuestion"
适用场景:
  • 任务执行中澄清模糊需求
  • 执行破坏性操作前获取用户批准
  • 提供选项并获取用户选择

AskUserQuestion Tool (v0.1.71+)

工具配置(v0.1.57+)

Enable user interaction during agent execution:
typescript
const response = query({
  prompt: "Review and refactor the codebase",
  options: {
    allowedTools: ["Read", "Write", "Edit", "AskUserQuestion"]
  }
});

// Agent can now ask clarifying questions
// Questions appear in message stream as tool_call with name "AskUserQuestion"
Use cases:
  • Clarify ambiguous requirements mid-task
  • Get user approval before destructive operations
  • Present options and get selection
三种工具配置形式:
typescript
// 1. 精确白名单(字符串数组)
tools: ["Read", "Write", "Grep"]

// 2. 禁用所有工具(空数组)
tools: []

// 3. 预设默认值(对象形式)
tools: { type: 'preset', preset: 'claude_code' }
注意:
allowedTools
disallowedTools
仍然可用,但
tools
提供了更大的灵活性。

Tools Configuration (v0.1.57+)

MCP服务器(模型上下文协议)

Three forms of tool configuration:
typescript
// 1. Exact allowlist (string array)
tools: ["Read", "Write", "Grep"]

// 2. Disable all tools (empty array)
tools: []

// 3. Preset with defaults (object form)
tools: { type: 'preset', preset: 'claude_code' }
Note:
allowedTools
and
disallowedTools
still work but
tools
provides more flexibility.

服务器类型:
  • 进程内 - 使用
    createSdkMcpServer()
    tool()
    定义
  • 外部 - stdio、HTTP、SSE传输
工具定义:
typescript
tool(name: string, description: string, zodSchema, handler)
处理器返回值:
typescript
{ content: [{ type: "text", text: "..." }], isError?: boolean }

MCP Servers (Model Context Protocol)

外部MCP服务器(stdio)

Server Types:
  • In-process -
    createSdkMcpServer()
    with
    tool()
    definitions
  • External - stdio, HTTP, SSE transport
Tool Definition:
typescript
tool(name: string, description: string, zodSchema, handler)
Handler Return:
typescript
{ content: [{ type: "text", text: "..." }], isError?: boolean }
typescript
const response = query({
  prompt: "List files and analyze Git history",
  options: {
    mcpServers: {
      // 文件系统服务器
      "filesystem": {
        command: "npx",
        args: ["@modelcontextprotocol/server-filesystem"],
        env: {
          ALLOWED_PATHS: "/Users/developer/projects:/tmp"
        }
      },
      // Git操作服务器
      "git": {
        command: "npx",
        args: ["@modelcontextprotocol/server-git"],
        env: {
          GIT_REPO_PATH: "/Users/developer/projects/my-repo"
        }
      }
    },
    allowedTools: [
      "mcp__filesystem__list_files",
      "mcp__filesystem__read_file",
      "mcp__git__log",
      "mcp__git__diff"
    ]
  }
});

External MCP Servers (stdio)

外部MCP服务器(HTTP/SSE)

typescript
const response = query({
  prompt: "List files and analyze Git history",
  options: {
    mcpServers: {
      // Filesystem server
      "filesystem": {
        command: "npx",
        args: ["@modelcontextprotocol/server-filesystem"],
        env: {
          ALLOWED_PATHS: "/Users/developer/projects:/tmp"
        }
      },
      // Git operations server
      "git": {
        command: "npx",
        args: ["@modelcontextprotocol/server-git"],
        env: {
          GIT_REPO_PATH: "/Users/developer/projects/my-repo"
        }
      }
    },
    allowedTools: [
      "mcp__filesystem__list_files",
      "mcp__filesystem__read_file",
      "mcp__git__log",
      "mcp__git__diff"
    ]
  }
});
typescript
const response = query({
  prompt: "Analyze data from remote service",
  options: {
    mcpServers: {
      "remote-service": {
        url: "https://api.example.com/mcp",
        headers: {
          "Authorization": "Bearer your-token-here",
          "Content-Type": "application/json"
        }
      }
    },
    allowedTools: ["mcp__remote-service__analyze"]
  }
});

External MCP Servers (HTTP/SSE)

MCP工具命名规范

typescript
const response = query({
  prompt: "Analyze data from remote service",
  options: {
    mcpServers: {
      "remote-service": {
        url: "https://api.example.com/mcp",
        headers: {
          "Authorization": "Bearer your-token-here",
          "Content-Type": "application/json"
        }
      }
    },
    allowedTools: ["mcp__remote-service__analyze"]
  }
});
格式:
mcp__<server-name>__<tool-name>
关键注意事项:
  • 服务器名称和工具名称必须与配置匹配
  • 使用双下划线(
    __
    )作为分隔符
  • 需添加到
    allowedTools
    数组中
示例:
mcp__weather-service__get_weather
,
mcp__filesystem__read_file

MCP Tool Naming Convention

子代理编排

AgentDefinition类型

Format:
mcp__<server-name>__<tool-name>
CRITICAL:
  • Server name and tool name MUST match configuration
  • Use double underscores (
    __
    ) as separators
  • Include in
    allowedTools
    array
Examples:
mcp__weather-service__get_weather
,
mcp__filesystem__read_file

typescript
type AgentDefinition = {
  description: string;        // 该代理的适用场景
  prompt: string;             // 代理的系统提示
  tools?: string[];           // 允许使用的工具(可选)
  model?: 'sonnet' | 'opus' | 'haiku' | 'inherit';  // 模型(可选)
  skills?: string[];          // 加载的技能(v0.2.10+)
  maxTurns?: number;          // 停止前的最大轮次(v0.2.10+)
}
字段详情:
  • description: 代理的适用场景(主代理用于任务委托)
  • prompt: 系统提示(定义角色,继承主上下文)
  • tools: 允许使用的工具(若省略,继承自主代理)
  • model: 模型覆盖选项(
    haiku
    /
    sonnet
    /
    opus
    /
    inherit
  • skills: 为代理加载的技能(v0.2.10+)
  • maxTurns: 代理返回控制权前的最大轮次(v0.2.10+)
用法:
typescript
agents: {
  "security-checker": {
    description: "Security audits and vulnerability scanning",
    prompt: "You check security. Scan for secrets, verify OWASP compliance.",
    tools: ["Read", "Grep", "Bash"],
    model: "sonnet",
    skills: ["security-best-practices"],  // 加载特定技能
    maxTurns: 10  // 限制为10轮
  }
}

Subagent Orchestration

⚠️ 子代理清理警告

AgentDefinition Type

typescript
type AgentDefinition = {
  description: string;        // When to use this agent
  prompt: string;             // System prompt for agent
  tools?: string[];           // Allowed tools (optional)
  model?: 'sonnet' | 'opus' | 'haiku' | 'inherit';  // Model (optional)
  skills?: string[];          // Skills to load (v0.2.10+)
  maxTurns?: number;          // Maximum turns before stopping (v0.2.10+)
}
Field Details:
  • description: When to use agent (used by main agent for delegation)
  • prompt: System prompt (defines role, inherits main context)
  • tools: Allowed tools (if omitted, inherits from main agent)
  • model: Model override (
    haiku
    /
    sonnet
    /
    opus
    /
    inherit
    )
  • skills: Skills to load for agent (v0.2.10+)
  • maxTurns: Limit agent to N turns before returning control (v0.2.10+)
Usage:
typescript
agents: {
  "security-checker": {
    description: "Security audits and vulnerability scanning",
    prompt: "You check security. Scan for secrets, verify OWASP compliance.",
    tools: ["Read", "Grep", "Bash"],
    model: "sonnet",
    skills: ["security-best-practices"],  // Load specific skills
    maxTurns: 10  // Limit to 10 turns
  }
}
已知问题: 父代理停止时,子代理不会自动停止(Issue #132
当父代理停止(通过取消或错误)时,已生成的子代理会作为孤立进程继续运行,可能导致:
解决方法: 在Stop钩子中实现清理逻辑:
typescript
const response = query({
  prompt: "Deploy to production",
  options: {
    agents: {
      "deployer": {
        description: "Handle deployments",
        prompt: "Deploy the application",
        tools: ["Bash"]
      }
    },
    hooks: {
      Stop: async (input) => {
        // 手动清理生成的进程
        console.log("Parent stopped - cleaning up subagents");
        // 实现进程跟踪和终止逻辑
      }
    }
  }
});
增强功能跟踪: Issue #142 提出了自动终止的建议

⚠️ Subagent Cleanup Warning

会话管理

Known Issue: Subagents don't stop when parent agent stops (Issue #132)
When a parent agent is stopped (via cancellation or error), spawned subagents continue running as orphaned processes. This can lead to:
  • Resource leaks
  • Continued tool execution after parent stopped
  • RAM out-of-memory in recursive scenarios (Claude Code Issue #4850)
Workaround: Implement cleanup in Stop hooks:
typescript
const response = query({
  prompt: "Deploy to production",
  options: {
    agents: {
      "deployer": {
        description: "Handle deployments",
        prompt: "Deploy the application",
        tools: ["Bash"]
      }
    },
    hooks: {
      Stop: async (input) => {
        // Manual cleanup of spawned processes
        console.log("Parent stopped - cleaning up subagents");
        // Implement process tracking and termination
      }
    }
  }
});
Enhancement Tracking: Issue #142 proposes auto-termination

选项:
  • resume: sessionId
    - 继续之前的会话
  • forkSession: true
    - 从会话创建新分支
  • continue: prompt
    - 使用新提示恢复会话(与
    resume
    不同)
会话分支模式(独特功能):
typescript
// 在不修改原始会话的情况下探索替代方案
const forked = query({
  prompt: "Try GraphQL instead of REST",
  options: {
    resume: sessionId,
    forkSession: true  // 创建新分支,原始会话保持不变
  }
});
捕获会话ID:
typescript
for await (const message of response) {
  if (message.type === 'system' && message.subtype === 'init') {
    sessionId = message.session_id;  // 保存以便后续恢复/分支
  }
}

Session Management

V2会话API(预览版 - v0.1.54+)

Options:
  • resume: sessionId
    - Continue previous session
  • forkSession: true
    - Create new branch from session
  • continue: prompt
    - Resume with new prompt (differs from
    resume
    )
Session Forking Pattern (Unique Capability):
typescript
// Explore alternative without modifying original
const forked = query({
  prompt: "Try GraphQL instead of REST",
  options: {
    resume: sessionId,
    forkSession: true  // Creates new branch, original session unchanged
  }
});
Capture Session ID:
typescript
for await (const message of response) {
  if (message.type === 'system' && message.subtype === 'init') {
    sessionId = message.session_id;  // Save for later resume/fork
  }
}
更简洁的多轮对话模式:
typescript
import {
  unstable_v2_createSession,
  unstable_v2_resumeSession,
  unstable_v2_prompt
} from "@anthropic-ai/claude-agent-sdk";

// 创建新会话
const session = await unstable_v2_createSession({
  model: "claude-sonnet-4-5",
  workingDirectory: process.cwd(),
  allowedTools: ["Read", "Grep", "Glob"]
});

// 发送提示并流式接收响应
const stream = unstable_v2_prompt(session, "Analyze the codebase structure");
for await (const message of stream) {
  console.log(message);
}

// 在同一会话中继续对话
const stream2 = unstable_v2_prompt(session, "Now suggest improvements");
for await (const message of stream2) {
  console.log(message);
}

// 恢复之前的会话
const resumedSession = await unstable_v2_resumeSession(session.sessionId);
注意: V2 API处于预览阶段(带有
unstable_
前缀)。在v0.1.72版本中,
.receive()
方法已重命名为
.stream()

V2 Session APIs (Preview - v0.1.54+)

权限控制

Simpler multi-turn conversation pattern:
typescript
import {
  unstable_v2_createSession,
  unstable_v2_resumeSession,
  unstable_v2_prompt
} from "@anthropic-ai/claude-agent-sdk";

// Create a new session
const session = await unstable_v2_createSession({
  model: "claude-sonnet-4-5",
  workingDirectory: process.cwd(),
  allowedTools: ["Read", "Grep", "Glob"]
});

// Send prompts and stream responses
const stream = unstable_v2_prompt(session, "Analyze the codebase structure");
for await (const message of stream) {
  console.log(message);
}

// Continue conversation in same session
const stream2 = unstable_v2_prompt(session, "Now suggest improvements");
for await (const message of stream2) {
  console.log(message);
}

// Resume a previous session
const resumedSession = await unstable_v2_resumeSession(session.sessionId);
Note: V2 APIs are in preview (
unstable_
prefix). The
.receive()
method was renamed to
.stream()
in v0.1.72.

权限模式:
typescript
type PermissionMode = "default" | "acceptEdits" | "bypassPermissions" | "plan";
  • default
    - 标准权限检查
  • acceptEdits
    - 自动批准文件编辑
  • bypassPermissions
    - 跳过所有检查(仅在CI/CD中使用)
  • plan
    - 规划模式(v0.1.45+)

Permission Control

自定义权限逻辑

Permission Modes:
typescript
type PermissionMode = "default" | "acceptEdits" | "bypassPermissions" | "plan";
  • default
    - Standard permission checks
  • acceptEdits
    - Auto-approve file edits
  • bypassPermissions
    - Skip ALL checks (use in CI/CD only)
  • plan
    - Planning mode (v0.1.45+)
typescript
const response = query({
  prompt: "Deploy application to production",
  options: {
    permissionMode: "default",
    canUseTool: async (toolName, input) => {
      // 允许只读操作
      if (['Read', 'Grep', 'Glob'].includes(toolName)) {
        return { behavior: "allow" };
      }

      // 阻止破坏性bash命令
      if (toolName === 'Bash') {
        const dangerous = ['rm -rf', 'dd if=', 'mkfs', '> /dev/'];
        if (dangerous.some(pattern => input.command.includes(pattern))) {
          return {
            behavior: "deny",
            message: "Destructive command blocked for safety"
          };
        }
      }

      // 部署操作需要确认
      if (input.command?.includes('deploy') || input.command?.includes('kubectl apply')) {
        return {
          behavior: "ask",
          message: "Confirm deployment to production?"
        };
      }

      // 默认允许
      return { behavior: "allow" };
    }
  }
});

Custom Permission Logic

canUseTool回调

typescript
const response = query({
  prompt: "Deploy application to production",
  options: {
    permissionMode: "default",
    canUseTool: async (toolName, input) => {
      // Allow read-only operations
      if (['Read', 'Grep', 'Glob'].includes(toolName)) {
        return { behavior: "allow" };
      }

      // Deny destructive bash commands
      if (toolName === 'Bash') {
        const dangerous = ['rm -rf', 'dd if=', 'mkfs', '> /dev/'];
        if (dangerous.some(pattern => input.command.includes(pattern))) {
          return {
            behavior: "deny",
            message: "Destructive command blocked for safety"
          };
        }
      }

      // Require confirmation for deployments
      if (input.command?.includes('deploy') || input.command?.includes('kubectl apply')) {
        return {
          behavior: "ask",
          message: "Confirm deployment to production?"
        };
      }

      // Allow by default
      return { behavior: "allow" };
    }
  }
});
typescript
type CanUseToolCallback = (
  toolName: string,
  input: any
) => Promise<PermissionDecision>;

type PermissionDecision =
  | { behavior: "allow" }
  | { behavior: "deny"; message?: string }
  | { behavior: "ask"; message?: string };
示例:
typescript
// 阻止所有文件写入操作
canUseTool: async (toolName, input) => {
  if (toolName === 'Write' || toolName === 'Edit') {
    return { behavior: "deny", message: "No file modifications allowed" };
  }
  return { behavior: "allow" };
}

// 特定文件需要确认
canUseTool: async (toolName, input) => {
  const sensitivePaths = ['/etc/', '/root/', '.env', 'credentials.json'];
  if ((toolName === 'Write' || toolName === 'Edit') &&
      sensitivePaths.some(path => input.file_path?.includes(path))) {
    return {
      behavior: "ask",
      message: `Modify sensitive file ${input.file_path}?`
    };
  }
  return { behavior: "allow" };
}

// 记录所有工具使用情况
canUseTool: async (toolName, input) => {
  console.log(`Tool requested: ${toolName}`, input);
  await logToDatabase(toolName, input);
  return { behavior: "allow" };
}

canUseTool Callback

沙箱设置(安全关键)

typescript
type CanUseToolCallback = (
  toolName: string,
  input: any
) => Promise<PermissionDecision>;

type PermissionDecision =
  | { behavior: "allow" }
  | { behavior: "deny"; message?: string }
  | { behavior: "ask"; message?: string };
Examples:
typescript
// Block all file writes
canUseTool: async (toolName, input) => {
  if (toolName === 'Write' || toolName === 'Edit') {
    return { behavior: "deny", message: "No file modifications allowed" };
  }
  return { behavior: "allow" };
}

// Require confirmation for specific files
canUseTool: async (toolName, input) => {
  const sensitivePaths = ['/etc/', '/root/', '.env', 'credentials.json'];
  if ((toolName === 'Write' || toolName === 'Edit') &&
      sensitivePaths.some(path => input.file_path?.includes(path))) {
    return {
      behavior: "ask",
      message: `Modify sensitive file ${input.file_path}?`
    };
  }
  return { behavior: "allow" };
}

// Log all tool usage
canUseTool: async (toolName, input) => {
  console.log(`Tool requested: ${toolName}`, input);
  await logToDatabase(toolName, input);
  return { behavior: "allow" };
}

为Bash命令启用沙箱执行:
typescript
const response = query({
  prompt: "Run system diagnostics",
  options: {
    sandbox: {
      enabled: true,
      autoAllowBashIfSandboxed: true,  // 沙箱中自动批准bash命令
      excludedCommands: ["rm", "dd", "mkfs"],  // 永远需要权限的命令
      allowUnsandboxedCommands: false  // 拒绝无法沙箱化的命令
    }
  }
});

Sandbox Settings (Security-Critical)

SandboxSettings类型

Enable sandboxed execution for Bash commands:
typescript
const response = query({
  prompt: "Run system diagnostics",
  options: {
    sandbox: {
      enabled: true,
      autoAllowBashIfSandboxed: true,  // Auto-approve bash in sandbox
      excludedCommands: ["rm", "dd", "mkfs"],  // Never auto-approve these
      allowUnsandboxedCommands: false  // Deny unsandboxable commands
    }
  }
});
typescript
type SandboxSettings = {
  enabled: boolean;
  autoAllowBashIfSandboxed?: boolean;  // 默认值: false
  excludedCommands?: string[];
  allowUnsandboxedCommands?: boolean;  // 默认值: false
  network?: NetworkSandboxSettings;
  ignoreViolations?: SandboxIgnoreViolations;
};

type NetworkSandboxSettings = {
  enabled: boolean;
  proxyUrl?: string;  // 网络请求的HTTP代理
};
关键选项:
  • enabled
    - 激活沙箱隔离
  • autoAllowBashIfSandboxed
    - 跳过安全bash命令的权限提示
  • excludedCommands
    - 始终需要权限的命令
  • allowUnsandboxedCommands
    - 允许无法沙箱化的命令(有风险)
  • network.proxyUrl
    - 通过代理路由网络请求以进行监控
最佳实践: 在处理不受信任输入的生产代理中始终使用沙箱。

SandboxSettings Type

文件检查点

typescript
type SandboxSettings = {
  enabled: boolean;
  autoAllowBashIfSandboxed?: boolean;  // Default: false
  excludedCommands?: string[];
  allowUnsandboxedCommands?: boolean;  // Default: false
  network?: NetworkSandboxSettings;
  ignoreViolations?: SandboxIgnoreViolations;
};

type NetworkSandboxSettings = {
  enabled: boolean;
  proxyUrl?: string;  // HTTP proxy for network requests
};
Key Options:
  • enabled
    - Activate sandbox isolation
  • autoAllowBashIfSandboxed
    - Skip permission prompts for safe bash commands
  • excludedCommands
    - Commands that always require permission
  • allowUnsandboxedCommands
    - Allow commands that can't be sandboxed (risky)
  • network.proxyUrl
    - Route network through proxy for monitoring
Best Practice: Always use sandbox in production agents handling untrusted input.

启用文件状态快照以支持回滚功能:
typescript
const response = query({
  prompt: "Refactor the authentication module",
  options: {
    enableFileCheckpointing: true  // 启用文件快照
  }
});

// 后续: 将文件更改回滚到特定点
for await (const message of response) {
  if (message.type === 'user' && message.uuid) {
    // 后续可以回滚到该点
    const userMessageUuid = message.uuid;

    // 回滚操作(调用Query对象的方法)
    await response.rewindFiles(userMessageUuid);
  }
}
适用场景:
  • 撤销失败的重构尝试
  • A/B测试代码变更
  • 安全探索替代方案

File Checkpointing

文件系统设置

Enable file state snapshots for rollback capability:
typescript
const response = query({
  prompt: "Refactor the authentication module",
  options: {
    enableFileCheckpointing: true  // Enable file snapshots
  }
});

// Later: rewind file changes to a specific point
for await (const message of response) {
  if (message.type === 'user' && message.uuid) {
    // Can rewind to this point later
    const userMessageUuid = message.uuid;

    // To rewind (call on Query object)
    await response.rewindFiles(userMessageUuid);
  }
}
Use cases:
  • Undo failed refactoring attempts
  • A/B test code changes
  • Safe exploration of alternatives

设置来源:
typescript
type SettingSource = 'user' | 'project' | 'local';
  • user
    -
    ~/.claude/settings.json
    (全局)
  • project
    -
    .claude/settings.json
    (团队共享)
  • local
    -
    .claude/settings.local.json
    (Git忽略的本地覆盖配置)
默认值: 不加载任何设置(
settingSources: []

Filesystem Settings

设置优先级

Setting Sources:
typescript
type SettingSource = 'user' | 'project' | 'local';
  • user
    -
    ~/.claude/settings.json
    (global)
  • project
    -
    .claude/settings.json
    (team-shared)
  • local
    -
    .claude/settings.local.json
    (gitignored overrides)
Default: NO settings loaded (
settingSources: []
)
当加载多个来源时,设置按以下顺序合并(优先级从高到低):
  1. 程序化选项(传递给
    query()
    )- 优先级最高
  2. 本地设置
    .claude/settings.local.json
  3. 项目设置
    .claude/settings.json
  4. 用户设置
    ~/.claude/settings.json
示例:
typescript
// .claude/settings.json
{
  "allowedTools": ["Read", "Write", "Edit"]
}

// .claude/settings.local.json
{
  "allowedTools": ["Read"]  // 覆盖项目设置
}

// 程序化配置
const response = query({
  options: {
    settingSources: ["project", "local"],
    allowedTools: ["Read", "Grep"]  // ← 此配置优先级最高
  }
});

// 实际生效的allowedTools: ["Read", "Grep"]
最佳实践: 在CI/CD中使用
settingSources: ["project"]
以确保行为一致。

Settings Priority

Query对象方法

When multiple sources loaded, settings merge in this order (highest priority first):
  1. Programmatic options (passed to
    query()
    ) - Always win
  2. Local settings (
    .claude/settings.local.json
    )
  3. Project settings (
    .claude/settings.json
    )
  4. User settings (
    ~/.claude/settings.json
    )
Example:
typescript
// .claude/settings.json
{
  "allowedTools": ["Read", "Write", "Edit"]
}

// .claude/settings.local.json
{
  "allowedTools": ["Read"]  // Overrides project settings
}

// Programmatic
const response = query({
  options: {
    settingSources: ["project", "local"],
    allowedTools: ["Read", "Grep"]  // ← This wins
  }
});

// Actual allowedTools: ["Read", "Grep"]
Best Practice: Use
settingSources: ["project"]
in CI/CD for consistent behavior.

query()
函数返回一个
Query
对象,包含以下方法:
typescript
const q = query({ prompt: "..." });

// 异步迭代(主要用法)
for await (const message of q) { ... }

// 运行时模型控制
await q.setModel("claude-opus-4-5");           // 会话中切换模型
await q.setMaxThinkingTokens(4096);            // 设置思考预算

// 内省
const models = await q.supportedModels();     // 列出可用模型
const commands = await q.supportedCommands(); // 列出可用命令
const account = await q.accountInfo();        // 获取账户详情

// MCP状态
const status = await q.mcpServerStatus();     // 检查MCP服务器状态
// 返回值: { [serverName]: { status: 'connected' | 'failed', error?: string } }

// 文件操作(需要启用enableFileCheckpointing)
await q.rewindFiles(userMessageUuid);         // 回滚到检查点
适用场景:
  • 根据任务复杂度动态切换模型
  • 监控MCP服务器健康状态
  • 为推理任务调整思考预算

Query Object Methods

消息类型与流式传输

The
query()
function returns a
Query
object with these methods:
typescript
const q = query({ prompt: "..." });

// Async iteration (primary usage)
for await (const message of q) { ... }

// Runtime model control
await q.setModel("claude-opus-4-5");           // Change model mid-session
await q.setMaxThinkingTokens(4096);            // Set thinking budget

// Introspection
const models = await q.supportedModels();     // List available models
const commands = await q.supportedCommands(); // List available commands
const account = await q.accountInfo();        // Get account details

// MCP status
const status = await q.mcpServerStatus();     // Check MCP server status
// Returns: { [serverName]: { status: 'connected' | 'failed', error?: string } }

// File operations (requires enableFileCheckpointing)
await q.rewindFiles(userMessageUuid);         // Rewind to checkpoint
Use cases:
  • Dynamic model switching based on task complexity
  • Monitoring MCP server health
  • Adjusting thinking budget for reasoning tasks

消息类型:
  • system
    - 会话初始化/完成(包含
    session_id
  • assistant
    - 代理响应
  • tool_call
    - 工具执行请求
  • tool_result
    - 工具执行结果
  • error
    - 错误消息
  • result
    - 最终结果(v0.1.45+包含
    structured_output
流式传输模式:
typescript
for await (const message of response) {
  if (message.type === 'system' && message.subtype === 'init') {
    sessionId = message.session_id;  // 捕获以便后续恢复/分支
  }
  if (message.type === 'result' && message.structured_output) {
    // 结构化输出可用(v0.1.45+)
    const validated = schema.parse(message.structured_output);
  }
}

Message Types & Streaming

错误处理

Message Types:
  • system
    - Session init/completion (includes
    session_id
    )
  • assistant
    - Agent responses
  • tool_call
    - Tool execution requests
  • tool_result
    - Tool execution results
  • error
    - Error messages
  • result
    - Final result (includes
    structured_output
    for v0.1.45+)
Streaming Pattern:
typescript
for await (const message of response) {
  if (message.type === 'system' && message.subtype === 'init') {
    sessionId = message.session_id;  // Capture for resume/fork
  }
  if (message.type === 'result' && message.structured_output) {
    // Structured output available (v0.1.45+)
    const validated = schema.parse(message.structured_output);
  }
}

错误代码:
错误代码原因解决方案
CLI_NOT_FOUND
未安装Claude Code安装:
npm install -g @anthropic-ai/claude-code
AUTHENTICATION_FAILED
API密钥无效检查ANTHROPIC_API_KEY环境变量
RATE_LIMIT_EXCEEDED
请求过多实现带退避的重试机制
CONTEXT_LENGTH_EXCEEDED
提示过长使用会话压缩,减少上下文
PERMISSION_DENIED
工具被阻止检查permissionMode和canUseTool配置
TOOL_EXECUTION_FAILED
工具执行错误检查工具实现
SESSION_NOT_FOUND
会话ID无效验证会话ID
MCP_SERVER_FAILED
服务器错误检查服务器配置

Error Handling

已知问题与预防

Error Codes:
Error CodeCauseSolution
CLI_NOT_FOUND
Claude Code not installedInstall:
npm install -g @anthropic-ai/claude-code
AUTHENTICATION_FAILED
Invalid API keyCheck ANTHROPIC_API_KEY env var
RATE_LIMIT_EXCEEDED
Too many requestsImplement retry with backoff
CONTEXT_LENGTH_EXCEEDED
Prompt too longUse session compaction, reduce context
PERMISSION_DENIED
Tool blockedCheck permissionMode, canUseTool
TOOL_EXECUTION_FAILED
Tool errorCheck tool implementation
SESSION_NOT_FOUND
Invalid session IDVerify session ID
MCP_SERVER_FAILED
Server errorCheck server configuration

本技能可预防14种已记录的问题:

Known Issues Prevention

问题#1: CLI未找到错误

This skill prevents 14 documented issues:
错误:
"Claude Code CLI not installed"
来源: SDK需要Claude Code CLI 原因: 未全局安装CLI 预防: 使用SDK前先安装:
npm install -g @anthropic-ai/claude-code

Issue #1: CLI Not Found Error

问题#2: 认证失败

Error:
"Claude Code CLI not installed"
Source: SDK requires Claude Code CLI Why It Happens: CLI not installed globally Prevention: Install before using SDK:
npm install -g @anthropic-ai/claude-code
错误:
"Invalid API key"
来源: 缺少或错误的ANTHROPIC_API_KEY 原因: 未设置环境变量 预防: 始终设置
export ANTHROPIC_API_KEY="sk-ant-..."

Issue #2: Authentication Failed

问题#3: 权限拒绝错误

Error:
"Invalid API key"
Source: Missing or incorrect ANTHROPIC_API_KEY Why It Happens: Environment variable not set Prevention: Always set
export ANTHROPIC_API_KEY="sk-ant-..."
错误: 工具执行被阻止 来源:
permissionMode
限制 原因: 权限配置不允许使用该工具 预防: 使用
allowedTools
或自定义
canUseTool
回调

Issue #3: Permission Denied Errors

问题#4: 上下文长度超出(会话中断)

Error: Tool execution blocked Source:
permissionMode
restrictions Why It Happens: Tool not allowed by permissions Prevention: Use
allowedTools
or custom
canUseTool
callback
错误:
"Prompt too long"
来源: 输入超出模型上下文窗口(Issue #138原因: 代码库过大、对话过长
⚠️ 关键行为: 一旦会话达到上下文限制:
  1. 该会话的所有后续请求都会返回"Prompt too long"
  2. /compact
    命令也会返回相同错误
  3. 会话永久损坏,必须放弃
预防策略:
typescript
// 1. 主动创建会话分支(在达到限制前创建检查点)
const checkpoint = query({
  prompt: "Checkpoint current state",
  options: {
    resume: sessionId,
    forkSession: true  // 在达到限制前创建分支
  }
});

// 2. 监控时间并主动轮换会话
const MAX_SESSION_TIME = 80 * 60 * 1000;  // 80分钟(在90分钟崩溃前)
let sessionStartTime = Date.now();

function shouldRotateSession() {
  return Date.now() - sessionStartTime > MAX_SESSION_TIME;
}

// 3. 在达到上下文限制前启动新会话
if (shouldRotateSession()) {
  const summary = await getSummary(currentSession);
  const newSession = query({
    prompt: `Continue with context: ${summary}`
  });
  sessionStartTime = Date.now();
}
注意: SDK会自动压缩上下文,但如果达到限制,会话将无法恢复

Issue #4: Context Length Exceeded (Session-Breaking)

问题#5: 工具执行超时

Error:
"Prompt too long"
Source: Input exceeds model context window (Issue #138) Why It Happens: Large codebase, long conversations
⚠️ Critical Behavior: Once a session hits context limit:
  1. All subsequent requests to that session return "Prompt too long"
  2. /compact
    command fails with same error
  3. Session is permanently broken and must be abandoned
Prevention Strategies:
typescript
// 1. Proactive session forking (create checkpoints before hitting limit)
const checkpoint = query({
  prompt: "Checkpoint current state",
  options: {
    resume: sessionId,
    forkSession: true  // Create branch before hitting limit
  }
});

// 2. Monitor time and rotate sessions proactively
const MAX_SESSION_TIME = 80 * 60 * 1000;  // 80 minutes (before 90-min crash)
let sessionStartTime = Date.now();

function shouldRotateSession() {
  return Date.now() - sessionStartTime > MAX_SESSION_TIME;
}

// 3. Start new sessions before hitting context limits
if (shouldRotateSession()) {
  const summary = await getSummary(currentSession);
  const newSession = query({
    prompt: `Continue with context: ${summary}`
  });
  sessionStartTime = Date.now();
}
Note: SDK auto-compacts, but if limit is reached, session becomes unrecoverable
错误: 工具无响应 来源: 工具执行时间过长 原因: 工具执行时间超过默认5分钟限制 预防: 在工具实现中添加超时处理

Issue #5: Tool Execution Timeout

问题#6: 会话未找到

Error: Tool doesn't respond Source: Long-running tool execution Why It Happens: Tool takes too long (>5 minutes default) Prevention: Implement timeout handling in tool implementations
错误:
"Invalid session ID"
来源: 会话过期或无效 原因: 会话ID不正确或过旧 预防: 从
system
初始化消息中捕获
session_id

Issue #6: Session Not Found

问题#7: MCP服务器连接失败

Error:
"Invalid session ID"
Source: Session expired or invalid Why It Happens: Session ID incorrect or too old Prevention: Capture
session_id
from
system
init message
错误: 服务器无响应 来源: 服务器未运行或配置错误 原因: 命令/URL不正确、服务器崩溃 预防: 独立测试MCP服务器,验证命令/URL

Issue #7: MCP Server Connection Failed

问题#8: 子代理定义错误

Error: Server not responding Source: Server not running or misconfigured Why It Happens: Command/URL incorrect, server crashed Prevention: Test MCP server independently, verify command/URL
错误: 无效的AgentDefinition 来源: 缺少必填字段 原因: 缺少
description
prompt
字段 预防: 始终包含
description
prompt
字段

Issue #8: Subagent Definition Errors

问题#9: 设置文件未找到

Error: Invalid AgentDefinition Source: Missing required fields Why It Happens:
description
or
prompt
missing Prevention: Always include
description
and
prompt
fields
错误:
"Cannot read settings"
来源: 设置文件不存在 原因:
settingSources
包含不存在的文件 预防: 在添加到来源前检查文件是否存在

Issue #9: Settings File Not Found

问题#10: 工具名称冲突

Error:
"Cannot read settings"
Source: Settings file doesn't exist Why It Happens:
settingSources
includes non-existent file Prevention: Check file exists before including in sources
错误: 工具名称重复 来源: 多个工具使用相同名称 原因: 两个MCP服务器定义了相同的工具名称 预防: 使用唯一的工具名称,以服务器名称为前缀

Issue #10: Tool Name Collision

问题#11: Zod Schema验证错误

Error: Duplicate tool name Source: Multiple tools with same name Why It Happens: Two MCP servers define same tool name Prevention: Use unique tool names, prefix with server name
错误: 工具输入无效 来源: 输入不匹配Zod schema 原因: 代理提供了错误的数据类型 预防: 使用带
.describe()
的描述性Zod schema

Issue #11: Zod Schema Validation Error

问题#12: 文件系统权限拒绝

Error: Invalid tool input Source: Input doesn't match Zod schema Why It Happens: Agent provided wrong data type Prevention: Use descriptive Zod schemas with
.describe()
错误: 无法访问路径 来源: 文件系统访问受限 原因: 路径超出
workingDirectory
或无权限 预防: 设置正确的
workingDirectory
,检查文件权限

Issue #12: Filesystem Permission Denied

问题#13: MCP服务器配置缺少
type
字段

Error: Cannot access path Source: Restricted filesystem access Why It Happens: Path outside
workingDirectory
or no permissions Prevention: Set correct
workingDirectory
, check file permissions
错误:
"Claude Code process exited with code 1"
(信息模糊,无上下文) 来源: GitHub Issue #131 原因: 基于URL的MCP服务器需要显式的
type: "http"
type: "sse"
字段 预防: 始终为基于URL的MCP服务器指定传输类型
typescript
// ❌ 错误 - 缺少type字段(导致模糊的退出代码1)
mcpServers: {
  "my-server": {
    url: "https://api.example.com/mcp"
  }
}

// ✅ 正确 - 基于URL的服务器需要type字段
mcpServers: {
  "my-server": {
    url: "https://api.example.com/mcp",
    type: "http"  // 或"sse"用于服务器发送事件
  }
}
诊断线索: 如果看到"process exited with code 1"且无其他上下文,请检查MCP服务器配置是否缺少
type
字段。

Issue #13: MCP Server Config Missing
type
Field

问题#14: MCP工具结果包含Unicode行分隔符

Error:
"Claude Code process exited with code 1"
(cryptic, no context) Source: GitHub Issue #131 Why It Happens: URL-based MCP servers require explicit
type: "http"
or
type: "sse"
field Prevention: Always specify transport type for URL-based MCP servers
typescript
// ❌ Wrong - missing type field (causes cryptic exit code 1)
mcpServers: {
  "my-server": {
    url: "https://api.example.com/mcp"
  }
}

// ✅ Correct - type field required for URL-based servers
mcpServers: {
  "my-server": {
    url: "https://api.example.com/mcp",
    type: "http"  // or "sse" for Server-Sent Events
  }
}
Diagnostic Clue: If you see "process exited with code 1" with no other context, check your MCP server configuration for missing
type
fields.
错误: JSON解析错误,代理挂起 来源: GitHub Issue #137 原因: Unicode U+2028(行分隔符)和U+2029(段落分隔符)在JSON中是合法的,但会破坏JavaScript解析 预防: 在MCP工具结果中转义这些字符
typescript
// MCP工具处理器 - 清理外部数据
tool("fetch_content", "Fetch text content", {}, async (args) => {
  const content = await fetchExternalData();

  // ✅ 清理Unicode行/段落分隔符
  const sanitized = content
    .replace(/\u2028/g, '\\u2028')
    .replace(/\u2029/g, '\\u2029');

  return {
    content: [{ type: "text", text: sanitized }]
  };
});
适用场景: 外部数据源(API、网页抓取、用户输入)可能包含这些字符

Issue #14: MCP Tool Result with Unicode Line Separators

官方文档

Error: JSON parse error, agent hangs Source: GitHub Issue #137 Why It Happens: Unicode U+2028 (line separator) and U+2029 (paragraph separator) are valid in JSON but break JavaScript parsing Prevention: Escape these characters in MCP tool results
typescript
// MCP tool handler - sanitize external data
tool("fetch_content", "Fetch text content", {}, async (args) => {
  const content = await fetchExternalData();

  // ✅ Sanitize Unicode line/paragraph separators
  const sanitized = content
    .replace(/\u2028/g, '\\u2028')
    .replace(/\u2029/g, '\\u2029');

  return {
    content: [{ type: "text", text: sanitized }]
  };
});
When This Matters: External data sources (APIs, web scraping, user input) that may contain these characters


令牌效率:
  • 不使用本技能: ~15,000令牌(MCP设置、权限模式、会话API、沙箱配置、钩子、结构化输出、错误处理)
  • 使用本技能: ~4,500令牌(全面覆盖v0.2.12版本 + 错误预防 + 高级模式)
  • 节省: ~70%(约10,500令牌)
预防的错误: 14种已记录的问题及确切解决方案(包括2个社区发现的陷阱) 核心价值: V2会话API、沙箱设置、文件检查点、Query方法、AskUserQuestion工具、结构化输出(v0.1.45+)、会话分支、canUseTool模式、完整钩子系统(12种事件)、Zod v4支持、子代理清理模式

最后验证: 2026-01-20 | 技能版本: 3.1.0 | 变更: 添加问题#13(MCP type字段)、问题#14(Unicode U+2028/U+2029)、扩展问题#4(会话中断)、添加带Stop钩子模式的子代理清理警告

Official Documentation


Token Efficiency:
  • Without skill: ~15,000 tokens (MCP setup, permission patterns, session APIs, sandbox config, hooks, structured outputs, error handling)
  • With skill: ~4,500 tokens (comprehensive v0.2.12 coverage + error prevention + advanced patterns)
  • Savings: ~70% (~10,500 tokens)
Errors prevented: 14 documented issues with exact solutions (including 2 community-sourced gotchas) Key value: V2 Session APIs, Sandbox Settings, File Checkpointing, Query methods, AskUserQuestion tool, structured outputs (v0.1.45+), session forking, canUseTool patterns, complete hooks system (12 events), Zod v4 support, subagent cleanup patterns

Last verified: 2026-01-20 | Skill version: 3.1.0 | Changes: Added Issue #13 (MCP type field), Issue #14 (Unicode U+2028/U+2029), expanded Issue #4 (session-breaking), added subagent cleanup warning with Stop hook pattern