Claude Code 学习站

Agent SDK:Skills 与 Slash 命令集成指南

介绍 Claude Agent SDK 中如何通过 skills 选项控制 Skill 调用、发现与派发 /command,以及 /compact、/clear 等内置命令的用法。

本页目录21
AI 摘要 · 已核查整理于 2026-08-05原文:Extend agents with skills(Anthropic)Claude Agent SDKSkillsSlash CommandsTypeScript/Python
要点速览
  • 原文 URL 已重定向到「Extend agents with skills」页面,该页同时覆盖 Skills 与 Agent SDK 会话中的命令(原 slash-commands 内容)
  • skills 是文件系统产物(.claude/skills/<name>/SKILL.md),通过 settingSources/setting_sources 中的 user、project 加载,SDK 不提供编程注册 API
  • query() 的 skills 选项接受 "all"、技能名数组或 [],用于控制 Claude 可调用哪些技能;按名称派发(/<name>)不受此列表限制
  • system/init 消息的 skills 字段列出已加载的可用户调用技能,slash_commands 字段列出会话中可用的全部命令(内置命令、bundled skills、自定义技能、命令文件)
  • /compact 需要已有对话历史才能生效,压缩结果通过 subtype 为 compact_boundary 的 system 消息返回;/clear 重置上下文但不删除磁盘上的历史,可通过 resume 选项恢复
  • skills 列表中的名称必须精确匹配,不支持通配符,非法名称会在会话启动前被 query() 拒绝(TypeScript 抛 Error,Python 抛 ValueError)

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

说明:该原文链接目前会重定向/合并到官方文档「Extend agents with skills」页面,该页明确注明「本页同时覆盖 Agent SDK 会话中的命令(Commands in Agent SDK sessions)」,即原 slash-commands 页的内容。以下整理基于该合并后的页面全文。

Skills 与 Agent SDK 的关系

Agent Skills 用于扩展 Claude 的专项能力,Claude 会在相关场景下自动调用。Skills 打包为 SKILL.md 文件,包含说明、描述以及可选的配套资源。

在 Claude Agent SDK 中,skills 具有以下特点:

  • 以文件系统产物定义:每个 skill 是独立目录下的一个 SKILL.md 文件,例如 .claude/skills/<name>/SKILL.md
  • 从文件系统加载:SDK 根据 settingSources(TypeScript)或 setting_sources(Python)所指定的位置加载 skills
  • 自动发现:文件系统设置加载后,SDK 会在启动时从用户和项目目录发现 skill 元数据,并在 Claude 调用该 skill 时加载完整内容
  • 由模型调用:Claude 根据上下文自主决定何时使用
  • 由用户调用:可以在 prompt 中发送 /<name> 直接派发某个 skill(见下文「Agent SDK 会话中的命令」)
  • 通过 skills 选项限定范围:默认情况下,已发现的 skills 都会启用;可以传入技能名称列表、"all"[] 来控制 Claude 可调用哪些 skills

与可以通过 agents 选项 编程定义的子代理(subagents)不同,skills 只能创建为磁盘上的文件,SDK 不提供编程方式注册它们的 API。

说明:Skills 通过文件系统 setting sources 被发现。在 query() 的默认选项下,SDK 会加载 user 与 project 源,因此 ~/.claude/skills/<cwd>/.claude/skills/,以及从 <cwd> 到仓库根目录之间任意父目录下的 .claude/skills/ 都可用。如果显式设置了 settingSources,需要包含 'user''project' 才能保留 skill 发现能力;也可以使用 plugins 选项 从特定路径加载 skills。

在 Agent SDK 中使用 Skills

query() 上设置 skills 选项,控制 Claude 在会话中可调用哪些 skill。省略该选项时,已发现的 skills 会全部启用,且 Skill 工具可用,行为与 CLI 一致。传入 "all" 可让 Claude 调用所有已发现的 skill;传入名称列表则只允许列表中的;传入 [] 则不允许调用任何 skill。

例如,只允许 Claude 调用两个指定名称的 skill:

options = ClaudeAgentOptions(skills=["pdf", "docx"])
const options = { skills: ["pdf", "docx"] };

在会话中配置 Skills

