Claude_Code_Skills 更新后指南
太累了,真的,这更新频率太高了,前段时间还是用json和md形势的skill,现在马上变成YAML了
本文将详细介绍如何通过 Skills 扩展 Claude Code 的能力,包括创建、配置、管理和共享技能的全流程。
一、前置知识
在阅读本文之前,你需要具备以下基础:
- 熟悉 Claude Code 的基本使用方法
- 了解 YAML 语法和 Markdown 写作基础
- 具备基本的命令行操作能力
二、核心概念:什么是 Skills
2.1 Skills 的本质
Claude Code Skills 是一种扩展 Claude 能力的标准化方式。通过创建一个包含说明的 SKILL.md 文件,Claude 会将其添加到工具包中,在相关场景下自动调用或通过 /skill-name 手动触发。
Skills 遵循 Agent Skills 开放标准,Claude Code 在此基础上扩展了调用控制、子代理执行和动态上下文注入等功能。
2.2 Skills 的存储位置
技能的存储位置决定了其作用域:
| 位置 | 路径 | 适用范围 |
|---|---|---|
| 企业级 | 托管设置中配置 | 组织内所有用户 |
| 个人级 | ~/.claude/skills/<skill-name>/SKILL.md |
用户的全部项目 |
| 项目级 | .claude/skills/<skill-name>/SKILL.md |
仅当前项目 |
| 插件级 | <plugin>/skills/<skill-name>/SKILL.md |
启用插件的位置 |
优先级规则:项目技能 > 个人技能 > 企业技能
2.3 技能目录结构
graph TD
A[技能目录] --> B[SKILL.md 必需]
A --> C[template.md 可选]
A --> D[examples/ 可选]
A --> E[scripts/ 可选]
B --> F[前置元数据 YAML]
B --> G[Markdown 说明内容]
D --> H[sample.md 示例输出]
E --> I[validate.sh 验证脚本]
三、快速入门:创建你的第一个技能
3.1 创建步骤详解
假设我们需要创建一个用于解释代码的技能,包含视觉图表和类比:
步骤 1:创建技能目录
# 在个人技能目录下创建目录
mkdir -p ~/.claude/skills/explain-code
步骤 2:编写 SKILL.md 文件
---
name: explain-code
description: 使用视觉图表和类比解释代码。当解释代码工作原理、教学代码库或用户询问"这是如何工作的"时使用。
---
# 代码解释技能使用指南
在解释代码时,始终遵循以下结构:
## 1. 类比开场
将代码概念与日常生活中的事物进行类比,降低理解门槛
## 2. 可视化图表
使用 ASCII art 展示代码流程、数据结构或关系
## 3. 逐步解读
按执行顺序逐步说明代码逻辑
## 4. 常见误区
指出开发者容易犯的错误或误解
保持解释的对话感,对于复杂概念使用多种类比进行阐述。
3.3 测试技能
技能创建后,可以通过两种方式测试:
方式一:让 Claude 自动触发
用户:这段代码是如何工作的?
方式二:手动调用技能
/explain-code src/auth/login.ts
四、SKILL.md 深入解析
4.1 前置元数据配置
SKILL.md 文件由两部分组成:YAML 前置元数据和 Markdown 说明内容。
---
name: deploy # 技能名称(小写字母、数字、连字符)
description: 将应用部署到生产环境 # 技能描述(Claude 自动加载的依据)
disable-model-invocation: true # 禁止 Claude 自动调用
user-invocable: true # 是否可在 / 菜单中显示
allowed-tools: Read, Grep # 允许使用的工具列表
context: fork # 运行上下文(fork 为子代理模式)
agent: Explore # 子代理类型
hooks: # 生命周期钩子
post-tool: scripts/hook.sh
---
技能说明内容...
4.2 前置元数据字段详解
| 字段 | 必需 | 描述 |
|---|---|---|
name |
否 | 技能显示名称,省略则使用目录名 |
description |
推荐 | 技能作用描述,决定何时自动加载 |
argument-hint |
否 | 参数提示,如 [issue-number] |
disable-model-invocation |
否 | 设为 true 仅允许用户手动调用 |
user-invocable |
否 | 设为 false 从 / 菜单隐藏 |
allowed-tools |
否 | 技能激活时允许使用的工具 |
model |
否 | 指定使用的模型 |
context |
否 | fork 表示在子代理中运行 |
agent |
否 | 子代理类型 |
hooks |
否 | 技能生命周期钩子 |
4.3 字符串替换变量
技能支持动态值注入:
---
name: session-logger
description: 记录当前会话活动
---
# 会话日志
日志将保存到 logs/${CLAUDE_SESSION_ID}.log
调用参数:$ARGUMENTS
| 变量 | 描述 |
|---|---|
$ARGUMENTS |
传递的所有参数 |
${CLAUDE_SESSION_ID} |
当前会话 ID |
五、调用控制策略
5.1 三种调用模式
graph LR
A[用户调用] --> B[Claude 调用]
subgraph 默认模式
C1[描述在上下文]
C2[完整内容调用时加载]
end
subgraph 手动模式
D1[添加 disable-model-invocation: true]
D2[仅用户可调用]
D3[内容不在上下文中]
end
subgraph 背景模式
E1[添加 user-invocable: false]
E2[仅 Claude 可调用]
E3[描述常驻上下文]
end
5.2 调用控制示例
仅允许用户手动调用的部署技能
---
name: deploy
description: 将应用部署到生产环境
disable-model-invocation: true
---
部署步骤:
1. 运行测试套件
2. 构建应用
3. 推送到部署目标
4. 验证部署成功
仅允许 Claude 调用的背景知识技能
---
name: legacy-system-context
description: 遗留系统的技术背景知识
user-invocable: false
---
# 遗留系统上下文
本系统是一个2015年构建的单体架构,主要技术栈:
- 后端:Java 7 + Spring 4
- 数据库:Oracle 11g
- 部署:WebLogic 12c
注意:数据库连接池配置复杂,不要轻易调整参数。
5.3 调用权限矩阵
| 前置元数据 | 用户可调用 | Claude 可调用 | 何时加载到上下文 |
|---|---|---|---|
| (默认) | 是 | 是 | 描述始终在,调用时加载完整内容 |
disable-model-invocation: true |
是 | 否 | 仅调用时加载完整内容 |
user-invocable: false |
否 | 是 | 描述始终在,调用时加载完整内容 |
六、工具访问控制
6.1 限制技能可用工具
使用 allowed-tools 字段创建只读模式技能:
---
name: safe-reader
description: 以只读方式浏览文件,不进行修改
allowed-tools: Read, Grep, Glob
---
# 安全阅读模式
你可以浏览代码库但不能修改任何文件。
使用 Read 工具阅读文件内容
使用 Grep 工具搜索特定模式
使用 Glob 工具查找文件
6.2 工具限制语法
# 精确工具列表
allowed-tools: Read, Write, Edit
# 使用通配符
allowed-tools: Bash(gh:*)
# 组合使用
allowed-tools: Read, Grep, Bash(git:*), Bash(gh:*)
七、高级模式
7.1 动态上下文注入
使用反引号命令语法在技能执行前注入动态数据:
---
name: pr-summary
description: 总结 Pull Request 的变更内容
context: fork
agent: Explore
allowed-tools: Bash(gh:*)
---
## Pull Request 上下文
- 变更差异:`!gh pr diff`
- PR 评论:`!gh pr view --comments`
- 变更文件列表:`!gh pr diff --name-only`
## 任务
请总结这个 Pull Request 的主要变更,包括:
1. 新增功能
2. 修改内容
3. 可能的潜在问题
执行流程:
sequenceDiagram
participant 用户
participant Claude
participant Shell
用户->>Claude: /pr-summary 123
Claude->>Shell: 执行 gh pr diff
Shell-->>Claude: 返回 PR diff 内容
Claude->>Shell: 执行 gh pr view --comments
Shell-->>Claude: 返回评论内容
Claude->>Shell: 执行 gh pr diff --name-only
Shell-->>Claude: 返回文件列表
Claude->>Claude: 替换占位符,生成完整提示
Claude->>Claude: 返回总结结果
7.2 在子代理中运行技能
使用 context: fork 在隔离环境中运行技能:
---
name: deep-research
description: 深入研究某个主题
context: fork
agent: Explore
---
研究目标:$ARGUMENTS
研究步骤:
1. 使用 Glob 和 Grep 定位相关文件
2. 阅读并分析代码实现
3. 总结发现,附上具体文件引用
子代理类型选项:
| 代理类型 | 用途 |
|---|---|
Explore |
代码库探索,只读工具 |
Plan |
制定实施计划 |
general-purpose |
通用任务(默认) |
| 自定义 | .claude/agents/ 中定义的代理 |
7.3 技能与子代理的协同
graph TB
subgraph 技能驱动子代理
A1[SKILL.md] -->|context: fork| B1[子代理]
B1 --> C1[执行任务]
end
subgraph 子代理预加载技能
A2[子代理定义] -->|skills 字段| B2[预加载技能]
B2 --> C2[作为参考材料]
end
八、支持文件管理
8.1 分离详细文档
保持 SKILL.md 简洁,将详细文档分离到单独文件:
my-skill/
├── SKILL.md # 必需 - 概述和导航
├── reference.md # 详细 API 文档(按需加载)
├── examples.md # 使用示例(按需加载)
└── scripts/
└── helper.py # 工具脚本(执行,不加载)
SKILL.md 中引用支持文件:
# 我的技能
这是技能的简要概述。
## 详细信息
- 完整 API 说明:查看 [reference.md](reference.md)
- 使用示例:查看 [examples.md)
## 警告
<Tip>保持 SKILL.md 在 500 行以下,将详细材料移到单独文件。</Tip>
九、实战场景
9.1 场景一:代码库可视化技能
创建交互式代码库结构可视化工具:
创建技能目录结构
mkdir -p ~/.claude/skills/codebase-visualizer/scripts
创建 SKILL.md
---
name: codebase-visualizer
description: 生成代码库的交互式树状可视化。用于探索新仓库、理解项目结构或识别大文件。
allowed-tools: Bash(python:*)
---
# 代码库可视化技能
生成一个交互式 HTML 树视图,展示项目文件结构,支持目录展开折叠。
## 使用方法
从项目根目录运行:
```bash
python ~/.claude/skills/codebase-visualizer/scripts/visualize.py .
这将在当前目录生成 codebase-map.html 并在浏览器中打开。
可视化特性
- 可折叠目录:点击文件夹展开或折叠
- 文件大小:每个文件旁边显示
- 颜色编码:不同文件类型使用不同颜色
- 目录汇总:显示每个文件夹的总大小
**创建可视化脚本(Python)**
```python
#!/usr/bin/env python3
"""生成代码库的交互式树状可视化"""
import json
import sys
import webbrowser
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:
"""生成 HTML 可视化文件"""
# 统计扩展名占比
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',
}
# 生成语言占比条形图
lang_bars = "".join(
f'<div class="bar-row"><span class="bar-label">{ext}</span>'
f'<div class="bar" style="width:{(size/total_size)*100}%;'
f'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 内容
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; }}
/* 其他样式... */
</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>📁 {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) {{ /* 大小格式化 */ }}
function render(node, parent) {{ /* 渲染逻辑 */ }}
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()}')
9.2 场景二:GitHub Issue 自动修复技能
---
name: fix-issue
description: 自动修复 GitHub Issue
disable-model-invocation: true
---
# 自动修复 Issue
修复编号:$ARGUMENTS
## 步骤
1. 读取 Issue 描述,理解需求
2. 分析相关代码文件
3. 实现修复方案
4. 编写测试用例
5. 创建提交
## 编码规范
- 遵循项目现有的代码风格
- 函数需要有完整的类型注解
- 提交信息格式:[fix] #Issue号 简述
9.3 场景三:API 设计规范技能
---
name: api-conventions
description: 当前项目的 API 设计规范
---
# API 设计规范
## 命名约定
- 使用 RESTful 命名规范
- 资源名称使用复数形式
- 使用连字符分隔多词路由
## 请求格式
- GET: 获取资源列表
- POST: 创建新资源
- PUT: 全量更新资源
- PATCH: 部分更新资源
- DELETE: 删除资源
## 响应格式
```json
{
"data": {},
"meta": {
"page": 1,
"per_page": 20,
"total": 100
}
}
错误响应
{
"error": {
"code": "VALIDATION_ERROR",
"message": "邮箱格式不正确",
"details": []
}
}
十、共享与分发
10.1 共享方式
| 方式 | 适用场景 |
|---|---|
| 项目技能 | 将 .claude/skills/ 提交到版本控制 |
| 插件 | 在插件中创建 skills/ 目录 |
| 托管 | 通过托管设置部署组织范围技能 |
10.2 从嵌套目录自动发现
Claude Code 支持从嵌套的 .claude/skills/ 目录自动发现技能:
packages/
├── frontend/
│ └── .claude/skills/frontend-conventions/
└── backend/
└── .claude/skills/backend-conventions/
当你在 packages/frontend/ 中编辑文件时,Claude 会自动加载该目录下的技能。
十一、故障排除
11.1 技能未触发
如果 Claude 在预期时不使用技能:
- 检查描述是否包含用户会自然说的关键词
- 验证技能是否出现在"有哪些技能可用?"中
- 尝试重新表述请求以更接近描述
- 使用
/skill-name直接调用
11.2 技能触发过于频繁
如果 Claude 在不想要的时候使用技能:
- 使描述更加具体
- 添加
disable-model-invocation: true限制为手动调用
11.3 Claude 看不到所有技能
技能描述加载到上下文中有字符限制(默认 15000 字符):
# 增加字符预算
export SLUFFIX_COMMAND_TOOL_CHAR_BUDGET=30000
十二、总结要点
-
Skills 本质:通过
SKILL.md文件扩展 Claude 能力的标准化方式 -
存储位置:企业级 > 项目级 > 个人级 > 插件级
-
核心配置:YAML 前置元数据 + Markdown 说明内容
-
调用控制:
disable-model-invocation: true- 仅用户可调用user-invocable: false- 仅 Claude 可调用
-
高级特性:
- 动态上下文注入(
`!command`) - 子代理执行(
context: fork) - 支持文件管理
- 动态上下文注入(
-
最佳实践:
- SKILL.md 保持在 500 行以下
- 详细文档分离到独立文件
- 使用描述性强的技能名称
LEAVE A COMMENT