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