Интеграция навыков и инструментальной цепочки

Благодаря интеграции с внешними инструментальными цепочками навыки могут выполнять задачи, которые Claude не может выполнить в одиночку.

В этой статье рассказывается, как вызывать инструменты командной строки, системные инструменты и сторонние библиотеки в Навыке, а также приводится полный пример интеграции.


Типы инструментов, которые могут вызывать навыки

Тип инструментаПримерМетод вызова
Системные командыls、cp、find、wcsubprocess.run()
Среда выполнения языкаpython、node、bashsubprocess.run()
Инструменты обработки документовpandoc、pdflatexsubprocess.run()
Инструменты обработки медиаffmpeg、imagemagicksubprocess.run()
Библиотеки Pythonpandas、openpyxl、pypdfВызов напрямую после импорта
Инструменты Node.jsprettier、eslintВызов через npx

Перед вызовом внешних инструментов убедитесь, что инструменты установлены в среде выполнения. Обычные инструменты (python3, pip, node, npm) предустановлены в песочнице Claude, но pandoc, ffmpeg и т. д. нужно устанавливать отдельно.


Вызов внешних команд в скриптах

Модульsubprocess`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
        }
    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 обеспечивает четкую обратную связь до того, как задача потерпит неудачу на полпути.

Пример

# Путь к файлу: 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"Все инструменты готовы, продолжайте выполнение.")
检查工具依赖...
  已安装:pandoc → /usr/bin/pandoc
  未安装:ffmpeg  安装命令:sudo apt-get install ffmpeg
  未安装:convert  安装命令:sudo apt-get install imagemagick

请先安装缺少的工具。

Объявление зависимостей инструментов в SKILL.md

Используйте в YAML frontmattercompatibilityполе `dependencies`, чтобы перечислить все внешние зависимости, чтобы пользователи знали, что подготовить перед установкой навыка.

---
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`npx`, можно напрямую вызывать инструменты CLI из пакетов npm без глобальной установки.

Пример

# Путь к файлу: 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. В средах с ограниченным доступом к сети установите его глобально заранее:npm install -g prettier。


Стандартизация результатов вызова инструментов

Разные инструменты имеют разные форматы вывода. Рекомендуется единообразно оборачивать их на уровне Skill, предоставляя наружу только согласованную структуру.

Способ обработкиПрименимый сценарийТипичные инструменты
Захват stdoutИнструмент выводит результат в стандартный выводpandoc、wc、cat
Проверка кода возвратаИнструмент возвращает 0 при успехе и ненулевое значение при ошибкеПочти все CLI-инструменты
Чтение выходного файлаИнструмент записывает результат в указанный файлffmpeg、pandoc -o
Парсинг JSON-выводаИнструмент поддерживает параметр --jsoneslint --format json

Полный пример интеграции: отчёт Markdown в PDF

В следующем примере pandoc объединяется со скриптом Python для реализации полного скрипта Skill генерации Markdown → PDF.

Пример

# Путь к файлу: 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()
正在转换:/mnt/user-data/uploads/example_report.md
{
  "status": "success",
  "output": "/mnt/user-data/outputs/example_report_20260518_102305.pdf",
  "size_kb": 248
}

Вызовите этот скрипт в SKILL.md:

## 执行转换

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

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

解析 JSON 输出:
- status 为 "success":调用 present_files 展示 output 路径的文件
- status 为 "error":将 message 内容展示给用户,说明可能原因
Другие расширения