Blog
Tutorials

Custom Skills verfassen: Vorlagen, die sicher bleiben

Die Kompilierung eines Skills zu einem markierten Kontexteintrag: Whitelist, Single-Pass, drei Scope-Ebenen, DLP vor dem Kompilieren und das max_skills-Freemium (3 oder unbegrenzt).

Simmetric Team8 Min. Lesezeit12/10/2026
Custom Skills verfassen: Vorlagen, die sicher bleiben

Aufrufbare Anweisungen, nicht Code, dem man blind vertraut

Ein Custom Skill ist eine wiederverwendbare Prompt-Vorlage: einmal verfasst, wiederholt aus dem Chat als Slash-Befehl aufgerufen. Die Design-Wette steckt in der Formel „Prompt-Vorlage": Ein Skill enthält keine HTTP-Aufrufe, keine Datei-I/O, keine bedingte Logik, keine Sandbox - es gibt nichts zu entkommen, also ist die Funktion dem Konstrukt nach air-gap-safe. Was ein Skill enthält, ist eine feste Kompilierpipeline mit echten Grenzen: gegen ein Schema whitelistete Parameter, genau ein Ersetzungsdurchlauf, Maskierung vor dem Kompilieren, und eine Injektion, die als nicht vertrauenswürdige Daten ankommt.

Dieser Artikel geht den Verfassungsweg von Ende zu Ende durch: wie eine Vorlage geschrieben und kompiliert wird, die Slash-Befehl-Grammatik, die drei Scope-Ebenen, die Privilegiengrenze, die kompilierte Ausgabe ehrlich hält, und die Lizenzform (max_skills - 3 in Community, unbegrenzt in Enterprise).

Die Vorlage und ihre Regeln

Eine Vorlage ist ein einfacher String mit {{param}}-Platzhaltern:

text
Translate to {{targetLang}}: {{input}}

Die Kompilierpipeline erzwingt vier Regeln (im Schema verankert):

  • Whitelist - nur Schlüssel, die der Skill unter inputSchema.properties deklariert (plus seine Default-Parameter), substituieren. Ein unbekannter Platzhalter bleibt literally in der Ausgabe - nie aus der Umgebung, dem Systemkontext oder sonst etwas aufgelöst.
  • Single-Pass - genau ein Ersetzungsdurchlauf läuft. Ein substituierter Wert, der selbst {...}-Markerformen enthält, expandiert nie erneut; der Injektionsversuch über Vorlagen stirbt hier auf Strukturebene.
  • Kohärenz - jeder Platzhalter der Vorlage braucht seinen Eintrag im Input-Schema; create/patch ohne = ein benannter 400.
  • Marker-Abweisung - der statische Text der Vorlage (ohne Platzhalter) darf keine tool-call-Markerformen von Fremdanbietern enthalten; sie werden bei create/patch abgewiesen. Parameterwerte tragen ihre eigene Verteidigung wie unten.

Die Slash-Befehl-Grammatik

Das Tippen von / öffnet die Skill-Palette (Autocomplete); eine gewählte Zeile fügt ihren Slug ein, ohne zu senden. Beim Absenden analysiert der Client die Argumente und schickt den Aufruf samt getippten Nachricht:

  • Positional: /translate Ciao mondo - die Tokens verschmelzen zum ersten Pflichtfeld.
  • Paare: /translate input=Ciao - benannte Füllungen; in Anführungszeichen (input="Ciao mondo") tragen Leerraum.
  • Gemischt und Defaults: input="Ciao" targetLang=Spanish, oder ein Pflichtschlüssel, der seinen deklarierten Default nimmt.

Zwei Verhaltensweisen machen die Grammatik vertrauenswürdig statt listig:

  • Die Never-Error-Regel - ein unbekanntes /wort, ein Builtin-Name oder eine deaktivierte Zeile fällt auf eine normale Nachricht durch: kein Aufruf, kein Fehler, nichts versteckt.
  • Der Server validiert alles nach - unbekannte Schlüssel ignoriert; der Slug wird serverseitig mit demselben Scope-Filter bei jeder Invocation neu aufgelöst (die IDOR-Wache).

Die Liste reservierter Slugs (die festen Chat-Befehle + die Builtin-Skill-Namen) macht Verschattung unmöglich: Ein Custom Skill kann nie einen reservierten Namen nehmen.

Der Anfragepfad: auflösen, maskieren, kompilieren, einpacken

