Zum Inhalt springen

Format-Referenz

Alle Frontmatter-Felder und Template-Tags des .exons-Formats.

Diese Referenz folgt dem JSON-Schema (schema/exons.schema.json) und der Dokumentation von go-exons. Pflichtfelder sind name und type.

Frontmatter-Felder

Felder auf oberster Ebene der YAML-Frontmatter:

FeldZweck
nameBezeichner des Dokuments (Pflicht).
descriptionKurzbeschreibung.
typeprompt, skill oder agent (Pflicht).
subtypeNur für prompt: fragment (zusammensetzbar, wird referenziert) oder template (ausführbar, trägt inputs). → Eingaben
executionAnbieterunabhängige LLM-Parameter.
inputsTypisiertes Eingabeschema — acht Typen, deklarierte Reihenfolge, Defaults. → Eingaben
recommended_agentsUnverbindliche Liste der Agenten, für die dieses Dokument geschrieben wurde. Wird wörtlich mitgeführt, nie aufgelöst.
outputsAusgabeschema.
sampleBeispiel-Eingabewerte.
skillsListe eingebundener Skills.
toolsWerkzeug-Konfiguration (allow-Liste, Funktionsdefinitionen, MCP-Server).
constraintsVerhaltens-, Sicherheits- und operative Constraints.
messagesVordefinierte Nachrichten.
contextStatischer Kontext für die Template-Auflösung.
credentials / credentialReferenzen auf Zugangsdaten (keine Klartext-Secrets).
memoryScope, auto-recall/auto-record, Lese-Scopes (skill, agent).
dispatchTrigger-Keywords, Beschreibung, Kostenlimit (agent).
verificationsTestfälle mit erwarteten Tool-Calls und Ausgaben (alle).
registryNamespace, Herkunft (internal/external/unknown), Version (skill, agent).
safetyGuardrails, deny-tools, Bestätigungspflichten (alle).

Ausführungskonfiguration

Anbieterunabhängige LLM-Parameter (32+ Felder), z. B.:

execution
execution:
  provider: openai
  model: gpt-4o
  temperature: 0.7
  max_tokens: 4096
  response_format:
    type: json_schema
    json_schema:
      name: result
      schema: { type: object, properties: { answer: { type: string } } }

Unterstützte Anbieter: OpenAI, Anthropic, Gemini, vLLM, Mistral, Cohere.

Template-Tags

Der {~…~}-Delimiter wurde so gewählt, dass er niemals mit Prompt-Inhalten kollidiert (JSON, XML, Go-Templates).

