Skills-Skript-Erweiterung
Zusätzlich zum Schreiben von Anweisungen in SKILL.md kannst du auch ausführbaren Code über das scripts-Verzeichnis zu einem Skill hinzufügen.
In diesem Abschnitt erfährst du, wie du Skripte verwendest, um die Funktionalität eines Skills zu erweitern.
Warum Skripte verwenden
Die Verwendung von Skripten ermöglicht es dir:
- Komplexe Logik kapseln und vermeiden, große Mengen Code in SKILL.md zu schreiben
- Getestete, zuverlässige Implementierungen bereitstellen
- Agenten die Wiederverwendung derselben Tools und Funktionen ermöglichen
- Komplexere Eingabe-/Ausgabeoperationen verarbeiten
Tipp: Wenn du bemerkst, dass der Agent dieselbe Logik über mehrere Ausführungen hinweg wiederholt implementiert, ist das oft ein guter Zeitpunkt, ein Skript zu erstellen.
Struktur des Skriptverzeichnisses
Skripte sollten im Unterverzeichnis scripts/ des Skill-Verzeichnisses abgelegt werden:
Verzeichnisstruktur
├── SKILL.md
└── scripts/
├── script1.py
├── script2.sh
└── helper.js
Richtlinien zum Schreiben von Skripten
1. Eigenständigkeit
Skripte sollten so eigenständig wie möglich sein oder ihre Abhängigkeiten klar dokumentieren.
Beispiel für ein eigenständiges Skript
"""
Skript zur PDF-Textextraktion
Abhängigkeit: pip install pdfplumber
Ausführen: python scripts/extract_pdf.py input.pdf
"""
import sys
import pdfplumber
def extract_text_from_pdf(pdf_path):
"""Text aus einer PDF-Datei extrahieren"""
with pdfplumber.open(pdf_path) as pdf:
text = ""
for page in pdf.pages:
text += page.extract_text() or ""
return text
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Verwendung: python extract_pdf.py <PDF-Datei>")
sys.exit(1)
pdf_path = sys.argv[1]
text = extract_text_from_pdf(pdf_path)
print(text)
2. Klare Fehlerbehandlung
Skripte sollten nützliche Fehlermeldungen bereitstellen, damit Agenten verstehen, was schiefgelaufen ist.
Beispiel für Fehlerbehandlung
def main():
if len(sys.argv) < 2:
print("Fehler: Erforderliches Argument fehlt", file=sys.stderr)
print("Verwendung: python script.py <Eingabedatei> [Ausgabedatei]", file=sys.stderr)
sys.exit(1)
input_file = sys.argv[1]
try:
# Hauptlogik ausführen
process_file(input_file)
except FileNotFoundError:
print(f"Fehler: Datei {input_file} nicht gefunden", file=sys.stderr)
sys.exit(1)
except PermissionError:
print(f"Fehler: Keine Berechtigung zum Lesen der Datei {input_file}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Fehler: Unbekannter Fehler beim Verarbeiten der Datei: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
3. Behandlung von Randfällen
Skripte sollten verschiedene Randfälle elegant behandeln, anstatt abzustürzen.
Beispiel für die Behandlung von Randfällen
"""Überprüfen, ob die Eingabe gültig ist"""
if not text:
return False, "Die Eingabe darf nicht leer sein"
if len(text) > 10000:
return False, "Die Eingabelänge überschreitet das Limit (max 10000 Zeichen)"
return True, ""
# Validierung verwenden
is_valid, error_msg = validate_input(user_input)
if not is_valid:
print(f"Validierung fehlgeschlagen: {error_msg}")
sys.exit(1)
Referenzieren von Skripten in SKILL.md
Wenn ein Skill ein Skript ausführen muss, beschreiben Sie in SKILL.md, wie es aufgerufen wird.
Skripte referenzieren:
## PDF 文本提取 使用脚本提取 PDF 中的文本: ```bash python scripts/extract_pdf.py input.pdf ``` 脚本会从 input.pdf 提取所有文本并输出到标准输出。 如果需要将结果保存到文件: ```bash python scripts/extract_pdf.py input.pdf > output.txt ```
Hinweis: Verwenden Sie beim Referenzieren von Skripten Pfade relativ zum Skill-Stammverzeichnis.
Unterstützte Skriptsprachen
Die unterstützten Skriptsprachen hängen von der Agent-Implementierung ab, die Sie verwenden. Häufige Optionen sind:
| Sprache | Beschreibung |
|---|---|
| Python | Die am häufigsten verwendete Wahl, leistungsstark und einfach zu schreiben |
| Bash | Geeignet für Systemoperationen und Kommandozeilen-Tools |
| JavaScript | Geeignet für Web-bezogene Aufgaben |
Tipp: Berücksichtigen Sie bei der Wahl einer Skriptsprache die Laufzeitumgebung des Zielbenutzers. Wenn Sie unsicher sind, ist Python die sicherste Wahl.
Vollständiges Beispiel: PDF-Verarbeitungs-Skill
Schauen wir uns ein vollständiges Beispiel an, das zeigt, wie man SKILL.md und Skripte kombiniert:
Skill-Struktur
├── SKILL.md
└── scripts/
├── extract.py
├── fill_form.py
└── merge.py
SKILL.md-Inhalt:
---
name: pdf-tool
description: 处理 PDF 文件,包括提取文本、填写表单、合并文件。使用场景:处理 PDF、提取文本、填写表单、合并 PDF.
---
## 提取 PDF 文本
从 PDF 文件中提取文本内容:
```bash
python scripts/extract.py input.pdf
```
输出是提取的纯文本内容。
## 填写 PDF 表单
使用 JSON 数据填写 PDF 表单:
```bash
python scripts/fill_form.py input.pdf data.json output.pdf
```
data.json 格式:
```json
{
"field_name": "字段值",
"another_field": "另一个值"
}
```
## 合并 PDF
将多个 PDF 文件合并为一个:
```bash
python scripts/merge.py output.pdf input1.pdf input2.pdf input3.pdf
```
## 依赖安装
需要安装 pdfplumber 和 PyPDF2:
```bash
pip install pdfplumber PyPDF2
```
Zwei Verwendungsmodi
Es gibt zwei Möglichkeiten, Code in einem Skill zu verwenden:
| Methode | Anwendungsfall | Ob das scripts/-Verzeichnis benötigt wird |
|---|---|---|
| Einmaliger Befehl | Es müssen nur vorhandene Werkzeuge aufgerufen werden, keine benutzerdefinierte Logik erforderlich | Nicht erforderlich |
| Eigenständiges Skript | Komplexe Logik, die wiederverwendet werden muss | Erforderlich |
Einmalige Befehle
Wenn vorhandene Paketmanager-Tools die Anforderungen bereits erfüllen, können Sie sie direkt in den SKILL.md-Anweisungen referenzieren, ohne ein scripts/-Verzeichnis zu erstellen.
Die folgenden sind gängige Ausführungsmethoden in jedem Sprach-Ökosystem:
uvx(Python)
uvx ist der Befehl zum Ausführen von Tools, der mit uv geliefert wird. Er führt Python-Pakete in einer isolierten Umgebung aus, und mit aggressivem Caching sind wiederholte Ausführungen nahezu augenblicklich.
Beispiel
uvx ruff@0.8.0 check .
# Führe die angegebene Version von black aus, um Code zu formatieren
uvx black@24.10.0 .
pipx(Python)
pipx ist eine ausgereifte Alternative zu uvx und kann über System-Paketmanager installiert werden (z. B.,brew install pipx)。
Beispiel
pipx run 'black==24.10.0' .
# Führe die angegebene Version von ruff aus
pipx run '[email protected]' check .
npx(Node.js)
npx ist in npm enthalten und lädt npm-Pakete bei Bedarf herunter und führt sie aus.
Beispiel
npx eslint@9 --fix .
# Ein Projekt mit Vite erstellen
npx create-vite@6 my-app
go run(Go)
Gos integrierter Befehl zum Ausführen von Tools kompiliert und führt Remote-Pakete direkt aus.
Beispiel
go run golang.org/x/tools/cmd/goimports@v0.28.0 .
# golangci-lint-Prüfung ausführen
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 ausführen
Empfehlungen für das Schreiben von Einmalbefehlen: Versionsnummern festlegen (z. B.
npx [email protected]) um konsistentes Verhalten zu gewährleisten; geben Sie Voraussetzungen in SKILL.md an (z. B. "Node.js 18+ erforderlich"); wenn Befehle komplex werden, lagern Sie sie in das Verzeichnis scripts/ aus.
Referenzieren von Skripten in SKILL.md
Verwenden Sie Pfade ausgehend vom Stammverzeichnis des Skill-Verzeichnissesrelative Pfade, um auf mitgelieferte Dateien zu verweisen.
Der Agent löst diese Pfade automatisch auf; es ist nicht nötig, absolute Pfade zu verwenden.
Listen Sie zunächst die verfügbaren Skripte in SKILL.md auf:
Beispiel
- **`scripts/validate.sh`** — Konfigurationsdateien validieren
- **`scripts/process.py`** — Eingabedaten verarbeiten
- **`scripts/report.py`** — Analyseberichte generieren
Verweisen Sie dann in den Arbeitsschritten darauf:
Beispiel
1. Führen Sie das Validierungsskript aus:
```bash
bash scripts/validate.sh "$INPUT_FILE"
```
2. Daten verarbeiten:
```bash
python3 scripts/process.py --input results.json
```
Die Ausführungspfade von Skripten sind relativ zum Stammverzeichnis des Skill-Verzeichnisses, da der Agent Befehle aus dem Skill-Verzeichnis ausführt. Dies gilt auch für Hilfsdateien wie references/*.md.
Eigenständige Skripte
Wenn Sie wiederverwendbare Logik benötigen, können Sie Skripte imscripts/Verzeichnis paketieren und Abhängigkeiten im Skript deklarieren.
Der Agent kann es mit einem einzigen Befehl ausführen, ohne zusätzliche Installationsschritte.
Eigenständiges Python-Skript (PEP 723)
PEP 723 definiert ein Standardformat zum Deklarieren von Abhängigkeiten in Python-Skripten.
Verwenden Sie# ///Marker zum Umschließen der Abhängigkeitsdeklaration im TOML-Format:
Beispiel: Eigenständiges Python-Skript
# dependencies = [
# "beautifulsoup4",
# ]
# ///
from bs4 import BeautifulSoup
# Beispiel-HTML-Inhalt
html = '<html><body><h1>Willkommen</h1><p class="info">BEISPIEL Test</p></body></html>'
# HTML mit BeautifulSoup parsen
soup = BeautifulSoup(html, "html.parser")
# Den Absatztext mit class="info" extrahieren
info_text = soup.select_one("p.info").get_text()
print(info_text)
So führen Sie aus:
Beispiel
uv run scripts/extract.py
# Mit pipx ausführen
pipx run scripts/extract.py
EXAMPLE 测试
Eigenständiges Deno-Skript
Deno verwendetnpm:undjsr:Import-Spezifizierer, um Eigenständigkeit zu erreichen:
Beispiel: Eigenständiges Deno-Skript
import * as cheerio from "npm:[email protected]";
const html = `<html><body><h1>Willkommen</h1><p class="info">BEISPIEL Test</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());
Beispiel
Eigenständiges Bun-Skript
Wenn Bun keinnode_modulesVerzeichnis hat, installiert es automatisch fehlende Pakete:
Beispiel: Eigenständiges Bun-Skript
import * as cheerio from "[email protected]";
const html = `<html><body><h1>Willkommen</h1><p class="info">BEISPIEL Test</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());
Beispiel
Eigenständiges Ruby-Skript
Ruby verwendetbundler/inlineum Gem-Abhängigkeiten im Skript zu deklarieren:
Beispiel: Eigenständiges Ruby-Skript
gemfile do
source 'https://rubygems.org'
gem 'nokogiri'
end
html = '<html><body><h1>Welcome</h1><p class="info">EXAMPLE Test</p></body></html>'
doc = Nokogiri::HTML(html)
puts doc.at_css('p.info').text
Beispiel
Wichtige Punkte für das Entwerfen von Skripten für Agenten
Der Agent bestimmt seine nächsten Aktionen durch Lesen von stdout und stderr, daher sollte das Skriptdesign die Nutzungsmerkmale des Agenten berücksichtigen.
Interaktive Eingabeaufforderungen vermeiden
Dies ist eine zwingende Anforderung. Der Agent läuft in einer nicht interaktiven Shell und kann nicht auf TTY-Aufforderungen, Passwortdialoge oder Bestätigungsmenüs reagieren.
Alle Eingaben sollten über Kommandozeilenargumente, Umgebungsvariablen oder stdin übergeben werden.
Beispiel: Falscher Ansatz vs. korrekter Ansatz
$ python scripts/deploy.py
Zielumgebung: _
# Richtig: klare Fehlermeldung und Anleitung
$ python scripts/deploy.py
Fehler: --env ist erforderlich. Optionen: development, staging, production.
Verwendung: python scripts/deploy.py --env staging --tag v1.2.3
--help-Dokumentation bereitstellen
--helpDie Ausgabe ist der primäre Weg für den Agenten, die Schnittstelle des Skripts zu verstehen.
Fügen Sie eine kurze Beschreibung, verfügbare Parameter und Anwendungsbeispiele hinzu:
Beispiel: Gute --help-Ausgabe
Eingabedaten verarbeiten und einen Zusammenfassungsbericht erstellen.
Optionen:
--formatFORMAT Ausgabeformat: json, csv, table(Standard: json)
--outputFILE Ausgabe in eine Datei anstelle von stdout schreiben
--verboseFortschrittsinformationen auf stderr ausgeben
Beispiele:
scripts/process.py data.csv
scripts/process.py --format csv --output report.csv data.csv
Nützliche Fehlermeldungen schreiben
Wenn der Agent eine Fehlermeldung sieht, passt er seine Strategie entsprechend an; je spezifischer die Meldung, desto leichter kann der Agent sich selbst korrigieren.
Beispiel
Fehler: ungültige Eingabe
# Gute Fehlermeldung
Fehler: --format muss einer der folgenden Werte sein: json, csv, table.
Empfangen: "xml"
Strukturierte Ausgabe verwenden
Bevorzuge strukturierte Formate wie JSON, CSV und TSV für die Ausgabe, statt Freitext.
Strukturierte Formate können sowohl vom Agenten als auch von Standardwerkzeugen (jq, cut, awk) verarbeitet werden, was ihre Kombination erleichtert.
Beispiel
NAME STATUS CREATED
my-service running 2025-01-15
# Empfohlen: JSON-Format mit klaren Feldgrenzen
{"name": "my-service", "status": "running", "created": "2025-01-15"}
Gib strukturierte Daten an stdout aus und Fortschrittsmeldungen sowie Diagnoseinformationen an stderr. Auf diese Weise erhält der Agent eine saubere, parsebare Ausgabe und kann bei Bedarf weiterhin Diagnoseinformationen einsehen.
Weitere Vorschläge zum Skriptdesign
| Vorschlag | Beschreibung |
|---|---|
| Idempotenz | Der Agent kann Befehle wiederholen. "Erstellen, falls nicht vorhanden" ist sicherer als "erstellen und bei Duplikaten einen Fehler ausgeben". |
| Eingabebeschränkungen | Mehrdeutige Eingaben mit einem klaren Fehler ablehnen, statt die Absicht des Nutzers zu erraten |
| Dry-Run-Unterstützung | Für destruktive oder zustandsbehaftete Operationen ein--dry-runFlag bereitstellen, mit dem der Agent die Operation vorab anzeigen kann |
| Aussagekräftige Exit-Codes | Verwenden Sie unterschiedliche Exit-Codes für verschiedene Fehlertypen (nicht gefunden, ungültiges Argument, Authentifizierungsfehler usw.) |
| Vorhersehbare Ausgabegröße | Standardmäßig eine Zusammenfassung ausgeben und--offsetweitere Parameter bereitstellen, damit der Agent bei Bedarf mehr Informationen erhalten kann. |
| Sichere Standardeinstellungen | Destruktive Operationen sollten ein explizites Bestätigungs-Flag erfordern (--confirm、--force) |
Vollständiges Beispiel für ein Skill-Skript
Nachfolgend finden Sie eine vollständige Skill-Verzeichnisstruktur mit Skripten:
Beispiel
├── SKILL.md # Hauptanweisungsdatei
├── scripts/
│ ├── overview.py # Datenübersichtsskript
│ ├── summary.py # Skript zur statistischen Zusammenfassung
│ └── validate.py # Datenvalidierungsskript
├── references/
│ └── api-errors.md # API-Fehlerreferenz
└── assets/
└── report-template.md # Berichtsvorlage
Der entsprechende SKILL.md-Inhalt:
Beispiel
name: csv-analyzer
description: >
Analysieren Sie CSV- und tabellarische Datendateien. Wenn der Benutzer CSV-, TSV- oder Excel-Dateien hat
und Daten erkunden, transformieren oder visualisieren möchte, verwenden Sie dies.
---
# CSV-Datenanalyse
## Verfügbare Skripte
- **`scripts/overview.py`** — Zeigt die Datenübersicht an (Zeilenanzahl, Spaltennamen, Typen)
- **`scripts/summary.py`** — Erzeugt eine statistische Zusammenfassung
- **`scripts/validate.py`** — Validiert die Datenqualität
## Arbeitsablauf
1. Führen Sie zuerst das Übersichtsskript aus, um die Datenstruktur zu verstehen:
```bash
uv run scripts/overview.py input.csv
```
2. Erzeugen Sie die statistische Zusammenfassung:
```bash
uv run scripts/summary.py input.csv --output summary.json
```
3. Validieren Sie die Datenqualität:
```bash
uv run scripts/validate.py input.csv
```
## Hinweise
- Verwenden Sie bei großen Dateien den Parameter `--chunk-size`, um die Verarbeitung in Chunks durchzuführen
- Probieren Sie bei chinesischen CSV-Dateien den Parameter `--encoding gbk` aus
Skriptverteilung und Abhängigkeiten
Wenn Ihre Skripte externe Abhängigkeiten benötigen, haben Sie mehrere Möglichkeiten:
1. Abhängigkeiten in SKILL.md dokumentieren
Der einfachste Weg ist, die erforderlichen Abhängigkeiten in SKILL.md zu dokumentieren.
2. Virtuelle Umgebungen verwenden
Für komplexe Projekte können Sie eine virtuelle Umgebung erstellen.
3. Docker verwenden
Wenn eine vollständige Laufzeitumgebung benötigt wird, können Sie einen Docker-Container verwenden.
Hinweis: Stellen Sie sicher, dass die Skripte in der Zielumgebung ausgeführt werden können. Bevor Sie Skripte schreiben, sollten Sie die Laufzeitumgebung des Zielbenutzers verstehen.
Zusammenfassung
In diesem Abschnitt haben wir gelernt, wie man Skripte verwendet, um die Skill-Funktionalität zu erweitern:
- Legen Sie Skripte im Verzeichnis scripts/ ab
- Skripte sollten eigenständig sein und eine klare Fehlerbehandlung aufweisen
- Verwenden Sie relative Pfade, wenn Sie Skripte in SKILL.md referenzieren
- Stellen Sie sicher, dass die Skripte in der Zielumgebung ausgeführt werden können