Skill中使用脚本和资源
简单 Skill 只用 SKILL.md 就够了,但当任务需要确定性的执行或复杂参考资料时,就要用到脚本、模板、参考文档等辅助资源。
1. 为什么需要脚本
SKILL.md 只是给 Claude 看的"指示文档",Claude 按指示去生成代码或答案。但有些任务:
- 需要严格确定性:每次输出格式完全一致
- 涉及外部数据:从数据库、API、文件系统读
- 数据量大:让模型 hardcode 不现实
- 重复性强:不该让模型每次重新推导
这时候,让 Skill 调用真实脚本比让模型生成更可靠。
2. 在 SKILL.md 中调用脚本
只需要在 SKILL.md 中明确告诉 Claude 该执行什么命令:
---
name: project-stats
description: 统计项目的代码行数、文件数、贡献者等信息时使用
---
# Project Stats
## 步骤
1. 进入项目根目录
2. 执行以下命令获取统计数据:
```bash
bash <skill-dir>/scripts/stats.sh
```
3. 解析输出(JSON 格式),整理成 Markdown 报告给用户
<skill-dir> 是 Claude Code 自动展开的占位符,指向当前 Skill 的根目录。
scripts/stats.sh 内容:
#!/bin/bash
TOTAL_FILES=$(find . -type f -name "*.py" | wc -l)
TOTAL_LINES=$(find . -type f -name "*.py" -exec cat {} + | wc -l)
CONTRIBUTORS=$(git log --format='%aN' | sort -u | wc -l)
cat <<EOF
{
"total_files": $TOTAL_FILES,
"total_lines": $TOTAL_LINES,
"contributors": $CONTRIBUTORS
}
EOF
Claude 会执行这个脚本,得到精确的数字,再组织成报告。
3. 让 Skill 自动执行 Python 脚本
更复杂的逻辑用 Python 实现:
SKILL.md:
---
name: log-analyzer
description: 分析应用日志、统计错误、定位异常时使用
---
# Log Analyzer
## 步骤
1. 询问用户要分析的日志文件路径
2. 执行:
```bash
python <skill-dir>/scripts/analyze.py <log_file>
```
3. 根据脚本输出生成易读的报告
scripts/analyze.py:
import sys
import re
import json
from collections import Counter
def analyze(log_path):
error_pattern = re.compile(r"ERROR: (.+)")
errors = Counter()
with open(log_path, "r") as f:
for line in f:
match = error_pattern.search(line)
if match:
errors[match.group(1)] += 1
return {
"total_errors": sum(errors.values()),
"unique_errors": len(errors),
"top_5": errors.most_common(5),
}
if __name__ == "__main__":
print(json.dumps(analyze(sys.argv[1]), indent=2, ensure_ascii=False))
模型不擅长精确统计大文件,但 Python 几行代码就搞定。这种"把确定性任务交给代码"的模式是 Skill 的强大之处。
4. 模板文件
需要生成结构化文件(代码、配置、文档)时,用模板比让模型从头写更稳定。
react-component/
├── SKILL.md
└── templates/
├── component.tsx.tpl
├── test.tsx.tpl
└── stories.tsx.tpl
templates/component.tsx.tpl:
import React from 'react';
import styles from './{{Name}}.module.css';
interface {{Name}}Props {
// TODO: 定义 props
}
export const {{Name}}: React.FC<{{Name}}Props> = (props) => {
return (
<div className={styles.container}>
{/* TODO: 实现 */}
</div>
);
};
SKILL.md:
---
name: react-component
description: 创建新的 React 组件时使用,按公司模板生成 TSX、测试、Stories 三件套
---
# React Component Generator
## 步骤
1. 询问组件名(PascalCase)和用途
2. 创建目录 `src/components/<Name>/`
3. 用 [templates/component.tsx.tpl](templates/component.tsx.tpl) 创建 `<Name>.tsx`,将 `{{Name}}` 替换为实际名称
4. 同样创建 `<Name>.test.tsx` 和 `<Name>.stories.tsx`
5. 创建 `<Name>.module.css`(空文件,让用户后续填充)
## 注意
- 组件名必须 PascalCase(如 UserProfile,不是 userProfile)
- 不要在创建后立即填充 props 和实现,留 TODO 给用户
5. 参考文档(reference/)
知识量大、不需要每次加载的内容放 reference/。SKILL.md 在需要时引用:
api-design/
├── SKILL.md
├── reference/
│ ├── error-codes.md # 公司错误码规范
│ ├── auth.md # 认证方式
│ └── pagination.md # 分页约定
└── examples/
└── user-api.md # 完整示例
SKILL.md:
---
name: api-design
description: 设计 RESTful API、定义路由、写规范文档时使用
---
# API Design
## 通用规则
- URL 用名词复数,路径全小写
- HTTP 方法对应 CRUD:GET / POST / PATCH / DELETE
- 时间字段统一用 ISO 8601 (UTC)
## 详细规范(按需查阅)
- 错误码:[reference/error-codes.md](reference/error-codes.md)
- 认证:[reference/auth.md](reference/auth.md)
- 分页:[reference/pagination.md](reference/pagination.md)
## 示例
完整 API 设计示例参考 [examples/user-api.md](examples/user-api.md)
reference/error-codes.md 写完整的错误码表,几百条都没问题——Claude 只在设计错误处理时才读。
6. 静态资源(图片等)
某些 Skill 需要参考图表、架构图:
Claude Code 等支持读取图片的客户端会真正"看"这些图。
7. 综合示例:完整的 Skill 工作流
下面用一个SQL 慢查询分析 Skill 演示综合用法:
sql-slowquery/
├── SKILL.md
├── scripts/
│ ├── explain.sh # 执行 EXPLAIN 并格式化
│ └── analyze.py # 分析 EXPLAIN 输出,给优化建议
├── reference/
│ └── index-types.md # 各种索引类型的适用场景
└── examples/
└── before-after.md # 优化前后对比示例
SKILL.md:
---
name: sql-slowquery
description: 分析 MySQL 慢查询、给出索引和重写建议时使用,需要数据库连接信息
---
# SQL 慢查询分析
## 步骤
1. 让用户提供慢 SQL 和数据库连接信息(host、user、db)
2. 执行 EXPLAIN:
```bash
bash <skill-dir>/scripts/explain.sh "<host>" "<user>" "<db>" "<sql>"
```
3. 用分析脚本读取 EXPLAIN 结果:
```bash
python <skill-dir>/scripts/analyze.py <explain_output>
```
4. 根据分析结果生成报告,参考 [examples/before-after.md](examples/before-after.md) 的格式
## 索引建议
如果建议加索引,参考 [reference/index-types.md](reference/index-types.md) 选择正确的索引类型(B-Tree、Hash、Full-Text)。
## 输出格式
```markdown
## 性能问题
(关键问题列表)
## EXPLAIN 解读
(关键字段解读)
## 优化建议
(具体的 SQL 重写或索引方案)
## 优化后的 SQL
(重写后的查询)
```
这个 Skill 综合用了:
- 脚本做确定性工作(EXPLAIN、解析)
- 参考文档提供深度知识(索引类型)
- 示例指导输出格式
- SKILL.md 编排整个流程
8. 安全考虑
Skill 中的脚本会被 Claude 直接执行,要注意:
1. 不要写入危险命令
❌ 危险:
如果 Claude 调用时把 $TARGET 解释错误,可能删错文件。
✅ 安全:
# 加保护
if [ -z "$TARGET" ] || [ "$TARGET" = "/" ] || [ "$TARGET" = "$HOME" ]; then
echo "ERROR: invalid target"
exit 1
fi
rm -rf "$TARGET"
2. 输入参数校验
脚本接收来自 Claude 的参数,要做基本校验:
import sys
def validate_path(p):
if ".." in p or p.startswith("/"):
raise ValueError("不允许绝对路径或路径穿越")
return p
3. 限制 Skill 的 allowed-tools
可以在 frontmatter 中限制 Skill 能调用的工具:
---
name: read-only-skill
description: 只读分析,不修改文件
allowed-tools:
- Read
- Bash(grep:*)
- Bash(find:*)
---
这样即使 SKILL.md 被恶意修改,也不能执行写操作。
9. 调试脚本
直接执行验证
写完脚本先在终端跑一下,确认正常:
bash ~/.claude/skills/my-skill/scripts/run.sh test_arg
python ~/.claude/skills/my-skill/scripts/analyze.py sample.log
加日志输出
脚本里多 print 中间结果,方便 Claude 在执行时知道发生了什么:
import json, sys
print(f"读取文件: {sys.argv[1]}", file=sys.stderr)
data = open(sys.argv[1]).read()
print(f"文件大小: {len(data)} 字符", file=sys.stderr)
result = analyze(data)
print(json.dumps(result, indent=2)) # stdout 给 Claude
stderr 是辅助信息(Claude 也会看到),stdout 是结构化结果。
10. 经验和最佳实践
1. 脚本输出 JSON
文本输出模型容易解析错,JSON 最稳定:
2. 模板用占位符
模板文件用 {{Name}} 这样的占位符,Claude 替换更可靠:
3. 脚本路径用 <skill-dir>
不要 hardcode 绝对路径,用 <skill-dir> 占位符让 Skill 可移植。
4. 一个脚本只做一件事
避免一个脚本接受十几个参数搞所有事情。拆分成多个小脚本,让 Claude 串起来用。
5. Reference 写详细
Reference 文档可以写得很详细(几千字),因为只在需要时加载。把所有边界情况、罕见场景都列上。
6. Examples 给完整产出
示例不要只给片段,要给从输入到输出的完整流程,让模型有清晰参照。
总结
- 简单 Skill 只用 SKILL.md,复杂 Skill 配合脚本、模板、参考文档
- 脚本做确定性工作(统计、解析、查询),交给代码比交给模型更可靠
- 模板用
{{Name}}这类占位符生成结构化文件 - Reference 放深度知识,按需加载不浪费上下文
- 用
<skill-dir>占位符让 Skill 可移植 - 安全:脚本要做参数校验,敏感 Skill 用
allowed-tools限制权限 - 脚本输出 JSON 最容易被模型解析