Skip to content

Skills 与工具链集成

Skills 可以通过与外部工具链集成,Skill 可以完成单靠 Claude 无法完成的任务。

本篇介绍如何在 Skill 中调用命令行工具、系统工具及第三方库,并提供一个完整的集成示例。


Skills 可以调用的工具类型

工具类型示例调用方式
系统命令ls、cp、find、wcsubprocess.run()
语言运行时python、node、bashsubprocess.run()
文档处理工具pandoc、pdflatexsubprocess.run()
媒体处理工具ffmpeg、imagemagicksubprocess.run()
Python 库pandas、openpyxl、pypdfimport 后直接调用
Node.js 工具prettier、eslintnpx 调用

调用外部工具前,先确认工具在运行环境中已安装。Claude 沙箱中预装了常用工具(python3、pip、node、npm),但 pandoc、ffmpeg 等需要额外安装。


在脚本中调用外部命令

Python 的 subprocess 模块是调用外部命令的标准方式,推荐统一封装成工具函数复用。

实例

python

# 文件路径:scripts/tool_integration.py

import subprocess

import sys

import json

def run_command(cmd: list, timeout: int = 60) -> dict:

    """

    运行外部命令并捕获输出

    参数:

        cmd:     命令列表,如 ["pandoc", "--version"]

        timeout: 超时秒数,默认 60

    返回:

        包含 success、stdout、stderr、returncode 的字典

    """

    try:

        result = subprocess.run(

            cmd,

            capture_output=True,   # 同时捕获 stdout 和 stderr

            text=True,             # 以字符串返回,而非字节

            timeout=timeout

        )

        return {

            "success":    result.returncode == 0,

            "returncode": result.returncode,

            "stdout":     result.stdout.strip(),

            "stderr":     result.stderr.strip()

        }

    except FileNotFoundError:

        return {

            "success":    False,

            "returncode": -1,

            "stdout":     "",

            "stderr":     f"命令不存在:{cmd[0]},请确认已安装"

        }

    except subprocess.TimeoutExpired:

        return {

            "success":    False,

            "returncode": -1,

            "stdout":     "",

            "stderr":     f"命令执行超时(超过 {timeout} 秒)"

        }

# 示例:用 pandoc 将 Markdown 转换为 HTML

if __name__ == "__main__":

    result = run_command([

        "pandoc",

        "/mnt/user-data/uploads/readme.md",

        "-o", "/mnt/user-data/outputs/readme.html",

        "--standalone"

    ])

    if result["success"]:

        print("转换成功")

    else:

        print(f"转换失败:{result['stderr']}")

        sys.exit(1)

检查工具是否可用

在 Skill 执行前检查所需工具是否安装,能在任务中途失败前给出清晰提示。

实例

bash

# 文件路径:scripts/check_tools.py

import shutil

import sys

REQUIRED_TOOLS = [

    ("pandoc",  "sudo apt-get install pandoc"),

    ("ffmpeg",  "sudo apt-get install ffmpeg"),

    ("convert", "sudo apt-get install imagemagick"),

]

def check_tools(tools: list) -> bool:

    """检查工具列表,返回 True 表示全部就绪"""

    all_ok = True

    for tool, install_cmd in tools:

        path = shutil.which(tool)   # 在 PATH 中查找工具路径

        if path:

            print(f"  已安装:{tool} → {path}")

        else:

            print(f"  未安装:{tool}  安装命令:{install_cmd}")

            all_ok = False

    return all_ok

if __name__ == "__main__":

    print("检查工具依赖...")

    if not check_tools(REQUIRED_TOOLS):

        print("\n请先安装缺少的工具。")

        sys.exit(1)

    print("\n所有工具已就绪,继续执行。")
bash
检查工具依赖...
  已安装:pandoc /usr/bin/pandoc
  未安装:ffmpeg  安装命令:sudo apt-get install ffmpeg
  未安装:convert  安装命令:sudo apt-get install imagemagick

请先安装缺少的工具。

在 SKILL.md 中声明工具依赖

用 YAML frontmatter 的 compatibility 字段列出所有外部依赖,让用户安装 Skill 前就知道需要准备什么。

yaml
---
name: doc-converter
description: >
  将文档在不同格式间转换,支持 Markdown、HTML、PDF、Word。
  当用户需要格式转换、导出文档时触发。
compatibility:
  tools:
    - pandoc >= 2.14   # 文档格式转换
    - python >= 3.8    # 运行辅助脚本
  python_packages:
    - pypdf >= 3.0     # PDF 处理
    - python-docx >= 1.0
---

集成 Node.js 工具

通过 npx 可以直接调用 npm 包中的 CLI 工具,无需全局安装。

实例

python

