Agent Skills in der Claude API: pptx-Skill ohne Claude Code nutzen
MarkdownWie Sie einen fertigen pptx-Skill mit der Claude API verbinden: container.skills, das Codeausführungstool, die Überprüfung der Antwort und der Download der Präsentation über die Files API.
Vollständigen Artikel lesen
Das Wichtigste
Fertige Agent Skills für Dokumente lassen sich über die direkte Claude API verwenden: Geben Sie den Skill in container.skills an und aktivieren Sie code_execution. Verwenden Sie für Ihre erste Anfrage die kompatible Modell- und Tool-Kombination aus dem offiziellen Beispiel. Laden Sie die generierte Datei separat anhand ihrer file_id herunter; im Beispiel wird für die Anfrage und den Download derselbe API-Schlüssel verwendet.
Weitere Anleitungen finden Sie in der Ailoot-Dokumentation.
Was benötigt man, um Agent Skills in der Claude API zu verwenden?
Diese Anleitung richtet sich an den direkten API-Aufruf aus einem Programm und nicht an die Installation eines Skills in Claude Code. Sie benötigen einen Claude-API-Schlüssel, Zugriff auf das ausgewählte Modell und Python 3. Der folgende Code verwendet die Python-Standardbibliothek und HTTP und ist daher unabhängig davon, welche SDK-Version Sie installiert haben. Der Schlüssel wird über die Umgebungsvariable ANTHROPIC_API_KEY übergeben. Fügen Sie ihn nicht in den Programmtext oder eine Unterhaltung ein.
Die API bietet fertige Anthropic-Skills an: pptx für Präsentationen, xlsx für Tabellen, docx für Word-Dokumente und pdf für PDFs. Sie werden mit type: "anthropic" eingebunden. Diese Anleitung verwendet einen fertigen Skill, ohne einen eigenen hochzuladen.
Der offizielle Schnellstart, der bei der Vorbereitung dieses Materials geöffnet wurde, verwendet die Kombination claude-opus-5-5 und code_execution_20260521. Diese Kombination wird im Folgenden verwendet. Das Beispiel wurde anhand der Dokumentation überprüft; es ist kein Bericht über einen kostenpflichtigen API-Aufruf.
Welche Beta-Header werden benötigt?
Das Beispiel folgt dem aktuellen HTTP-Vertrag des Schnellstarts: Die Header lauten x-api-key, anthropic-version: 2023-06-01 und content-type: application/json; anthropic-beta wird nicht gesendet. Kombinieren Sie kein Modell, keine Aufrufmethode und kein Antwortformat aus unterschiedlichen Generationen der Dokumentation.
Auch die Dokumentation zur Files API besagt, dass sich die API nicht mehr in der Beta-Phase befindet. Der alte Header files-api-2025-04-14 behält die alten Antwortformate bei; durch Entfernen des Headers werden die aktuellen Formate aktiviert. Deshalb lässt sich ein altes Beispiel mit client.beta.files nicht einfach mit einem neuen kombinieren.
Hier migrieren wir keinen bestehenden Dienst vom alten Beta-Vertrag. Wenn Sie bereits einen solchen Dienst haben, prüfen Sie zuerst dessen Header und Antwortformate. Das Wort beta in einem SDK-Methodennamen reicht für sich genommen nicht aus: Die Dokumentation zur Files API erläutert gesondert, wie sich verschiedene SDK-Versionen verhalten.
Präsentation erstellen und Datei herunterladen
Das Beispiel sendet eine Aufgabe, fünf Folien über erneuerbare Energien zu erstellen, speichert die vollständige Antwort in skill-response.json und extrahiert anschließend die IDs der generierten Dateien. Es übernimmt keinen Speicherpfad aus der Antwort des Modells: Die Dateien werden in einem neuen lokalen Ordner namens skill-output gespeichert. Falls dieser Ordner bereits existiert, bricht das Programm ab, damit es das vorherige Ergebnis nicht überschreibt. Der Ordner wird vor dem API-Aufruf erstellt und bleibt deshalb auch nach einem fehlgeschlagenen Aufruf bestehen. Prüfen und bewahren Sie diesen Versuch, bevor Sie erneut handeln; löschen Sie ihn nicht bloß, damit eine Wiederholung durchläuft.
import json
import os
from pathlib import Path
from urllib.error import HTTPError
from urllib.request import Request, urlopen
API = "https://api.anthropic.com/v1"
KEY = os.environ["ANTHROPIC_API_KEY"]
HEADERS = {
"x-api-key": KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
}
def request(path, payload=None, binary=False):
data = None if payload is None else json.dumps(payload).encode("utf-8")
req = Request(API + path, data=data, headers=HEADERS)
try:
with urlopen(req, timeout=600) as result:
body = result.read()
except HTTPError as error:
try:
details = json.loads(error.read().decode("utf-8"))
except (ValueError, UnicodeError):
details = {}
info = details.get("error", {})
request_id = error.headers.get("request-id") or details.get("request_id")
diagnostic = {
"http_status": error.code,
"request_id": request_id,
"error_type": info.get("type"),
"message": str(info.get("message", "No JSON error message")).replace(KEY, "[REDACTED]")[:1000],
}
(out / "skill-error.json").write_text(
json.dumps(diagnostic, ensure_ascii=False, indent=2), encoding="utf-8"
)
raise RuntimeError(
f"Claude API HTTP {error.code}; request_id={request_id}; inspect skill-error.json"
) from None
return body if binary else json.loads(body)
out = Path("skill-output")
out.mkdir(exist_ok=False)
response = request("/messages", {
"model": "claude-opus-5-5",
"max_tokens": 16000,
"container": {
"skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]
},
"messages": [{
"role": "user",
"content": "Erstelle eine Präsentation über erneuerbare Energien mit 5 Folien in meiner bevorzugten Sprache.",
}],
"tools": [{"type": "code_execution_20260521", "name": "code_execution"}],
})
(out / "skill-response.json").write_text(
json.dumps(response, ensure_ascii=False, indent=2), encoding="utf-8"
)
print("stop_reason:", response.get("stop_reason"))
file_ids = []
for block in response["content"]:
if block["type"] == "bash_code_execution_tool_result":
result = block["content"]
if result["type"] == "bash_code_execution_result":
for item in result["content"]:
file_id = item.get("file_id")
if file_id and file_id not in file_ids:
file_ids.append(file_id)
if not file_ids:
raise RuntimeError("No generated file_id; inspect skill-response.json")
for index, file_id in enumerate(file_ids, start=1):
from urllib.parse import quote
file_path = "/files/" + quote(file_id, safe="")
metadata = request(file_path)
if metadata.get("downloadable") is not True:
raise RuntimeError("This file cannot be downloaded through Files API")
target = out / f"result-{index}.pptx"
target.write_bytes(request(file_path + "/content", binary=True))
print("Saved:", target)
Die Namen result-1.pptx und so weiter wurden für diese Präsentationsaufgabe gewählt. Eine Dateiendung beweist nicht, was die Datei enthält: Öffnen Sie das heruntergeladene Dokument und prüfen Sie dessen Format, Folienzahl und Text. Betrachten Sie weder einen HTTP-Status 200 noch das Vorhandensein einer file_id allein als erfolgreiches Ergebnis.
Das Programm gibt stop_reason, den Grund für das Ende der Antwort, aus und speichert die vollständige Antwort zur Überprüfung. Es setzt die Unterhaltung nicht fort und wiederholt den kostenpflichtigen Aufruf nicht automatisch. Eine heruntergeladene Datei bedeutet nicht, dass die gesamte Aufgabe erledigt ist: Prüfen Sie die gespeicherte Antwort und das Dokument selbst, bevor Sie entscheiden, ob eine weitere Anfrage erforderlich ist.
Prüfen Sie nach einem fehlgeschlagenen Versuch die Datei skill-error.json, falls sie vorhanden ist. Sie enthält den HTTP-Status, eine vom Anbieter gelieferte Anfrage-ID und eine begrenzte Fehlermeldung, aus der der konfigurierte API-Schlüssel entfernt wurde. Prüfen Sie die Meldung vor dem Teilen auf weitere private Inhalte. Vergleichen Sie Authentifizierungsfehler, Berechtigungs- und Modellfehler, Abrechnungslimits und Formatfehler mit der offiziellen Fehlerreferenz; nicht jeder Fehler erfordert eine weitere kostenpflichtige Generierung.
Enthält skill-response.json bereits generierte file_id-Werte und scheiterte nur ein Download, setzen Sie diesen mit den bekannten IDs fort, statt die Präsentation erneut zu generieren. Ist der Ausgang der Generierung unbekannt, klären Sie zunächst den ursprünglichen Versuch. FileExistsError für skill-output ist ein lokaler Verzeichniskonflikt und kein API-Fehler. Erst für eine begründete neue Generierung wählen Sie bewusst einen neuen, unbenutzten Ausgabeordner; behalten Sie exist_ok=False und überschreiben Sie den früheren Versuch nicht. Ein anderer Ordner verhindert keine doppelte Generierung oder doppelte Kosten.
Welche Dateiberechtigungen werden benötigt?
Die Files API ordnet Dateien einem Workspace zu und nicht einem einzelnen Nutzer Ihrer Anwendung oder einer Unterhaltung. Laut Dokumentation kann jeder API-Schlüssel mit Zugriff auf diesen Workspace auf die dort hochgeladenen Dateien zugreifen. Im Beispiel wird zum Herunterladen derselbe Schlüssel wie zum Generieren verwendet. Akzeptieren Sie niemals eine file_id von Endnutzern oder anderen nicht vertrauenswürdigen Quellen. Speichern Sie diese IDs auf dem Server und verwalten Sie die Zuordnung zwischen Nutzern und ihren Dateien in Ihrer eigenen Anwendung.
Prüfen Sie die Dateimetadaten gesondert: Sie müssen downloadable: true enthalten. Laut Dokumentation können Dateien heruntergeladen werden, die von Skills oder dem Codeausführungstool generiert wurden. Hochgeladene Dateien haben downloadable: false; ein Downloadversuch gibt den Status 400 zurück. Der Zugriff auf den Workspace und die Berechtigung, eine bestimmte Datei herunterzuladen, sind separate Voraussetzungen.
Für Anwendungen mit mehreren Nutzern empfiehlt die Dokumentation zur Files API einen separaten Workspace pro Kunde als Grenze für die Datei-Isolation. Diese Empfehlung bezieht sich ausdrücklich auf Dateien. Übertragen Sie sie nicht ohne Prüfung der jeweiligen API auf alle Entitäten und Berechtigungen.
Fertige Skills und eigene Skills
Fertige Skills haben die IDs pptx, xlsx, docx und pdf. In der Referenz zur Skills-Liste wird die Quelle custom als privat für den Workspace beschrieben, während anthropic gemeinsam genutzt wird und schreibgeschützt ist.
version: "latest" bedeutet im ersten Beispiel die zuletzt veröffentlichte Version des Skills. Berücksichtigen Sie bei einer reproduzierbaren Integration, dass sich diese Auswahl ändern kann. Für den Wechsel zu einer festen Version müssen Sie eine vorhandene Version des verwendeten Skills auswählen, statt eine erfundene ID aus einem Beispiel zu übernehmen.
Einschränkungen und nächste Schritte
Das Beispiel behandelt nur das Erstellen einer Präsentation mit einem fertigen Skill und das Herunterladen. Das Hochladen eigener Skills, das Löschen von Skills und der Zugriff auf Dienste Dritter wurden hier nicht getestet. Für diese Aufgaben ist eine gesonderte Prüfung der jeweiligen API erforderlich.
Wenn Ihre Aufgabe Dateien in der Claude-Oberfläche betrifft, gibt es eine separate Anleitung dazu, wie Sie eine Datei in Claude hochladen. Für direkte Aufrufe lesen Sie, wie Sie den API-Tokenverbrauch berechnen. Für die Arbeit mit einem Terminal-Agenten lesen Sie wie Sie Claude-Code-Skills auswählen: Sie werden auf andere Weise eingebunden.
Für die erste Prüfung genügt ein einzelner fertiger pptx-Skill: Untersuchen Sie die Antwort, laden Sie eine Datei herunter, die heruntergeladen werden darf, und öffnen Sie sie. Fügen Sie eigene Skills und eine Zugriffstrennung zwischen Kunden erst nach dieser Prüfung hinzu.
Wenn Sie bereit sind, lernen Sie Ailoot kennen.
Weitere Details
Fragen und Antworten
Warum genügt eine file_id nicht, um eine Präsentation als fertig zu betrachten?
Die ID zeigt nur, dass eine Datei zurückgegeben wurde, nicht dass eine nutzbare Präsentation vorliegt. Prüfen Sie in den Metadaten downloadable: true, laden Sie sie mit Arbeitsbereichszugriff herunter und öffnen Sie sie. Kontrollieren Sie Dateiformat, Folienzahl und Texte.
Kann ich jede in die Claude Files API hochgeladene Datei herunterladen?
Nein. Der Leitfaden unterscheidet erzeugte Dateien mit downloadable: true von hochgeladenen Dateien mit downloadable: false. Arbeitsbereichszugriff und Downloadberechtigung einer bestimmten Datei sind getrennte Prüfungen. Akzeptieren Sie keine beliebigen Datei-IDs von Nutzern.