text
"/slug params" → POST chat stream { message, skillCall }
→ resolveInvocableSkill (serverseitig, scope-gefiltert)
→ DLP-Maske VOR dem Kompilieren (Werte gescannt, wenn DLP aktiv ist)
→ compileTemplate (Whitelist-Ersetzung, ein Durchlauf) + der Spotlight-Umschlag
→ EIN markierter Eintrag auf Benutzerebene im Orchestrator

Die DLP-Reihenfolge ist das tragende Detail: Parameter werden vor dem Kompilieren maskiert. In umgekehrter Reihenfolge kompiliert könnte Vorlagentext einen Parameter vor dem Scanner verstecken; mit dieser Ordnung enthält der kompilierte Prompt nur maskierte Werte. (Die DLP-Pipeline selbst - die nummerierten Masken, die verschlüsselten Originale, der Admin-Unmask - ist eine eigene Geschichte.)

Die Privilegiengrenze

Die kompilierte Vorlagenausgabe ist vom Benutzer gelieferte Daten, keine Anweisungen. Sie geht als ein einziger markierter Kontexteintrag in die Konversation - etikettiert, wie jeder andere Tool-Result budgetiert, und durch einen Privilegien-Test verankert: Ein Custom Skill kann Kontext hinzufügen, aber nie Tools, Berechtigungen oder Registry-Einträge. Das Transkript behält die getippte Nachricht; nur der kompilierte Prompt geht als Skill-Kontext hinein.

Deshalb ist „keine Sandbox" eine Eigenschaft und keine Einschränkung: Die Machtfläche der Vorlage - das, was sie beeinflussen kann - ist exakt ein Kontexteintrag, und sonst nichts.

Scoping: drei Ebenen, serverseitig abgeleitet

  • Persönlich - nur der Verfasser löst ihn auf (jeder Nutzer mit der Erstell-Berechtigung).
  • Workspace - jeder, der in diesem Workspace chattet (erstellt von Editor+; ein Viewer bekommt einen expliziten 403). Die persistierte Zeile trägt eine Null-User-ID - eine vom Ersteller gestempelte Zeile würde über Workspaces hinweg auslaufen, und das Schema schließt diese Klasse.
  • Global - alle in der Organisation (nur von Admins erstellt).

Der vom Client beanspruchte Scope gilt nie: Die Betriebsleitung leitet die Ebene aus der persistierten Form ab und filtert die Auflösung pro Chat. Edits und Deletes wirken ab dem nächsten Chat - keine Hooks, keine Neustarts. Delete ist ein weicher Grabstein, und der Slug freist sofort: Der Name eines gelöschten Skills ist sofort neu vergebbar.

Die Freemium-Facts: max_skills

Die Lizenzgrenze spiegelt die anderen numerischen Schranken der Plattform: 3 Custom Skills in Community, unbegrenzt in Enterprise - die Census-Zeile F-SKILL-1, fundiert an den Lizenzkonstanten:

  • Erzwungen nur beim CREATE - Invocations zu schranke würde den Chat mitten drin aus Lizenzgründen unterbrechen - ein verworfenes Design; der Zähler lebt beim Provisioning.
  • Die Zählung ist organisationsweit über Custom-Zeilen - Builtin- und Marketplace-Zeilen zählen nie mit.
  • Über der Grenze benennt die Standard-Paywall-Form die Funktion und die Stufe - und der Ausweg ist Self-Service: Jeder Nutzer kann die eigenen Skills löschen, um Kontingent freizugeben, ohne Admin-Eingriff.

Diese letzte Eigenschaft ist der Freemium-Vertrag, ehrlich gemacht: Die Grenze ist in der Verwaltungsoberfläche sichtbar, der 402 erklärt sich selbst, und der Ausgang kostet kein Support-Ticket.

Weiterlesen

Die Anleitung trägt die vollständige Betriebsreferenz - Endpunkte, den Formular-Dialog, die Test-Preview-Semantik - unter /de/docs/custom-skills:

  • Custom skills - die Anleitung
  • Fakten dieses Beitrags: Zeilen FACT-CENSUS.md F-SKILL-1 (die Custom Skills + das max_skills-Freemium) und F-DLP-1 (die Maskierungsschicht, durch die dieser Pfad reist)

Provenance: Simmetric Chat docs/CUSTOM_SKILLS.md (v0.28.1, Phase 190 SKIL-01..05), packages/shared/src/schemas/skill.schema.ts, license.ts (max_skills) - am vom Census fixierten Dokumentenstand (SHA aca5b8ff).

Ähnliche Artikel