Tools and plugins
用技能扩展 Claude
用技能扩展 Claude 这一页讲的,就是 用技能扩展 Claude 这件事在 Claude Code 里到底怎么用。
页面信息
这页不是官方原文,而是顺着官方文档结构做的中文解释版。命令、参数、配置名这些硬东西尽量保留,解释部分则尽量讲成人能照着做的话。
如果你碰到特别敏感的配置、权限或企业环境差异,最好顺手点上面的“查看原始文档”再核一遍。
这一页先讲明白
技能就是预先写好的绝活说明书,Claude 遇到对应场景就能直接拿来用。
它很适合把团队里的固定套路固化下来。
你可以把技能当成“遇到这种活就照这个打法来”的小抄。比如审查 PR、写单测、写接口文档,都能做成技能。
这样做的好处是口径统一,不靠每次临场发挥。
技能描述要短、准、能执行,最好明确输入、输出和边界。
别把技能写成长篇空话。能用几条清楚规则说完,就不要写成一大篇作文。
Documentation Index
这里不是让你背"Documentation Index"这个词,而是让你看它真干活时怎么使。
看这段时要特别盯工具和权限边界,别为了省事一把全开。
Bundled skills
这一段主要是在把"Bundled skills"讲实,不是只摆个标题给你看。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Getting started
这一块主要是在说"Getting started"真到手上该怎么用,哪里最容易踩坑。
Create your first skill
这里主要是在交代"Create your first skill"这一块会碰到哪些事。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Create your first skill 1
真到动手的时候了,下面这条直接敲一遍,看它回什么。
mkdir -p ~/.claude/skills/summarize-changes Create your first skill 2
光知道意思还不够,这里得把规矩落进配置里,下面这块照着填。
---
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. Create your first skill 3
这里不用敲命令,直接把下面这句话发给 Claude 就行,让它按"Create your first skill"这一段的意思去办。
What did I change? Create your first skill 4
这里不用敲命令,直接把下面这句话发给 Claude 就行,让它按"Create your first skill"这一段的意思去办。
/summarize-changes Where skills live
这一块主要是在说"Where skills live"真到手上该怎么用,哪里最容易踩坑。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Where skills live
这一段主要是认目录和文件摆放位置。先把地方放对,后面才不容易串。
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 Configure skills
看到这类标题,就当是在调一个具体开关。
如果你打算把外接能力往里挂,这里提到的 hooks、MCP、skills、memory 都要分清各自负责哪一摊。
Types of skill content
这一段主要是在把"Types of skill content"讲实,不是只摆个标题给你看。
如果你打算把外接能力往里挂,这里提到的 hooks、MCP、skills、memory 都要分清各自负责哪一摊。
Types of skill content 1
这会儿轮到改配置了,字段名和关键字别自己乱换。
---
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 Types of skill content 2
这会儿轮到改配置了,字段名和关键字别自己乱换。
---
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 Frontmatter reference
看到这里,就别靠猜了,字段、格式和写法都得按说明来。
如果你打算把外接能力往里挂,这里提到的 hooks、MCP、skills、memory 都要分清各自负责哪一摊。
Frontmatter reference 1
想把这条规矩固定住,就把下面这块老老实实写进去。
---
name: my-skill
description: What this skill does
disable-model-invocation: true
allowed-tools: Read Grep
---
Your skill instructions here... Frontmatter reference 2
想把这条规矩固定住,就把下面这块老老实实写进去。
---
name: session-logger
description: Log activity for this session
---
Log the following to logs/${CLAUDE_SESSION_ID}.log:
$ARGUMENTS Add supporting files
看到这里,就把"Add supporting files"当成一件真要上手的活来看。
如果你打算把外接能力往里挂,这里提到的 hooks、MCP、skills、memory 都要分清各自负责哪一摊。
Add supporting files 1
这一段主要是认目录和文件摆放位置。先把地方放对,后面才不容易串。
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) Add supporting files 2
先看下面这块原始片段,等会儿再回头看解释会顺得多。
## Additional resources
- For complete API details, see [reference.md](reference.md)
- For usage examples, see [examples.md](examples.md) Control who invokes a skill
这段主要是在说平时怎么管,不是光教你怎么开。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Control who invokes a 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 Skill content lifecycle
这一段更像在讲判断条件,什么时候该上,什么时候先别急。把触发条件看清,比背标题更重要。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Pre-approve tools for a skill
这一段不只是挂个标题,它是在说明"Pre-approve tools for a skill"这一块到底负责什么。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Pre-approve tools for a skill
想把这条规矩固定住,就把下面这块老老实实写进去。
---
name: commit
description: Stage and commit the current changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
--- Pass arguments to skills
这里不是让你背"Pass arguments to skills"这个词,而是让你看它真干活时怎么使。
如果你打算把外接能力往里挂,这里提到的 hooks、MCP、skills、memory 都要分清各自负责哪一摊。
Pass arguments to skills 1
光知道意思还不够,这里得把规矩落进配置里,下面这块照着填。
---
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 Pass arguments to skills 2
光知道意思还不够,这里得把规矩落进配置里,下面这块照着填。
---
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. Pass arguments to skills 3
光知道意思还不够,这里得把规矩落进配置里,下面这块照着填。
---
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. Advanced patterns
看到这里,就把"Advanced patterns"当成一件真要上手的活来看。
Inject dynamic context
别把这段只当成标题看,它其实是在给"Inject dynamic context"划边界。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Inject dynamic context 1
这一段说完,最后还得写到配置里才算真的生效。
---
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... Inject dynamic context 2
这一段不是只让你理解意思,下面这条命令就是现在要跑的。
## Environment
```!
node --version
npm --version
git status --short
``` Run skills in a subagent
这一段主要是在把"Run skills in a subagent"讲实,不是只摆个标题给你看。
看这段时要特别盯工具和权限边界,别为了省事一把全开。
Run skills in a subagent
这会儿轮到改配置了,字段名和关键字别自己乱换。
---
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 Restrict Claude’s skill access
看到这里,就把"Restrict Claude’s skill access"当成一件真要上手的活来看。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Restrict Claude’s skill access 1
先看下面这块原始片段,等会儿再回头看解释会顺得多。
# Add to deny rules:
Skill Restrict Claude’s skill access 2
先看下面这块原始片段,等会儿再回头看解释会顺得多。
# Allow only specific skills
Skill(commit)
Skill(review-pr *)
# Deny specific skills
Skill(deploy *) Override skill visibility from settings
这段看着像个标题,其实是在说"Override skill visibility from settings"管到哪儿。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Override skill visibility from settings
这会儿轮到改配置了,字段名和关键字别自己乱换。
{
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
}
} Share skills
这一块主要是在说"Share skills"真到手上该怎么用,哪里最容易踩坑。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Generate visual output
这一段主要是在把"Generate visual output"讲实,不是只摆个标题给你看。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Generate visual output 1
先别急着往下翻,下面这条命令跑完,心里才有底。
mkdir -p ~/.claude/skills/codebase-visualizer/scripts Generate visual output 2
这会儿轮到改配置了,字段名和关键字别自己乱换。
---
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 Generate visual output 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()}') Troubleshooting
这里讲的是怎么找毛病,先查明白哪一步出错,再决定怎么修。
Skill not triggering
这一段更像在讲判断条件,什么时候该上,什么时候先别急。把触发条件看清,比背标题更重要。
这里还牵扯作用域,意思就是这条规则到底管当前项目、你个人,还是只管这一趟会话。
Skill triggers too often
这一段更像在讲判断条件,什么时候该上,什么时候先别急。把触发条件看清,比背标题更重要。
如果你打算把外接能力往里挂,这里提到的 hooks、MCP、skills、memory 都要分清各自负责哪一摊。
Skill descriptions are cut short
这里不是让你背"Skill descriptions are cut short"这个词,而是让你看它真干活时怎么使。
看这段时要特别盯工具和权限边界,别为了省事一把全开。
Related resources
这一段主要是在把"Related resources"讲实,不是只摆个标题给你看。
看这段时要特别盯工具和权限边界,别为了省事一把全开。
照着做一遍
第一次做 skill,最稳就是做一个“解释代码”的小抄。
因为它不碰危险权限,也最容易一眼看出有没有生效。
第 1 步:先建 skill 目录
先给这个小抄找个固定住处。
mkdir -p ~/.claude/skills/explain-code 第 2 步:写 SKILL.md
前面写 frontmatter,后面写这套 skill 的具体打法。
---
name: explain-code
description: Explains code with visual diagrams and analogies.
---
When explaining code, always include an analogy and a simple diagram. 第 3 步:试自动触发
先用一句自然话问它,看它会不会自己把这套 skill 调出来。
How does this code work? 第 4 步:试手动点名
如果你想确认就是这套 skill 在起作用,直接点名叫它。
/explain-code src/auth/login.ts 一眼看懂这一页
这页的作用,就是把原本偏专业的话题,拆成能直接照着走的明白话。
用技能扩展 Claude
|
v
用技能扩展 Claude 这一页讲的,就是 用技能扩展 Claude 这件事在 Claude Code 里到底怎么用。
|
v
照着步骤去做 文末提醒
这站会按官方 docs 的导航和内容变化继续重生成,原站加页、删页、改页时,这里会跟着更新。
人话解释会尽量顺着原页往下讲,但命令、参数名、配置名这些硬东西还是保留原样,免得你抄过去跑不起来。