现在位置: 首页 > Skills 教程 > 正文

Skills 设计模式与最佳实践

经过大量实践总结出来的 Skill 设计模式,能帮助你在面对新需求时快速做出合理决策。

本篇汇总了最常用的 7 种设计模式及其适用场景。


模式一:单一职责 Skill

每个 Skill 只做一件事,做好一件事。

功能越聚焦,description 越精准,触发准确率越高,维护也越容易。

做法示例
正确:职责单一pdf-to-text(只负责提取文字)
错误:职责混杂pdf-tools(读取、转换、合并、加水印……全放一起)

如果你发现一个 Skill 的 description 需要写很长才能说清楚它"不做什么",通常意味着它承担了太多职责,应该拆分。


模式二:防御性输入检查

在 Skill 脚本入口处集中完成所有输入验证,通过后再进入业务逻辑。

实例

# 文件路径:scripts/defensive_entry.py
# 模式:防御性输入检查——入口处集中验证,通过后放行

import sys
import os
import json

def validate(args) -> list:
    """集中验证所有输入,返回错误列表(空列表表示全部通过)"""
    errors = []

    if not args.file:
        errors.append("缺少参数 --file")
    elif not os.path.exists(args.file):
        errors.append(f"文件不存在:{args.file}")
    elif os.path.getsize(args.file) == 0:
        errors.append("文件内容为空")

    if args.limit < 1:
        errors.append("--limit 必须大于 0")

    return errors

def run(args):
    """业务逻辑入口,只在验证通过后才会被调用"""
    # 执行实际处理...
    return {"status": "success", "file": args.file}

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--file",  required=False, default="")
    parser.add_argument("--limit", type=int, default=100)
    args = parser.parse_args()

    # 1. 集中验证
    errors = validate(args)
    if errors:
        result = {"status": "input_error", "errors": errors}
        print(json.dumps(result, ensure_ascii=False))
        sys.exit(1)

    # 2. 通过验证后执行业务逻辑
    result = run(args)
    print(json.dumps(result, ensure_ascii=False))

模式三:渐进式输出

对于耗时超过 5 秒的 Skill,应当分阶段输出进度,而不是让用户面对沉默的等待。

## 执行流程(渐进式输出示例)

### 步骤一:读取文件
运行读取脚本后,立即告知用户:
> 已读取文件:runoob_data.csv(1,024 行,8 列)正在进行数据清洗...

### 步骤二:数据清洗
清洗完成后,告知用户:
> 数据清洗完成:删除重复行 3 条,空值填充 12 处。正在生成报告...

### 步骤三:生成报告
报告生成后,展示下载链接并说明内容:
> 报告已生成,包含统计摘要和数据质量评估。

模式四:幂等操作

Skill 的执行结果应该是幂等的:同样的输入,无论执行多少次,输出都应当一致。

非幂等操作(如每次执行都追加内容)会导致用户重试时产生混乱。

实例

# 文件路径:scripts/idempotent_output.py
import os
from datetime import datetime

OUTPUT_DIR = "/mnt/user-data/outputs"

def get_output_path(base_name: str, suffix: str = ".xlsx") -> str:
    """
    生成确定性的输出路径

    幂等方式:每次执行覆盖同名文件(而不是追加或生成新文件)
    确保同样的输入始终对应同样的输出文件
    """

    # 方式 A:固定文件名(同一输入始终覆盖)
    return os.path.join(OUTPUT_DIR, f"{base_name}_report{suffix}")

    # 方式 B(时间戳):每次生成新文件(非幂等,但保留历史)
    # ts = datetime.now().strftime("%Y%m%d_%H%M%S")
    # return os.path.join(OUTPUT_DIR, f"{base_name}_{ts}{suffix}")

模式五:明确的结束信号

Skill 执行完毕后,应当给出明确的"完成信号",让用户知道任务已结束,不需要继续等待。

## 任务完成后的输出规范

无论成功还是失败,最后一步必须输出一个明确的状态行:

成功时:
> 任务完成:报告已生成,共处理 1,024 行数据,耗时约 3 秒。

失败时:
> 任务中断:在"数据清洗"步骤遇到错误(原因:文件编码不是 UTF-8)。
> 建议:将文件另存为 UTF-8 格式后重新上传。

模式六:版本兼容性声明

在 SKILL.md 的 frontmatter 中声明兼容的模型版本,防止在不支持的环境中产生不可预期的行为。

---
name: data-analyzer
version: 1.2.0
description: 分析 CSV/Excel 数据,生成统计报告。
compatibility:
  claude_models:
    - claude-sonnet-4-20250514   # 经过验证的模型版本
    - claude-opus-4              # 同样支持
  python: ">=3.8"
  platforms:
    - linux    # Claude 计算机使用环境
---

模式七:Fail Fast(快速失败)

一旦发现无法继续的错误,立即停止并清晰报告,而不是带着错误继续执行产生无意义的输出。

实例

# 文件路径:scripts/fail_fast.py
import sys
import json

def assert_condition(condition: bool, message: str, hint: str = ""):
    """如果条件不满足,立即输出错误并退出(Fail Fast 模式)"""
    if not condition:
        result = {
            "status":  "error",
            "message": message,
            "hint":    hint
        }
        print(json.dumps(result, ensure_ascii=False))
        sys.exit(1)

# 在脚本开头集中做所有前置检查
import os
file_path = sys.argv[1] if len(sys.argv) > 1 else ""

assert_condition(bool(file_path),
                 "缺少文件路径参数",
                 "用法:python script.py <文件路径>")

assert_condition(os.path.exists(file_path),
                 f"文件不存在:{file_path}",
                 "请检查路径是否正确,或重新上传文件")

assert_condition(file_path.endswith(".csv"),
                 "文件格式不支持,期望 .csv",
                 f"实际文件:{file_path}")

# 所有检查通过,执行实际逻辑
print(json.dumps({"status": "ok", "file": file_path}))

模式速查表

模式核心原则解决的问题
单一职责一个 Skill 只做一件事触发不准确、难以维护
防御性输入检查入口处集中验证运行到一半才报错
渐进式输出分阶段汇报进度用户不知道是否在执行
幂等操作同输入同输出重试产生混乱结果
明确结束信号完成后给出终态通知用户不知道任务是否完成
版本兼容声明声明支持的运行环境环境不匹配时行为异常
Fail Fast遇到错误立即停止带着错误继续产生无效输出