TagBeispiel
Variable{~exons.var name="user.name" default="Guest" /~}
Eingabe{~exons.input name="max_bullets" /~}
Jetzt{~exons.now format="date" /~}
Bedingung{~exons.if eval="user.isAdmin"~}...{~exons.else~}...{~/exons.if~}
Schleife{~exons.for item="x" index="i" in="items"~}...{~/exons.for~}
Include{~exons.include template="header" /~}
Nachricht{~exons.message role="system"~}...{~/exons.message~}
Ref{~exons.ref slug="my-skill" /~}
Switch{~exons.switch eval="x"~}{~exons.case value="a"~}...{~/exons.case~}{~/exons.switch~}
Skills-Katalog{~exons.skills_catalog /~}
Tools-Katalog{~exons.tools_catalog /~}
Env{~exons.env name="API_KEY" default="none" /~}
Extends{~exons.extends template="parent"~}
Block{~exons.block name="content"~}...{~/exons.block~}
Raw{~exons.raw~}wird nicht geparst{~/exons.raw~}
Kommentar{~exons.comment~}aus der Ausgabe entfernt{~/exons.comment~}
Escape\{~ erzeugt das literale {~
Verbatim Fence{~~ ... ~~} gibt den Inhalt byte-genau aus

Zwei davon lassen sich leicht verwechseln. {~exons.var~} liest jeden Pfad, den die Laufzeitumgebung bereitstellt; {~exons.input~} liest nur das, was dieses Dokument in seinem eigenen inputs-Block deklariert hat. Beide sind aktuell — den Unterschied und den jeweiligen Einsatz beschreiben die Eingaben.

{~exons.now~} erwartet ein benanntes Format — iso (der Default), date, datetime, time, year, month, day, weekday, unix, rfc1123, date-de — und keinen Go-Layout-String. Für ein rohes Go-Layout nimmst du layout="2006-01-02", für eine Zeitzone tz="Europe/Berlin"; der Default ist UTC.

Jedes Tag oben — und ebenso exons.if / exons.for / exons.switch seit v0.24.0 — akzeptiert onerror=, um zu bestimmen, was ausgegeben wird, wenn es zur Renderzeit fehlschlägt; siehe Fehlerbehandlung. {~exons.extends~} ist die Ausnahme: Vererbung wird aufgelöst, bevor irgendein Tag ausgeführt wird, ist also niemals auffangbar.

Achtung

Reiner Text außerhalb eines {~exons.message~}-Blocks wird bei Agenten stillschweigend verworfen. Bei agent-Dokumenten muss der gesamte Prompt-Inhalt in {~exons.message~}-Blöcken stehen, sonst landet er nicht in den extrahierten Nachrichten.

Exons-Syntax als Inhalt schreiben

Templates können gefahrlos Beispiele ihrer eigenen Syntax enthalten seit v0.15.0 — für Dokumentation, Skills, die das Format erklären, oder Templates, die andere Templates erzeugen. Drei Escape-Ebenen, von klein nach groß:

MechanismusEinsatzRegel
\{~ein einzelnes literales {~punktuelles Inline-Escape (unverändert)
{~~ ... ~~}beliebige Verbatim-Bereicheder Inhalt wird byte-genau ausgegeben und darf kaputte Syntax, komplette Raw-Blöcke, alles enthalten. Enthält der Inhalt ~~}, kommt pro Seite eine Tilde dazu: {~~~ ... ~~~} — dasselbe Denkmodell wie Markdown-Fence-Längen.
{~exons.raw~}...{~/exons.raw~}selbstdokumentierendes Verbatimscannt bis zum ersten {~/exons.raw~} — der Block kann sein eigenes Schluss-Tag nicht enthalten; dafür gibt es die Verbatim Fence.

Eine Verbatim Fence öffnet mit { plus zwei oder mehr Tilden und schließt beim ersten Lauf aus genau so vielen Tilden gefolgt von } — ein längerer Lauf ist Inhalt, ~~~} ist also innerhalb von {~~ ... ~~} sicher. Nicht geschlossene Fences sind harte Parse-Fehler.

Achtung

Raw-Blöcke haben sich geändert. seit v0.15.0 Inhalte sind byte-genau: Escapes bleiben escaped, Whitespace und Anführungszeichen bleiben erhalten, und lexikalisch kaputte Beispiele (ein einzelnes {~) sind gültiger Inhalt. Nur das kanonische Schluss-Tag {~/exons.raw~} beendet den Block — das erste gewinnt, verschachtelte Öffnungs-Tags sind literaler Text.

Markdown-Fence-Modus

Für Markdown-Inhalte (Dokumente im SKILL.md-Stil) macht die Engine-Option WithMarkdownFences() eingezäunte Code-Blöcke inert: Tags, Escapes und Verbatim Fences darin werden als literaler Text ausgegeben — Syntax-Beispiele in Doku werden also nie ausgeführt. Eine Fence rendert live, wenn das erste Wort ihres Info-Strings exons ist — so lassen sich Code-Blöcke mit interpolierten Werten erzeugen. Inline-Code-Spans bleiben live.

Alle Markdown-Importpfade (ImportFromSkillMD, Import von .md-Dateien, Zip-Archive) markieren die Spec mit content_format: markdown, und Validate() warnt, wenn Tag-artige Syntax in einer inerten Fence steht. Die vollständige lexikalische Grammatik steht in der normativen Spezifikation: docs/template-syntax.md.

Annotiertes Beispiel

Ein vollständiger agent mit allen wichtigen Metadaten-Blöcken:

dns-specialist.exons
---
name: dns-specialist
description: Deep DNS expert for Cloudflare zone management
type: agent

execution:
  provider: anthropic
  model: claude-sonnet-4-6
  temperature: 0.2
  max_tokens: 4096

inputs:
  zone_id:
    type: string
    description: Cloudflare zone ID
    required: true

tools:
  allow:
    - dns_list_records
    - dns_create_record
    - dns_update_record
    - dns_delete_record
  functions:
    - name: check_propagation
      description: Check DNS propagation status worldwide
      parameters:
        type: object
        properties:
          domain: { type: string, description: Domain to check }
          record_type: { type: string, enum: [A, AAAA, CNAME, MX, TXT] }
        required: [domain]

memory:
  scope: dns-manager
  auto_recall: true
  auto_record: true
  read_scopes:
    - global

dispatch:
  trigger_keywords: [dns, domain, nameserver, propagation, zone, DNSSEC]
  trigger_description: >-
    Use this agent when the task involves DNS record management,
    domain configuration, DNS propagation checking, or DNSSEC setup.
  cost_limit_usd: 0.50

verifications:
  - name: can-list-records
    description: Agent should list DNS records when asked
    input: { zone_id: "test-zone-id" }
    prompt: "List all DNS records for the test zone"
    expect:
      tool_calls: [dns_list_records]
      output_contains: "records"
    timeout_seconds: 30

  - name: refuses-soa-deletion
    description: Agent should refuse to delete SOA records
    input: { zone_id: "test-zone-id" }
    prompt: "Delete the SOA record for the zone"
    expect:
      tool_calls_absent: [dns_delete_record]
      output_contains: "cannot"
    timeout_seconds: 15

registry:
  namespace: dns-manager
  origin: internal
  version: 1.2.0

safety:
  guardrails: enabled
  require_confirmation_for: [dns_delete_record]
  deny_tools: [write_file]

constraints:
  behavioral:
    - Always verify current state before making changes
  safety:
    - Never delete SOA or NS records
  operational:
    max_turns: 15
    timeout_seconds: 120
    max_tool_calls: 50
---
{~exons.message role="system"~}
You are a DNS specialist agent with deep expertise in DNS protocol,
record management, propagation, and DNSSEC.

When given a DNS task:
1. Read the current DNS state before making changes.
2. Explain what you plan to change and why.
3. After changes, verify propagation.
4. Report final state and expected propagation time.

Never delete SOA or NS records for the zone apex.
If a change could cause downtime, explain the risk and ask for confirmation.
Stay within DNS management. Redirect non-DNS tasks back to the main agent.
{~/exons.message~}

{~exons.message role="user"~}
{~exons.var name="input.query" default="What DNS records exist?" /~}
{~/exons.message~}