Claude Code 学习站

Agent SDK 中的 Claude Code 功能加载指南

介绍如何在 Agent SDK 中通过 settingSources 加载 CLAUDE.md、技能(Skills)、钩子(Hooks)等文件系统级 Claude Code 功能,并说明各功能适用场景。

本页目录9
AI 摘要 · 已核查整理于 2026-07-29原文:Use Claude Code features in the SDK(Anthropic)Agent SDKClaude Code配置TypeScript/Python
要点速览
  • 省略 `settingSources` 时,`query()` 默认按 `["user", "project", "local"]` 读取用户、项目、本地三类文件系统设置;传空数组 `[]` 可关闭全部,仅保留编程方式配置的内容
  • `settingSources` 不控制的内容包括:托管策略设置、`~/.claude.json` 全局配置、自动记忆(auto memory)、claude.ai MCP 连接器——多租户部署时需额外设置 `strictMcpConfig: true` 和 `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` 才能彻底隔离
  • CLAUDE.md 与 `.claude/rules/*.md` 提供项目持久上下文;各级别(project/local/user)内容是叠加关系,没有强制优先级,冲突需在更具体的文件中显式声明覆盖规则
  • 技能(Skills)默认按需加载,`skills` 选项设为 `"all"`、技能名列表或 `[]`;设置 `skills` 后 SDK 会自动把 `Skill` 加入 `allowedTools`,若自定义了 `tools` 列表需手动包含 `Skill`
  • 钩子分为文件系统钩子(`settings.json` 中的 shell/http/mcp_tool/prompt/agent 命令)与编程钩子(传给 `query()` 的回调函数),二者并行执行,回调返回 `{}` 表示放行,返回带 `permissionDecision: "deny"` 的 `hookSpecificOutput` 表示拦截
  • 文档给出「选对功能」对照表:项目约定用 CLAUDE.md,按需参考资料/可复用工作流用 Skills,隔离子任务委派用 Subagents,多实例协作用 Agent teams(仅 CLI 功能),确定性拦截逻辑用 Hooks,外部服务结构化访问用 MCP

本文是对官方 Agent SDK 某页的中文整理,完整与最新内容以原文为准:https://code.claude.com/docs/en/agent-sdk/claude-code-features

Agent SDK 与 Claude Code 基于同一套底层实现,因此 SDK 编写的 agent 可以访问与 Claude Code 相同的、基于文件系统的功能:项目指令(CLAUDE.md 与 rules)、技能(skills)、钩子(hooks)等。

省略 settingSources 时,query() 读取的文件系统设置与 Claude Code CLI 相同:用户级、项目级、本地级设置,CLAUDE.md 文件,以及 .claude/ 下的 skills、agents、commands。若要在不加载这些内容的情况下运行,传入 settingSources: [],此时 agent 只拥有你以编程方式配置的能力。托管策略设置(managed policy settings)与全局 ~/.claude.json 配置无论该选项如何设置都会被读取(详见下文「settingSources 不控制的内容」)。

关于每个功能的用途与使用时机的概念性介绍,参见 Extend Claude Code

用 settingSources 控制文件系统设置

setting sources 选项(Python 中为 setting_sources;TypeScript 中为 settingSources)控制 SDK 加载哪些基于文件系统的设置。传入一个明确的列表来选择特定来源,或传入空数组关闭用户级、项目级、本地级设置。

下例通过将 settingSources 设为 ["user", "project"] 同时加载用户级与项目级设置:

from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessage
import asyncio


async def main():
    async for message in query(
        prompt="Help me refactor the auth module",
        options=ClaudeAgentOptions(
            # "user" loads from ~/.claude/, "project" loads from ./.claude/ in cwd.
            # Together they give the agent access to CLAUDE.md, skills, hooks, and
            # permissions from both locations.
            setting_sources=["user", "project"],
            allowed_tools=["Read", "Edit", "Bash"],
        ),
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text)
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(f"\nResult: {message.result}")


asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Help me refactor the auth module",
  options: {
    // "user" loads from ~/.claude/, "project" loads from ./.claude/ in cwd.
    // Together they give the agent access to CLAUDE.md, skills, hooks, and
    // permissions from both locations.
    settingSources: ["user", "project"],
    allowedTools: ["Read", "Edit", "Bash"]
  }
})) {
  if (message.type === "assistant") {
    for (const block of message.message.content) {
      if (block.type === "text") console.log(block.text);
    }
  }
  if (message.type === "result" && message.subtype === "success") {
    console.log(`\nResult: ${message.result}`);
  }
}