# 文件路径:scripts/use_node_tool.py

import subprocess

import sys

def run_prettier(file_path: str) -> bool:

    """用 prettier 格式化代码文件"""

    result = subprocess.run(

        ["npx", "--yes", "prettier", "--write", file_path],

        capture_output=True,

        text=True

    )

    if result.returncode == 0:

        print(f"格式化成功:{file_path}")

        return True

    print(f"格式化失败:{result.stderr}")

    return False

if __name__ == "__main__":

    if len(sys.argv) < 2:

        print("用法:python use_node_tool.py <文件路径>")

        sys.exit(1)

    sys.exit(0 if run_prettier(sys.argv[1]) else 1)

npx --yes 首次运行时会自动下载工具包,需要网络连接到 npm registry。在网络受限的环境中应提前全局安装:npm install -g prettier


工具调用结果的标准化处理

不同工具的输出格式各不相同,建议在 Skill 层统一封装,对外只暴露一致的结构。

处理方式适用场景典型工具
捕获 stdout工具将结果输出到标准输出pandoc、wc、cat
检查返回码工具成功返回 0,失败返回非 0几乎所有 CLI 工具
读取输出文件工具将结果写入指定文件ffmpeg、pandoc -o
解析 JSON 输出工具支持 --json 参数eslint --format json

完整集成示例:Markdown 转 PDF 报告

以下示例将 pandoc 与 Python 脚本结合,实现一个完整的 Markdown → PDF 生成 Skill 脚本。

实例

bash

# 文件路径:scripts/md_to_pdf.py

# 完整工作流:检查工具 → 验证输入 → 调用 pandoc → 确认输出

import subprocess

import shutil

import sys

import os

import json

from datetime import datetime

def check_pandoc() -> bool:

    """检查 pandoc 是否可用"""

    if not shutil.which("pandoc"):

        print("错误:未找到 pandoc,请运行:sudo apt-get install pandoc")

        return False

    return True

def validate_input(md_path: str) -> bool:

    """验证输入的 Markdown 文件"""

    if not os.path.exists(md_path):

        print(f"错误:文件不存在 → {md_path}")

        return False

    if not md_path.lower().endswith(".md"):

        print(f"错误:文件必须是 .md 格式 → {md_path}")

        return False

    return True

def convert_to_pdf(md_path: str, output_dir: str) -> dict:

    """调用 pandoc 将 Markdown 转换为 PDF"""

    os.makedirs(output_dir, exist_ok=True)

    # 生成带时间戳的输出文件名,避免覆盖旧文件

    base_name   = os.path.splitext(os.path.basename(md_path))[0]

    timestamp   = datetime.now().strftime("%Y%m%d_%H%M%S")

    output_path = os.path.join(output_dir, f"{base_name}_{timestamp}.pdf")

    result = subprocess.run(

        [

            "pandoc", md_path,

            "-o", output_path,

            "--pdf-engine=xelatex",      # 支持中文

            "-V", "CJKmainfont=SimSun",  # 中文字体(按环境调整)

            "-V", "geometry:margin=2cm"  # 页边距

        ],

        capture_output=True,

        text=True,

        timeout=120

    )

    if result.returncode == 0 and os.path.exists(output_path):

        size_kb = os.path.getsize(output_path) // 1024

        return {

            "status":  "success",

            "output":  output_path,

            "size_kb": size_kb

        }

    return {

        "status": "error",

        "message": result.stderr or "pandoc 未生成输出文件"

    }

def main():

    if len(sys.argv) < 2:

        print("用法:python md_to_pdf.py <Markdown文件路径>")

        sys.exit(1)

    md_path    = sys.argv[1]

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

    # 逐步检查,任一步骤失败立即退出

    if not check_pandoc():

        sys.exit(1)

    if not validate_input(md_path):

        sys.exit(1)

    print(f"正在转换:{md_path}")

    result = convert_to_pdf(md_path, output_dir)

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

    sys.exit(0 if result["status"] == "success" else 1)

if __name__ == "__main__":

    main()
bash
正在转换:/mnt/user-data/uploads/runoob_report.md
{
  "status": "success",
  "output": "/mnt/user-data/outputs/runoob_report_20260518_102305.pdf",
  "size_kb": 248
}

在 SKILL.md 中调用该脚本:

bash
## 执行转换

获取用户上传的 .md 文件路径后,运行:

```bash
python scripts/md_to_pdf.py <文件路径>
```

解析 JSON 输出:
- status "success":调用 present_files 展示 output 路径的文件
- status "error":将 message 内容展示给用户,说明可能原因

AI 思考中...

Skills 目录结构

Skills 依赖管理

基于 VitePress 构建,部署于 GitHub Pages