跳转至

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 实现:

my-skill/
├── SKILL.md
└── scripts/
    └── analyze.py

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 需要参考图表、架构图:

system-design/
├── SKILL.md
└── assets/
    ├── microservices.png
    └── data-flow.png
## 架构参考

设计微服务系统时参考 [assets/microservices.png](assets/microservices.png) 中的标准架构。

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. 不要写入危险命令

❌ 危险:

rm -rf $TARGET

如果 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 最稳定:

print(json.dumps(result, ensure_ascii=False))

2. 模板用占位符

模板文件用 {{Name}} 这样的占位符,Claude 替换更可靠:

# 在模板中
class {{ClassName}}:
    """{{Description}}"""

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 最容易被模型解析

评论