24 KiB
tags, create time
| tags | create time | |||
|---|---|---|---|---|
|
2026-05-03 15:30 |
怎么创建一个自己的 CLAUDE CODE SKILL
概述
本文系统梳理 Claude Code(原 Claude Desktop / Anthropic SDK)的 Agent Skill 概念、定义语法、开发工作流和最佳实践,并通过多个实战场景案例帮助读者从零创建属于自己的可复用 AI 助手技能。
[!QUESTION] 💡 思考 你是否有过这样的场景——反复向 AI 助手解释同样的上下文、规则或约束,才能让它按你的预期完成工作?Skill 机制正是为了解决这个问题而生的:将"重复教育"变成一键加载的「能力插件」。
什么是 Agent Skill
核心概念
Agent Skill 是 Anthropic 提供的一种 结构化指令注入机制。它允许开发者/用户通过 YAML 格式的 skill definition,在不修改模型权重的前提下,向 Claude 注入特定的行为规则、知识框架和工具调用策略。
flowchart TD
U["用户提示词\nFix the auth bug"] --> S{"Claude 模型"}
subgraph Context ["Skill Context 注入层"]
direction TB
T["Trigger: trigger(auth)"]
R["Rules: System Prompt"]
C["Constraints: Tool Limits"]
end
S --> Context
Context --> S
S --> O["专精行为输出\nSecurity Review / Config Update / etc."]
classDef normal fill:#e3f2fd,stroke:#1565c0
classDef highlight fill:#fff3e0,stroke:#ef6c00
class U,O normal
class T,R,C highlight
Skill vs 普通 Prompt vs Project Instructions
| 维度 | 普通 Prompt | CLAUDE.md (Project Instructions) | Agent Skill |
|---|---|---|---|
| 粒度 | 单次对话级别 | 整个 workspace 级别 | 特定任务域级别 |
| 触发方式 | 必须明确提及 | 始终生效 | 自动检测触发 / 手动 @ 调用 |
| 作用范围 | 不持久化 | 全局覆盖 | 按需挂载,不影响其他任务 |
| 复杂度 | 简单 | 中等 | 高(含系统级指令注入) |
| 典型用例 | 快速提问 | 编码规范、语言偏好 | 安全审计、配置管理、代码审查 |
[!NOTE] 🔑 关键区别
- CLAUDE.md 是你的"项目宪法",适用于所有对话
- Skill 是你的"专业技能包",在特定场景下挂载到对话上,提供更深层的行为控制
- 两者可以共存 —— Skill 中的指令仅在 skill 激活时生效,优先级高于 CLAUDE.md
内置 Skill 一览
Claude Code SDK 自带一组开箱即用的 Skill,理解它们是学习自定义 Skill 的最佳起点:
| Skill | 功能 | 触发条件 |
|---|---|---|
update-config |
修改 settings.json、管理权限和环境变量 | 涉及配置文件、hook、权限变更 |
keybindings-help |
定制键盘快捷键 | 用户询问快捷键相关 |
simplify |
审查并重用冗余代码 | 代码审查场景 |
fewer-permission-prompts |
扫描代码,生成 .claude/settings.json 的 allowlist |
请求减少权限提示时 |
loop |
运行定时/循环任务(如 /loop 5m /foo) |
用户要求周期性任务 |
claude-api |
构建和优化 Claude API 应用(含缓存策略) | 导入 anthropic SDK、问 API/模型相关问题 |
init |
初始化新的 CLAUDE.md | 新项目初始化 |
review |
审查 Pull Request | PR 审查请求 |
security-review |
安全审查当前分支变更 | 安全审查请求 |
Skill 定义语法详解
YAML Frontmatter 结构
每个 Skill 通过 YAML frontmatter 定义其元数据和触发逻辑:
---
name: security-review
description: Complete a security review of the pending changes on the current branch
---
一个完整的核心字段表:
| 字段 | 必填 | 说明 |
|---|---|---|
name |
✅ | Skill 的唯一标识符(kebab-case) |
description |
✅ | 简短描述,用于匹配用户意图 |
trigger |
❌ | 何时自动激活(正则表达式) |
skip |
❌ | 什么情况下跳过该 Skill |
tools |
❌ | Skill 可用的工具白名单 |
systemPrompt |
❌ | 注入的系统级指令(核心内容区) |
Trigger 模式匹配
Trigger 决定了 Skill 在什么情况下被自动激活。支持以下模式:
trigger: "code imports .anthropic. or @anthropic-ai/sdk."
trigger: 'filename like \*-openai.py/.*-generic\.py'
trigger: "/loop"
常见的触发方式:
| 方式 | 示例 | 适用场景 |
|---|---|---|
| 关键词匹配 | trigger: "send email" |
功能明确的任务 |
| 文件路径匹配 | trigger: "\.secrets\."" |
特定文件或目录变更时 |
| 命令前缀 | trigger: "/deploy" |
Slash Command 触发 |
| 正则表达式 | trigger: "imports .anthropic." |
复杂模式匹配 |
| 手动 @ 引用 | @my-skill |
用户主动调用 |
[!TIP] ⚡ 最佳实践 Trigger 要尽可能精确。过于宽泛会导致错误的 Skill 被激活,干扰正常对话。遵循 "最小充分原则":用最少的匹配条件覆盖目标场景。
Skill 开发工作流
Step 1: 确定需求边界
[!QUESTION] 🧭 先问自己
这个 Skill 解决的是 一次性问题 还是 反复出现的需求?
- 一次性 → 直接写 prompt
- 反复出现 → 考虑做成 Skill
这个 Skill 的规则能否用 明确的 trigger + system prompt 表达?
- 能 → 适合做成 Skill
- 不能 → 可能需要更复杂的 Agent 类型
这个 Skill 会和其他 Skill 冲突吗?
- 检查已有 Skill 的 trigger,避免重叠
Step 2: 编写 Skill Definition
一个典型的 Skill 定义放在项目的 .claude/skills/<skill-name>/SKILL.md 文件中:
---
name: my-cool-skill
description: Help with X when Y happens
trigger: "X scenario appears"
---
# My Cool Skill
When this skill is active, follow these rules:
## Rules
1. Rule one...
2. Rule two...
## Workflow
Step-by-step instructions for Claude to follow.
## Examples
Concrete examples showing expected behavior.
Step 3: 测试与迭代
| 阶段 | 操作 | 目的 |
|---|---|---|
| 单元测试 | 针对单个触发场景验证 | 确认 trigger 正确匹配 |
| 集成测试 | 模拟真实用户输入 | 观察 Skill 是否正确激活 |
| 负样本测试 | 用不应触发的输入测试 | 防止误触发 |
| 冲突检查 | 同时存在多 Skill 时测试 | 确保无歧义匹配 |
最佳实践
✅ Do's
[!SUCCESS] 推荐做法
1. 职责单一原则(Single Responsibility)
每个 Skill 只负责一个明确的领域。不要试图在一个 Skill 里塞入所有邮件发送逻辑。拆分为独立的 Skill:
graph LR
Root["skills/"] --> A["send-email-report/\n发送邮件报告"]
Root --> B["generate-changelog/\n生成 Changelog"]
Root --> C["notify-team/\n团队通知"]
classDef folder fill:#e8f5e9,stroke:#2e7d32
classDef item fill:#fff3e0,stroke:#ef6c00
class Root folder
class A,B,C item
2. System Prompt 要明确且封闭
# good — 明确的正面指令 + 负面约束
## Rules
- ALWAYS use the smtp.send() helper from utils/email.py
- NEVER hardcode credentials; always use os.getenv()
- After sending, log the message ID to the database
- If SMTP fails, queue the email and retry in 5 minutes
# bad — 模糊、开放式的描述
## Notes
You can send emails however you think is best, just make sure it works.
3. Trigger 要精确且有排他性
# good — 具体的文件名 + 动作组合
trigger: "user asks to review .migrations/ or changes to schema files"
# bad — 太宽泛
trigger: "database"
4. 包含错误处理路径
优秀的 Skill 不是只在理想情况下工作,还要定义失败时的行为:
## Error Handling
- If the required config file is missing: create a template and ask the user to fill it in
- If the API returns 429: implement exponential backoff (initial: 1s, max: 30s)
- If the recipient list is empty: abort with an informative error message
❌ Don'ts
[!WARNING] ⚠️ 常见陷阱
1. 过度依赖 Skill 解决简单问题
如果只是一个简单的 git commit 封装,不需要写成 Skill。Skill 适合 复杂、多步骤、有严格规则 的场景。
2. Trigger 相互冲突
两个 Skill 的 trigger 匹配同一个输入时,行为不可预测:
flowchart LR
Input["用户说: fix auth bug"] --> SkillA["Skill A\ntrigger: fix the bug in auth"]
Input --> SkillB["Skill B\ntrigger: fix authentication bug"]
classDef input fill:#e3f2fd,stroke:#1565c0
classDef conflict fill:#f9d0c4,stroke:#d84315
class Input input
class SkillA,SkillB conflict
3. 在 Skill 中硬编码敏感信息
绝对不要在 system prompt 中写入密码、API Key、URL 等。使用环境变量或配置文件引用:
❌ BAD:
Always use password = "mySuperSecret123!" at host smtp.example.com
✅ GOOD:
Use credentials from ENV vars EMAIL_USER and EMAIL_PASS
4. 忽略性能影响
过长的 system prompt 会增加 token 消耗和响应延迟。保持精简,只注入必要的上下文。
实战场景案例集
下面通过四个不同难度级别的实战场景,展示如何从需求到完整的 Skill 定义。
场景一:中间件集成的最佳编码实践(入门级)
需求: 当检测到项目中引入 Redis/MQ 等中间件时,自动注入最佳实践指导。
[!QUESTION] 🤔 为什么需要这个 Skill? 每次引入新中间件,你都需要告诉 AI:"记得连接池、超时设置、重试策略..." —— 这正是 Skill 的用武之地。
Skill 定义
---
name: redis-best-practices
description: Guide proper Redis integration patterns when Redis-related code is detected
trigger: "redis OR redigo OR go-redis OR ioredis OR Lettuce"
---
# Redis Integration Best Practices
## Overview
This skill activates when Redis-related imports or configuration appear in the codebase.
It ensures the assistant guides the developer through production-ready patterns.
## Core Principles
> [!INFO] 三大基石
> 1. **资源管理**: 连接必须复用,禁止每次请求新建连接
> 2. **容错设计**: 网络异常必须有降级方案,Redis 不可用时服务不能完全崩溃
> 3. **数据安全**: 敏感数据不能明文存储,大 value 要考虑内存水位
## Checklist
When reviewing or writing Redis code, verify:
- [ ] Connection pool configured with MinIdle/MaxActive ratios
- [ ] Read/write timeouts explicitly set (> 0)
- [ ] Retry logic implemented with bounded attempts (max 3)
- [ ] Hot key detection strategy in place
- [ ] Cache penetration/breakdown/avalanche handled
- [ ] Distributed lock has auto-expiry + reentrant design
- [ ] Pipeline used for batch operations (> 3 commands)
- [ ] Keys have TTL set (except explicit no-expiry cases)
## Common Patterns
### Pattern 1: Safe Cache-Aside
```go
func GetProductCacheable(ctx context.Context, id string) (*Product, error) {
// 1. Try cache first
data, err := rdb.Get(ctx, productKey(id)).Result()
if err == nil {
// deserialized...
return parse(data)
}
// 2. Cache miss -> query DB with double-check pattern
mu.Lock()
defer mu.Unlock()
// Double-check after acquiring lock
data, err = rdb.Get(ctx, productKey(id)).Result()
if err == nil {
return parse(data)
}
result, err := db.QueryProduct(ctx, id)
if err != nil {
// Write cache with short TTL to prevent penetration
rdb.Set(ctx, productKey(id), "", 30*time.Second)
return nil, fmt.Errorf("product not found: %w", err)
}
rdb.Set(ctx, productKey(id), marshal(result), 15*time.Minute)
return result, nil
}
[!SUMMARY] 这段代码的关键点
- 使用了 Cache-Aside 模式(缓存旁路),而非 Write-Through
- 实现了 Double-Check 加锁机制,防止缓存击穿下的并发穿透
- 穿透保护用了 30 秒短 TTL(空值缓存),常规数据用 15 分钟
- 注意这里用
marshal/unmarshal抽象了序列化,实际应统一使用 msgpack 或 protobuf
Pattern 2: Distributed Lock (Redisson-style)
func WithDistributedLock(ctx context.Context, key string, ttl time.Duration, fn func() error) error {
lockKey := "lock:" + key
locked, err := rdb.SetNX(ctx, lockKey, uuid.New().String(), ttl).Result()
if err != nil {
return fmt.Errorf("acquire lock failed: %w", err)
}
if !locked {
return ErrLockAcquireFailed
}
// Auto-release on exit
defer rdb.Del(ctx, lockKey)
return fn()
}
Anti-patterns to Avoid
[!FAILURE] ❌ 反模式
- 全量导出:
KEYS *在生产环境禁用,改用SCAN - 阻塞操作:
BLPOP无超时时间可能导致 goroutine 泄漏 - 主从切换丢失: 同步写后立即读可能命中 slave 导致不一致,需用
READONLY或WAIT - Large Key: Value > 10KB 的 hash/string 需特别注意内存和网络开销
graph LR
A["客户端请求"] --> B{"缓存命中?"}
B -- "Yes" --> C["返回缓存值"]
B -- "No" --> D["获取分布式锁"]
D --> E{"获取成功?"}
E -- "No" --> F["等待后重试"]
F --> D
E -- "Yes" --> G["查询数据库"]
G --> H["写入缓存 + 设置 TTL"]
H --> C2["返回数据"]
flowchart TD
A["客户端"] --> B["Sentinel / Cluster"]
B --> C[Master Node]
C -- "异步复制" --> D[Slave 1]
C -- "异步复制" --> E[Slave N]
subgraph Problem ["主从切换期间的风险"]
W1["写入 Master"] -.->|"可能未复制到 Slave"| W2["Master 故障"]
W2 --> W3["Slave 晋升为新 Master"]
W3 --> W4["新写入丢失"]
end
classDef warn fill:#f9d0c4,stroke:#d84315
class W1,W2,W3,W4 warn
关联笔记
---
### 场景二:自动化邮件报告(进阶级)
**需求**: 创建 Skill 让 AI 能够自动生成周报、月报并通过邮件发送。
> [!SUCCESS] 这个 Skill 的优势在于 —— 它不仅是一个模板,还包含了完整的错误处理和幂等保证。
#### Skill 定义
```markdown
---
name: email-report
description: Generate and send automated reports (weekly/monthly) via email
trigger: "generate report AND email OR send weekly OR monthly report OR 生成报告"
---
# Automated Email Report Skill
## Overview
Guides the creation of structured reports and their delivery via email,
handling template rendering, attachment generation, and notification delivery.
## Pre-flight Checks
Before sending any report, verify these environment variables are set:
| Variable | Required | Description |
|----------|----------|-------------|
| `SMTP_HOST` | Yes | SMTP server address |
| `SMTP_PORT` | Yes | SMTP port (587 for TLS) |
| `EMAIL_USER` | Yes | Sender address |
| `EMAIL_PASS` | Yes | App-specific password or API token |
| `REPORT_RECIPIENTS` | No | Comma-separated recipient list |
> [!IMPORTANT] 安全提醒
> All credentials must come from ENV or secrets manager. NEVER hardcode.
## Workflow
```mermaid
sequenceDiagram
participant U as User
participant S as Email Report Skill
participant T as Template Engine
participant A as Attachment Generator
participant M as SMTP Client
participant R as Recipients
U->>S: "Generate weekly report"
S->>S: Parse scope & date range
S->>T: Render HTML template
T-->>S: Generated HTML
S->>A: Generate PDF attachment
A-->>S: PDF bytes
S->>M: Send email with attachments
M-->>R: Deliver to all recipients
S->>S: Log delivery status
S-->>U: Report sent successfully
Step 1: Report Template Structure
All reports follow this standard structure:
<h1>{{report_type}} Report — {{period}}</h1>
<section>
<h2>Summary</h2>
<p>{{summary}}</p>
</section>
<section>
<h2>Key Metrics</h2>
<table>
<!-- rendered metrics table -->
</table>
</section>
<section>
<h2>Action Items</h2>
<ul>
<!-- rendered action items -->
</ul>
</section>
<footer>Sent by automated reporting system</footer>
Step 2: Sending Implementation
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
def send_report(subject: str, html_body: str,
attachments: list[str] | None = None,
recipients: list[str] | None = None):
"""Send report email with optional attachments."""
msg = MIMEMultipart("mixed")
msg["From"] = os.getenv("EMAIL_USER")
msg["To"] = ", ".join(recipients or [])
msg["Subject"] = subject
# HTML body
msg.attach(MIMEText(html_body, "html"))
# Attachments (PDFs, charts, etc.)
for filepath in attachments or []:
with open(filepath, "rb") as f:
part = MIMEBase("application", "octet-stream")
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", "attachment", filename=os.path.basename(filepath))
msg.attach(part)
# Send with TLS and timeout protection
with smtplib.SMTP(os.getenv("SMTP_HOST"), int(os.getenv("SMTP_PORT"))) as server:
server.starttls()
server.login(msg["From"], os.getenv("EMAIL_PASS"))
server.send_message(msg, to_addrs=recipients)
Step 3: Retry Strategy
import tenacity
@tenacity.retry(
stop=tenacity.stop_after_attempt(3),
wait=tenacity.wait_exponential(multiplier=1, min=2, max=30),
retry=tenacity.retry_if_exception_type(smtplib.SMTPException),
before_sleep=lambda retry_state: print(f"Retrying email delivery... ({retry_state.attempt_number}/3)")
)
def send_with_retry(email_fn, *args, **kwargs):
"""Email sending with exponential backoff retry."""
return email_fn(*args, **kwargs)
Error Handling Matrix
| Scenario | Action | Logging Level |
|---|---|---|
| Missing env vars | Abort early, output help text | ERROR |
| SMTP connection refused | Queue job for retry | WARN |
| Authentication failed | Notify admin via web hook | CRITICAL |
| Attachment too large (> 25MB) | Split into multiple emails | WARN |
| Empty recipient list | Skip sending, log info | INFO |
Cron Integration (Optional)
If scheduling is needed, recommend platform-native schedulers over custom cron scripts:
| Platform | Recommendation | Example |
|---|---|---|
| Linux | systemd timer or crontab | 0 9 * * 1 /usr/bin/python report.py |
| Docker | entrypoint wrapper script | Health-checked container |
| Cloud | EventBridge / Cloud Scheduler | Configured via IaC |
关联笔记
---
### 场景三:PR Review Checklist(实用级)
**需求**: 每当用户请求审查某个 PR 或 diff 时,自动以预设的检查清单来审视代码变更。
#### 快速定义
```markdown
---
name: pr-review-checklist
description: Run a structured code review checklist on PR diffs
trigger: "review PR OR review diff OR review pull request"
---
# PR Review Checklist
## Quick Reference
Review each change against these categories:
### 1. Correctness
- [ ] Logic matches requirements?
- [ ] Edge cases handled (empty input, null, zero)?
- [ ] Error propagation correct (not swallowed)?
### 2. Performance
- [ ] No O(n²) loops where O(n) suffices?
- [ ] Database queries not N+1?
- [ ] Large data streaming instead of loading entirely into memory?
### 3. Security
- [ ] Input sanitization present?
- [ ] AuthN/AuthZ verified before sensitive operations?
- [ ] Secrets never logged or committed?
### 4. Maintainability
- [ ] Function size reasonable (< 50 lines)?
- [ ] Meaningful variable/function names?
- [ ] Comments explain WHY not WHAT?
### 5. Testing
- [ ] Unit tests cover happy path + edge cases?
- [ ] Test isolation maintained (no shared mutable state)?
- [ ] Integration tests if external dependency involved?
场景四:数据库迁移脚本生成器(高级)
需求: 基于当前的数据库 schema 和用户提出的变更需求,自动生成带版本控制和回滚能力的迁移脚本。
[!FAILURE] ⚠️ 这个场景比较危险 —— 涉及数据库变更的操作,必须在 Skill 中加入强制确认步骤。
---
name: db-migration-generator
description: Generate safe database migration scripts with rollback support
trigger: "migration OR alter table OR add column AND database"
---
# Database Migration Generator
> [!CRITICAL] 安全协议
> This skill operates on real databases. Every generated migration MUST include:
> 1. A rollback script
> 2. Data safety analysis
> 3. Explicit confirmation requirement before execution
## Safe Migration Rules
### Zero-Downtime Pattern for Schema Changes
```mermaid
flowchart LR
A["Step 1: Add nullable column"] --> B["Step 2: Backfill existing data"]
B --> C["Step 3: Deploy app with dual-write"]
C --> D["Step 4: Validate new data correctness"]
D --> E["Step 5: Switch reads to new column"]
E --> F["Step 6: Remove old column (next release)"]
classDef step fill:#e8f5e9,stroke:#2e7d32
class A,B,C,D,E,F step
Never Do This on Large Tables
[!FAILURE] 高危操作 —— 以下操作在 > 100K 行的表上执行会导致锁表:
| 操作 | 风险等级 | 推荐替代方案 |
|---|---|---|
ALTER TABLE ADD NOT NULL |
🔴 致命 | 分步添加 + backfill |
ALTER TABLE DROP COLUMN |
🔴 致命 | 标记废弃 + 下周期清理 |
ALTER TABLE MODIFY TYPE |
🟠 危险 | 新建列 + 数据迁移 + 切换 |
ADD UNIQUE INDEX CONCURRENTLY |
🟢 安全 | PostgreSQL 原生支持 |
Generated Script Template
-- Migration: 0042_add_user_email_verified
-- Date: YYYY-MM-DD
-- Risk: LOW (additive change only)
BEGIN;
-- Step 1: Add new nullable column
ALTER TABLE users
ADD COLUMN email_verified_at TIMESTAMP WITH TIME ZONE DEFAULT NULL;
-- Step 2: Create index (non-blocking where possible)
CREATE INDEX CONCURRENTLY idx_users_email_verified
ON users(email_verified_at) WHERE email_verified_at IS NOT NULL;
COMMIT;
-- ============================
-- ROLLBACK SCRIPT
-- ============================
-- BEGIN;
-- DROP INDEX CONCURRENTLY IF EXISTS idx_users_email_verified;
-- ALTER TABLE users DROP COLUMN IF EXISTS email_verified_at;
-- COMMIT;
Confirmation Steps
Before generating any migration, ask the user:
- What is the target database and version? (PostgreSQL 15, MySQL 8.x, etc.)
- Is the table large (> 1M rows)? If yes, enforce zero-downtime pattern.
- Can rolling deploy be supported? If no, plan full downtime window.
- Has the migration been reviewed by a second person?
关联笔记
## 总结与进阶方向
### Skill 成熟度模型
```mermaid
graph BT
P1["Level 1: Prompt 库"]
P2["Level 2: CLAUDE.md snippets"]
P3["Level 3: Custom Skill"]
P4["Level 4: Custom Agent Type"]
P5["Level 5: MCP Server Integration"]
P1 --> P2 --> P3 --> P4 --> P5
classDef low fill:#fff3e0,stroke:#ef6c00
classDef mid fill:#e3f2fd,stroke:#1565c0
classDef high fill:#e8f5e9,stroke:#2e7d32
class P1,P2 low
class P3,P4 mid
class P5 high
下一步学习路线
| 阶段 | 重点 | 推荐资源 |
|---|---|---|
| Phase 1 | 理解现有内置 Skill 的触发逻辑 | 阅读本 Skill 的定义源码 |
| Phase 2 | 创建第一个极简 Skill(3 条 rule) | 参考 PR Review Checklist 案例 |
| Phase 3 | 加入 workflow 图表 + 错误处理 | 参考 Email Report 案例 |
| Phase 4 | 探索自定义 Agent Type(超越 Skill 的能力边界) | Study Explore / Plan agent 的实现 |
| Phase 5 | 构建 MCP Server 实现跨工具链联动 | Anthropic MCP Protocol 文档 |
一句话总结
好的 Skill 不是"教 AI 怎么做",而是"给 AI 一套它做这件事时一定会遵守的思维框架"。 就像给高级工程师一份技术规范——细节他可以自己决定,但红线和标准你必须写好。