Intégration des compétences et de la chaîne d’outils
En s'intégrant à des chaînes d'outils externes, les Skills peuvent accomplir des tâches que Claude seul ne peut pas.
Cet article présente comment appeler des outils en ligne de commande, des outils système et des bibliothèques tierces dans un Skill, et fournit un exemple complet d'intégration.
Types d'outils que les Skills peuvent appeler
| Type d'outil | Exemple | Méthode d'invocation |
|---|---|---|
| Commandes système | ls、cp、find、wc | subprocess.run() |
| Environnement d'exécution de langage | python、node、bash | subprocess.run() |
| Outils de traitement de documents | pandoc、pdflatex | subprocess.run() |
| Outils de traitement multimédia | ffmpeg、imagemagick | subprocess.run() |
| Bibliothèques Python | pandas、openpyxl、pypdf | Appeler directement après import |
| Outils Node.js | prettier, eslint | Invoquer via npx |
Avant d'appeler des outils externes, vérifiez que les outils sont installés dans l'environnement d'exécution. Les outils courants (python3, pip, node, npm) sont préinstallés dans le bac à sable Claude, mais pandoc, ffmpeg, etc. doivent être installés séparément.
Appel de commandes externes dans les scripts
Le modulesubprocess`subprocess` de Python est la méthode standard pour appeler des commandes externes. Il est recommandé de l'encapsuler uniformément dans des fonctions utilitaires réutilisables.
Exemple
import subprocess
import sys
import json
def run_command(cmd: list, timeout: int = 60) -> dict:
"""
Exécuter une commande externe et capturer la sortie
Paramètres :
cmd: liste de commandes, par exemple, ["pandoc", "--version"]
timeout: délai en secondes, par défaut 60
Retourne :
un dict contenant success, stdout, stderr, returncode
"""
try:
result = subprocess.run(
cmd,
capture_output=True, # Capturer à la fois stdout et stderr
text=True, # Retourner sous forme de chaîne, pas bytes
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"Commande introuvable : {cmd
}
except subprocess.TimeoutExpired:
return {
"success": False,
"returncode": -1,
"stdout": "",
"stderr": f"L'exécution de la commande a expiré (dépassement de {timeout} secondes)"
}
# Exemple : utiliser pandoc pour convertir du Markdown en 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("Conversion réussie")
else:
print(f"Échec de la conversion : {result['stderr']}")
sys.exit(1)
Vérification de la disponibilité d'un outil
Vérifier si les outils requis sont installés avant d'exécuter une Skill fournit un retour clair avant que la tâche n'échoue à mi-parcours.
Exemple
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:
"""Vérifie la liste des outils, renvoie True si tous sont prêts"""
all_ok = True
for tool, install_cmd in tools:
path = shutil.which(tool) # Trouver le chemin de l'outil dans PATH
if path:
print(f" Installé : {tool} → {path}")
else:
print(f" Non installé : {tool} Commande d'installation : {install_cmd}")
all_ok = False
return all_ok
if __name__ == "__main__":
print("Vérification des dépendances des outils...")
if not check_tools(REQUIRED_TOOLS):
print("\n"Veuillez d'abord installer les outils manquants.")
sys.exit(1)
print("\n"Tous les outils sont prêts, continuez l'exécution.")
检查工具依赖... 已安装:pandoc → /usr/bin/pandoc 未安装:ffmpeg 安装命令:sudo apt-get install ffmpeg 未安装:convert 安装命令:sudo apt-get install imagemagick 请先安装缺少的工具。
Déclaration des dépendances d'outils dans SKILL.md
Utilisez le champcompatibility`dependencies` du frontmatter YAML pour lister toutes les dépendances externes, afin que les utilisateurs sachent quoi préparer avant d'installer la Skill.
---
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
---
Intégration des outils Node.js
Grâce ànpx`npx`, vous pouvez directement appeler des outils CLI à partir de paquets npm sans installation globale.
Exemple
import subprocess
import sys
def run_prettier(file_path: str) -> bool:
"""Formater les fichiers de code avec prettier"""
result = subprocess.run(
["npx", "--yes", "prettier", "--write", file_path],
capture_output=True,
text=True
)
if result.returncode == 0:
print(f"Formatage réussi : {file_path}")
return True
print(f"Échec du formatage : {result.stderr}")
return False
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Utilisation : python use_node_tool.py <chemin du fichier>")
sys.exit(1)
sys.exit(0 if run_prettier(sys.argv[1]) else 1)
npx --yesLors de la première exécution, le paquet de l'outil est téléchargé automatiquement, ce qui nécessite une connexion réseau au registre npm. Dans les environnements à accès réseau restreint, installez-le globalement à l'avance :npm install -g prettier。
Normalisation des résultats d'appels d'outils
Différents outils ont différents formats de sortie. Il est recommandé de les encapsuler uniformément au niveau de la couche Skill, en n'exposant à l'extérieur qu'une structure cohérente.
| Méthode de traitement | Scénario applicable | Outils typiques |
|---|---|---|
| Capturer stdout | L'outil produit le résultat sur la sortie standard | pandoc、wc、cat |
| Vérifier le code de retour | L'outil renvoie 0 en cas de succès et une valeur non nulle en cas d'échec | Presque tous les outils CLI |
| Lire le fichier de sortie | L'outil écrit le résultat dans un fichier spécifié | ffmpeg、pandoc -o |
| Analyser la sortie JSON | L'outil prend en charge le paramètre --json | eslint --format json |
Exemple d'intégration complet : rapport Markdown vers PDF
L'exemple suivant combine pandoc avec un script Python pour implémenter un script Skill complet de génération Markdown → PDF.
Exemple
# Flux de travail complet : vérifier l'outil → valider l'entrée → appeler pandoc → confirmer la sortie
import subprocess
import shutil
import sys
import os
import json
from datetime import datetime
def check_pandoc() -> bool:
"""Vérifier si pandoc est disponible"""
if not shutil.which("pandoc"):
print("Erreur : pandoc introuvable, veuillez exécuter : sudo apt-get install pandoc")
return False
return True
def validate_input(md_path: str) -> bool:
"""Valider le fichier Markdown d'entrée"""
if not os.path.exists(md_path):
print(f"Erreur : le fichier n'existe pas → {md_path}")
return False
if not md_path.lower().endswith(".md"):
print(f"Erreur : le fichier doit être au format .md → {md_path}")
return False
return True
def convert_to_pdf(md_path: str, output_dir: str) -> dict:
"""Appeler pandoc pour convertir Markdown en PDF"""
os.makedirs(output_dir, exist_ok=True)
# Générer un nom de fichier de sortie avec un horodatage pour éviter d'écraser les anciens fichiers
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", # Prise en charge du chinois
"-V", "CJKmainfont=SimSun", # Police chinoise (à ajuster selon l'environnement)
"-V", "geometry:margin=2cm" # Marge de page
],
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 n'a pas généré de fichier de sortie"
}
def main():
if len(sys.argv) < 2:
print("Utilisation : python md_to_pdf.py <chemin du fichier Markdown>")
sys.exit(1)
md_path = sys.argv[1]
output_dir = "/mnt/user-data/outputs"
# Vérifier étape par étape ; quitter immédiatement si une étape échoue
if not check_pandoc():
sys.exit(1)
if not validate_input(md_path):
sys.exit(1)
print(f"Conversion : {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
}
Appelez ce script dans SKILL.md :
## 执行转换 获取用户上传的 .md 文件路径后,运行: ```bash python scripts/md_to_pdf.py <文件路径> ``` 解析 JSON 输出: - status 为 "success":调用 present_files 展示 output 路径的文件 - status 为 "error":将 message 内容展示给用户,说明可能原因Autres extensions