设置 skills 后,SDK 会自动将 Skill 工具加入 allowedTools。如果同时传入了显式的 tools 列表,需要在其中包含 "Skill",Claude 才能调用 skills。

配置完成后,Claude 会自动从文件系统发现 skills,并在与用户请求相关时调用它们。

以下示例在一个会话中启用所有已发现的 skill,并预先批准 skills 常用的工具。示例将 cwd 设为进程当前工作目录,因此需要在包含 .claude/skills/(位于当前目录或其任一父目录)的项目内运行:

import asyncio
import os

from claude_agent_sdk import query, ClaudeAgentOptions


async def main():
    options = ClaudeAgentOptions(
        cwd=os.getcwd(),  # .claude/skills/ here or in a parent directory
        setting_sources=["user", "project"],  # Load skills from filesystem
        skills="all",  # Let Claude invoke every discovered skill
        allowed_tools=["Read", "Write", "Bash"],
    )

    async for message in query(
        prompt="Help me process this PDF document", options=options
    ):
        print(message)


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

for await (const message of query({
  prompt: "Help me process this PDF document",
  options: {
    cwd: process.cwd(), // .claude/skills/ here or in a parent directory
    settingSources: ["user", "project"], // Load skills from filesystem
    skills: "all", // Let Claude invoke every discovered skill
    allowedTools: ["Read", "Write", "Bash"]
  }
})) {
  console.log(message);
}

确认 Skills 已加载

在消息流的开始阶段,SDK 会产出一条 subtype 为 init 的 system 消息。检查其 skills 数组即可确认 skills 在 Claude 开始工作前已成功加载。该数组包含已定义的可供用户调用的 skills,以及 Claude Code 内置(bundled)的 skills

该数组只列出可供用户调用的 skills。在 frontmatter 中设置了 user-invocable: false 的 skill 仍会加载并可供 Claude 使用,但不会出现在该数组中。无论该 skill 是否在你的 skills 列表中,该数组都反映会话实际发现到的 skills。

只允许特定 Skills

若只想让 Claude 调用指定的 skills,在 skills 列表中传入其名称。名称需匹配 SKILL.md 中的 name 字段,或该 skill 所在目录名;对插件提供的 skill 使用 plugin:skill 形式。

该列表只接受精确的技能名称。如果某一项无法作为精确名称使用,query() 会在会话启动前就拒绝整个列表(见下文「无效 skill 名称错误」)。

未列入列表的 skill,模型看不到,Skill 工具也会拒绝调用,但其文件仍留在磁盘上,可通过 Read 和 Bash 访问。限制列表并不会限制按名称派发

若要让 Claude 调用所有已发现的 skill,应传入 skills: "all",而不是通配符写法。

Agent SDK 会话中的命令

本节即 SDK 的命令(command)文档。命令是指在 prompt 中发送 /<name> 所运行的任何东西。命令面板上的条目背后的实现各不相同:

  • 内置命令(Built-in commands):执行编码在 Claude Code 进程内部的逻辑,例如 /compact
  • 内置技能(Bundled skills):随 Claude Code 附带的 prompt 产物,例如 /code-review
  • 你自己的 skills:你编写的 prompt 产物,每个都是包含 SKILL.md 文件的目录。一个可供用户调用的 skill 名称会自动加入命令面板,因此派发你自己的 /security-check 与运行内置命令的方式相同
  • 自定义命令文件(Custom command files):一种较旧的产物形式,行为相同,是 .claude/commands/ 下的扁平 Markdown 文件,文件名即为命令名。Skills 是它推荐的继任者

默认情况下,你和 Claude 都可以调用任意 skill。可以通过 skill 的 frontmatter 分别限制这两条调用路径。两个术语的定义参见词汇表中的 CommandSkill 条目。完整的内置命令列表见 Commands in Claude Code,两种产物形式的完整指南见 Extend Claude with skills

发现可用命令

可以通过 SDK 派发那些无需交互式终端即可运行的命令。system/init 消息的 slash_commands 字段列出了当前会话中可用的命令。需要交互式终端的命令(如 /theme/terminal-setup)不会出现在列表中。可在会话启动时读取该字段:

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

