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

my-skill/
├── 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

#!/usr/bin/env python3
"""
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

import sys

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

def validate_input(text):
    """Ü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

pdf-tool/
├── 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

# Führe die angegebene Version von ruff aus, um Code zu prüfen
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

# Führe die angegebene Version von black aus
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

# ESLint-Prüfung ausführen
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

# goimports ausführen, um Importe zu formatieren
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

## Verfügbare Skripte

- **`scripts/validate.sh`** — Konfigurationsdateien validieren
- **`scripts/process.py`** — Eingabedaten verarbeiten
- **`scripts/report.py`** — Analyseberichte generieren

Verweisen Sie dann in den Arbeitsschritten darauf:

Beispiel

## Arbeitsablauf

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

# /// script
# 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

# Mit uv ausführen (empfohlen)
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

#!/usr/bin/env -S deno run

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

deno run scripts/extract.ts

Eigenständiges Bun-Skript

Wenn Bun keinnode_modulesVerzeichnis hat, installiert es automatisch fehlende Pakete:

Beispiel: Eigenständiges Bun-Skript

#!/usr/bin/env bun

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

bun run scripts/extract.ts

Eigenständiges Ruby-Skript

Ruby verwendetbundler/inlineum Gem-Abhängigkeiten im Skript zu deklarieren:

Beispiel: Eigenständiges Ruby-Skript

require 'bundler/inline'

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

ruby scripts/extract.rb

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

# Falsch: bleibt hängen und wartet auf Eingabe
$ 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

Verwendung: scripts/process.py [OPTIONEN] INPUT_FILE

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

# Schlechte Fehlermeldung
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

# Nicht empfohlen: Ausgerichteter Text ist programmatisch schwer zu parsen
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

csv-analyzer/
├── 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
Weitere Erweiterungen