Global agent framework
Versionierte Heimat meiner Agent Skills für Claude (claude.ai, Claude Code, API).
npx -y skills add wemwi/skill-library --skill global-agent-frameworkAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Build-Time-Framework zum Bauen, Konfigurieren, Deployen und Debuggen von Claude Managed Agents (Claude Platform / Anthropic Console) in diesem Stack — Anleitung für die Arbeit AM Agenten, kein Skill der einem laufenden Agent angehängt wird. IMMER laden, sobald ein Managed Agent erstellt, konfiguriert, verdrahtet, deployed, versioniert oder gedebuggt wird — auch wenn das Wort Skill nicht fällt. Trigger u.a.: Managed Agent anlegen, Agent-Config (system/tools/mcp_servers/skills), Session starten, Scheduled Deployment / Cron-Trigger, Webhook-Brücke zum Starten von Sessions, Vault für Agent-Secrets, Permission-Policy, Least-Privilege, Allowlist/ Denylist, Tool-Oberfläche minimieren, enabled:false vs permission_policy, Agent- Version bumpen, Agent debuggen, neuen Agent ins Portfolio aufnehmen. Gilt für jeden Managed Agent in diesem Stack.
SKILL.md
34.7 KB, as published. Nobody here has run it
global-agent-framework
Architektur- und Konfig-Wissen zum Bauen, Verdrahten, Deployen und Debuggen von
Claude Managed Agents (Claude Platform / Anthropic Console). Dieser Skill begleitet
die Bau-/Konfig-Arbeit am Agenten — analog zu global-mcp-framework für MCP-Server.
Er wird nicht einem laufenden Agent als dessen Skill angehängt.
Betrieb ist web-only — kein lokaler Rechner, kein VPS, kein Terminal. Agent-Config, Sessions, Scheduled Deployments und Vaults laufen über Console/Platform-API; die Webhook-Brücke (Abschnitt 8) ist ein Cloudflare Worker auf demselben Stack wie die MCP-Server.
Stand: Managed Agents sind Beta (managed-agents-2026-04-01). Felder und Limits
können sich ändern — bei Abweichung gewinnt die offizielle Doku, nicht dieser Skill.
Abgrenzung: MCP-Server-Mechanik → global-mcp-framework. Repo-Doku/SemVer/Release →
global-git-conventions. Hier geht es ausschließlich um den Agenten selbst.
1. Scope & Trigger
Greift, sobald ein Managed Agent in diesem Stack erstellt, konfiguriert, verdrahtet,
deployed, versioniert oder gedebuggt wird — auch ohne das Wort „Skill". Typische
Auslöser: Agent-Config schreiben (system / tools / mcp_servers / skills),
Session starten, Scheduled Deployment / Cron einrichten, Webhook-Brücke bauen, Vault
anbinden, Permission-Policy wählen, Agent-Version bumpen, neuen Agent ins Portfolio
aufnehmen.
Kein Trigger: die Arbeit innerhalb eines Agent-Laufs — die regeln die eigenen Skills des Agenten plus die User-Message, nicht dieser Skill.
2. Agent-Anatomie
Vier Kernkonzepte — gemeinsames Vokabular:
| Konzept | Bedeutung |
|---|---|
| Agent | Versionierte, wiederverwendbare Config. Per ID referenziert. Update → neue Version. Archive ist terminal. |
| Environment | Laufzeit-Kontext der Sandbox (u.a. Netzwerk an/aus). |
| Session | Ein konkreter Lauf in einer provisionierten Sandbox. |
| Events | Nachrichten in eine Session (v.a. user.message). Kein Event = keine Arbeit. |
Fünf Config-Felder (Kern, gemeinsames Vokabular für die Verdrahtung):
| Feld | Inhalt |
|---|---|
name | Aufruf-/Tracking-ID des Agenten (Abschnitt 4). |
model | Claude 4.5 oder neuer. |
system | Persona / Dauerverhalten (Abschnitt 3). |
tools | Toolset-Einträge. Eingebaut via agent_toolset_20260401 (Bash, File-Ops, Web Search/Fetch). Jeder in mcp_servers deklarierte Server braucht hier zusätzlich einen eigenen mcp_toolset-Eintrag (mcp_server_name = Server-name), sonst erscheinen seine Tools nicht. Gating je Toolset über enabled/permission_policy (Abschnitte 5+7). |
mcp_servers | Die MCP-Server dieses Agenten — je {type: url, name, url} (Abschnitt 5). |
skills | Domänen-Kontext mit Progressive Disclosure (optional, Abschnitt 3). |
Dazu optional description, metadata (Abschnitt 4) und callable_agents
(Research Preview).
Template (kanonischer Startpunkt). Die Config wird als YAML geschrieben; die
Console/Platform-API akzeptiert YAML. Zwei Vorlagen liegen unter assets/:
assets/agent-config.blank.yaml— kommentiertes Skeleton zum Kopieren. Jedes Feld trägt einen Verweis auf den zuständigen Abschnitt; diemcp_servers/mcp_toolset- Verdrahtung ist als auskommentiertes Muster hinterlegt.assets/agent-config.example.yaml— ausgefüllterrechnungs-agentals lebendes Vorbild: Drei-Ebenen-system,mcp_serversals URL-Objekt, einmcp_toolsetmit Allowlist (enabled) undpermission_policy-Gate auf dem Schreib-Tool, gefülltesmetadata. Referenz zum Abgucken, nicht garantiert deploybar — die Beta kann Feldnamen und erlaubte Modelle verschieben.
2a. Config-Schema-Wahrheit, Delivery-Kontrakt & Emit-Gate
Schema-Wahrheit ≠ diese Skill-Prosa ≠ die assets/-Templates. Die exakten Feld-Shapes
der Agent-Config stehen in der autoritativen API-Referenz anthropics/skills →
skills/claude-api/shared/managed-agents-api-reference.md. Diese SKILL.md ist die Landkarte,
die assets/*.yaml sind kommentierte Lehr-Vorlagen — beide können bei einem Referenz-Feld
hinter der API zurückliegen. Vor jedem Config-Bau die API-Referenz gegenprüfen, nicht aus
Erinnerung/Prosa/Template ableiten. Beta managed-agents-2026-04-01; bei Abweichung gewinnt
die API-Referenz.
Die drei Referenz-Felder, die als „invalid input" beißen — Objektform, NIE bloße Namen:
| Feld | Falsch (bloßer Name) | Richtig (Objektform) |
|---|---|---|
skills | - mein-skill | - {type: anthropic, skill_id: xlsx} oder - {type: custom, skill_id: skill_*, version: latest} |
mcp_servers | - lexware-mcp | - {type: url, name: lexware-mcp, url: https://…/mcp} |
permission_policy | always_allow (Skalar) | {type: always_allow} bzw. {type: always_ask} |
skill_idist nicht der Skill-Name: Anthropic-Skills = Kurz-ID (xlsx), Custom-Skills = dieskill_*-ID aus dem API-Workspace-Upload (ant beta:skills list --source custom). Der claude.ai-Mount vergibt keine solche ID — Skills syncen nicht über Surfaces.- Limits (API-Referenz):
tools≤128,skills≤20,mcp_servers≤20 (eindeutige Namen);metadata≤16 Paare, Keys ≤64 / Values ≤512 Zeichen.
Delivery-Kontrakt — das ausgelieferte Artefakt ist NICHT die Vorlage. Die assets/*.yaml
sind absichtlich durchkommentiert (Lehr-Skeleton). Was für einen Deploy geliefert wird, ist
sauberes YAML:
- Null Kommentare (kein
#), keine Lehr-Prosa. - Nur der kanonische Feld-Satz des Agent-Objekts:
name,description,model,system,mcp_servers,tools,skills,metadata(+ optionalmultiagent). - Deploy-Settings gehören NICHT ins Config-Objekt: Scheduled Deployment (Cron), Environment
(Netz/Pakete) und
vault_idswerden pro Session/Deployment gesetzt (Abschnitt 6/8/11) — sie stehen in der Deploy-Notiz/im Handover, nie in der Agent-Config.
Emit-Gate — vor JEDER Config-Auslieferung, drei Checks (Skript, kein Vorsatz):
- Parst —
yaml.safe_loadohne Fehler. - Kommentarfrei —
grep -c '#'== 0. - Feld-Set + Shapes — Top-Keys ⊆ kanonischer Satz;
skills/mcp_servers-Einträge sind Objekte (keine Strings); jedepermission_policyist{type: …}.
Fällt ein Check, wird nicht ausgeliefert.
3. Drei-Ebenen-Regel (Herzstück)
Jede Information gehört auf genau eine Ebene. Falsche Platzierung macht den Agenten entweder starr (Lauf-Auftrag im System-Prompt) oder unzuverlässig (Domänenwissen in der User-Message).
| Ebene | Was hier hingehört | Test |
|---|---|---|
System-Prompt (system) | Dauerverhalten, Persona, Leitplanken, Tonfall — gilt in jedem Lauf. | „Gilt das für jeden Lauf dieses Agenten?" |
Skill (skills) | Wiederverwendbares Domänenwissen (Regeln, Formate, Verfahren). Umfangreich, on-demand geladen. | „Gilt das für eine Aufgabenklasse, aber nicht jeden Lauf — und ist es zu groß für den System-Prompt?" |
User-Message (user.message) | Der konkrete Auftrag dieses Laufs mit seinen Daten. | „Ist das genau die Arbeit von jetzt?" |
Beispiel — ein rechnungs-agent:
- System: „Du bist ein sorgfältiger Buchhaltungs-Agent. Du schreibst nie ohne ausdrückliche Bestätigung in Lexware; du legst zuerst einen Entwurf vor."
- Skill (z.B. ein global-Lexware-Skill): Pflichtfelder einer Rechnung, USt-Logik, Nummernkreis-Regeln — gilt für jede Rechnung, aber nicht für jeden Lauf des Agenten.
- User-Message: „Erstelle die Rechnung zu Auftrag #4711, Kunde Müller GmbH, 3 Posten laut Anhang."
Faustregel: Persona → System. Domäne → Skill. Auftrag → User-Message. Secrets gehören auf keine dieser Ebenen (→ Abschnitt 6).
4. Naming & Metadata
Agent-Name (wemwi-Konvention): kebab-case, Suffix -agent, benennt den
wiederkehrenden Job, nicht den einzelnen Lauf — z.B. rechnungs-agent,
pos-manager-agent, telegram-poster-agent. Stabil über Versionen hinweg; die Version
steckt nie im Namen. Reiht sich in die Suffix-Familie ein: *-mcp / *-foundation /
*-library / *-agent.
Versionierung: Jedes Config-Update erzeugt anbieterseitig automatisch eine neue
Agent-Version (per ID referenziert, Archive terminal). Spiegle den Stand zusätzlich als
SemVer im metadata-Feld und — wenn die Config als Code im Repo liegt — als Commit nach
global-git-conventions. So bleibt nachvollziehbar, welche Repo-Version welcher
Agent-Version entspricht.
metadata-Felder fürs Tracking (Vorschlag): version (SemVer-Spiegel), owner,
repo (Quelle der Config), domain / purpose, optional runbook. Reines Tracking —
keine Secrets, keine Logik.
5. MCP-Verdrahtung & Least-Privilege
Leitfrage vor jeder Verdrahtung: Hängt die Eigenschaft, die du kontrollieren willst, am CREDENTIAL/an der VERBINDUNG — oder am einzelnen TOOL-CALL? Daraus folgt, wo die Grenze sitzt:
- Am Call (welches Tool, ob es überhaupt läuft) → in der Config lösen:
enabled: false(Tool weg) oderpermission_policy(Tool gegated, Abschnitt 7). Ein Connector genügt. - Am Credential/an der Verbindung → strukturell trennen: eigener Connector / eigenes Deployment / eigenes Credential / eigenes Environment.
Credential-gebundene Eigenschaften sind mehr als nur „darf kommunizieren": Absender- Identität, Berechtigungs-Scope, Blast-Radius bei Kompromittierung, Rotation/Widerruf, Audit-Zurechenbarkeit, Rate-Limit/Quota, Daten-Mandantentrennung. Sobald eine davon getrennt sein muss, reicht Config nicht — es braucht zwei Verbindungen.
- Telegram = Identität → Sende- und Lese-Bot sind token-gebunden: zwei Bots, zwei Deployments, nicht ein Bot mit gegateten Tools.
- Shopify = Scope → eine Identität genügt, aber Rechte begrenzen über das
read-only-Token (Credential +
enabled), nicht über zwei Stores. - Lexware = read-vs-write-Scope → hängt am Token: über das Credential trennen,
nicht allein über
enabled.
Darauf aufbauend die zeitlosen Server-Regeln:
- MCP pro Agent, nicht global. In
mcp_serversnur die Server eintragen, die dieser Agent wirklich braucht. Einrechnungs-agentbekommtlexware-mcp— nichttelegram-mcp, nichtshopify-mcp. - Jeder Agent nur seine Teilmenge. Die Server-Liste ist Teil der Least-Privilege-Grenze — zusammen mit Vaults (Abschnitt 6) und Permission-Policy (Abschnitt 7).
- Netzwerk muss an sein. MCP- und externe Calls brauchen das in der Environment-Config aktivierte Netzwerk. Default ist: aus.
- Nicht jeder Job braucht MCP. Die Sandbox bringt Bash + Python/Node u.a. mit; einfache Datei-Arbeit (z.B. PDF umbenennen oder komprimieren) erledigt der Agent direkt in der Sandbox, statt dafür einen Custom-MCP zu bauen.
Tool-Oberfläche minimieren — mit enabled: false, nicht mit permission_policy
Default für jedes MCP-Toolset ist die Allowlist: alles aus, nur das Benötigte an.
enabled: false entfernt ein Tool strukturell — es ist für den Agenten weder
auffindbar noch aufrufbar (harte Wand: „weg", nicht „gegated"). Das ist die saubere
Methode, nicht benötigte oder gefährliche Tools loszuwerden; nebenbei spart es
Kontext-Ballast.
Merksatz: Fähigkeit entfernen →
enabled: false. Fähigkeit gaten →permission_policy(Abschnitt 7). Nicht verwechseln. Einealways_ask-Policy lässt das Tool im Modell sichtbar und aufrufbar und pausiert nur davor — sie ist kein Ersatz fürs Entfernen. Wer ein Schreib-Tool gar nicht braucht, gated es nicht, sondern nimmt es weg.
- Allowlist (Standard):
default_config.enabled: false+ pro Toolenabled: true. Nur die freigeschalteten Tools erreichen das Modell. - Denylist (Ausnahme):
default_configweglassen,enabled: falsenur auf einzelne gefährliche Tools. - Präzedenz: per-Tool-
configs>default_config> System-Default.
Mini-Beispiel — von einem schreibmächtigen Server nur die read-only-Abfrage freischalten:
# tools[]: Allowlist auf dem MCP-Toolset — alles aus, nur graphql_query an
- type: mcp_toolset
mcp_server_name: shopify
default_config:
enabled: false
configs:
- name: graphql_query # read-only
enabled: true
(Das YAML-Grundgerüst der Agent-Config steht im Template assets/agent-config.*.yaml —
hier nur das Least-Privilege-Muster, nicht die ganze Config-Mechanik.)
6. Secrets via Vaults
- Nie hardcoden — nicht im System-Prompt, nicht im Skill, nicht in der User-Message.
- Vaults statt Klartext. Bei der Session-Erstellung die passenden
vault_idsübergeben; Anthropic übernimmt den Token-Refresh. - Credential-Isolation pro Agent. Ein Agent erhält nur die
vault_ids, die er für seine Server/Aufgaben braucht — gleiche Logik wie die MCP-Teilmenge. Eintelegram-poster-agentsieht keine Lexware-Credentials. - Konsequenz für Trigger: Weil
vault_idspro Session gesetzt werden, müssen Scheduler und Webhook-Brücke (Abschnitt 8) bei jeder Session die richtigen Vault-IDs mitliefern.
7. Permission-Policies & Human-in-the-Loop
enabled vs. permission_policy — die zentrale Unterscheidung. enabled: false ist
die strukturelle Grenze (Tool weg, Abschnitt 5). permission_policy ist die
Laufzeit-Grenze für Tools, die bleiben:
| Policy | Verhalten |
|---|---|
always_allow | Tool läuft ohne Rückfrage. |
always_ask | Session pausiert vor jedem Aufruf und wartet auf Freigabe. |
Defaults bewusst kennen — sie sind nicht symmetrisch:
- agent_toolset (
agent_toolset_20260401) → Defaultalways_allow. Bash, Write, Edit, web_fetch laufen also ungefragt, sobald das Toolset drin ist. - mcp_toolset → Default
always_ask. Auch neu hinzukommende Tools eines MCP-Servers führen so nichts ungefragt aus. Für einen vertrauten read-only-Server aufalways_allowheben; Schreib-Tools aufalways_asklassen.
Override pro Toolset über default_config.permission_policy, pro Tool über die
configs-Liste — gleiche Präzedenz wie bei enabled (per-Tool > default > System).
Daraus die HITL-Praxis:
- Default bewusst wählen. Für headless Betrieb (Cron, Webhook) ist
always_alloweine echte Entscheidung, kein Selbstläufer: ohne menschliches Gate führt der Agent jeden erlaubten Tool-Call sofort aus. - Lesen vs. Schreiben trennen. Für rein lesende/ableitende Agents ist
always_allowmeist okay. Schreibende oder geldrelevante Aktionen (Lexware-Rechnung finalisieren, Bestellung anlegen, öffentlich posten) brauchen ein Gate. - „Erst vorschlagen, dann schreiben". Sensible Agents zuerst einen Entwurf erzeugen
lassen (Artefakt/Nachricht); der irreversible Schreib-Schritt erfordert eine
Bestätigung — per
permission_policyauf den Schreib-Tools oder durch Aufteilen des Workflows (Agent liefert Entwurf, Mensch löst den Commit aus). Dieses Verhalten zusätzlich im System-Prompt verankern (Abschnitt 3).
Drei-Schichten-Schutz für schreibmächtige MCPs
Bei einem Server, der schreiben oder Geld bewegen kann, staffelt man drei unabhängige Wände — jede hält für sich, und Schicht 2 hält sogar dann, wenn Config oder Modell versagen:
enabled: false(Abschnitt 5) → die Schreib-Fähigkeit existiert nicht für den Agenten. Harte Wand in der Config.- scope-/read-only-Credential im Vault (Abschnitt 6) → der Server lehnt serverseitig ab, selbst bei Fehlverhalten; das Secret sieht die Sandbox nie. Harte Wand unabhängig vom Agentenverhalten — deshalb die belastbarste Schicht.
permission_policy: always_askin der Testphase, späteralways_allow, wenn vertraut. Weiche Wand, Laufzeit-Gate.
Beispiel Shopify: nur graphql_query aktiviert (Schicht 1), read-only-Token im Vault
(Schicht 2), in der Testphase always_ask (Schicht 3). Zum Read-only-Agenten wird er
schon durch Schicht 1+2 — Schicht 3 ist die Sicherung beim Einfahren.
Sonderfall: ein nötiger Write, aber nur ein generisches Mutation-Tool. Manchmal braucht
der Agent genau eine schmale Schreibaktion, der MCP-Server bietet dafür aber nur ein
generisches Tool an (z.B. ein graphql_mutation, das jede Mutation abdeckt, nicht nur
die gewünschte). Dann lässt sich Schicht 1 nicht halten: Du musst das generische Tool
enabled: true setzen und gewährst damit alle Writes, nicht nur den einen. Die tragende
Wand wandert in dem Moment auf Schicht 2 — der Credential-Scope muss aufs Minimum
des tatsächlich nötigen Writes begrenzt werden (server-seitige Ablehnung von allem anderen,
unabhängig vom Agentenverhalten). Besonders brisant, wenn der Agent auf ungeprüftem
Input operiert (OCR aus fremd gelieferten Dateien, eingehende Nachrichten): generisches
Write-Tool + weiter Token-Scope + always_allow = der Input steuert potenziell jeden
erlaubten Write. Sauberste Gegenmaßnahme, wenn du Schicht 1 zurückwillst: ein
Single-Purpose-Custom-MCP, das nur die eine Aktion kann — das generische Tool bleibt
aus. Passt in den *-mcp-Stack und ist strukturell richtig; Credential-Scope ist der
pragmatische Zwischenschritt.
Wo always_ask tatsächlich freigegeben wird. Eine always_ask-Policy pausiert die
Session im Zustand requires_action — wie du freigibst, hängt am Session-Start:
interaktiv gestartet siehst du den Entwurf und bestätigst auf dem Schirm; per
API/Webhook gestartet gibt es keinen Schirm → die Freigabe ist ein API-Call, der
requires_action auflöst (= Job der Webhook-Brücke, Abschnitt 8). Konsequenz: always_ask
für einen headless Agenten setzt einen Freigeber voraus (Brücke oder manueller
API-Aufruf). Ohne ihn stallt die Session am Gate — es erscheint kein Popup. Wer headless
fährt und (noch) keinen API-Freigeber hat, lehnt sich daher auf Schicht 1+2 statt auf
Schicht 3.
8. Trigger-Muster
Zwei Wege, einen Agent zu starten:
A) Cron — Scheduled Deployment (einziger eingebauter autonomer Trigger).
- Cron-Expression + IANA-Timezone, Minutengranularität, Jitter bis 10 s, max. 1000 Deployments/Org.
- DST: Wall-Clock-Matching. Nicht existierende Zeiten (Spring-Forward) feuern nicht, doppelte (Fall-Back) feuern zweimal. Deshalb 01–03 Uhr lokal meiden oder gleich in UTC planen.
- Lifecycle: pause / unpause / archive. Manual-Run-Endpoint zum Testen, ohne auf den Zeitplan zu warten.
B) Webhook-Brücke (für „eingehende Nachricht weckt Agent").
- Es gibt keinen nativen „Message-startet-Agent"-Trigger. Das baut man selbst: ein
Cloudflare Worker nimmt das externe Event entgegen und ruft die Sessions-API —
erst Session create (Agent-ID + Environment-ID +
vault_ids), dannuser.messagesenden. - Zweistufig denken: kein Event = keine Arbeit. Die Brücke liegt auf demselben web-only Stack wie die MCP-Server.
Wahl: planbar/wiederkehrend → Cron. Ereignisgetrieben/extern angestoßen → Webhook-Brücke.
Dispatch bei mehreren Agenten an einer Quelle (Manifest-Muster).
Sobald eine Webhook-Brücke mehr als einen Agent bedient, stellt sich die Routing-Frage: welches Event weckt welchen Agent? Diese Entscheidung gehört in die Brücke, nicht in den Agenten.
- Filtern VOR dem Session-Start, nicht danach. Ein Managed Agent ist rein reaktiv — er
kann sich nicht selbst „nicht zuständig" sagen, ohne vorher geweckt worden zu sein, und
die Session-Kosten fallen beim Wecken an, vor jedem Self-Filtering. Ein Agent, der
ein fremdes Event nur verwirft, hat schon bezahlt. Also entscheidet die Brücke, bevor
sie Session
createruft. - Eine Quelle, eine URL — Topic statt Pfad trennt. Ein Bot / eine Event-Quelle pro
Gruppe bekommt eine Webhook-URL. Die Agenten werden nicht über getrennte URL-Pfade
unterschieden, sondern über das Topic der eingehenden Nachricht (bei Telegram:
message_thread_id). Eine Quelle, ein Endpoint, n Agenten. - Deklaratives Manifest als Single Source. Die Zuordnung Topic → Agent-Key liegt als Manifest im Repo — nicht in KV. Versioniert, im Code-Review sichtbar, kein Live-State zum Pflegen. Ein neuer Agent ist eine Manifest-Zeile, kein Eingriff in die Dispatch-Logik.
- Kein Treffer → ignorieren, fail-closed. Die Auflösung (
resolveTopicRoute-Form) gibt bei fehlendem Manifest-Eintragnullzurück → das Event wird verworfen, ohne Session-Start. Ein unbekanntes Topic kostet damit nichts (vgl. Abschnitt 13). Niemals ein „Default-Agent"-Fallback, der jedes Fremd-Event in eine bezahlte Session zieht.
9. Idempotenz & irreversible Aktionen
Trigger können doppelt feuern: Fall-Back-DST (zweimal), Webhook-Redelivery, Retries. Ohne Schutz heißt das doppelte Rechnung, doppelter Post, doppelte Bestellung.
- Dedup-Schlüssel für jede Schreib-/Geld-Aktion. Vor dem Schreiben prüfen, ob der Schlüssel schon verarbeitet wurde; nur dann handeln.
- Schlüssel aus der fachlichen Identität bilden, nicht aus Zeit/Zufall:
rechnungs-agent→ Auftrags-ID;telegram-poster-agent→ (Channel, Datum, Typ). - Reversibles braucht keinen Dedup. Der Aufwand skaliert mit dem Schaden (Blast Radius).
- Mit Abschnitt 7 kombinieren: Der Entwurf ist idempotent unkritisch — der Commit braucht den Schlüssel.
10. Modellwahl
model wird bei jedem Agent gesetzt — entscheide es bewusst, nicht per Default.
Die Wahl läuft über vier Achsen, die sich nicht ändern, wenn Anthropic neue Modelle
bringt:
| Achse | Frage | Richtung |
|---|---|---|
| Komplexität | Mehrstufiges Reasoning, Tool-Orchestrierung, Code? | komplex → stärker; schematische Transformation → kleiner reicht |
| Kosten × Frequenz | Wie oft feuert der Agent (Abschnitt 8)? | hochfrequent + einfach → klein; selten + komplex → groß vertretbar |
| Autonomie/Risiko | Headless always_allow mit Schreibrechten (Abschnitt 7)? | kein Mensch liest gegen → eher stärker, trotz Kosten |
| Latenz | Wartet ein Auslöser auf Antwort? | Webhook/interaktiv → schnell; Cron nachts → egal |
Relative Tier-Logik statt absoluter Liste. Anthropic staffelt Modelle von „klein/schnell/günstig" bis „groß/fähig/teuer". Mappe die Achsen auf relative Tiers, nicht auf eine festgenagelte Spitze:
- Hochfrequente Cron-Transformation (PDF umbenennen, Zeile ins Sheet) → kleinstes tragfähiges Tier.
- Standard-Agent mit Tool-Arbeit und Urteilsbedarf → mittleres Tier.
- Headless Schreib-/Geld-Agent ohne menschliches Gate → stärkstes in der Beta verfügbares Tier.
Keine harten Modell-IDs hier. Die Tier-Landschaft verschiebt sich aktiv (oberhalb der bisherigen Spitze sind weitere Ebenen entstanden, Zugang teils eingeschränkt), und Managed Agents ist Beta — die erlaubte Modell-Teilmenge kann von der normalen API abweichen. Welche konkrete ID welchem Tier entspricht und welche die Beta zulässt: zum Bauzeitpunkt gegen die Console-Doku prüfen, nicht aus diesem Skill ableiten.
11. Environment-Strategie
Das Environment ist der Laufzeit-Kontext der Sandbox — Netzwerk und Pakete. Es ist keine Sicherheits-/Isolationsgrenze zwischen Agenten: Wer was darf, entscheiden Credential-Scope (Abschnitt 6) und Tool-Config (Abschnitte 5+7), nicht das Environment. Greife fürs Härten also dorthin, nicht ins Environment.
Trennen nach Bedarf, nicht zur Isolation. Environments separiert man nach Paket-/Netzbedarf — zwei Agenten mit denselben Paketen und demselben Netzprofil teilen sich eins; ein Agent mit Sonderpaketen bekommt ein eigenes. Mehr Environments „zur Sicherheit" bringen nichts (die Grenze sitzt woanders) und kosten nur Pflege.
Netzwerk — so eng wie möglich, Default ist aus. Wähle die engste Stufe, die noch trägt:
- Limited statt Full, wenn der Agent kein freies Web braucht. Erlaubte Hosts leer
lassen ist das sichere Minimum — jeder Eintrag weitet den Egress. Hosts nur eintragen,
wenn der Agent eine konkrete externe Domain wirklich braucht (z.B.
web_fetchauf eine feste API). - MCP-Egress nur an, wenn der Agent MCP-Server nutzt. Paketmanager-Egress nur an, wenn Pakete deklariert sind (siehe ungültige Kombi unten).
Pakete deklarieren + pinnen. Was der Agent an Bibliotheken/Tools braucht, gehört in die Environment-Pakete — nicht ins Skill, nicht in den System-Prompt. Versionen pinnen: reproduzierbarer Build, kein stiller Supply-Chain-Wechsel, kostet keine Funktionalität. Liste minimal halten, weil der Paketmanager-Egress eine Angriffsfläche ist, die du bei deklarierten Paketen nicht schließen kannst (siehe unten).
Kein Runtime-Install — harte Regel. Die Umkehrung der Soll-Seite ist verbindlich: Ein
Runtime-Skill oder System-Prompt installiert nie selbst — kein pip install, kein
npm install, kein apt install im Sandbox-Code, auch nicht in einem mitgelieferten
Code-Snippet. Erscheint ein Install-Aufruf im Agenten-Code, ist das immer ein Defekt mit
genau zwei Ursachen: Entweder fehlt das Paket in der Environment-Deklaration → dort
ergänzen (und pinnen), nicht im Code beschaffen. Oder es ist bereits deklariert und der
Aufruf ist redundant → streichen. Ein redundanter Laufzeit-Install ist nicht harmlos: Er
kostet pro Lauf Paketmanager-Egress plus mindestens einen Model-Request (bei
hochfrequenten Cron-Agenten multipliziert sich das), und ein Install ohne Pin holt zur
Laufzeit die neueste Version — also genau den stillen Drift, den das Pinning oben verhindern
soll. Das Environment ist die einzige Wahrheitsquelle fürs Provisioning; ein Paket an
zwei Orten (Env-Liste und Skill-Snippet) driftet auseinander.
Die Trennlinie — was im Skill-Code bleiben darf. Die Regel verbietet das Beschaffen, nicht das Benutzen. Ein Snippet, das ein bereits installiertes Paket nur lokalisiert oder konfiguriert, ist kein Verstoß und gehört in den Skill:
| Im Skill-Code erlaubt | Im Skill-Code verboten |
|---|---|
Importieren (import fitz, import pytesseract) | Das Paket beschaffen (pip / npm / apt install) |
Ein installiertes Paket lokalisieren (z. B. den tessdata-Ordner finden, der deu.traineddata enthält) | Das Sprach-/Datenpaket selbst nachladen, das schon Env-deklariert ist |
Pfade auflösen, Engine konfigurieren (--tessdata-dir) | Provisioning-Schritte in den Lauf verlagern |
Beispiel: Der tessdata_dir()-Finder eines OCR-Skills (sucht den Ordner mit
deu.traineddata und übergibt ihn via --tessdata-dir) ist korrekt und bleibt — er
findet das deklarierte Paket, er installiert es nicht. Ein vorangestelltes
pip install tessdata.fast-deu im selben Snippet ist der Defekt und gehört raus.
Die ungültige Kombi. „Limited + Paketmanager-Egress AUS + deklarierte Pakete" ist ungültig: Das Provisioning braucht Repo-Egress (PyPI/apt), um die Pakete zu ziehen — ohne ihn schlägt der Build fehl. Wer Pakete deklariert, muss den Paketmanager-Egress anlassen. Du sparst also keine Sicherheit, indem du ihn abschaltest; der Hebel ist eine minimale, gepinnte Paketliste, nicht „aus".
Egress-Kopplung durch Tool-Design. Wenn ein Agent per Tool einen externen HTTP-Aufruf auslöst (z. B. curl PUT an eine Upload-URL), entsteht eine Egress-Abhängigkeit, auch wenn der MCP-Server selbst Limited-Egress betreibt. Die URL ist dabei oft dynamisch (Session-spezifisch, host-verifiziert erst zur Laufzeit). Regel: Jeden solchen Host einmalig per isoliertem Testaufruf aus der zurückgegebenen URL ablesen und dann build-time in die Allowed-Hosts-Liste des Environments eintragen — nicht raten, nicht hardcoden im Skill. Erst nach dem Eintrag die Kette scharf stellen.
Beispiel: create_upload_session im google-drive-mcp gibt uploadUrl zurück. Der Agent liest den Hostnamen, Betreiber trägt ihn in die Allowed-Hosts ein, dann erst wird der curl PUT-Schritt verdrahtet.
Environment-Naming. §4 regelt nur Agent-Namen — Umgebungen brauchen ihr eigenes Muster, weil sie nach Profil geteilt werden (oben): Der Name benennt das Profil, nie den Agenten (sonst lügt er, sobald ein zweiter Agent dasselbe Profil mitbenutzt). Muster, kebab-case, lowercase, keine Version im Namen (Umgebungen sind per ID versioniert):
<capability>[-<variante>][-<netz-ausnahme>]
- capability (Pflicht): der Zweck des Paket-/Tool-Profils, nie die Paketliste —
z.B.
ocr-pdf,node-build,headless-chrome;plain, wenn keine Sonderpakete. - variante (optional): nur wenn ein Sub-Detail den Paketsatz selbst ändert (Locale,
Runtime-Version, Toolchain-Variante) — z.B.
ocr-pdf-devs.ocr-pdf-en. - netz-ausnahme (nur die riskante Abweichung):
-open(Full/Unrestricted),-offline(kein Netz). Limited = sicherer Default = stilles Weglassen. Das Sichere schweigt, das Gefährliche wird zum Token.
Was nicht in den Namen kommt: Config-Werte und harmlose Toggles. Maßgeblich die
Egress-Regel — eine Egress-Achse bekommt nur dann ein Token, wenn ihr „An" die
Exfil-/Angriffsfläche spürbar weitet: freies Web ja (-open); MCP-Egress nein
(harmlose Obermenge — erreicht nur die ohnehin selektiv genutzten MCP-Endpoints, macht einen
Nicht-MCP-Agenten nicht unsicherer); Paketmanager-Egress nein (durch „hat Pakete"
impliziert). Auch der Compute-Typ (in der Beta nur Cloud) ist kein Differenzierer. Käme
später eine echte Share-Achse dazu (GPU, Region), wäre die ein neuer optionaler Slot — das
Muster bleibt.
Beispiele: plain · plain-offline · node-build · headless-chrome-open ·
ocr-pdf-de / ocr-pdf-en · data-science.
Environment-Metadaten. Sparsam. Native Config-Felder nicht spiegeln (Netz-Typ und
Pakete stehen schon sichtbar in der Console). Bei kleinem Portfolio meist leer lassen. Der
einzige Eintrag mit eigenständigem Wert wäre ein Reverse-Index consumers (welche
Agenten die Umgebung nutzen — für „wer bricht, wenn ich sie ändere/lösche"); er ist aber
manuell gepflegt und driftet — ein veralteter Eintrag führt in die Irre, also nur mit
Pflege-Disziplin, sonst leer lassen und auf die Agent-Seite verlassen (jeder Agent nennt
seine Env-ID). Keine Logik, keine Secrets.
12. Tool-Datenfluss & Sandbox-Grenze
Grundregel: Bytes nie durch den Kontext routen. Der Modell-Kontext ist kein Datenpuffer für binäre oder große Nutzlasten. Alles, was der Agent als Tool-Argument konstruieren muss, zahlt aus seinem Output-Budget — bei binären oder langen Dateien ist dieses Budget erschöpft, bevor der Inhalt vollständig ist.
Drei Klassen, drei Wege:
| Klasse | Größenordnung | Weg |
|---|---|---|
| Strukturierte Daten / kurze Texte | < ~10 KB | Direkt als Argument (inline) — kein Problem |
| Mittlere Dateien (Textdokumente, kleine JSONs) | 10–100 KB | Abhängig vom Agenten; kritisch prüfen |
| Binäre oder gescannte PDFs, Bilder, Archivdateien | > ~100 KB | Referenz-Pfad zwingend: Tool holt/speichert, Bytes laufen nie durch Kontext |
Referenz-Pfad — Muster:
- Session holen — das Tool initiiert eine Upload-Session serverseitig (Credential bleibt auf MCP-Server-Seite), gibt nur eine kurzlebige URL/Referenz zurück.
- Bytes direkt transportieren — Sandbox führt
curl PUT(oder äquivalent) aus, Bytes fließen direkt zwischen Sandbox und Ziel. Kein Modell-Kontext involviert.
Tool-Kontrakt vor der Verdrahtung prüfen. Bevor ein neues Tool in eine Kette eingebaut wird: Welche Argumente konstruiert der Agent? Welche sind binär/groß? Kann das realistische Payload-Volumen als Argument produziert werden? Ein Tool, das Datei-Bytes inline als base64-Argument erwartet, ist für Dateien > ~100 KB in einer Agenten-Kette nicht einsetzbar — das ist ein Architektur-Mismatch, kein Laufzeit-Fehler.
Fehlerbild, das auf diesen Abschnitt zeigt: Der Agent produziert ein abgeschnittenes oder leeres Argument, versucht alternative Wege (liest andere Credentials, fragt nach Hilfsmitteln, ruft interne Endpunkte ab), oder bricht in einer Schleife ab — ohne dass ein offensichtlicher Fehler im Fachcode liegt.
13. Fail-closed als Default
Headless Agenten ohne menschliches Gate müssen bei Fehler abbrechen, nicht improvisieren.
Warum Improvisation gefährlicher ist als Abbruch: Ein Agent, der bei einem Tool-Fehler weiterläuft und alternative Wege sucht, kann:
- Credentials anderer Tools lesen (Scope-Überschreitung, selbst wenn unbeabsichtigt)
- Interne Infrastruktur erkunden (Metadata-Endpunkte, LAN-Hosts)
- Einen Post absetzen, obwohl eine vorgelagerte Prüfung fehlschlug
- In einer Wiederholungsschleife externe APIs mit Anfragen fluten
Regel — Fail-closed-Verhalten ist kein Konfigurationswunsch, sondern Architektur-Default:
- Jeder Schritt, der eine Voraussetzung für Nachfolgeschritte bildet (Idempotenz-Check, Upload, Daten-Schreiben), ist eine Abbruch-Barriere: schlägt er fehl, folgt kein Nachfolgeschritt.
- Kein stiller Weiter-Lauf. Der Fehler wird mit konkretem Kontext ins Status-Topic geschrieben, der Lauf endet.
- Kein Off-Surface-Verhalten. Schlägt ein Tool fehl, sucht der Agent keine alternativen Wege, die außerhalb der deklarierten Tool-Oberfläche liegen — der System-Prompt muss das explizit verbieten.
Im System-Prompt verankern (Formulierungsvorlage):
Wenn ein Tool-Aufruf fehlschlägt oder ein unerwartetes Ergebnis liefert,
brichst du sofort ab und schreibst einen konkreten Fehler-Status ins Topic.
Du suchst keine alternativen Wege außerhalb deiner Tool-Oberfläche.
Du postest nie öffentlich, wenn ein vorgelagerter Schritt nicht erfolgreich war.
Kombination mit §9 (Idempotenz): Der Dedup-Schlüssel schützt vor Doppel-Ausführung bei Retry — Fail-closed schützt vor Halbzuständen (Post ohne Ablage, Ablage ohne Idempotenz-Eintrag). Beide gemeinsam ergeben eine robuste Kette.
Observability-Tiefe, restliches Kostenmodell (Token-Budgets, Caching), Lifecycle-Details, Anti-Pattern-Katalog.