运行时,助手回复会打印到 stdout,运行结束后再打印一行最终结果。

每个来源从特定位置加载设置,其中 <cwd> 为你通过 cwd 选项传入的工作目录,若未设置则为进程当前目录。完整类型定义参见 TypeScript 的 SettingSource 与 Python 的 SettingSource

来源加载内容位置
"project"项目 CLAUDE.md、.claude/rules/*.md、项目技能、项目钩子、项目 settings.json<cwd>/.claude/(用于 settings.json 与钩子);<cwd> 及其所有父目录(用于 CLAUDE.md 与 rules);<cwd> 及其所有父目录直到仓库根目录(用于 skills)
"user"用户 CLAUDE.md、~/.claude/rules/*.md、用户技能、用户设置~/.claude/
"local"CLAUDE.local.md、.claude/settings.local.json<cwd>/.claude/(用于 settings.local.json);<cwd> 及其所有父目录(用于 CLAUDE.local.md)

省略 settingSources 等价于 ["user", "project", "local"]

cwd 选项决定 SDK 从哪里查找项目级输入。项目 settings.json 与钩子只从 <cwd>/.claude/ 加载,没有父目录回退机制。

settingSources 不控制的内容

settingSources 覆盖用户、项目、本地三类设置。以下几项无论其取值如何都会被读取:

输入项行为如何禁用
托管策略设置由端点管理的策略(如 MDM plist、注册表策略或托管设置文件)从主机加载。服务端托管设置会在符合条件的配置下、当会话通过组织 OAuth 登录或直接配置的 API key 认证时被拉取端点策略:从主机移除托管设置文件、plist 或注册表策略;服务端托管设置:由组织管理员控制,无法从 SDK 端禁用
~/.claude.json 全局配置始终被读取通过 env 中的 CLAUDE_CONFIG_DIR 重新定位
位于 ~/.claude/projects/<project>/memory/ 的自动记忆(auto memory)会话启动时加载进系统提示词。agent 使用标准的 Write/Edit 工具(而非专用记忆工具)写入新记忆,因此这两个工具必须启用才能保存记忆在 settings 中设置 autoMemoryEnabled: false,或在 env 中设置 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1
claude.ai MCP 连接器当会话通过你的 claude.ai 登录认证时加载。当 CLAUDE_CODE_OAUTH_TOKEN 持有来自 claude setup-token 的令牌(该令牌只能发起模型请求)时不加载。传入 mcpServers: {} 并不能屏蔽这些连接器设置 strictMcpConfig: true、settings 中的 disableClaudeAiConnectors: true,或在 env 中设置 ENABLE_CLAUDEAI_MCP_SERVERS=false

警告:不要依赖 query() 的默认选项来实现多租户隔离。因为上述输入项无论 settingSources 如何设置都会被读取,SDK 进程可能会读取到主机级配置以及按目录存储的记忆。对于多租户部署,应让每个租户运行在各自独立的文件系统中,并设置 settingSources: [](query 选项),同时在 env 中设置 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。当进程使用组织凭据认证时,服务端托管设置仍会被拉取;文件系统隔离并不能移除它们。详见 Secure deployment

项目指令(CLAUDE.md 与 rules)

CLAUDE.md 文件与 .claude/rules/*.md 文件为 agent 提供关于项目的持久上下文:编码规范、构建命令、架构决策与指令。当 settingSources 包含 "project"(如上例)时,SDK 会在会话启动时把这些文件加载进上下文。此后 agent 会遵循你的项目规范,无需在每条提示词中重复说明。

CLAUDE.md 加载位置

级别位置何时加载
Project(根目录)<cwd>/CLAUDE.md<cwd>/.claude/CLAUDE.mdsettingSources 包含 "project"
Project rules<cwd>/.claude/rules/*.md 及每个父目录下的 .claude/rules/*.mdsettingSources 包含 "project"
Project(父目录)cwd 上层目录中的 CLAUDE.md 文件settingSources 包含 "project",在会话启动时加载
Project(子目录)cwd 子目录中的 CLAUDE.md 文件settingSources 包含 "project",在 agent 读取该子树中的文件时按需加载
Local<cwd>/CLAUDE.local.md 及每个父目录下的 CLAUDE.local.mdsettingSources 包含 "local"
User~/.claude/CLAUDE.mdsettingSources 包含 "user"
User rules~/.claude/rules/*.mdsettingSources 包含 "user"

所有级别都是叠加关系:如果项目级与用户级 CLAUDE.md 同时存在,agent 会同时看到两者。各级别之间没有强制的优先级规则;如果指令冲突,结果取决于 Claude 如何解读。建议编写不冲突的规则,或在更具体的文件中显式声明优先级(例如「这些项目指令会覆盖任何冲突的用户级默认设置」)。

提示:你也可以直接通过 systemPrompt 注入上下文,而不使用 CLAUDE.md 文件,详见 Modify system prompts。当你希望在交互式 Claude Code 会话与 SDK agent 之间共享同一份上下文时,使用 CLAUDE.md。

关于如何组织 CLAUDE.md 内容,参见 Manage Claude's memory

技能(Skills)

技能是为 agent 提供专门知识与可调用工作流的 markdown 文件。与每次会话都会加载的 CLAUDE.md 不同,技能按需加载:agent 在启动时接收技能的描述,只有在相关时才加载完整内容。

技能通过 settingSources 从文件系统中被发现。当 query() 上的 skills 选项被省略时,已发现的用户级与项目级技能会被启用,且 Skill 工具可用,这与 CLI 行为一致。要控制启用哪些技能,可将 skills 传入为 "all"、技能名列表,或 [](禁用全部)。当设置了 skills 时,SDK 会自动把 Skill 工具加入 allowedTools。如果你还传入了明确的 tools 列表,需要在该列表中包含 "Skill",Claude 才能调用技能。

from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
import asyncio


# Skills in .claude/skills/ are discovered automatically
# when settingSources includes "project"
async def main():
    async for message in query(
        prompt="Review this PR using our code review checklist",
        options=ClaudeAgentOptions(
            setting_sources=["user", "project"],
            skills="all",
            allowed_tools=["Read", "Grep", "Glob"],
        ),
    ):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";

// Skills in .claude/skills/ are discovered automatically
// when settingSources includes "project"
for await (const message of query({
  prompt: "Review this PR using our code review checklist",
  options: {
    settingSources: ["user", "project"],
    skills: "all",
    allowedTools: ["Read", "Grep", "Glob"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

注意:技能必须以文件系统制品(.claude/skills/<name>/SKILL.md)的形式创建。SDK 没有用于注册技能的编程式 API。完整细节参见 Agent Skills in the SDK

钩子(Hooks)

SDK 支持两种定义钩子的方式,二者并行运行:

  • 文件系统钩子:在 settings.json 中定义的 shell 命令,当 settingSources 包含相应来源时加载。这与你为交互式 Claude Code 会话配置的钩子相同。
  • 编程钩子:直接传给 query() 的回调函数。这些回调在你的应用进程中运行,并可返回结构化决策。参见 Control execution with hooks

两种类型在同一个钩子生命周期内执行。如果你的项目 .claude/settings.json 中已有钩子,且你设置了 settingSources: ["project"],这些钩子会在 SDK 中自动运行,无需额外配置。

钩子回调接收工具输入并返回一个决策字典。返回 {} 表示允许工具继续执行。要拦截执行,返回一个带有 permissionDecision: "deny"permissionDecisionReasonhookSpecificOutput 对象;该原因会作为工具结果发送给 Claude。完整回调签名与返回类型参见钩子指南

from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, ResultMessage
import asyncio


# PreToolUse hook callback. Positional args:
#   input_data: HookInput dict with tool_name, tool_input, hook_event_name
#   tool_use_id: str | None, the ID of the tool call being intercepted
#   context: HookContext, reserved for future abort-signal support
async def audit_bash(input_data, tool_use_id, context):
    command = input_data.get("tool_input", {}).get("command", "")
    if "rm -rf" in command:
        return {
            "hookSpecificOutput": {
                "hookEventName": "PreToolUse",
                "permissionDecision": "deny",
                "permissionDecisionReason": "Destructive command blocked",
            }
        }
    return {}  # Empty dict: allow the tool to proceed


# Filesystem hooks from .claude/settings.json run automatically
# when settingSources loads them. You can also add programmatic hooks:
async def main():
    async for message in query(
        prompt="Refactor the auth module",
        options=ClaudeAgentOptions(
            setting_sources=["project"],  # Loads hooks from .claude/settings.json
            hooks={
                "PreToolUse": [
                    HookMatcher(matcher="Bash", hooks=[audit_bash]),
                ]
            },
        ),
    ):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())
import { query, type HookInput, type HookJSONOutput } from "@anthropic-ai/claude-agent-sdk";

// PreToolUse hook callback. HookInput is a discriminated union on
// hook_event_name, so narrowing on it gives TypeScript the right
// tool_input shape for this event.
const auditBash = async (input: HookInput): Promise<HookJSONOutput> => {
  if (input.hook_event_name !== "PreToolUse") return {};
  const toolInput = input.tool_input as { command?: string };
  if (toolInput.command?.includes("rm -rf")) {
    return {
      hookSpecificOutput: {
        hookEventName: "PreToolUse",
        permissionDecision: "deny",
        permissionDecisionReason: "Destructive command blocked",
      },
    };
  }
  return {}; // Empty object: allow the tool to proceed
};

// Filesystem hooks from .claude/settings.json run automatically
// when settingSources loads them. You can also add programmatic hooks:
for await (const message of query({
  prompt: "Refactor the auth module",
  options: {
    settingSources: ["project"], // Loads hooks from .claude/settings.json
    hooks: {
      PreToolUse: [{ matcher: "Bash", hooks: [auditBash] }]
    }
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

何时使用哪种钩子类型

钩子类型最适合场景
文件系统钩子settings.json在 CLI 与 SDK 会话之间共享钩子。支持 "command"(shell 脚本)、"http"(向某端点发 POST 请求)、"mcp_tool"(调用已连接 MCP 服务器的工具)、"prompt"(由 LLM 评估某个提示词),以及 "agent"(生成一个验证者 agent)。这些钩子在主 agent 及其生成的任何子 agent 中都会触发
编程钩子query() 中的回调)应用特定逻辑、结构化决策、进程内集成。这些钩子在子 agent 内部也会触发。钩子输入(回调的第一个参数)携带 agent_idagent_type 字段,用于标识是哪个 agent 触发了该钩子

注意:TypeScript SDK 支持的钩子事件比 Python 更多,包括 SessionStartSessionEndTeammateIdleTaskCompleted。完整事件兼容性表参见钩子指南

关于编程钩子的完整细节,参见 Control execution with hooks。关于文件系统钩子语法,参见 Hooks

如何选择合适的功能

Agent SDK 提供多种扩展 agent 行为的方式。如果不确定该用哪种,下表将常见目标映射到对应方法:

你想要...使用SDK 接入方式
设置 agent 始终遵循的项目约定CLAUDE.mdsettingSources: ["project"] 自动加载
让 agent 拥有在相关时才加载的参考资料SkillssettingSources + skills 选项
运行可复用的工作流(部署、评审、发布)User-invocable skillssettingSources + skills 选项
把独立子任务委派给全新上下文(调研、评审)Subagentsagents 参数 + allowedTools: ["Agent"]
协调多个 Claude Code 实例,共享任务列表并直接互相通信Agent teams不直接通过 SDK 选项配置。Agent teams 是一项 CLI 功能,由一个会话作为团队负责人,协调各独立队友的工作
对工具调用运行确定性逻辑(审计、拦截、转换)Hookshooks 参数配合回调,或通过 settingSources 加载的 shell 脚本
让 Claude 结构化地访问外部服务的工具MCPmcpServers 参数

提示Subagents 与 agent teams 的区别:Subagents 是短暂且隔离的——全新对话、单一任务、向父级返回摘要。Agent teams 则协调多个独立的 Claude Code 实例,它们共享任务列表并直接互相发消息。Agent teams 是一项 CLI 功能。详见 What subagents inheritagent teams 对比

每启用一项功能都会增加 agent 上下文窗口的占用。关于各功能的具体成本以及它们如何叠加,参见 Extend Claude Code

相关资源

  • Extend Claude Code:所有扩展功能的概念性总览,含对比表与上下文成本分析
  • Skills in the SDK:以编程方式使用技能的完整指南
  • Subagents:为隔离子任务定义与调用子 agent
  • Hooks:在关键执行节点拦截并控制 agent 行为
  • Permissions:通过模式、规则与回调控制工具访问
  • System prompts:不使用 CLAUDE.md 文件注入上下文