使用 skills 扩展 Claude
创建、管理和共享 skills 以在 Claude Code 中扩展 Claude 的功能。包括自定义命令和捆绑的 skills。
Skills 扩展了 Claude 能做的事情。创建一个 SKILL.md 文件,其中包含说明,Claude 会将其添加到其工具包中。Claude 在相关时使用 skills,或者你可以使用 /skill-name 直接调用一个。
当你不断将相同的说明、检查清单或多步骤程序粘贴到聊天中时,或者当 CLAUDE.md 的某个部分已经演变成一个程序而不是事实时,就创建一个 skill。与 CLAUDE.md 内容不同,skill 的主体仅在使用时加载,因此长参考资料在你需要之前几乎不花费任何成本。
对于内置命令如 /help 和 /compact,以及捆绑的 skills 如 /debug 和 /code-review,请参阅命令参考。
自定义命令已合并到 skills 中。 .claude/commands/deploy.md 中的文件和 .claude/skills/deploy/SKILL.md 中的 skill 都会创建 /deploy 并以相同的方式工作。你现有的 .claude/commands/ 文件继续工作。Skills 添加了可选功能:支持文件的目录、用于控制你或 Claude 是否调用它们的 frontmatter,以及 Claude 在相关时自动加载它们的能力。
Claude Code skills 遵循 Agent Skills 开放标准,该标准适用于多个 AI 工具。Claude Code 使用额外功能扩展了该标准,如调用控制、子代理执行和动态上下文注入。请参阅在 Claude Code 外使用 skill frontmatter,了解哪些 frontmatter 字段是标准的一部分,哪些是 Claude Code 扩展。
捆绑技能
Claude Code 包含一组捆绑技能,例如 /doctor、/code-review、/batch、/debug、/loop 和 /claude-api。捆绑技能是基于提示的:它们为 Claude 提供详细的指令,让它使用其工具来协调工作。大多数内置命令则直接执行固定逻辑。
您调用捆绑技能的方式与调用任何其他技能相同,即输入 / 后跟技能名称。Claude 在相关时会自动调用某些捆绑技能;其他技能(包括 /verify)仅在您调用它们时运行,这样可以让您控制这些耗时较长的检查何时花费时间和令牌。
大多数捆绑技能在每个会话中都可用。少数技能取决于特定功能:例如,/workflow-authoring 仅在动态工作流启用时可用。
要关闭捆绑技能,请使用 disableBundledSkills 设置。
在 Claude Code v2.1.205 及更高版本中,当 disableBundledSkills 打开时,/doctor 设置检查仍然可以输入。要隐藏它,请设置 DISABLE_DOCTOR_COMMAND 环境变量或 skillOverrides 条目 "doctor": "off"。在 v2.1.205 之前,/doctor 是内置命令而不是捆绑技能。
捆绑技能与内置命令一起列在命令参考中,在"目的"列中标记为技能。
运行并验证您的应用
三个捆绑技能协同工作来启动您的应用并根据运行中的应用而不仅仅是测试来确认更改:
| 技能 | 目的 |
|---|---|
/run |
启动并驱动您的应用以查看更改是否有效 |
/verify |
构建并运行您的应用以确认代码更改是否按预期工作,无需回退到测试或类型检查 |
/run-skill-generator |
教 /run 和 /verify 如何构建和启动您的项目 |
/run 和 /verify 无需设置即可工作。它们从您的项目类型(CLI、服务器、TUI、浏览器驱动)以及 README、package.json 或 Makefile 中的内容推断启动。对于需要超出标准启动范围的任何内容的项目,该推断变得不可靠:数据库、env 文件、图形会话、多步骤构建。
/run-skill-generator 改为记录配方。它从干净的环境中让您的应用运行,捕获有效的内容(安装命令、环境变量、启动脚本),并将其作为每个项目的技能提交到 .claude/skills/run-<name>/。之后,/run、/verify 和存储库中的任何其他代理都遵循记录的配方而不是重新发现它。每个项目运行一次 /run-skill-generator,如果构建或启动过程更改,则再次运行。
/verify 也可以记录自己的配方。当它必须在没有记录的配方的情况下构建和驱动您的应用时,它会将有效的内容写入存储库根目录的 .claude/skills/verify/SKILL.md,或在 monorepo 中的受触及的包目录中,以便后续运行和其他代理遵循相同的步骤。在存储库根目录,记录的技能替换捆绑的 /verify。这需要 Claude Code v2.1.200 或更高版本。
Claude 仅在它引导运行出错时编辑记录的文件,例如失败的命令或缺少的步骤,因此您可以提交文件而无需每个会话的差异。在 v2.1.205 之前,捆绑技能告诉 Claude 折叠运行学到的任何内容,这导致频繁的合并冲突。
在每次提交前运行检查
当会话启动时已存在名为 verify 或 simplify 的 skill,Claude Code 的提交指令会告诉 Claude 在每次提交之前运行它,但对文档或测试的更改除外。这需要 Claude Code v2.1.286 或更高版本。当会话开始时满足以下条件,Claude 会收到该指令:
- 位置:该 skill 从企业、个人、项目或附加目录位置加载,或来自具有该名称的
.claude/commands/文件。/verify在您的存储库根目录记录的配方是项目 skill,因此也算在内。随附的/verify和/simplify、插件 skill 以及来自您 claude.ai 账户的 skill 不算在内。 - 调用:Claude 可以调用该 skill。如果您已阻止 Claude 调用它,例如使用
disable-model-invocation: true,Claude 不会收到该指令。 - Git 指令:您没有关闭
includeGitInstructions。关闭它会将此指令与其余内置提交和 PR 指令一起移除。
处理 Claude API 项目
捆绑的 /claude-api 技能为您的项目语言加载 Claude API 和托管代理参考资料。当您的代码导入 anthropic 或 @anthropic-ai/sdk 时,Claude 也会自动激活它。
要启动技能的工作流之一,请在 Claude Code 提示符处的技能名称后键入子命令,例如 /claude-api migrate。该表列出了每个子命令的作用以及包含它的最早 Claude Code 版本。migrate 和 managed-agents-onboard 早于 v2.1.221,这是该表跟踪的最早版本。
| 子命令 | 作用 | 最低版本 |
|---|---|---|
migrate |
将您现有的 Claude API 代码更新到更新的模型 | 早于 v2.1.221 |
upgrade |
跨主要版本移动您的项目的 Anthropic SDK 依赖项,目前是 Python anthropic 包从 0.x 到 1.x |
v2.1.236 或更高版本 |
managed-agents-onboard |
逐步完成创建新的托管代理 | 早于 v2.1.221 |
prompt-audit |
标记为旧模型编写的指令在您的提示、技能和工具描述中,并提议修复作为差异 | v2.1.221 或更高版本 |
cost-optimize |
分析您的项目的 Claude API 支出去向,并提议从提示缓存、修剪不需要的输入和输出令牌、批处理、工作量和模型选择等选项中节省成本,一次一个更改 | v2.1.247 或更高版本 |
build-eval |
为您的 Claude 驱动的应用构建评估集 | v2.1.259 或更高版本 |
hillclimb |
针对现有评估迭代改进您的应用 | v2.1.259 或更高版本 |
preserved-thinking-migration |
查找您的集成对早期轮次、其系统提示或其工具列表所做的编辑,这些编辑使保留的思考块失效,测量每个块丢弃多少推理,并提议一次一个修复,在每次更改后重新测量 | v2.1.282 或更高版本 |
开始使用
创建你的第一个 skill
这个示例创建了一个 skill,它总结你的 git 仓库中未提交的更改,并标记任何有风险的内容。它在 Claude 读取之前将实时差异拉入提示中,因此响应基于你的实际工作树,而不是 Claude 从打开的文件中猜测的内容。当你询问你的更改时,Claude 会自动加载该 skill,或者你可以使用 /summarize-changes 直接调用它。
创建 skill 目录
在你的个人 skills 文件夹中为该 skill 创建一个目录。个人 skills 在所有项目中都可用。
mkdir -p ~/.claude/skills/summarize-changes
编写 SKILL.md
每个 skill 都需要一个 SKILL.md 文件,包含两部分:--- 标记之间的 YAML frontmatter,告诉 Claude 何时使用该 skill,以及包含 Claude 在 skill 运行时遵循的说明的 markdown 内容。目录名称或你设置的 frontmatter name 会成为你输入的命令,description 帮助 Claude 决定何时自动加载该 skill。
将其保存到 ~/.claude/skills/summarize-changes/SKILL.md:
---
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff.
---
## Current changes
!`git diff HEAD`
## Instructions
Summarize the changes above in two or three bullet points, then list any risks you notice such as missing error handling, hardcoded values, or tests that need updating. If the diff is empty, say there are no uncommitted changes.
!`git diff HEAD` 行使用动态上下文注入:Claude Code 运行该命令,并在 Claude 看到 skill 内容之前将该行替换为其输出,因此说明会随着当前差异已内联而到达。
测试 skill
打开一个 git 项目,对任何文件进行小的编辑,并通过运行 claude 启动 Claude Code。你可以通过两种方式测试该 skill。
让 Claude 自动调用它,通过询问与描述匹配的内容:
What did I change?
或直接使用 skill 名称调用它:
/summarize-changes
无论哪种方式,Claude 都应该用你的编辑的简短摘要和风险列表进行响应。
选择 skills 的加载位置
skills 的保存位置决定了哪些会话会加载它。将其保存在主目录下可在每个项目中使用,将其提交到存储库可与该处的所有人共享,或通过插件或托管设置分发以覆盖整个团队。
| 位置 | 路径 | 加载位置 |
|---|---|---|
| Enterprise | .claude/skills/<skill-name>/SKILL.md 在 托管设置目录 |
您的组织部署它的所有机器上的所有用户 |
| Personal | ~/.claude/skills/<skill-name>/SKILL.md |
此机器上的所有项目,但不包括 Cowork 或云会话 |
| Project | .claude/skills/<skill-name>/SKILL.md |
此存储库中的会话。提交它以便您的团队也能获得它 |
| Nested | <subdir>/.claude/skills/<skill-name>/SKILL.md |
在 <subdir> 中或其下方启动的会话。在其上方启动的会话在 Claude 处理该处的文件时加载该 skill。请参阅 monorepos 和子目录 |
| Additional directory | .claude/skills/<skill-name>/SKILL.md 在使用 --add-dir 传递的目录中 |
该会话。请参阅 项目外的目录 |
| Plugin | <plugin>/skills/<skill-name>/SKILL.md |
在 插件 启用的任何位置,作为 /plugin-name:skill-name |
| claude.ai account | 为您的 claude.ai 账户启用的 skills | Cowork 会话、云会话和使用该账户登录的终端会话。请参阅 从 claude.ai 同步的 Skills |
Skill 文件夹还遵循以下规则:
- 符号链接文件夹:enterprise、personal 或 project 位置中的
<skill-name>条目可以是指向磁盘上其他位置的目录的符号链接。Claude Code 从目标读取SKILL.md并加载 skill,即使多个位置指向同一目标也只加载一次。插件 skills 以不同方式处理符号链接。 - 保留名称
synced:不要将 skill 文件夹命名为synced,无论大小写如何。Claude Code 使用~/.claude/skills/synced/来存放 从 claude.ai 下载的 skills,并跳过您在 enterprise、personal 和 project 位置中以该名称创作的 skill。 - 保留名称
anthropic-skills:在插件外,名称为anthropic-skills或以anthropic-skills:开头的 skill 文件夹或命令文件不会加载。请参阅 为同步 skills 保留的名称。 - 命令文件:
.claude/commands/中的 Markdown 文件是较旧的格式,仍然有效。它支持相同的 frontmatter,除了name和paths。要找到您输入以调用它的名称,请参阅 skill 如何获得其命令名称。对于新工作,更倾向于使用 skill,因为 skills 还支持 支持文件。 - Skill 文件夹作为插件:将
.claude-plugin/plugin.json添加到 skill 文件夹,它将作为 插件 加载,名称为<name>@skills-dir,因此它可以捆绑代理、hooks 和 MCP 服务器。在项目的.claude/skills/中,这需要首先接受工作区信任对话框。
在 monorepos 和子目录中加载 skills
Claude Code 从启动它的目录和每个父目录(直到存储库根目录)中的 .claude/skills/ 加载项目 skills,因此在 packages/frontend/ 中启动仍会获取在根目录定义的 skills。当您在 v2.1.246 或更高版本上 使用 /cd 移动会话 时,Claude Code 会添加新目录的项目 skills。
在链接的 git worktree 中运行的会话中,Claude Code 仅在 worktree 根目录之前搜索父目录。在 Claude Code v2.1.277 或更高版本上,当 worktree 检出在其根目录没有 .claude/skills 目录时,Claude Code 会改为加载主检出的项目 skills。请参阅 worktrees 与主检出共享的内容。
.claude/skills/ 目录中启动位置下方的 skills 在启动时不会加载。它们在 Claude 首次读取或编辑该子目录中的文件时加载,并在会话的其余时间保持可用。在此之前,它们不会出现在 / 菜单中,您也无法按名称调用它们。要更早加载它们,请使用子目录的路径运行 /add-dir,这需要 Claude Code v2.1.257 或更高版本。
当嵌套 skill 的目录名称与另一个 skill 的名称匹配时,两者都保持可用。在存储库根目录有一个 deploy skill,在 apps/web/.claude/skills/ 中有另一个:
/deploy运行根 skill。Claude Code 还为 Claude 列出目录限定的变体,并指示调用其目录包含它正在处理的文件的那个,因此嵌套 skill 仍然适用于apps/web/中的工作。/apps/web:deploy单独运行嵌套 skill。其描述命名了它适用的目录。
从项目外的目录加载 skills
当您使用 --add-dir 或 /add-dir 添加目录时,Claude Code 会加载该目录的 .claude/skills/ 中的 skills,以及其 .claude/commands/ 和 .claude/agents/。Agent SDK 通过 TypeScript 中的 additionalDirectories 或 Python 中的 add_dirs 添加的目录以相同方式加载,因为 SDK 将它们作为 --add-dir 传递。settings.json 中的 permissions.additionalDirectories 设置仅授予文件访问权限,不加载这些中的任何一个。
Claude Code 在启动时使用 --add-dir 传递的目录中监视 .claude/skills/,如 在会话期间编辑 skill 所述。它不监视添加目录的 .claude/commands/ 或 .claude/agents/,因此在更改该处的文件后重新启动会话。
这些加载取决于 project 设置源,默认情况下处于启用状态。strictPluginOnlyCustomization 策略、bare mode 和 --safe-mode 各自进一步限制它们,如这些页面所述。请参阅 其他目录授予文件访问权限,而不是配置 以获取添加目录加载的完整表格,包括 CLAUDE.md 和插件设置。
解决共享名称的 skills
当两个 skills 共享目录或文件名称时,每个来自的位置决定了 /name 运行哪一个。对于由 frontmatter name 字段设置的名称,请参阅 skill 如何获得其命令名称。该表涵盖 enterprise、personal、project、nested、plugin 和 claude.ai 位置、捆绑 skills 和命令文件:
| 相同名称在 | 运行哪一个 |
|---|---|
| Enterprise、personal 和 project 中的两个 | Enterprise 优先于 personal,personal 优先于 project。在 ~/.claude/skills/ 和项目的 .claude/skills/ 中都有 deploy 时,/deploy 运行 personal 的 |
| 这些位置中的任何一个和 捆绑 skill | 您的 skill 替换捆绑命令,但不替换其别名。项目 code-review skill 替换 /code-review,捆绑别名 /review 永远不会运行您的 skill |
Skill 和 .claude/commands/ 中的文件 |
Skill |
| 项目根 skill 和嵌套 skill | 两者都加载。请参阅 monorepos 和子目录 |
| 插件 skill 和上述任何位置的 skill | 两者都加载,因为插件 skills 被命名为 /plugin-name:skill-name |
| 上述任何一个和 从您的 claude.ai 账户同步的 skill 的短名称 | 其他 skill 或命令。同步 skill 随后被列出并仅在其完整名称下运行。请参阅 当同步 skill 名称与另一个命令匹配时 |
在 Cowork 和云会话中使用 skills
Cowork 会话和 云会话(包括 routines)不会读取您机器上的 ~/.claude/skills/。交互式和计划的 Cowork 会话都加载为您的 claude.ai 账户启用的 skills,在会话启动时同步;从 Desktop 应用侧边栏中的 Customize 或从 claude.ai 上的 skills 设置管理它们。云会话另外加载提交到克隆存储库的 .claude/skills/ 的项目 skills。
如果 skill 仅存在于您机器上的 ~/.claude/skills/ 中,当 routine 调用它时,Claude Code 会报告找不到该 skill,因为每个 routine 运行都作为新的云会话启动。要在这些会话中使用个人 skill:
- 对于 Cowork 和云会话,为您的 claude.ai 账户启用该 skill。
- 对于云会话,您可以改为将 skill 提交到存储库的
.claude/skills/。在存储库的.claude/settings.json中声明的插件和仅在您的用户设置中启用的插件 不会在云会话中加载。
Desktop 计划任务 在您的机器上本地运行,因此它们确实加载 ~/.claude/skills/。
从 claude.ai 同步的 Skills
如果您使用 Cowork 或云会话,或使用 claude.ai 账户在终端中登录 Claude Code,本部分适用于您。在这些会话中,Claude Code 加载为您的 claude.ai 账户启用的 skills,无需您进行任何设置,如 同步 skills 加载的位置 所述。这些 skills 包括您在 claude.ai 设置中创建或打开的 skills、您的组织在那里提供的 skills 以及 Anthropic 的内置 skills,例如 pdf 和 xlsx。
Claude Code 从您的账户下载同步 skill,而不是读取您在会话运行的机器上编写的文件,因此它对同步 skills 应用不适用于您存储在 skills 位置 中的 skills 的规则。
同步 skills 加载的位置
在 Cowork 或云会话中,Claude Code 加载为您的 claude.ai 账户启用的 skills,Cowork 和云会话中的 Skills 说明了如何选择这些会话获得哪些 skills。
在您的终端中,Claude Code 在您使用 claude.ai 账户登录的会话中同步这些 skills。会话启动时,Claude Code 在后台将您账户的 skills 下载到 ~/.claude/skills/synced/ 中,然后在会话运行时大约每 10 分钟检查一次 claude.ai 是否有更改。当检查发现 skill 在 claude.ai 上被添加、编辑或关闭时,Claude Code 在运行的会话中添加、更新或删除它,无需重新启动。终端会话中的同步需要 Claude Code v2.1.273 或更高版本。
同步永远不会延迟启动,因为 Claude 仅在调用 skill 时等待其下载。因此,短 非交互式 运行可能在新添加的 skill 下载之前完成,在这种情况下,稍后的会话会下载它。要使非交互式运行下载您的 skills 并在回答提示之前等待列表,请将 CLAUDE_CODE_SYNC_SKILLS 设置为 1。
Claude Code 仅在使用您的 claude.ai 账户登录的会话中同步,并 从 Anthropic 获取功能标志。它不在这些会话中同步:
- 不使用由
/login存储的登录的会话,例如使用 API 密钥进行身份验证的会话,或ANTHROPIC_AUTH_TOKEN、CLAUDE_CODE_OAUTH_TOKEN或apiKeyHelper脚本提供凭证的会话 - 不获取功能标志的会话,例如 Amazon Bedrock 上的会话或您设置
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC的会话 - bare mode 中的会话或您使用
--safe-mode启动的会话 - 您的组织的托管设置 将 skills 锁定到插件源 的会话,或您使用
--setting-sources列表启动的会话,该列表省略了user
如果您在会话期间使用 /login 登录,请重新启动 Claude Code 以开始同步。
较早会话同步的 skills 保留在磁盘上。Claude Code 在稍后登录到同一账户的会话中加载它们,即使它无法到达 claude.ai。
Claude Code 下载同步 skills,从不上传它们。如果您或 Claude 编辑 ~/.claude/skills/synced/ 下的文件,更改不会保存到您的 claude.ai 账户,稍后的同步可能会覆盖或删除它。要更改同步 skill,请在 claude.ai 上更新它;下一次同步会下载新版本。
要查看哪些 skills 已同步,请运行 /skills。菜单在 claude.ai sync 下列出它们。
Anthropic 的某些 skills,例如 pdf 和 xlsx,总是同步。对于其余的,在 claude.ai 上的 skills 设置中打开或关闭 skill 以更改是否同步。
要停止在机器上同步,请在您的用户设置中将 syncClaudeAiSkills 设置为 false。Claude Code 停止下载,下次启动时它会将已同步的 skills 移动到 ~/.claude/skills/.trash/,不再加载它们。您的组织可以通过在 claude.ai 上关闭 Skills 来为所有人关闭同步。要在保持 Skills 打开的情况下停止同步,它可以在 托管设置 中设置相同的密钥。
如果您的组织在 claude.ai 上关闭 Skills,Claude Code 会删除下载的 skills,它们停止加载。删除的 skills 移动到 ~/.claude/skills/.trash/,您可以在 保留扫描 删除它们之前恢复文件。一旦您的组织重新打开 Skills,Claude Code 会在下一次同步时下载您启用的 skills。
当同步 skill 名称与另一个命令匹配时
您可以通过其短名称 /<name> 或完整名称 /anthropic-skills:<name> 调用同步 skill。当另一个命令使用短名称时,/<name> 运行另一个命令,同步 skill 仅作为 /anthropic-skills:<name> 运行。使用本地 deploy skill 和同步 deploy 时,/deploy 运行本地 skill,/anthropic-skills:deploy 运行同步的。在 v2.1.269 之前,同步 skill 仅有其短名称。
在 / 菜单、/skills 和 /context 中,同步 skill 出现在其短名称下,或在另一个命令使用短名称时出现在其完整名称下。在您的会话中运行 /skills。列表下的注释解释了每个失去其短名称的同步 skill。如果您在 ~/.claude/ 中的个人 skills 或命令文件之一使用该名称,注释还会说明要重命名或删除什么以释放它。
从 v2.1.269 到 v2.1.280,这些列表在其完整名称下显示每个同步 skill,/skills 没有这样的注释;两者都在 v2.1.281 中更改。
使用短名称的命令可以是以下任何一个:
- 内置命令或 捆绑 skill,包括在您的会话中不可用的,例如在您关闭捆绑 skills 后
- 任何 本地级别 的 skill 或
.claude/commands/中的文件 - 插件 skill
- MCP 提示
Claude Code 标记同步 skills,以便您可以看出它们来自何处。/skills 菜单和 /context 在 claude.ai sync 下分组同步 skills,/ 命令菜单将它们标记为来自 claude.ai。
比较名称时,Claude Code 忽略大小写、间距和不可见字符,并将兼容性形式(如全宽字母和破折号变体)视为其纯等效形式。例如,名为 Commit 的同步 skill 和名为 commit 的本地 skill 计为相同名称,因此 /commit 继续运行您的本地 skill。
仅因另一个字母表中的相似字母而不同的名称计为不同名称,claude.ai sync 标签是您区分两者的方式。这些检查和标签需要 Claude Code v2.1.228 或更高版本。
为同步 skills 保留的名称
Claude Code 保留名称 anthropic-skills 和该命名空间内的每个名称(例如 anthropic-skills:pdf)用于从 claude.ai 同步的 skills,因此同步 skill 的完整名称永远不会运行其他任何东西。该名称在每个会话中保留,无论您是否使用 claude.ai 账户登录。
- Skill 文件夹、frontmatter
name、.claude/commands/中的文件或子文件夹,或 保存的工作流:它不加载。启动通知 命名要重命名或编辑的第一项。 - 名为
anthropic-skills的插件:它加载。当其 skills 之一和同步 skill 都命名为<name>时,/anthropic-skills:<name>运行同步 skill。 - 名为
anthropic-skills的 MCP 服务器:它连接并且其工具有效,但 其提示不显示为命令。在您的 MCP 配置中重命名服务器以列出它们。
Claude Code 如何处理同步 skill 的 frontmatter
Claude Code 对同步 skill 的 frontmatter 应用两条规则:
- frontmatter 在每种会话中都适用,因此
allowed-tools授予通过正常 权限流 进行。如果您的组织设置了allowManagedPermissionRulesOnly,该授予 不适用。 - Claude Code 清理 skill 提供的显示文本,例如其描述。它删除控制字符,在到达 Claude 的文本(例如描述)中,它还转义尖括号,以便文本无法模仿 Claude Code 的内部格式。此清理需要 Claude Code v2.1.228 或更高版本。
Claude Code 如何处理同步 skill 的正文
Claude Code 对同步 skill 的正文的处理取决于会话运行的位置:
- 在云会话中,正文保持本地 skill 具有的行为,因为会话在隔离容器中运行。
- 在您桌面上的 Cowork 会话中,正文保持本地 skill 具有的行为,除了 Claude Code 将每个
!命令行替换为disableSkillShellExecution占位符,就像它对您在那里提供的每个 skill 所做的那样。 - 在您机器上的任何其他会话中,Claude Code 不运行
!命令,不附加@引用命名的文件(就像它对本地 skill 所做的那样),不替换${CLAUDE_PROJECT_DIR}和${CLAUDE_SESSION_ID}占位符,因此@引用和两个占位符都作为文字文本到达 Claude。!命令行也作为文字文本到达 Claude,或当disableSkillShellExecution打开时作为该占位符。此处理需要 Claude Code v2.1.228 或更高版本。
在会话期间编辑 skill
Claude Code 监视 skill 目录的文件更改,除了在 bare mode 中。当您在 ~/.claude/skills/、项目 .claude/skills/ 或 --add-dir 目录内的 .claude/skills/ 中添加、编辑或删除 skill 时,Claude Code 在当前会话中获取更改,无需重新启动。
如果您创建了会话启动时不存在的顶级 skills 目录,请运行 /reload-skills 以获取您放在那里的 skills。Claude Code 还没有监视该目录,因此在稍后每次更改后再次运行 /reload-skills。
实时更改检测仅涵盖 SKILL.md 文本。对于也是 插件 的 skill 文件夹,对 hooks/、.mcp.json、agents/ 和 output-styles/ 的更改需要 /reload-plugins 才能生效。
删除 skill
删除 skill 的方式取决于它来自何处:
- Personal 或 project skill:删除 skill 的目录,
~/.claude/skills/<skill-name>/或.claude/skills/<skill-name>/。Claude Code 在当前会话中从/skills中删除它;Claude Code 已从中加载的内容遵循 skill 内容生命周期。 - Enterprise skill:管理员从 托管设置目录 内的
.claude/skills/删除 skill 的目录,例如 Linux 上的/etc/claude-code/.claude/skills/<skill-name>/。 - Plugin skill:从
/plugin菜单禁用或卸载提供它的插件,或使用/plugin uninstall <plugin-name>@<marketplace-name>。Claude Code 在 更改应用 时或重新启动时卸载插件的 skills。 - 从 claude.ai 同步的 Skill:在您 启用它 的同一位置为您的 claude.ai 账户关闭该 skill。Claude Code 在下一次 同步您的 skills 时从
~/.claude/skills/synced/中删除它。如果您改为手动删除目录,下一次同步会在 skill 在 claude.ai 上保持启用时再次下载它。 - Bundled skill:将
disableBundledSkills设置为true以关闭捆绑 skills,或在skillOverrides中将一个 skill 设置为"off"以隐藏它。
要保留 personal 或 project skill 但阻止 Claude 自动调用它,请在其 frontmatter 中设置 disable-model-invocation: true,或在不想编辑文件时在 skillOverrides 中设置 "user-invocable-only"。
配置 skill
skill 通过 SKILL.md 顶部的 YAML frontmatter 及其后的 markdown 内容进行配置。
skill 内容的类型
skill 文件可以包含任何指令,但思考您希望如何调用它们有助于确定应包含哪些内容:
参考内容为 Claude 添加可应用于当前工作的知识,例如约定、模式、风格指南、领域知识。此类内容以内联方式运行,因此 Claude 可以将其与对话上下文结合使用。
---
name: api-conventions
description: API design patterns for this codebase
---
When writing API endpoints:
- Use RESTful naming conventions
- Return consistent error formats
- Include request validation
任务内容为 Claude 提供执行特定操作的分步指令,例如部署、提交或代码生成。这些通常是您希望通过 /skill-name 直接调用的操作,而不是让 Claude 决定何时运行。添加 disable-model-invocation: true 可防止 Claude 自动触发它。下面的示例添加了 context: fork,它会在 skill 自己的子代理上下文中运行该 skill;请参阅在子代理中运行 skill。
---
name: deploy
description: Deploy the application to production
context: fork
disable-model-invocation: true
---
Deploy the application:
1. Run the test suite
2. Build the application
3. Push to the deployment target
请保持正文本身简洁。skill 加载后,其内容会在各轮次之间保留在上下文中,因此每一行都是重复的 token 开销。说明要做什么,而不是叙述如何做或为什么做,并采用与 CLAUDE.md 内容相同的简洁性标准。
Frontmatter 参考
在 SKILL.md 顶部的 --- 标记之间使用 YAML frontmatter 配置 skill,并在结束的 --- 之后以 Markdown 编写 skill 的指令。字段名使用以连字符分隔的小写单词,when_to_use 除外。.claude/commands/ 中的命令文件接受相同的字段,但 name 和 paths 除外。此示例设置了四个字段:
---
name: my-skill
description: What this skill does
disable-model-invocation: true
allowed-tools: Read Grep
---
Your skill instructions here...
所有字段都是可选的。仅建议设置 description,以便 Claude 知道何时使用该 skill。字段名必须与表格完全一致,包括连字符:Claude Code 会忽略无法识别的字段,且不会报告错误。
仅当开头的 --- 位于文件第一行时,Claude Code 才会读取 frontmatter。否则,它会将整个文件(包括 --- 标记)视为 skill 内容。如果标记之间的 YAML 无法解析,skill 仍会加载,但不会设置任何字段;请参阅 Skill 未触发以查找并修复错误。
除 true 和 false 外,布尔字段还接受任意大小写的 yes、no、on、off、1 和 0。在 v2.1.218 之前,Claude Code 仅识别 true 和 false。
| 字段 | 必需 | 描述 |
|---|---|---|
name |
否 | 在 / 菜单中显示的命令名称。默认为目录名称。有关该字段如何与您为调用 skill 而输入的名称交互,请参阅 skill 如何获得其命令名称。 |
description |
建议 | skill 的功能以及何时使用它。Claude 据此决定何时应用该 skill。如果省略,则使用 markdown 内容的第一个非空行。请将关键用例放在最前面:为减少上下文占用,description 和 when_to_use 的合并文本在 skill 列表中会被截断为 1,536 个字符。 |
when_to_use |
否 | 关于 Claude 何时应调用该 skill 的附加上下文,例如触发短语或示例请求。在 skill 列表中附加到 description 之后,并计入 1,536 个字符的上限。 |
argument-hint |
否 | 自动补全期间显示的提示,用于指示预期的参数。示例:[issue-number] 或 [filename] [format]。 |
arguments |
否 | 用于 skill 内容中 $name 替换的命名位置参数。接受以空格分隔的字符串或 YAML 列表。名称按顺序映射到参数位置。 |
disable-model-invocation |
否 | 设置为 true 可防止 Claude 自动加载此 skill。适用于您希望通过 /name 手动触发的工作流。还会阻止该 skill 预加载到子代理中。从 v2.1.196 起,当以该 skill 作为提示词的定时任务触发时,也会阻止该 skill 运行。默认值:false。 |
user-invocable |
否 | 当只有 Claude 应调用该 skill 时设置为 false:Claude Code 会将其从 / 菜单中隐藏,并且在您输入 /name 时不会运行它。适用于用户不应直接调用的背景知识。默认值:true。 |
allowed-tools |
否 | 在调用此 skill 的轮次中,Claude 无需请求权限即可使用的工具。当您发送下一条消息时,该授予即被清除。接受以空格或逗号分隔的字符串,或 YAML 列表。请参阅为 skill 预先批准工具。 |
disallowed-tools |
否 | 在此 skill 处于活动状态时,从 Claude 可用工具池中移除的工具。适用于永远不应调用某些工具的自主 skill,例如对后台循环禁用 AskUserQuestion。接受以空格或逗号分隔的字符串,或 YAML 列表。当您发送下一条消息时,该限制即被清除。与拒绝规则一样,只要还有其他工具存在,该字段就无法移除 EndConversation。 |
model |
否 | 此 skill 处于活动状态时使用的模型。该覆盖适用于当前轮次的剩余部分,且不会保存到设置中。当您发送下一个提示词时,会话模型即恢复。接受与 /model 相同的值,或使用 inherit 保留当前活动的模型。被组织的 availableModels 允许列表排除的值不会被使用,会话将保留其当前模型。在自动模式下,以及在分类器审查命令时的计划模式下,自动模式不支持的模型同样不会被使用,会话将保留其当前模型。使用 context: fork 时,该值改为设置分叉子代理的模型,被排除的值遵循与子代理模型覆盖相同的规则。 |
effort |
否 | 此 skill 处于活动状态时的 effort 级别。覆盖会话的 effort 级别。默认值:继承自会话。选项:low、medium、high、xhigh、max;可用级别取决于模型。 |
context |
否 | 设置为 fork 可在分叉的子代理上下文中运行。请参阅在子代理中运行 skill。 |
agent |
否 | 设置 context: fork 时使用的子代理类型。 |
background |
否 | 仅在使用 context: fork 时适用。设置为 false 可在调用该 skill 的轮次中等待分叉子代理的结果,而不是在后台运行它。默认值:true。需要 Claude Code v2.1.218 或更高版本。 |
hooks |
否 | Claude Code 在调用该 skill 时注册并在会话剩余时间内持续运行的 hook。有关配置格式和 once 选项,请参阅 skill 和 Agent 中的 hook。 |
paths |
否 | 限制此 skill 何时激活的 Glob 模式。接受以逗号分隔的字符串或 YAML 列表。设置后,仅当处理与这些模式匹配的文件时,Claude 才会自动加载该 skill。使用与特定路径规则相同的格式。 |
shell |
否 | 此 skill 中 !`command` 和 ```! 块使用的 shell。接受 bash(默认)或 powershell。当 PowerShell 工具启用时,设置 powershell 会通过 PowerShell 运行内联 shell 命令:在没有 Git Bash 的 Windows 上默认启用,对于 claude.ai 和 Console 账户在有 Git Bash 时默认启用,而在 Amazon Bedrock、Google Cloud 的 Agent Platform 和 Microsoft Foundry 会话中以及在 macOS、Linux 和 WSL 上需要设置 CLAUDE_CODE_USE_POWERSHELL_TOOL=1。将其设置为 0 可关闭该工具。 |
metadata |
否 | 用于存放您自己的键值数据的自由格式 YAML 映射,例如权益或目录字段,由您自己的工具从 SKILL.md 中读取。Claude Code 不会处理其内容,并会丢弃非映射类型的值。请勿将 paths 等 frontmatter 字段名用作键。 |
license |
否 | 适用于该 skill 的许可证。属于 Agent Skills 规范的一部分;请参阅在 Claude Code 之外使用 skill frontmatter。Claude Code 接受该字段,但不会对其进行处理。 |
compatibility |
否 | skill 的环境要求,例如目标产品或系统前提条件,由 Agent Skills 规范定义;请参阅在 Claude Code 之外使用 skill frontmatter。接受最多 500 个字符的字符串。Claude Code 接受该字段,但不会对其进行处理。 |
在 Claude Code 之外使用 skill frontmatter
Claude Code 接受上表中的所有字段。在 Claude Code 之外,您只能使用 Agent Skills 规范中的字段:
| 分发途径 | 可使用的 frontmatter 字段 |
|---|---|
| 任意级别的 Claude Code skill,包括插件 skill | 上表中的所有字段 |
claude.ai skill 上传、Skills API,以及使用 anthropics/skills 中的 package_skill.py 打包 |
name、description、license、compatibility、metadata、allowed-tools |
当您为 claude.ai 账户启用个人 skill 时(例如在 Cowork 和云端会话以及 Routine 中使用),您会将其上传到 claude.ai,因此适用相同的规则。
如果您包含了规范不允许的任何字段,打包或上传将以硬错误失败,而不是忽略该字段:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name
将 frontmatter 限制为规范中的六个字段可避免上述意外键错误。Agent Skills 规范和 Skills API 要求定义了这些途径所验证的其他所有内容。仅限 Claude Code 的正文功能(例如动态上下文注入)在 claude.ai 聊天中或通过 API 无法发挥作用。Claude Code 接受全部六个字段,因此遵循规范的 frontmatter 无需修改即可在 Claude Code 中加载。
skill 如何获得其命令名称
您为调用 skill 而输入的命令取决于 skill 文件所在的位置,对于 skill 目录和插件 skill,还取决于 frontmatter 的 name 字段。在个人或项目 skill 目录中,name 设置 / 菜单中显示且由您输入的命令,除非已有其他命令使用该名称。目录名称同样可以调用该 skill。在插件 skill 中,name 设置命令的最后一段,插件前缀保持不变。
下表显示了每种布局下命令名称的来源:
| Skill 位置 | 命令名称来源 | 示例 |
|---|---|---|
~/.claude/skills/ 或 .claude/skills/ 下的 skill 目录 |
Frontmatter name 或目录名称 |
.claude/skills/deploy-staging/SKILL.md → /deploy-staging,或使用 name: deploy 时为 /deploy |
嵌套的 .claude/skills/ 目录,当目录名称与其他 skill 冲突时 |
相对于工作目录的子目录路径,然后是 skill 目录名称 | apps/web/.claude/skills/deploy/SKILL.md → /apps/web:deploy |
.claude/commands/ 下的文件 |
不含扩展名的文件名 | .claude/commands/deploy.md → /deploy |
.claude/commands/ 子目录中的文件 |
相对于 commands/ 的子目录路径(每个 / 替换为 :),然后是不含扩展名的文件名 |
.claude/commands/frontend/component.md → /frontend:component |
插件 skills/ 子目录 |
Frontmatter name 或目录名称,以插件作为命名空间 |
my-plugin/skills/review/SKILL.md → /my-plugin:review,或使用 name: fancy 时为 /my-plugin:fancy |
插件根目录 SKILL.md |
Frontmatter name,以插件目录名称作为回退 |
带有 name: review 的 my-plugin/SKILL.md → /my-plugin:review。请参阅插件根目录下的单个 skill |
| 从 claude.ai 同步的 skill | 该 skill 在您 claude.ai 账户中的名称,加上 anthropic-skills: 前缀 |
账户 skill deploy → /anthropic-skills:deploy,或在没有其他命令使用该名称时为 /deploy |
在插件 skill 中,frontmatter name 会替换命令最后一段中的目录名称,因此带有 name: fancy 的 my-plugin/skills/review/SKILL.md 会变为 /my-plugin:fancy。除非已有其他命令使用该名称,否则不带前缀的 /fancy 也可以调用该 skill。在 v2.1.246 或更高版本中,如果您编写的 name 已经以插件自身的前缀开头,Claude Code 不会再次添加该前缀。例如,name: my-plugin:fancy 仍会变为 /my-plugin:fancy。在 v2.1.216 至 v2.1.245 中,当 name 已带有前缀时,Claude Code 会重复添加前缀。
在非交互式会话中,名称 help 和 feedback 不会为其仅限终端的内置命令保留,因此使用这两个名称之一的插件 skill 在此类会话中会保留其不带前缀的命令。其他所有仅限终端的内置命令的名称(例如 /login)仍会保留,即使该命令无法在此类会话中运行。
对于插件根目录的 SKILL.md,没有可供获取名称的 skill 目录,因此由 name 提供整个最后一段。如果没有 name 字段,Claude Code 会回退到插件的目录名称。
可用的字符串替换
skill 支持对 skill 内容中的动态值进行字符串替换:
| 变量 | 描述 |
|---|---|
$ARGUMENTS |
调用 skill 时传递的所有参数。当没有占位符接收参数时,Claude Code 会将其以 ARGUMENTS: <value> 的形式附加。请参阅向 skill 传递参数。 |
$ARGUMENTS[N] |
按从 0 开始的索引访问特定参数,例如 $ARGUMENTS[0] 表示第一个参数。 |
$N |
$ARGUMENTS[N] 的简写,例如 $0 表示第一个参数,$1 表示第二个参数。 |
$name |
在 arguments frontmatter 列表中声明的命名参数。名称按顺序映射到位置,因此使用 arguments: [issue, branch] 时,占位符 $issue 展开为第一个参数,$branch 展开为第二个参数。 |
${CLAUDE_SESSION_ID} |
当前会话 ID。可用于记录日志、创建会话专属文件,或将 skill 输出与会话关联。 |
${CLAUDE_EFFORT} |
当前 effort 级别:low、medium、high、xhigh 或 max。可用于根据当前的 effort 设置调整 skill 指令。 |
${CLAUDE_SKILL_DIR} |
包含该 skill 的 SKILL.md 文件的目录。对于插件 skill,这是该 skill 在插件中的子目录,而不是插件根目录。在 bash 注入命令中使用此变量,可引用与 skill 捆绑的脚本或文件,而不受当前工作目录影响。 |
${CLAUDE_PROJECT_DIR} |
项目根目录。这与 hook 和 MCP 服务器作为 CLAUDE_PROJECT_DIR 接收的路径相同。使用此变量可引用项目本地的脚本或文件,例如 ${CLAUDE_PROJECT_DIR}/.claude/hooks/helper.sh,而不受 skill 安装位置的影响。 |
${CLAUDE_PLUGIN_ROOT} |
插件的安装目录。仅在插件 skill 中进行替换。使用此变量可引用捆绑在插件中任意位置的脚本或文件,包括插件各 skill 之间共享的资源。请参阅插件环境变量。 |
${CLAUDE_PLUGIN_DATA} |
插件的持久数据目录,在插件更新后仍会保留。仅在插件 skill 中进行替换。使用此变量可引用已安装的依赖、生成的文件或必须在更新后保留的缓存。 |
Claude Code 会在两个位置替换 ${CLAUDE_SKILL_DIR} 和 ${CLAUDE_PROJECT_DIR}:skill 的 markdown 内容,以及 allowed-tools frontmatter 中的 Bash 规则。在插件 skill 中,Claude Code 会在相同的两个位置替换 ${CLAUDE_PLUGIN_ROOT} 和 ${CLAUDE_PLUGIN_DATA}。在这两个位置使用相同的变量,可让 skill 运行捆绑的脚本而不出现权限提示。以下 skill 展示了这种模式:
---
name: render-chart
description: Render a chart from a CSV file
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---
Run `${CLAUDE_SKILL_DIR}/scripts/render.sh <csv-file>` to render the chart.
如果此 skill 安装在 ~/.claude/skills/render-chart/,则两处 ${CLAUDE_SKILL_DIR} 都会展开为该目录。这样,allowed-tools 规则就会与 skill 正文指示 Claude 运行的命令完全匹配,因此脚本运行时无需提示。
${CLAUDE_PROJECT_DIR} 替换需要 Claude Code v2.1.196 或更高版本。
索引参数使用 shell 风格的引号规则,因此请将多词值用引号括起来,以将其作为单个参数传递。例如,/my-skill "hello world" second 会使 $0 展开为 hello world,$1 展开为 second。$ARGUMENTS 占位符始终展开为输入时的完整参数字符串。
没有对应参数的索引占位符(例如仅传递了一个参数时的 $2)会原样保留在内容中。来自 arguments frontmatter 的命名占位符如果没有匹配的参数,则展开为空字符串。
如果您传递的参数值本身包含 $1 或 $ARGUMENTS 之类的文本,Claude Code 会将其作为字面文本插入,而不会展开它。例如,如果 skill 正文包含 Summarize $0,而您运行 /summarize "$ARGUMENTS from yesterday",则 Claude 收到的是 Summarize $ARGUMENTS from yesterday。在插入参数之后,Claude Code 仍会替换 ${CLAUDE_*} 变量,例如 ${CLAUDE_SKILL_DIR}。
要在数字、ARGUMENTS 或已声明的参数名之前包含字面 $(例如正文中的 $1.00),请使用反斜杠对其进行转义:\$1.00。其他任何 $ 之前的反斜杠都保持不变。只有紧接在标记之前的单个反斜杠才会对其进行转义。双反斜杠(例如 \\$1)会保留两个反斜杠,且 $1 仍会展开为参数值。反斜杠转义仅适用于这些参数占位符。在 ${CLAUDE_*} 变量适用的位置,反斜杠无法阻止对该变量的替换。
使用替换的示例:
---
name: session-logger
description: Log activity for this session
---
Log the following to logs/${CLAUDE_SESSION_ID}.log:
$ARGUMENTS
添加支持文件
skill 可以在其目录中包含多个文件。这样可以使 SKILL.md 专注于核心内容,同时让 Claude 仅在需要时访问详细的参考资料。大型参考文档、API 规范或示例集合无需在每次运行 skill 时都加载到上下文中。
my-skill/
├── SKILL.md (required - overview and navigation)
├── reference.md (detailed API docs - loaded when needed)
├── examples.md (usage examples - loaded when needed)
└── scripts/
└── helper.py (utility script - executed, not loaded)
在 SKILL.md 中引用支持文件,以便 Claude 知道每个文件包含什么内容以及何时加载它:
## Additional resources
- For complete API details, see [reference.md](/anthropic/claude-code/history/docs/zh-CN/2026-10-01-2359..2026-10-02-1159/reference/)
- For usage examples, see [examples.md](/anthropic/claude-code/history/docs/zh-CN/2026-10-01-2359..2026-10-02-1159/examples/)
请将 SKILL.md 保持在 500 行以内。将详细的参考资料移到单独的文件中。
控制谁可以调用 skill
默认情况下,您和 Claude 都可以调用任何 skill。您可以输入 /skill-name 直接调用它,Claude 也可以在与您的对话相关时自动加载它。有两个 frontmatter 字段可用于限制这一点:
-
disable-model-invocation: true:只有您可以调用该 skill。适用于具有副作用或您希望控制时机的工作流,例如/commit、/deploy或/send-slack-message。您不会希望 Claude 因为代码看起来已准备就绪就决定进行部署。 -
user-invocable: false:只有 Claude 可以调用该 skill。适用于无法作为命令执行的背景知识。例如,legacy-system-contextskill 解释旧系统的工作原理。Claude 应在相关时了解这些内容,但/legacy-system-context对用户而言并不是一个有意义的操作。
此示例创建了一个只有您可以触发的部署 skill。如果您设置 disable-model-invocation: true,Claude 就无法自动运行该 skill:
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
---
Deploy $ARGUMENTS to production:
1. Run the test suite
2. Build the application
3. Push to the deployment target
4. Verify the deployment succeeded
如果 Claude 仍然尝试调用,Claude Code 会阻止该调用,并指示它不要以其他方式重现部署步骤,因此 Claude 通常会建议您自行运行 /deploy。
以下是这两个字段对调用和上下文加载的影响:
| Frontmatter | 您可以调用 | Claude 可以调用 | 何时加载到上下文中 |
|---|---|---|---|
| (默认) | 是 | 是 | 描述始终在上下文中,调用时加载完整 skill |
disable-model-invocation: true |
是 | 否 | 描述不在上下文中,您调用时加载完整 skill |
user-invocable: false |
否 | 是 | 描述始终在上下文中,调用时加载完整 skill |
在常规会话中,skill 描述会加载到上下文中,以便 Claude 知道有哪些可用的 skill,但完整的 skill 内容仅在调用时加载。预加载了 skill 的子代理的工作方式不同:完整的 skill 内容会在启动时注入。
Skill 内容生命周期
当您或 Claude 调用 skill 时,渲染后的 SKILL.md 内容会作为一条消息进入对话,并在后续轮次中保留。这种持久性适用于 skill 的指令,而不适用于其权限:allowed-tools 授予会在您发送下一条消息时清除。Claude Code 不会在后续轮次中重新读取 skill 文件,因此请将应在整个任务中适用的指导写成持续有效的指令,而不是一次性步骤。
当 Claude 重新调用某个 skill,且其渲染后的内容与上下文中已有的副本完全相同时,Claude Code 会添加一条简短说明,指出该 skill 已加载,而不是添加第二份内容副本。当渲染后的内容不同时(因为参数发生了变化,或动态上下文命令产生了新的输出),Claude Code 会再次附加完整内容。
自动压缩会在 token 预算范围内保留已调用的 skill。当对话被总结以释放上下文时,Claude Code 会在总结之后重新附加每个 skill 的最近一次调用,每个保留前 5,000 个 token。重新附加的 skill 共享 25,000 个 token 的总预算。Claude Code 从最近调用的 skill 开始填充该预算,因此如果您在一个会话中调用了许多 skill,较早的 skill 可能会在压缩后被完全丢弃。
如果 Claude 在会话中途停止遵循某个 skill,请参阅 Claude 停止遵循 skill。
为 skill 预先批准工具
allowed-tools 字段会在调用该 skill 的轮次中为列出的工具授予权限,因此 Claude 可以使用这些工具而无需提示您批准。即使 skill 内容保留在上下文中,该授予也会在您发送下一条消息时清除;再次调用该 skill 会在该轮次中重新应用授予。它不会限制哪些工具可用:所有工具仍然可以调用,未列出的工具仍受您的权限设置约束。要为整个会话而非单个轮次预先批准工具,请改为在这些权限设置中添加允许规则。
工作区信任不会限制此字段。即使在您从未信任过的文件夹中进行 -p 运行,Claude Code 也会应用项目 skill 的 allowed-tools。skill 可以为自身授予广泛的工具访问权限,因此在仓库中运行 Claude Code 之前,请检查提交到该仓库的 skill 的 allowed-tools。要在整个组织范围内对仓库 skill 禁用该字段,请参阅仅适用托管权限规则时。
每当您调用此 skill 时,它都允许 Claude 运行 git 命令而无需逐次批准:
---
name: commit
description: Stage and commit the current changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---
要在 skill 处于活动状态时从 Claude 的可用工具池中移除工具,请在 skill 的 frontmatter 中的 disallowed-tools 里列出这些工具。当您发送下一条消息时,该限制即被清除。与拒绝规则一样,只要还有其他工具存在,该字段就无法移除 EndConversation。要在所有 skill 和提示词中阻止工具,请在您的权限设置中添加拒绝规则。
仅适用托管权限规则时
当您的组织在托管设置中设置了 allowManagedPermissionRulesOnly 时,Claude Code 会忽略项目和个人 skill 中的 allowed-tools,以及该设置条目所列的其他来源中的 allowed-tools。这需要 Claude Code v2.1.282 或更高版本。
受影响的 skill 所列出的工具会改为经过您组织的托管规则和常规权限提示。运行 /status 可列出在当前会话中到目前为止 Claude Code 已忽略其 allowed-tools 的每个 skill。skill 中不被任何托管规则允许的注入命令遵循注入命令的权限检查。
向 skill 传递参数
您和 Claude 都可以在调用 skill 时传递参数。参数可通过 $ARGUMENTS 占位符获取。
此 skill 按编号修复 GitHub issue。$ARGUMENTS 占位符会被替换为 skill 名称之后的任何内容:
---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Understand the requirements
3. Implement the fix
4. Write tests
5. Create a commit
当您运行 /fix-issue 123 时,Claude 会收到 "Fix GitHub issue 123 following our coding standards..."
如果您在调用 skill 时传递了参数,但 skill 内容中没有占位符接收参数,Claude Code 会将 ARGUMENTS: <your input> 附加到 skill 内容的末尾,以便 Claude 仍能看到您输入的内容。占位符是指 $ARGUMENTS、索引形式(例如 $1)或命名参数。在其位置上没有参数的索引占位符会保留为字面文本,不算作接收了参数。命名占位符即使在其位置上没有参数也算作接收了参数,因为它会展开为空字符串。
您还可以在一条消息的开头叠加多个 skill。输入 /write-tests /fix-issue 123 会加载这两个 skill,并将末尾的文本 123 作为 $ARGUMENTS 传递给每个 skill。在 v2.1.199 之前,只有第一个 skill 会加载,并将 /fix-issue 123 作为字面参数文本接收。
Claude Code 会展开第一个 skill 以及其后叠加的最多五个 skill。展开会在第一个不是内联用户可调用 skill 的标记处停止,因此以分叉子代理方式运行的 skill(例如 /code-review),或其参数本身可能以斜杠命令开头的 skill(例如 /loop),也会在该处终止叠加。该标记及其后的所有内容会成为每个已展开 skill 的参数文本。从 v2.1.218 起,/code-review 以分叉子代理方式运行;在更早的版本中,它以内联方式运行并可叠加。
要按位置访问单个参数,请使用 $ARGUMENTS[N] 或更简短的 $N:
---
name: migrate-component
description: Migrate a component from one language to another
---
Migrate the $ARGUMENTS[0] component from $ARGUMENTS[1] to $ARGUMENTS[2].
Preserve all existing behavior and tests.
运行 /migrate-component SearchBar JavaScript TypeScript 会将 $ARGUMENTS[0] 替换为 SearchBar,$ARGUMENTS[1] 替换为 JavaScript,$ARGUMENTS[2] 替换为 TypeScript。使用 $N 简写的同一 skill:
---
name: migrate-component
description: Migrate a component from one language to another
---
Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
高级模式
注入动态上下文
!`<command>` 语法在技能内容发送给 Claude 之前运行 shell 命令。命令输出替换占位符,因此 Claude 接收实际数据,而不是命令本身。当技能从你的 claude.ai 账户同步时,Claude Code 不会在你的机器上运行这些命令。这个限制需要 Claude Code v2.1.228 或更高版本。
这个技能通过使用 GitHub CLI 获取实时 PR 数据来总结拉取请求。!`gh pr diff` 和其他命令首先运行,它们的输出被插入到提示中:
---
name: pr-summary
description: Summarize changes in a pull request
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---
## Pull request context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
## Your task
Summarize this pull request...
替换在原始文件上运行一次。命令输出作为纯文本插入,不会重新扫描以查找进一步的 !`<command>` 占位符,因此命令无法为后续传递发出占位符来扩展。
内联形式仅在 ! 出现在行首或紧跟在空格后时被识别。如果 ! 跟在另一个字符后面,如 KEY=!`cmd`,占位符保留为字面文本,命令不运行。
对于多行命令,使用以 ```! 开头的围栏代码块而不是内联形式:
## Environment
```!
node --version
git status --short
```
要为来自用户、项目、插件或附加目录源的技能和自定义命令禁用此行为,请在设置中设置 "disableSkillShellExecution": true。每个命令都被替换为 [shell command execution disabled by policy] 而不是被运行。捆绑和托管技能不受影响。此设置在托管设置中最有用,用户无法覆盖它。
当命令出现在从你的 claude.ai 账户同步的技能中时,Claude Code 永远不会在你的机器上运行这些命令,无论此设置如何。这个限制需要 Claude Code v2.1.228 或更高版本。Claude Code 如何处理同步技能的主体说明了在每种会话中 Claude 接收什么来代替命令。
要在技能运行时请求更深入的推理,请在技能内容中的任何地方包含 ultrathink。请参阅使用 ultrathink 进行一次性深入推理。
注入命令如何运行
Claude Code 从技能的 frontmatter 中的 shell 键和你的环境中选择运行技能的注入命令的工具。除了一个会直接导致调用失败的组合外,每个组合都通过 Bash 工具或 PowerShell 工具运行命令:
shell: powershell,启用了 PowerShell 工具:命令通过 PowerShell 工具运行。shell: bash当 bash 不可用时:调用在任何命令运行之前失败。这发生在没有 Git Bash 的 Windows 上。Claude Code 显示Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found。- 任何其他组合:当 bash 可用时,命令通过 Bash 工具运行。当它不可用时,它们通过 PowerShell 工具运行。
任一工具运行命令的方式与它运行 Claude 自己的 shell 命令的方式相同。它们共享工作目录、超时和输出处理:
- 工作目录:Claude Code 在会话 shell 的当前工作目录中运行每个命令。当 Claude 运行
cd时,该目录会移动。在必须每次都以相同方式解析的路径中使用${CLAUDE_SKILL_DIR}或${CLAUDE_PROJECT_DIR}。 - stderr:使用默认的
bashshell,Claude Code 将 stderr 合并到 stdout。命令写入 stderr 的任何内容都会出现在注入的文本中。 - 超时:每个命令在 Bash 工具的默认 2 分钟超时下运行。当 Bash 工具将超时的命令移到后台时,技能仍然呈现。注入的文本报告移动并命名后台任务和收集命令输出的文件。当命令是 Bash 工具从不自动后台化的命令之一时,Claude Code 在超时时杀死它。该失败中止调用。
- 输出大小:超过 Bash 工具内联上限的输出作为文件路径加短预览到达,而不是截断的文本。输出限制涵盖上限以及如何调整每个边界。
PowerShell 工具对它运行的命令应用相同的超时、后台化和输出上限行为。有关其具体信息,请参阅 PowerShell 工具部分。
当注入命令失败时
失败的命令中止整个技能调用,而不仅仅是其自己的占位符。Claude 永远看不到该调用的技能内容。中止显示 Shell command failed for pattern "..."。错误消息包括命令的输出在 [stderr] 下。
使用默认的 bash shell,任何非零退出代码都算作失败。一个例外适用:Claude Code 将来自搜索和比较命令的退出代码 1 视为正常结果并注入其输出。退出代码 2 或更高的代码即使对于这些命令也会失败。
哪些命令获得例外取决于 shell:
- 默认
bashshell:输出限制下列出的命令 shell: powershell,当启用 PowerShell 工具时:一个不同的集合,包括grep和git diff但不包括find或diff
使用默认的 bash shell,将 || true 附加到任何你期望退出非零的其他命令。一个在发现问题时退出 1 的检查脚本就是一个例子。
注入命令的权限检查
注入命令在技能呈现时永远不会提示权限。Claude Code 首先根据你的权限规则检查每一个。命令与拒绝规则匹配的命令会中止调用,显示 Shell command permission check failed for pattern "..."。
在自动模式之外,当命令的权限检查返回除允许之外的任何结果时,Claude Code 都会以相同的错误中止调用。这包括通常会询问您的规则。为避免未匹配的命令在此处导致中止,请使用 allowed-tools 预先批准它。如果您的组织将权限规则限制为仅来自托管设置,请参阅仅应用托管权限规则时。拒绝规则和询问规则仍然会覆盖 allowed-tools。请参阅管理权限。
在自动模式中,原本需要你批准的命令不会中止调用。技能加载时带有指令,告诉 Claude 首先运行该命令,然后 Claude 自己的调用通过自动模式的常规检查。调用仍然会在分叉技能中中止,该技能设置 agent,以及在 Claude 没有运行注入命令的 shell 工具的会话中。
在子代理中运行技能
当你希望技能在隔离中运行时,将 context: fork 添加到你的 frontmatter。Claude Code 启动 agent 字段中设置的类型的新子代理,并将技能内容作为其提示提供给它。子代理看不到你的对话历史,因此技能的说明必须独立存在。
尽管名称如此,具有 context: fork 的技能不会在当前对话的分叉中运行,这会将你迄今为止讨论的所有内容交给子代理。当任务依赖于该历史时,分叉对话而不是使用 context: fork。
分叉的子代理在后台运行:你继续工作,而它运行,其结果在完成时到达你的对话。在 frontmatter 中设置 background: false 以改为在调用技能的轮次中等待结果。在 v2.1.218 之前,分叉的技能总是阻止轮次直到它们完成。
Claude Code 也会等待结果,即使技能没有设置 background: false,在这些情况下:
- 在非交互模式中,使用
-p标志或 Agent SDK - 当你将
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS设置为1时,这也会关闭所有其他后台任务功能 - 当你在同一技能的早期调用仍在运行时调用分叉技能时
- 当计划任务以技能作为其提示触发时
后台化的分叉也使用适用于后台子代理的更窄工具集运行:技能的子代理是常规代理类型,因此分叉对话的子代理的豁免不适用于它。如果你的技能的步骤依赖于该集合之外的工具,请设置 background: false 以保持完整的工具集。
在后台运行的分叉技能在你的会话的检查点之外应用其编辑,因此 /rewind 不会撤销它们;使用 git 来恢复它们。
context: fork 仅对具有明确说明的技能有意义。如果你的技能包含"使用这些 API 约定"之类的指南而没有任务,子代理会收到指南但没有可操作的提示,并返回而没有有意义的输出。
技能和子代理在两个方向上协同工作:
| 方法 | 系统提示 | 任务 | 也加载 |
|---|---|---|---|
具有 context: fork 的技能 |
来自代理类型 | SKILL.md 内容 | CLAUDE.md,根据代理的启动上下文 |
具有 skills 字段的子代理 |
子代理的 markdown 主体 | Claude 的委派消息 | 预加载的技能 + CLAUDE.md,根据子代理的启动上下文 |
使用 context: fork,你在你的技能中编写任务并选择一个代理类型来执行它。内置的 Explore 和 Plan 代理跳过 CLAUDE.md 和 git 状态以保持其上下文较小,因此使用 agent: Explore 的分叉技能仅看到 SKILL.md 内容和代理自己的系统提示。对于相反的情况,你定义一个使用技能作为参考材料的自定义子代理,请参阅子代理。
示例:使用 Explore 代理的研究技能
这个技能在分叉的 Explore 代理中运行研究。技能内容成为任务,代理提供针对代码库探索优化的只读工具:
---
name: deep-research
description: Research a topic thoroughly
context: fork
agent: Explore
---
Research $ARGUMENTS thoroughly:
1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Summarize findings with specific file references
当这个技能运行时:
- 创建一个新的隔离上下文
- 子代理接收技能内容作为其提示("Research $ARGUMENTS thoroughly...")
agent字段确定执行环境(模型、工具和权限)- 子代理总结其结果并在完成时将其返回到你的主对话
agent 字段指定要使用的子代理配置。选项包括内置代理(Explore、Plan、general-purpose)或来自 .claude/agents/ 的任何自定义子代理。如果省略,使用 general-purpose。
限制 Claude 的技能访问
默认情况下,Claude 可以调用任何未设置 disable-model-invocation: true 的 skill。定义了 allowed-tools 的 skill 会在调用该 skill 的轮次中授予 Claude 使用这些工具的权限,无需逐次批准;当您发送下一条消息时,该授予即被清除。您的权限设置仍然管理所有其他工具的基线批准行为。一些内置命令也可以通过 Skill 工具使用,包括 /init 和 /security-review。其他内置命令(例如 /compact)则不可用。
控制 Claude 可以调用哪些技能的三种方法:
通过在 /permissions 中拒绝 Skill 工具来禁用所有技能:
# Add to deny rules:
Skill
使用权限规则允许或拒绝特定技能:
# Allow only specific skills
Skill(commit)
Skill(review-pr *)
# Deny specific skills
Skill(deploy *)
权限语法:Skill(name) 用于精确匹配,Skill(name *) 用于带任何参数的前缀匹配。
下表显示了你的 deny 规则命名的名称类型,Claude Code 除了你写的名称外还会阻止什么。
你的 deny 规则名称 |
示例规则 | Claude Code 也会阻止 |
|---|---|---|
| 别名 | Skill(review) |
捆绑的 /code-review,通过其 /review 别名 |
| 不合格的名称 | Skill(deploy) |
列为 apps/web:deploy 的嵌套技能 |
| 从 claude.ai 同步的技能 | Skill(anthropic-skills:deploy) |
当 Claude Desktop 将其作为插件交付给会话时的该技能 |
| 同步技能的插件形式 | Skill(deploy:deploy) |
同步的技能 |
| 参数形式中的技能 | Skill(skill:deploy) |
该技能无论 Claude 以哪个名称调用它,包括其别名和显示名称 |
在 v2.1.260 之前,当拒绝规则仅命名不合格的名称时,Claude Code 不会阻止列在其合格名称下的嵌套技能。
Claude Code 仅针对技能自己的名称和 Claude 调用中的名称匹配 allow 规则。要在不提示的情况下批准同步技能,请在其保留命名空间内命名它:
Skill(anthropic-skills:pdf)批准同步的pdf技能Skill(anthropic-skills *)批准每个同步的技能Skill(anthropic *)不涵盖anthropic-skills:pdf,因为命名空间外的前缀不匹配其中的名称
通过向其 frontmatter 添加 disable-model-invocation: true 来隐藏单个技能。这将技能从 Claude 的上下文中完全删除。
使用 user-invocable: false,你无法调用该技能,但 Claude 仍然可以。要防止 Claude 通过 Skill 工具调用它,请设置 disable-model-invocation: true。
从设置覆盖技能可见性
skillOverrides 设置从你的设置而不是技能自己的 frontmatter 控制技能可见性。将其用于你不想编辑 SKILL.md 的技能,例如检入共享项目仓库的技能。/skills 菜单为你编写它:突出显示一个技能并按 Space 循环状态,然后按 Esc 保存到 .claude/settings.local.json。
每个键是一个技能名称,每个值是四种状态之一:
| 值 | 列出给 Claude | 在 / 菜单中 |
|---|---|---|
"on" |
名称和描述 | 是 |
"name-only" |
仅名称 | 是 |
"user-invocable-only" |
隐藏 | 是 |
"off" |
隐藏 | 隐藏 |
/skills 菜单将 "user-invocable-only" 状态标记为 user-only。
从 v2.1.199 开始,"off" 也会从广告给远程控制客户端和Agent SDK调用者的命令列表中隐藏技能,除了终端 / 菜单。按其全名调用隐藏的技能仍然返回 skillOverrides 错误而不是运行它。
不在 skillOverrides 中的技能被视为 "on"。下面的示例将一个技能折叠为其名称,并完全关闭另一个:
{
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
}
}
一些捆绑的技能有别名,例如 checkup 用于 /doctor。如果你在托管设置中或在你使用 --settings 标志传递的文件中的别名下设置 skillOverrides 条目,Claude Code 会将其应用于别名后面的技能。你只能通过别名进一步限制技能,永远不能使其更可见,如果你也在托管设置中的技能自己的名称下设置条目,该条目优先。在 v2.1.260 之前,Claude Code 不会在任何设置源中的别名下应用条目到技能。
在用户、项目和本地设置中,Claude Code 仅针对技能名称匹配条目。如果你在那里为 review 设置条目,它适用于名为 review 的技能,而不是通过其 /review 别名的捆绑 /code-review。
插件技能不受 skillOverrides 影响。通过 /plugin 管理那些。
查找未使用的技能
技能列表中的每个技能都会在每个轮次上添加到你的上下文中,无论 Claude 是否曾使用过它。运行 /skill-doctor 以查看每个技能的成本以及它被使用的频率,以便你可以决定关闭哪些。在交互式会话中,报告在 /plugin 管理器的 Stats 选项卡中打开。在非交互模式中使用 -p,Claude Code 将其打印为文本。
该报告涵盖你的会话中的技能,除了捆绑技能和企业技能。它标记列表中从未被调用的技能,并说明在哪里关闭它们。在它告诉你在哪里关闭的技能中,从具有最高上下文成本的技能开始。该报告还列出你最近未使用的插件。
/skill-doctor 需要 Claude Code v2.1.252 或更高版本,在跳过功能标志获取的会话中不可用。如果你从你的手机或浏览器通过远程控制运行 /skill-doctor,Claude Code 回复Skill usage reports are not available on this connection.。在运行会话的机器上的终端中运行 /skill-doctor。
评估和迭代技能
看到技能触发告诉你 Claude 找到了它,但不代表它做了你想要的事情。要知道技能是否有效,需要分别测量两件事:Claude 是否在应该调用的提示上调用它,以及当它调用时输出是否与你的预期相符。
两者的检查都是基线比较。收集几个现实的提示,在启用技能的新会话中运行每个提示,然后在禁用技能的情况下再运行一次,并比较结果。新会话很重要,因为编写技能时留下的上下文会掩盖书面说明中的差距。
关闭技能进行第二次运行的方式取决于它来自何处:
- 个人或项目技能:在
skillOverrides中将其设置为"off"。 - 插件提供的技能:
skillOverrides不适用于插件技能。改用claude plugin eval,它在没有加载任何插件的情况下重复每次运行。
两个工具可以自动化基线比较。对于在插件中发布的技能,claude plugin eval 在隔离会话中运行每个提示,既有插件也没有插件,使用你定义的或它为你编写的评分器对其进行评分,并在低于阈值时以非零状态退出,以便你可以在 CI 上对其进行门控。对于在 Claude Code 对话中迭代单个技能,下面的 skill-creator 插件使用其自己的 evals/evals.json 格式运行类似的循环。这两种格式不可互换。
使用 skill-creator 运行评估
skill-creator 插件可在 Claude Code 内自动执行比较循环。在 VS Code 扩展或桌面应用中,请按照安装插件从官方市场安装它。在终端中,运行 claude 启动 Claude Code,然后在其提示符处输入:
/plugin install skill-creator@claude-plugins-official
如果安装失败,请匹配 Claude Code 报告的消息:
Marketplace "claude-plugins-official" not found:使用/plugin marketplace add anthropics/claude-plugins-official添加市场,然后重试安装。- 插件在市场中找不到:检查插件名称。
如果安装摘要报告 Run /reload-plugins to activate.,Claude Code 随后会为你运行该重新加载。如果重新加载警告你的下一条消息会重新读取对话,请运行 /reload-plugins --force 以在当前会话中使插件的技能可用。然后要求 Claude 评估现有技能,例如 evaluate my summarize-changes skill with skill-creator。该插件会引导你编写测试用例并运行循环:
- 测试用例:在技能目录内的
evals/evals.json中存储提示、输入文件和预期行为 - 隔离运行:为每个测试用例生成一个子代理,以便每次运行都从干净的上下文开始,并记录令牌计数和持续时间
- 评分:针对输出检查每个断言,并将通过或失败以及证据写入
grading.json - 基准:将有技能与无技能的通过率、时间和令牌聚合到
benchmark.json中,以便你可以比较通过率改进与令牌和时间开销 - 版本比较:在技能的两个版本之间运行盲 A/B 测试,以便你可以在提交编辑之前确认它是一个改进
- 描述调整:生成应该触发和不应该触发的提示,测量命中率,并在技能在错误的请求上激活时提议描述编辑
- 审查查看器:打开一个 HTML 报告,你可以在其中检查每个输出并记录下一次迭代读取的定性反馈
有关评估文件格式和完整迭代工作流,请参阅 agentskills.io 上的评估技能输出质量。有关基准和比较模式的背景,请参阅 skill-creator 公告。
分享 skills
Skills 可以根据你的受众在不同的范围内分发:
生成可视化输出
Skills 可以捆绑并运行任何语言的脚本,为 Claude 提供超越单个提示符可能实现的功能。一种模式是生成可视化输出:在浏览器中打开的交互式 HTML 文件,用于探索数据、调试或创建报告。
此示例创建一个代码库浏览器:一个交互式树形视图,你可以在其中展开和折叠目录、一目了然地查看文件大小,并通过颜色识别文件类型。
创建 Skill 目录:
mkdir -p ~/.claude/skills/codebase-visualizer/scripts
将其保存到 ~/.claude/skills/codebase-visualizer/SKILL.md。描述告诉 Claude 何时激活此 Skill,说明告诉 Claude 运行捆绑的脚本。脚本路径使用 ${CLAUDE_SKILL_DIR},因此无论 skill 是在个人、项目还是 plugin 级别安装,它都能正确解析:
---
name: codebase-visualizer
description: Generate an interactive collapsible tree visualization of your codebase. Use when exploring a new repo, understanding project structure, or identifying large files.
allowed-tools: Bash(python3 *)
---
# Codebase Visualizer
Generate an interactive HTML tree view that shows your project's file structure with collapsible directories.
## Usage
Run the visualization script from your project root:
```bash
python3 ${CLAUDE_SKILL_DIR}/scripts/visualize.py .
```
This creates `codebase-map.html` in the current directory and opens it in your default browser.
## What the visualization shows
- **Collapsible directories**: Click folders to expand/collapse
- **File sizes**: Displayed next to each file
- **Colors**: Different colors for different file types
- **Directory totals**: Shows aggregate size of each folder
将其保存到 ~/.claude/skills/codebase-visualizer/scripts/visualize.py。此脚本扫描目录树并生成一个自包含的 HTML 文件,包含:
- 一个摘要侧边栏,显示文件计数、目录计数、总大小和文件类型数量
- 一个条形图,按文件类型(按大小排名前 8)分解代码库
- 一个可折叠树,你可以在其中展开和折叠目录,带有颜色编码的文件类型指示器
该脚本需要 Python 3,但仅使用内置库,因此无需安装任何包:
#!/usr/bin/env python3
"""Generate an interactive collapsible tree visualization of a codebase."""
import json
import sys
import webbrowser
from html import escape
from pathlib import Path
from collections import Counter
IGNORE = {'.git', 'node_modules', '__pycache__', '.venv', 'venv', 'dist', 'build'}
def scan(path: Path, stats: dict) -> dict:
result = {"name": path.name, "children": [], "size": 0}
try:
for item in sorted(path.iterdir()):
if item.name in IGNORE or item.name.startswith('.'):
continue
if item.is_file():
size = item.stat().st_size
ext = item.suffix.lower() or '(no ext)'
result["children"].append({"name": item.name, "size": size, "ext": ext})
result["size"] += size
stats["files"] += 1
stats["extensions"][ext] += 1
stats["ext_sizes"][ext] += size
elif item.is_dir():
stats["dirs"] += 1
child = scan(item, stats)
if child["children"]:
result["children"].append(child)
result["size"] += child["size"]
except PermissionError:
pass
return result
def generate_html(data: dict, stats: dict, output: Path) -> None:
ext_sizes = stats["ext_sizes"]
total_size = sum(ext_sizes.values()) or 1
sorted_exts = sorted(ext_sizes.items(), key=lambda x: -x[1])[:8]
colors = {
'.js': '#f7df1e', '.ts': '#3178c6', '.py': '#3776ab', '.go': '#00add8',
'.rs': '#dea584', '.rb': '#cc342d', '.css': '#264de4', '.html': '#e34c26',
'.json': '#6b7280', '.md': '#083fa1', '.yaml': '#cb171e', '.yml': '#cb171e',
'.mdx': '#083fa1', '.tsx': '#3178c6', '.jsx': '#61dafb', '.sh': '#4eaa25',
}
lang_bars = "".join(
f'<div class="bar-row"><span class="bar-label">{ext}</span>'
f'<div class="bar" style="width:{(size/total_size)*100}%;background:{colors.get(ext,"#6b7280")}"></div>'
f'<span class="bar-pct">{(size/total_size)*100:.1f}%</span></div>'
for ext, size in sorted_exts
)
def fmt(b):
if b < 1024: return f"{b} B"
if b < 1048576: return f"{b/1024:.1f} KB"
return f"{b/1048576:.1f} MB"
html = f'''<!DOCTYPE html>
<html><head>
<meta charset="utf-8"><title>Codebase Explorer</title>
<style>
body {{ font: 14px/1.5 system-ui, sans-serif; margin: 0; background: #1a1a2e; color: #eee; }}
.container {{ display: flex; height: 100vh; }}
.sidebar {{ width: 280px; background: #252542; padding: 20px; border-right: 1px solid #3d3d5c; overflow-y: auto; flex-shrink: 0; }}
.main {{ flex: 1; padding: 20px; overflow-y: auto; }}
h1 {{ margin: 0 0 10px 0; font-size: 18px; }}
h2 {{ margin: 20px 0 10px 0; font-size: 14px; color: #888; text-transform: uppercase; }}
.stat {{ display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #3d3d5c; }}
.stat-value {{ font-weight: bold; }}
.bar-row {{ display: flex; align-items: center; margin: 6px 0; }}
.bar-label {{ width: 55px; font-size: 12px; color: #aaa; }}
.bar {{ height: 18px; border-radius: 3px; }}
.bar-pct {{ margin-left: 8px; font-size: 12px; color: #666; }}
.tree {{ list-style: none; padding-left: 20px; }}
details {{ cursor: pointer; }}
summary {{ padding: 4px 8px; border-radius: 4px; }}
summary:hover {{ background: #2d2d44; }}
.folder {{ color: #ffd700; }}
.file {{ display: flex; align-items: center; padding: 4px 8px; border-radius: 4px; }}
.file:hover {{ background: #2d2d44; }}
.size {{ color: #888; margin-left: auto; font-size: 12px; }}
.dot {{ width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; }}
</style>
</head><body>
<div class="container">
<div class="sidebar">
<h1>📊 Summary</h1>
<div class="stat"><span>Files</span><span class="stat-value">{stats["files"]:,}</span></div>
<div class="stat"><span>Directories</span><span class="stat-value">{stats["dirs"]:,}</span></div>
<div class="stat"><span>Total size</span><span class="stat-value">{fmt(data["size"])}</span></div>
<div class="stat"><span>File types</span><span class="stat-value">{len(stats["extensions"])}</span></div>
<h2>By file type</h2>
{lang_bars}
</div>
<div class="main">
<h1>📁 {escape(data["name"])}</h1>
<ul class="tree" id="root"></ul>
</div>
</div>
</body></html>'''
output.write_text(html)
if __name__ == '__main__':
target = Path(sys.argv[1] if len(sys.argv) > 1 else '.').resolve()
stats = {"files": 0, "dirs": 0, "extensions": Counter(), "ext_sizes": Counter()}
data = scan(target, stats)
out = Path('codebase-map.html')
generate_html(data, stats, out)
print(f'Generated {out.absolute()}')
webbrowser.open(f'file://{out.absolute()}')
要测试,在任何项目中打开 Claude Code 并询问"可视化此代码库。"Claude 运行脚本,该脚本打印生成的文件的路径,例如 Generated /path/to/codebase-map.html,并在浏览器中打开它。如果你在无浏览器环境中工作,其中没有浏览器打开,打印的路径确认脚本成功。
此模式适用于任何可视化输出:依赖关系图、测试覆盖率报告、API 文档或数据库架构可视化。捆绑的脚本完成工作,而 Claude 处理编排。
故障排除
Skill 未触发
如果 Claude 在预期时没有使用你的 skill:
- 检查描述是否包含用户会自然说出的关键词
- 验证 skill 是否出现在
What skills are available?中 - 尝试重新表述你的请求以更接近描述
- 如果 skill 是用户可调用的,使用
/skill-name直接调用它
如果 frontmatter YAML 格式不正确,Claude Code 会加载 skill 主体但元数据为空,所以 /skill-name 仍然有效,但 Claude 无法匹配你的 description。使用 --debug 运行以查看解析错误。
如果 skill 在 plugin 中,你可以在现实提示中测量它触发的频率,而不是逐个检查:使用 tool_used: Skill grader 编写一个 eval case,并在每次描述更改后使用 claude plugin eval 运行它。
要找到 frontmatter 无法解析的 SKILL.md 文件,在 skills 目录上运行 claude plugin validate,例如对于项目 skills 运行 claude plugin validate .claude/skills,或对于个人 skills 运行 claude plugin validate ~/.claude/skills。需要 Claude Code v2.1.233 或更高版本。
Skill 触发过于频繁
如果 Claude 在你不想要的时候使用你的 skill:
- 使描述更具体
- 如果你只想要手动调用,添加
disable-model-invocation: true
Claude 停止遵循 skill
如果 Claude 在其第一个响应中遵循 skill,但之后停止遵循它,请从与你的情况相匹配的以下任何一种情况开始:
- Claude 跳过了必须每次都成立的规则:将规则移到 hook 中。Claude Code 在其事件发生时每次都运行 hook,例如在每次文件编辑之前,无论 Claude 是否遵循 skill。要将规则与 skill 保持在一起,在 skill 的
hooksfrontmatter 中定义 hook。该 hook 从 skill 被调用时开始应用,直到会话结束。 - Claude 跳过了应该有判断力地应用的指导:措辞指导使其适用于整个任务,例如"在每次编辑后运行测试"而不是"运行测试"。Claude Code 在 skill 被调用时将 skill 的内容添加到对话中,并且 不会在后续轮次重新读取文件。
- 对话被压缩了:再次调用 skill 以恢复其完整内容。在 压缩 之后,Claude Code 只能保留被调用的 skill 的开始部分,所以将最重要的说明放在
SKILL.md的顶部。
Skill 描述被截断
Claude Code 将 skill 名称和描述的列表加载到上下文中,以便 Claude 知道有哪些可用。列表始终包含每个 skill 名称,但如果你有很多 skills,Claude Code 会缩短描述以适应列表的字符预算,这可能会删除 Claude 需要匹配你的请求的关键词。预算按模型上下文窗口的 1% 进行缩放。当列表溢出时,Claude Code 从你调用最少的 skills 开始删除描述,所以你使用最多的 skills 保持其完整文本。
运行 /doctor 以估计列表的上下文成本及其最大贡献者。要找到值得关闭的 skills,运行 /skill-doctor。当列表超过其预算时,Claude Code 也会向调试日志写入警告,可通过 --debug 查看。
/context 中的 Skills 行报告应用预算后列表的大小,因此它与模型接收的内容相匹配。在 v2.1.196 之前,该行计算每个描述的完整文本,可能显示的值比配置的预算大几倍。
要提高预算,设置 skillListingBudgetFraction 设置(例如 0.02 = 2%)或 SLASH_COMMAND_TOOL_CHAR_BUDGET 环境变量为固定字符数。要为其他 skills 释放预算,在 skillOverrides 中将低优先级条目设置为 "name-only",以便它们在没有描述的情况下列出。你也可以在源处修剪 description 和 when_to_use 文本:将关键用例放在首位,因为每个条目的组合文本被限制在 1,536 个字符,无论预算如何。该上限可通过 skillListingMaxDescChars 配置。
个人 skills 消失了
如果你在 ~/.claude/skills/ 中创建的 skill 文件夹消失了,请查看 ~/.claude/skills/.trash/。当 Claude Code 从 claude.ai 同步 skills 时,它会将它们下载到单独的 synced 子文件夹中,不会移动或删除你创建的文件夹。
在 v2.1.280 之前,~/.claude/skills/ 中名为 manifest.json 的文件会导致 Claude Code 将该文件列出的 skill 文件夹移动到 ~/.claude/skills/.trash/ 下的带时间戳的文件夹中,这些 skills 停止加载。
要恢复一个 skill,将其文件夹从带时间戳的文件夹移回 ~/.claude/skills/。在 保留扫描 删除垃圾条目之前执行此操作,默认情况下在移动到垃圾箱后 30 天。
相关资源
- 调试你的配置:诊断为什么 skill 没有出现或触发
- 在 agentskills.io 上评估 skill 输出质量:eval 文件格式和迭代工作流
- Skill 创作最佳实践:适用于 Claude 产品的写作指导
- Subagents:将任务委派给专门的代理
- Plugins:打包和分发 skills 与其他扩展
- Hooks:围绕工具事件自动化工作流
- Memory:管理 CLAUDE.md 文件以获得持久上下文
- Commands:内置命令和捆绑 skills 的参考
- Permissions:控制工具和 skill 访问
- Claude Tag skills:提交到仓库的项目 skills 在该仓库在 Claude Tag 频道中使用时也会加载