for await (const message of query({
  prompt: "Hello Claude",
  options: { maxTurns: 1 }
})) {
  if (message.type === "system" && message.subtype === "init") {
    console.log("Available commands:", message.slash_commands);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage


async def main():
    async for message in query(prompt="Hello Claude", options=ClaudeAgentOptions(max_turns=1)):
        if isinstance(message, SystemMessage) and message.subtype == "init":
            print("Available commands:", message.data["slash_commands"])


asyncio.run(main())

打印出的列表混合了内置命令、内置 skills、你可供用户调用的 skills,以及 .claude/commands/ 文件:

Available commands: ["clear", "compact", "context", "usage", "code-review", "verify", "security-check", ...]

你可供用户调用的 skills 会同时出现在这个列表和「确认 Skills 已加载」一节所述的 skills 数组中。slash_commands 列表还包含会话中其余的可用命令。设置了 user-invocable: false 的 skill 不会出现在任何一个列表中。配置了 MCP servers 的会话,还可以将 MCP prompts 作为命令暴露

按名称派发命令

在 prompt 字符串中包含 /<name> 即可发送命令,方式与发送普通文本相同。派发不依赖 skills 选项——即便某个可供用户调用的 skill 不在你的 skills 列表中,发送 /<name> 依然会运行它。像 /compact 这样作用于对话历史的命令,需要先有历史消息才能生效。

说明:命令与其它 prompt 一样,可能触发 maxTurns / max_turns 限制,这会导致查询以 error 类型的 result 结束,而不是 success。关于 error result 的约定,参见 Handle the result。如果命令可能触及该限制,请像 Single Message Input 中所示那样,用 TypeScript 的 try/catch 或 Python 的 try/except 包裹消息循环,或者将 maxTurns 设得足够大以完成任务。

/compact 压缩历史

/compact 命令通过总结较早的消息来缩减对话历史的大小,同时保留重要上下文。压缩需要已有对话且历史消息足够多才能进行总结。下面的示例先进行一轮对话,然后压缩它,并读取报告压缩结果的 compact_boundary system 消息:

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

// Compaction needs existing history, so have a conversation first
try {
  for await (const message of query({
    prompt: "Explain what this project does",
    options: { maxTurns: 2 }
  })) {
    if (message.type === "result" && message.subtype === "success") {
      console.log(message.result);
    }
  }
} catch (error) {
  // A single-shot query() throws after yielding an error result,
  // so the follow-up query below still runs.
  console.error(`Session ended with an error: ${error}`);
}

// Compact the same conversation
for await (const message of query({
  prompt: "/compact",
  options: { continue: true, maxTurns: 1 }
})) {
  if (message.type === "system" && message.subtype === "compact_boundary") {
    console.log("Compaction completed");
    console.log("Pre-compaction tokens:", message.compact_metadata.pre_tokens);
    console.log("Trigger:", message.compact_metadata.trigger);
    // Example output:
    // Compaction completed
    // Pre-compaction tokens: 1842
    // Trigger: manual
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage, SystemMessage


async def main():
    # Compaction needs existing history, so have a conversation first
    try:
        async for message in query(
            prompt="Explain what this project does",
            options=ClaudeAgentOptions(max_turns=2),
        ):
            if isinstance(message, ResultMessage) and message.subtype == "success":
                print(message.result)
    except Exception as error:
        # A single-shot query() raises after yielding an error result,
        # so the follow-up query below still runs.
        print(f"Session ended with an error: {error}")

    # Compact the same conversation
    async for message in query(
        prompt="/compact",
        options=ClaudeAgentOptions(continue_conversation=True, max_turns=1),
    ):
        if isinstance(message, SystemMessage) and message.subtype == "compact_boundary":
            print("Compaction completed")
            print("Pre-compaction tokens:", message.data["compact_metadata"]["pre_tokens"])
            print("Trigger:", message.data["compact_metadata"]["trigger"])
            # Example output:
            # Compaction completed
            # Pre-compaction tokens: 1842
            # Trigger: manual


asyncio.run(main())

说明:只有真正执行了压缩,才会产出 compact_boundary 消息。如果没有内容可总结,/compact 会报告原因而不是抛出异常。此时运行仍会以 success result 结束,且不会有 compact_boundary 消息,result 文本会携带原因,例如单轮简短对话后可能出现 Not enough messages to compact.。全新的一次性 query() 调用总是以空上下文开始,因此该模式应用在已有历史轮次的会话中,例如 流式输入模式,或恢复会话时。

/clear 重置上下文

/clear 命令将对话重置为空上下文,此后的 prompt 不再带有先前的对话历史。之前的对话仍保留在磁盘上。可以通过将其会话 ID 传给 resume 选项 返回该对话。

/clear流式输入模式中很有用(该模式下你在单一连接上发送多条 prompt)。对于一次性 query() 调用,每次调用本就以空上下文开始,因此发送 /clear 没有实际效果;此时应直接发起新的 query()

创建 Skills

将每个 skill 创建为一个目录,其中包含带 YAML frontmatter 和 Markdown 内容的 SKILL.md 文件。description 字段决定 Claude 何时调用该 skill。

示例目录结构

.claude/skills/security-check/
└── SKILL.md

选择发现级别

将 skills 保存在以下两个最常见的发现级别之一:

级别路径说明
项目级 skills.claude/skills/仅在当前项目中可用
个人级 skills~/.claude/skills/在你的所有项目中可用

如果已有 .claude/commands/ 下的自定义命令文件,它们会继续正常工作。位于 .claude/commands/deploy.md 的命令文件会创建 /deploy,其行为与位于 .claude/skills/deploy/SKILL.md 的 skill 相同。若命令文件与 skill 同名,具体以哪个生效见 Where skills live。SDK 会从与 skills 相同的两个作用域加载 .claude/commands/~/.claude/commands/ 文件。两种产物形式的完整指南见 Extend Claude with skills

创建并派发你的第一个 Skill

创建 .claude/skills/security-check/SKILL.md

---
name: security-check
description: Run a security vulnerability scan
---

Analyze the codebase for security vulnerabilities including:
- SQL injection risks
- XSS vulnerabilities
- Exposed credentials
- Insecure configurations

文件一旦存在,该 skill 就可以通过 SDK 使用了。当请求与其描述匹配时 Claude 会调用它,你也可以直接派发:

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

for await (const message of query({
  prompt: "/security-check",
  options: { maxTurns: 10 }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
    async for message in query(
        prompt="/security-check", options=ClaudeAgentOptions(max_turns=10)
    ):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())

成功运行会以 success result 结束,其文本携带扫描结果。针对一个植入了漏洞的小型 Express 应用,result 文本开头类似:

**Security scan of `app.js` — 4 findings (most severe first):**

1. **SQL Injection** (line 8) — `req.query.name` is concatenated directly into the SQL string. Trivially exploitable (`' OR '1'='1`, `'; DROP TABLE users;--`). **Fix:** use parameterized queries, e.g. `db.query("SELECT * FROM users WHERE name = ?", [req.query.name], cb)`.
...

该 skill 的名称也会出现在 init 消息的 slash_commands 数组中。

说明:Claude Code 内置了 code-reviewverify 两个 skill。如果你将某个 .claude/commands/ 文件命名为其中之一,例如 .claude/commands/code-review.md,该文件对应的命令会遮蔽内置的 skill,slash_commands 中该名称只会出现一次。

为 Skills 预授权工具

说明:对于项目级和个人级 skills,allowed-tools frontmatter 字段仅在直接使用 Claude Code CLI 时生效。在 SDK 会话中,应通过 query 配置里的 allowedTools 选项(Python 中为 allowed_tools)来管理这些 skills 的工具批准。从 claude.ai 同步而来的 skills 遵循它们自己的 frontmatter 规则。

Skills 使用会话的工具运行。下例通过 allowedTools(Python 中为 allowed_tools)预先批准 ReadGrepGlob,使 Claude 在运行 security-check skill 时能够检查文件而无需为审批而中断:

import asyncio

from claude_agent_sdk import query, ClaudeAgentOptions

options = ClaudeAgentOptions(
    setting_sources=["user", "project"],  # Load skills from filesystem
    skills="all",
    allowed_tools=["Read", "Grep", "Glob"],
)


async def main():
    async for message in query(prompt="Check this project for security issues", options=options):
        print(message)


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

for await (const message of query({
  prompt: "Check this project for security issues",
  options: {
    settingSources: ["user", "project"], // Load skills from filesystem
    skills: "all",
    allowedTools: ["Read", "Grep", "Glob"]
  }
})) {
  console.log(message);
}

在消息流中,skill 调用会表现为一次 Skill 工具调用,随后是针对项目文件的 Read 调用。运行以携带扫描结果的 success result 结束。

该列表是预先批准所列工具,而不是限制其它工具。关于完整的权限流程,包括权限模式和 canUseTool 回调,参见 Permissions

故障排查

找不到 Skills

检查 settingSources 配置:SDK 通过 userproject setting sources 发现 skills。如果显式设置了 settingSources/setting_sources 却省略了这两个源,SDK 就不会加载 skills:

# Skills not loaded: setting_sources excludes user and project
options = ClaudeAgentOptions(setting_sources=[], skills="all")

# Skills loaded: user and project sources included
options = ClaudeAgentOptions(
    setting_sources=["user", "project"],
    skills="all",
)
// Skills not loaded: settingSources excludes user and project
const optionsWithoutSkills = {
  settingSources: [],
  skills: "all"
};

// Skills loaded: user and project sources included
const optionsWithSkills = {
  settingSources: ["user", "project"],
  skills: "all"
};

各个源分别加载哪些 skill 目录,参见文件系统源对照表。关于 settingSources/setting_sources 的更多细节,参见 TypeScript SDK referencePython SDK reference

检查工作目录:SDK 会从 cwd 选项所指目录及其直到仓库根目录之间的每一层父目录中的 .claude/skills/ 加载 skills。确保 cwd 指向包含 .claude/skills/ 的目录、或其在同一仓库内的下级目录:

# Ensure your cwd points to the directory containing .claude/skills/
options = ClaudeAgentOptions(
    cwd="/path/to/project",  # .claude/skills/ here or in a parent directory
    setting_sources=["user", "project"],  # Loads skills from these sources
    skills="all",
)
// Ensure your cwd points to the directory containing .claude/skills/
const options = {
  cwd: "/path/to/project", // .claude/skills/ here or in a parent directory
  settingSources: ["user", "project"], // Loads skills from these sources
  skills: "all"
};

完整模式参见在 Agent SDK 中使用 Skills

核实文件系统位置

# Check project skills
ls .claude/skills/*/SKILL.md

# Check personal skills
ls ~/.claude/skills/*/SKILL.md

Skill 未被使用

检查 skills 选项:如果传入了 skills 列表,确认该 skill 的名称在其中。当 Claude 尝试调用一个未列入列表的 skill 时,Skill 工具会返回 Skill <name> is not in this session's skills allowlist。可将该名称加入列表,或直接在 prompt 中发送 /<name> 派发该 skill(此方式无需列入列表即可生效)。

检查 description:确保描述具体且包含相关关键词。写好 description 的指南参见 Agent Skills best practices

无效 Skill 名称错误

skills 列表中的某个名称无法作为精确的 skill 名称使用时,query() 会在启动 Claude Code 进程之前就拒绝该列表。会触发拒绝的名称包括:

  • 空名称
  • 名称中包含括号、逗号或控制字符
  • 名称前后带有空白填充
  • 通配符形式,例如裸的 * 或以 :* 结尾的后缀

各 SDK 的报错方式不同:

TypeScript:TypeScript SDK 会抛出一个 Error,说明该条目违反的规则。例如 skills: ["docs:*"] 会抛出:

Invalid skill name "docs:*": wildcard-suffix names are not allowed; list each skill by its exact name.

空名称会报告 Skill names must be non-empty strings.

Python:Python SDK 会抛出 ValueError,说明该条目违反的规则。例如 skills=["docs:*"] 会抛出:

ValueError: Invalid skill name 'docs:*': wildcard-suffix names are not allowed; list each skill by its exact name.

空名称会报告 Skill names must be non-empty strings

其它故障排查

关于一般性的 skills 故障排查(例如 YAML 语法错误和调试),参见 Claude Code skills troubleshooting section

后续步骤

Claude Code skills guide 深入讲解了如何编写 skill。其指导内容同样适用于 SDK 会话,但有一处例外:对于项目级和个人级 skills,为 Skills 预授权工具一节所述的 allowedTools 选项取代了 allowed-tools frontmatter 字段。可以从以下几节开始:

相关资源