文档索引
在此获取完整文档索引:https://code.claude.com/docs/llms.txt 使用此文件发现所有可用页面,然后再进一步探索。
使用技能扩展 Claude
在 Claude Code 中创建、管理和共享技能以扩展 Claude 的功能。包括自定义命令和捆绑技能。
技能扩展了 Claude 的能力。创建一个带有指令的 SKILL.md 文件,Claude 就会将其添加到工具包中。Claude 在相关时使用技能,或者你可以用 /skill-name 直接调用。
当你不断将相同的指令、检查清单或多步骤过程粘贴到聊天中时,或者当 CLAUDE.md 的某个部分已增长为程序而非事实时,请创建技能。与 CLAUDE.md 内容不同,技能的正文仅在使用时加载,因此长篇参考材料在你需要之前几乎没有成本。
有关内置命令如 /help 和 /compact,以及捆绑技能如 /debug 和 /code-review,请参阅命令参考。
自定义命令已合并到技能中。 .claude/commands/deploy.md 中的文件和 .claude/skills/deploy/SKILL.md 中的技能都创建 /deploy 并以相同方式工作。你现有的 .claude/commands/ 文件继续有效。技能添加了可选功能:支持文件的目录、用于控制是你还是 Claude 调用它们的前置数据,以及 Claude 在相关时自动加载它们的能力。
Claude Code 技能遵循 Agent Skills 开放标准,可在多个 AI 工具间使用。Claude Code 使用调用控制、子代理执行和动态上下文注入等额外功能扩展了该标准。
捆绑技能
Claude Code 包含一组捆绑技能,在每个会话中都可用,包括 /code-review、/batch、/debug、/loop 和 /claude-api。与大多数直接执行固定逻辑的内置命令不同,捆绑技能是基于提示的:它们给 Claude 详细的指令,让其使用工具来编排工作。你以与任何其他技能相同的方式调用它们,输入 / 后跟技能名称。
捆绑技能与内置命令一起列在命令参考中,在用途列中标记为技能。
运行和验证你的应用
三个捆绑技能协同工作,启动你的应用并根据运行中的应用而非仅测试来确认更改:
| 技能 | 用途 |
|---|---|
/run | 启动并驱动你的应用以查看更改是否生效 |
/verify | 构建并运行你的应用以确认代码更改是否如预期工作,而非回退到测试或类型检查 |
/run-skill-generator | 教 /run 和 /verify 如何构建和启动你的项目 |
这三个技能都需要 Claude Code v2.1.145 或更高版本。
/run 和 /verify 无需设置即可工作。它们从你的项目类型(CLI、服务器、TUI、浏览器驱动)以及 README、package.json 或 Makefile 中的内容推断启动方式。对于需要标准启动之外的任何内容的项目,这种推断变得不可靠:数据库、环境文件、图形会话、多步骤构建。
/run-skill-generator 记录配方代替。它让你的应用从干净环境运行,捕获有效的内容(安装命令、环境变量、启动脚本),并将其作为每项目技能提交到 .claude/skills/run-<name>/。之后,/run、/verify 以及仓库中的任何其他代理遵循记录的配方而非重新发现它。每个项目运行一次 /run-skill-generator,如果构建或启动过程更改则再次运行。
入门
创建你的第一个技能
此示例创建一个技能,总结 git 仓库中未提交的更改并标记任何风险。它在 Claude 读取之前将实时差异拉入提示,因此响应基于你的实际工作树而非 Claude 从打开的文件中猜测的内容。当你询问更改时,Claude 自动加载该技能,或者你可以用 /summarize-changes 直接调用。
创建技能目录
在你的个人技能文件夹中为技能创建目录。个人技能在你所有项目中可用。
mkdir -p ~/.claude/skills/summarize-changes编写 SKILL.md
每个技能需要一个
SKILL.md文件,包含两部分:---标记之间的 YAML 前置数据告诉 Claude 何时使用技能,以及技能运行时 Claude 遵循的 markdown 内容指令。目录名称成为你输入的命令,description帮助 Claude 决定何时自动加载技能。将以下内容保存到
~/.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 看到技能内容之前用其输出替换该行,因此指令到达时已内联当前差异。测试技能
打开一个 git 项目,对任何文件进行小编辑,然后运行
claude启动 Claude Code。你可以用两种方式测试技能。让 Claude 自动调用,通过询问匹配描述的内容:
What did I change?或直接调用,使用技能名称:
/summarize-changes无论哪种方式,Claude 应该以你的编辑的简短摘要和风险列表作为回应。
技能存放位置
你存储技能的位置决定了谁可以使用它:
| 位置 | 路径 | 适用于 |
|---|---|---|
| 企业 | 参见托管设置 | 你组织中的所有用户 |
| 个人 | ~/.claude/skills/<skill-name>/SKILL.md | 你所有项目 |
| 项目 | .claude/skills/<skill-name>/SKILL.md | 仅此项目 |
| 插件 | <plugin>/skills/<skill-name>/SKILL.md | 插件启用的地方 |
当技能在不同层级共享相同名称时,企业覆盖个人,个人覆盖项目。插件技能使用 plugin-name:skill-name 命名空间,因此它们不会与其他层级冲突。如果你在 .claude/commands/ 中有文件,它们以相同方式工作,但如果技能和命令共享相同名称,技能优先。
实时更改检测
Claude Code 监视技能目录的文件更改。在 ~/.claude/skills/、项目 .claude/skills/ 或 --add-dir 目录中的 .claude/skills/ 下添加、编辑或移除技能会在当前会话中生效,无需重启。创建会话启动时不存在的顶级技能目录需要重启 Claude Code 以便监视新目录。
从父目录和嵌套目录自动发现
项目技能从你的起始目录及每个父目录直到仓库根目录的 .claude/skills/ 加载,因此在子目录中启动 Claude 仍会获取在根目录定义的技能。当你在起始目录以下的子目录中处理文件时,Claude Code 也会按需从嵌套的 .claude/skills/ 目录发现技能。例如,如果你在 packages/frontend/ 中编辑文件,Claude Code 也会在 packages/frontend/.claude/skills/ 中查找技能。这支持包有自己技能的 monorepo 设置。
每个技能是以 SKILL.md 为入口点的目录:
my-skill/
├── SKILL.md # Main instructions (required)
├── template.md # Template for Claude to fill in
├── examples/
│ └── sample.md # Example output showing expected format
└── scripts/
└── validate.sh # Script Claude can execute
SKILL.md 包含主要指令,是必需的。其他文件是可选的,让你构建更强大的技能:Claude 填写的模板、显示预期格式的示例输出、Claude 可以执行的脚本或详细的参考文档。从你的 SKILL.md 引用这些文件,以便 Claude 知道它们包含什么以及何时加载它们。详见添加支持文件。
.claude/commands/ 中的文件仍然有效,并支持相同的前置数据。推荐使用技能,因为它们支持额外功能如支持文件。
来自额外目录的技能
--add-dir 标志和 /add-dir 命令授予文件访问权限而非配置发现,但技能是例外:添加目录中的 .claude/skills/ 会自动加载。此例外仅适用于 --add-dir 和 /add-dir。settings.json 中的 permissions.additionalDirectories 设置仅授予文件访问权限,不加载技能。参见实时更改检测了解会话期间如何获取编辑。
其他 .claude/ 配置如子代理、命令和输出样式不会从额外目录加载。参见例外表了解完整列表以及跨项目共享配置的推荐方式。
--add-dir 目录中的 CLAUDE.md 文件默认不加载。要加载它们,设置 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1。参见从额外目录加载。
配置技能
技能通过 SKILL.md 顶部的 YAML 前置数据和随后的 markdown 内容进行配置。
技能内容类型
技能文件可以包含任何指令,但思考你想如何调用它们有助于指导包含什么:
参考内容添加 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 自动触发它。
---
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.md 可以包含任何内容,但思考你想如何调用技能(由你、由 Claude 或两者)以及你想让它在哪里运行(内联或在子代理中)有助于指导包含什么。对于复杂技能,你也可以添加支持文件以保持主技能的重点。
保持正文本身简洁。一旦技能加载,其内容在轮次之间保持在上下文中,因此每一行都是重复的令牌成本。说明做什么而非叙述如何或为什么,应用与 CLAUDE.md 内容相同的简洁性测试。
前置数据参考
除了 markdown 内容,你可以使用 SKILL.md 文件顶部 --- 标记之间的 YAML 前置数据字段配置技能行为:
---
name: my-skill
description: What this skill does
disable-model-invocation: true
allowed-tools: Read Grep
---
Your skill instructions here...
所有字段都是可选的。仅推荐 description,以便 Claude 知道何时使用技能。
| 字段 | 必需 | 描述 |
|---|---|---|
name | 否 | 技能列表中显示的显示名称。默认为目录名称。参见技能如何获取其命令名称了解这与你输入调用技能的名称有何不同 |
description | 推荐 | 技能做什么以及何时使用它。Claude 使用此来决定何时应用技能。如果省略,使用 markdown 内容的第一段。将关键用例放在前面:组合的 description 和 when_to_use 文本在技能列表中截断为 1,536 个字符以减少上下文使用 |
when_to_use | 否 | Claude 何时应调用技能的额外上下文,如触发短语或示例请求。附加到技能列表中的 description 并计入 1,536 字符上限 |
argument-hint | 否 | 自动补全期间显示的提示,指示预期参数。示例:[issue-number] 或 [filename] [format] |
arguments | 否 | 用于技能内容中 $name 替换的命名位置参数。接受空格分隔的字符串或 YAML 列表。名称按顺序映射到参数位置 |
disable-model-invocation | 否 | 设置为 true 以防止 Claude 自动加载此技能。用于你想用 /name 手动触发的工作流。也防止技能被预加载到子代理中。默认:false |
user-invocable | 否 | 设置为 false 以从 / 菜单中隐藏。用于用户不应直接调用的背景知识。默认:true |
allowed-tools | 否 | 技能激活时 Claude 可以无需请求许可使用的工具。接受空格分隔的字符串或 YAML 列表 |
model | 否 | 技能激活时使用的模型。覆盖适用于当前轮次的其余部分且不保存到设置;会话模型在你的下一个提示时恢复。接受与 /model 相同的值,或 inherit 保持活动模型 |
effort | 否 | 技能激活时的努力程度。覆盖会话努力程度。默认:从会话继承。选项:low、medium、high、xhigh、max;可用级别取决于模型 |
context | 否 | 设置为 fork 以在分叉的子代理上下文中运行 |
agent | 否 | 设置 context: fork 时使用哪种子代理类型 |
hooks | 否 | 限定到此技能生命周期的钩子。参见技能和代理中的钩子了解配置格式 |
paths | 否 | 限制此技能何时激活的 Glob 模式。接受逗号分隔的字符串或 YAML 列表。设置后,Claude 仅在处理匹配模式的文件时自动加载技能。使用与路径特定规则相同的格式 |
shell | 否 | 此技能中 !`command` 和 ```! 块使用的 shell。接受 bash(默认)或 powershell。设置 powershell 在 Windows 上通过 PowerShell 运行内联 shell 命令。需要 CLAUDE_CODE_USE_POWERSHELL_TOOL=1 |
技能如何获取其命令名称
你输入调用技能的命令来自技能文件的位置。前置数据 name 字段设置技能列表中显示的显示标签,除了插件根目录的 SKILL.md 外,不会改变你在 / 后输入的内容。
下表显示每种布局的命令名称来源:
| 技能位置 | 命令名称来源 | 示例 |
|---|---|---|
~/.claude/skills/ 或 .claude/skills/ 下的技能目录 | 目录名称 | .claude/skills/deploy-staging/SKILL.md → /deploy-staging |
.claude/commands/ 下的文件 | 不带扩展名的文件名 | .claude/commands/deploy.md → /deploy |
插件 skills/ 子目录 | 目录名称,按插件命名空间 | my-plugin/skills/review/SKILL.md → /my-plugin:review |
插件根目录 SKILL.md | 前置数据 name,以插件目录名称作为回退 | my-plugin/SKILL.md 带 name: review → /my-plugin:review。参见路径行为规则 |
插件根目录情况是 name 确实设置命令名称的唯一位置,因为没有技能目录可以从中获取。如果前置数据中未设置 name,则使用插件的目录名称。
可用字符串替换
技能支持技能内容中动态值的字符串替换:
| 变量 | 描述 |
|---|---|
$ARGUMENTS | 调用技能时传递的所有参数。如果 $ARGUMENTS 不在内容中,参数附加为 ARGUMENTS: <value> |
$ARGUMENTS[N] | 通过 0 基索引访问特定参数,如 $ARGUMENTS[0] 表示第一个参数 |
$N | $ARGUMENTS[N] 的简写,如 $0 表示第一个参数或 $1 表示第二个 |
$name | arguments 前置数据列表中声明的命名参数。名称按顺序映射到位置,因此使用 arguments: [issue, branch] 时占位符 $issue 展开为第一个参数,$branch 为第二个 |
{{CONTENT}}amp;#123;CLAUDE_SESSION_ID} | 当前会话 ID。用于日志记录、创建会话特定文件或将技能输出与会话关联 |
{{CONTENT}}amp;#123;CLAUDE_EFFORT} | 当前努力程度:low、medium、high、xhigh 或 max。用于根据活动努力设置调整技能指令 |
{{CONTENT}}amp;#123;CLAUDE_SKILL_DIR} | 包含技能 SKILL.md 文件的目录。对于插件技能,这是插件中技能的子目录,而非插件根目录。在 bash 注入命令中使用此项引用与技能捆绑的脚本或文件,无论当前工作目录如何 |
索引参数使用 shell 风格的引号,因此将多词值用引号包裹以作为单个参数传递。例如,/my-skill "hello world" second 使 $0 展开为 hello world,$1 为 second。$ARGUMENTS 占位符始终展开为输入的完整参数字符串。
使用替换的示例:
---
name: session-logger
description: Log activity for this session
---
Log the following to logs/${CLAUDE_SESSION_ID}.log:
$ARGUMENTS
添加支持文件
技能可以在其目录中包含多个文件。这保持 SKILL.md 专注于要点,同时让 Claude 仅在需要时访问详细的参考材料。大型参考文档、API 规范或示例集合不需要每次技能运行时都加载到上下文中。
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](reference.md)
- For usage examples, see [examples.md](examples.md)
SKILL.md 在 500 行以下。将详细参考材料移到单独的文件中。控制谁调用技能
默认情况下,你和 Claude 都可以调用任何技能。你可以输入 /skill-name 直接调用,Claude 可以在与你的对话相关时自动加载。两个前置数据字段让你限制这一点:
-
disable-model-invocation: true:只有你可以调用技能。用于有副作用或你想控制时机的工作流,如/commit、/deploy或/send-slack-message。你不希望 Claude 因为你的代码看起来准备好了就决定部署。 -
user-invocable: false:只有 Claude 可以调用技能。用于不能作为命令操作的背景知识。legacy-system-context技能解释旧系统如何工作。Claude 应该在相关时知道这一点,但/legacy-system-context不是用户可以采取的有意义的操作。
此示例创建一个只有你可以触发的部署技能。disable-model-invocation: true 字段防止 Claude 自动运行它:
---
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 可以调用 | 加载到上下文时 |
|---|---|---|---|
| (默认) | 是 | 是 | 描述始终在上下文中,调用时加载完整技能 |
disable-model-invocation: true | 是 | 否 | 描述不在上下文中,你调用时加载完整技能 |
user-invocable: false | 否 | 是 | 描述始终在上下文中,调用时加载完整技能 |
在常规会话中,技能描述加载到上下文中以便 Claude 知道哪些可用,但完整技能内容仅在调用时加载。预加载技能的子代理的工作方式不同:完整技能内容在启动时注入。
技能内容生命周期
当你或 Claude 调用技能时,渲染的 SKILL.md 内容作为单条消息进入对话并在会话的其余时间留在那里。Claude Code 不会在后续轮次中重新读取技能文件,因此将应贯穿任务的指导编写为常设指令而非一次性步骤。
自动压缩在令牌预算内携带调用的技能。当对话被总结以释放上下文时,Claude Code 在总结后重新附加每个技能的最近调用,保留每个的前 5,000 个令牌。重新附加的技能共享 25,000 个令牌的组合预算。Claude Code 从最近调用的技能开始填充此预算,因此在一个会话中调用了许多技能后,较旧的技能可能在压缩后被完全丢弃。
如果技能在第一次响应后似乎停止影响行为,内容通常仍然存在且模型选择了其他工具或方法。加强技能的 description 和指令,以便模型继续偏好它,或使用钩子以确定性方式强制执行行为。如果技能较大或你在其后调用了其他几个技能,在压缩后重新调用它以恢复完整内容。
为技能预批准工具
allowed-tools 字段在技能激活时授予列出工具的许可,因此 Claude 可以使用它们而无需提示你批准。它不限制哪些工具可用:每个工具仍然可调用,你的权限设置仍然管理未列出的工具。
对于提交到项目 .claude/skills/ 目录的技能,allowed-tools 在你接受该文件夹的工作区信任对话框后生效,与 .claude/settings.json 中的权限规则相同。在信任仓库之前审查项目技能,因为技能可以授予自己广泛的工具访问权限。
此技能让 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 *)
---
要阻止技能使用某些工具,在你的权限设置中添加拒绝规则。
向技能传递参数
你和 Claude 都可以在调用技能时传递参数。参数通过 $ARGUMENTS 占位符可用。
此技能按编号修复 GitHub issue。$ARGUMENTS 占位符被技能名称后的任何内容替换:
---
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..."
如果你带参数调用技能但技能不包含 $ARGUMENTS,Claude Code 将 ARGUMENTS: <your input> 附加到技能内容的末尾,以便 Claude 仍然看到你输入的内容。
要按位置访问各个参数,使用 $ARGUMENTS[N] 或更短的 $N:
---
name: migrate-component
description: Migrate a component from one framework to another
---
Migrate the $ARGUMENTS[0] component from $ARGUMENTS[1] to $ARGUMENTS[2].
Preserve all existing behavior and tests.
运行 /migrate-component SearchBar React Vue 将 $ARGUMENTS[0] 替换为 SearchBar,$ARGUMENTS[1] 替换为 React,$ARGUMENTS[2] 替换为 Vue。使用 $N 简写的同一技能:
---
name: migrate-component
description: Migrate a component from one framework to another
---
Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
高级模式
注入动态上下文
!`<command>` 语法在技能内容发送给 Claude 之前运行 shell 命令。命令输出替换占位符,因此 Claude 接收到实际数据而非命令本身。
此技能通过使用 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>`立即执行(在 Claude 看到任何内容之前) - 输出替换技能内容中的占位符
- Claude 接收包含实际 PR 数据的完全渲染提示
这是预处理,不是 Claude 执行的内容。Claude 只看到最终结果。
替换在原始文件上运行一次。命令输出作为纯文本插入,不会重新扫描以查找进一步的 !`<command>` 占位符,因此命令不能发出供后续传递展开的占位符。
内联形式仅在 ! 出现在行首或紧跟空白时被识别。如果 ! 跟在另一个字符后面,如 KEY=!`cmd`,占位符保留为字面文本且命令不运行。
对于多行命令,使用以 ```! 开头的围栏代码块而非内联形式:
## Environment
```!
node --version
npm --version
git status --short
```
要为用户、项目、插件或额外目录来源的技能和自定义命令禁用此行为,在设置中设置 "disableSkillShellExecution": true。每个命令被替换为 [shell command execution disabled by policy] 而非运行。捆绑和托管技能不受影响。此设置在托管设置中最有用,用户无法覆盖。
要在技能运行时请求更深入的推理,在技能内容中的任何位置包含 ultrathink。参见使用 ultrathink 进行一次性深度推理。
在子代理中运行技能
当你想让技能在隔离环境中运行时,在前置数据中添加 context: fork。技能内容成为驱动子代理的提示。它不会访问你的对话历史。
context: fork 仅对有明确指令的技能有意义。如果你的技能包含如"使用这些 API 约定"的指南而没有任务,子代理接收到指南但没有可操作的提示,并在没有有意义输出的情况下返回。
技能和子代理在两个方向上协同工作:
| 方法 | 系统提示 | 任务 | 也加载 |
|---|---|---|---|
带 context: fork 的技能 | 来自代理类型 | SKILL.md 内容 | CLAUDE.md,除非代理是 Explore 或 Plan |
带 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 的技能。定义 allowed-tools 的技能在技能激活时授予 Claude 对这些工具的访问权限而无需每次使用批准。你的权限设置仍然管理所有其他工具的基线审批行为。一些内置命令也可通过技能工具使用,包括 /init、/review 和 /security-review。其他内置命令如 /compact 则不行。
控制 Claude 可以调用哪些技能的三种方式:
禁用所有技能,通过在 /permissions 中拒绝技能工具:
# Add to deny rules:
Skill
允许或拒绝特定技能,使用权限规则:
# Allow only specific skills
Skill(commit)
Skill(review-pr *)
# Deny specific skills
Skill(deploy *)
权限语法:Skill(name) 精确匹配,Skill(name *) 前缀匹配带任何参数。
隐藏个别技能,通过在其前置数据中添加 disable-model-invocation: true。这会将技能从 Claude 的上下文中完全移除。
user-invocable 字段仅控制菜单可见性,而非技能工具访问。使用 disable-model-invocation: true 阻止程序化调用。
从设置覆盖技能可见性
skillOverrides 设置从你的设置控制技能可见性,而非技能自己的前置数据。用于你不想编辑其 SKILL.md 的技能,如提交到共享项目仓库或由 MCP 服务器提供的技能。/skills 菜单为你写入它:高亮技能并按 Space 循环状态,然后按 Enter 保存到 .claude/settings.local.json。
每个键是技能名称,每个值是四种状态之一:
| 值 | 列出给 Claude | 在 / 菜单中 |
|---|---|---|
"on" | 名称和描述 | 是 |
"name-only" | 仅名称 | 是 |
"user-invocable-only" | 隐藏 | 是 |
"off" | 隐藏 | 隐藏 |
skillOverrides 中不存在的技能视为 "on"。以下示例将一个技能折叠为仅名称,另一个完全关闭:
{
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
}
}
插件技能不受 skillOverrides 影响。改用 /plugin 管理它们。
共享技能
技能可以根据你的受众在不同的范围分发:
生成视觉输出
技能可以捆绑和运行任何语言的脚本,赋予 Claude 超出单个提示可能的能力。一个强大的模式是生成视觉输出:在浏览器中打开的交互式 HTML 文件,用于探索数据、调试或创建报告。
此示例创建一个代码库浏览器:一个交互式树视图,你可以展开和折叠目录、一目了然地查看文件大小以及按颜色识别文件类型。
创建技能目录:
mkdir -p ~/.claude/skills/codebase-visualizer/scripts
将以下内容保存到 ~/.claude/skills/codebase-visualizer/SKILL.md。描述告诉 Claude 何时激活此技能,指令告诉 Claude 运行捆绑的脚本。脚本路径使用 {{CONTENT}}amp;#123;CLAUDE_SKILL_DIR},因此无论技能安装在个人、项目还是插件级别都能正确解析:
---
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>
<script>
const data = {json.dumps(data)};
const colors = {json.dumps(colors)};
function fmt(b) {{ if (b < 1024) return b + ' B'; if (b < 1048576) return (b/1024).toFixed(1) + ' KB'; return (b/1048576).toFixed(1) + ' MB'; }}
function esc(s) {{ return s.replace(/[&<>"']/g, c => ({{"&":"&","<":"<",">":">",'"':""","'":"'"}}[c])); }}
function render(node, parent) {{
if (node.children) {{
const det = document.createElement('details');
det.open = parent === document.getElementById('root');
det.innerHTML = `<summary><span class="folder">📁 ${{esc(node.name)}}</span><span class="size">${{fmt(node.size)}}</span></summary>`;
const ul = document.createElement('ul'); ul.className = 'tree';
node.children.sort((a,b) => (b.children?1:0)-(a.children?1:0) || a.name.localeCompare(b.name));
node.children.forEach(c => render(c, ul));
det.appendChild(ul);
const li = document.createElement('li'); li.appendChild(det); parent.appendChild(li);
}} else {{
const li = document.createElement('li'); li.className = 'file';
li.innerHTML = `<span class="dot" style="background:${{colors[node.ext]||'#6b7280'}}"></span>${{esc(node.name)}}<span class="size">${{fmt(node.size)}}</span>`;
parent.appendChild(li);
}}
}}
data.children.forEach(c => render(c, document.getElementById('root')));
</script>
</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 并要求"Visualize this codebase"。Claude 运行脚本,生成 codebase-map.html,并在你的浏览器中打开它。
此模式适用于任何视觉输出:依赖图、测试覆盖率报告、API 文档或数据库模式可视化。捆绑的脚本完成工作,而 Claude 处理编排。
故障排除
技能未触发
如果 Claude 在预期时未使用你的技能:
- 检查描述是否包含用户自然会说的关键词
- 验证技能出现在
What skills are available?中 - 尝试重新表述你的请求以更接近匹配描述
- 如果技能是用户可调用的,用
/skill-name直接调用
技能触发太频繁
如果 Claude 在你不想时使用你的技能:
- 使描述更具体
- 如果你只想要手动调用,添加
disable-model-invocation: true
技能描述被截断
技能描述加载到上下文中以便 Claude 知道哪些可用。所有技能名称始终包含,但如果你有很多技能,描述会缩短以适应字符预算,这可能剥离 Claude 匹配你的请求所需的关键词。预算按模型上下文窗口的 1% 缩放。当溢出时,你最不常调用的技能的描述先被丢弃,因此你实际使用的技能保持其完整文本。运行 /doctor 以查看预算是否溢出以及哪些技能受影响。
要提高预算,设置 skillListingBudgetFraction 设置(例如 0.02 = 2%)或 SLASH_COMMAND_TOOL_CHAR_BUDGET 环境变量为固定字符数。要为其他技能释放预算,在 skillOverrides 中将低优先级条目设置为 "name-only",这样它们列出但没有描述。你也可以在源头精简 description 和 when_to_use 文本:将关键用例放在前面,因为每个条目的组合文本上限为 1,536 个字符,无论预算如何。上限可通过 maxSkillDescriptionChars 配置。