Beacon — ein dauerhafter KI-Agent zum Veröffentlichen von Inhalten

Eine Referenzstudie. Ein realistischer Workflow, der die gesamte kyrie-Plattform nutzt: customer.http + customer.wasm + customer.script, ein paralleler Flow, Human-in-the-Loop-Freigabe, Benachrichtigungen und ein wiederkehrender self-rescheduling Job. Jede Garantie unten ist durch 19 Akzeptanzprüfungen gegen die laufende Engine belegt — inklusive eines echten Worker-Absturzes und einer Sandbox-Egress-Probe.

Die Geschichte

Beacon ist ein KI-gestütztes Content-Studio. Ein:e Autor:in — oder ein KI-Agent — reicht einen Entwurf ein. Bevor etwas live geht, muss Beacon ihn auf Markensicherheit prüfen, mit einer KI-Zusammenfassung anreichern, entscheiden, ob automatisch veröffentlicht oder an eine:n menschliche:n Redakteur:in geschickt wird, genau einmal in ein Live-CMS veröffentlichen, die Autor:in benachrichtigen und dann veröffentlichte Beiträge weiter beobachten, um veraltete aufzufrischen — nach Zeitplan, immer wieder.

Das ist ein dauerhafter Workflow: Schritte rufen wackelige Drittanbieter-APIs auf, das Veröffentlichen ist unumkehrbar, die Freigabe kann Stunden dauern, ein Worker kann mitten in der Arbeit abstürzen, und die Freshness-Schleife muss monatelang laufen, ohne zu driften oder doppelt auszulösen. Das selbst zu bauen bedeutet Queues, Retries, Idempotenz-Keys, einen Scheduler, eine State-Machine und eine Datenbank. Auf kyrie sind es vier Task-Definitionen, ein Flow und ~150 Zeilen Geschäftslogik.

Was du ohne kyrie bauen müsstest

Das SchwierigeNormalerweiseAuf kyrie
Bei Retry nicht doppelt abbuchen / veröffentlichenselbstgebaute Idempotenz + Dedupe-Tabellenctx.step(...) — läuft genau einmal
Einen Absturz mitten im Workflow übersteheneine Saga / State-Machine + Recovery-Codeder Run setzt beim letzten Schritt fort
Stundenlang auf einen Menschen warteneine Queue + eine „Warte“-Tabelle + ein Resume-Workerctx.waitFor(key)ResolveRun
Wackelige HTTP-Aufrufe sicher wiederholenBackoff + Max-Versuche + Poison-Handlingtransiente Schritte wiederholen; Memo behält den Rest
Alle X wiederholen, ohne DriftCron + Locking + Overlap-Schutzein self-rescheduling Run + idempotency_key

Drei Primitive, jedes am richtigen Ort

PrimitivAufgabe in BeaconWarum dieses Primitiv
customer.httpden Entwurf holen; den KI-Dienst zum Zusammenfassen aufrufendie unordentliche Außenwelt — Drittanbieter-/LLM-APIs — und der natürliche Ort, an dem Wackeligkeit auftritt
customer.wasmdas Markensicherheits-Guardrail: eine kompilierte Policy-EngineCompliance will ein reproduzierbares, prüfbares, sandboxed Urteil — gleicher Input, gleiche Antwort
customer.scriptSignale zu einem Urteil zusammenführen; dauerhaft veröffentlichen; für die Redaktion pausierenOrchestrierung plus die dauerhaften Garantien

Phase 1 — der automatisierte Prüf-Flow

 trigger: {draft_id}            ┌──────────────────────────────────────────┐
 ────────────────────────────► │  Flow: vet_draft                          │
                               │   fetch  (http GET /drafts/:id)            │
                               │     ├───────────────┬─────────────────────┐│
                               │     ▼               ▼                     ││  parallel
                               │  guardrail        enrich                  ││  ausgeführt
                               │  (wasm)           (http, flaky → retry)   ││
                               │     └───────┬───────┘                      ││
                               │             ▼                              ││
                               │          verdict (script)                  ││
                               │   auto · review · block                    ││
                               │   block ⇒ schließt den Flow kurz           ││
                               │   on_failure ⇒ alert                       ││
                               └────────────────────────────────────────────┘

Ein DAG, der {{trigger.*}} und {{steps.<id>.output.*}} zwischen Schritten verbindet, die Guardrail- und Enrich-Schritte parallel ausführt, bei einem unsicheren Entwurf kurzschließt und bei einem Fehler zu einer Benachrichtigung verzweigt.

Phase 2 — das dauerhafte Veröffentlichen

Die menschliche Freigabe lebt in einem eigenständigen, dauerhaften Script-Run — er parkt im Zustand WAITING und setzt fort, wenn eine Redakteur:in entscheidet. Das Veröffentlichen ist in ctx.step gekapselt, sodass es genau einmal passiert — selbst über einen Absturz, Retry oder Resume hinweg.

export default async (input, ctx) => {
  if (input.decision === "review") {
    const review = await ctx.waitFor("editor");      // parkt stundenlang, ohne Kosten
    if (!review.approve) {
      await ctx.step("notify-changes", () => notify(input.draft_id));
      return { published: false };
    }
  }
  // idempotent: läuft einmal, auch bei Resume oder Retry
  const post = await ctx.step("publish", () => cms.publish(input.draft_id));
  return { published: true, post_id: post.id };
};

Der Clou — ein wiederkehrender Freshness-Monitor

kyrie hat kein Cron-Primitiv; du baust Wiederholung aus einem self-rescheduling Run. Der Monitor prüft auf veraltete Beiträge, löst bedingt ein Refresh-Event aus und plant dann seinen eigenen Nachfolger, indem er kyries API aufruft — Continue-as-new, mit idempotentem Re-Arm, sodass ein wiederholter Tick nie zwei plant.

        ┌──────────────────────────────────────────────────────────┐
  tick →│  monitor (script, scheduled)                              │
        │   1. GET /cms/stale-check                                  │
        │   2. wenn veraltet → PublishEvent("draft.refresh_due") ─┐  │
        │   3. sich selbst neu planen: CreateRun(in_seconds, tick+1) │
        └──────────────────────────────────────────────────────────┼─┘
                 ▲                                                  │ trigger
                 └──── nächster Tick ◄───────── Re-Vet-Flow ◄───────┘

Ein veralteter Beitrag läuft zurück durch Phase 1; ein frischer Beitrag bleibt unangetastet.

Bedingte Verzweigung — drei Varianten

MechanismusIn BeaconLiest sich als
Flow-Kurzschlussverdict blockiert einen unsicheren Entwurf„wenn unsicher → Pipeline stoppen“
Event-TriggerRefresh-Event nur für veraltete Beiträge ausgelöst„wenn veraltet → die Re-Vet-Journey starten“
In-Script-if + ctx.waitForreview → menschliches Gate; auto → veröffentlichen„wenn grenzwertig → einen Menschen fragen“

Was es beweist

  • Nie doppelt veröffentlichenctx.step-Memoisierung; genau einmal auch bei erneutem Absenden.
  • Übersteht Abstürze — die Suite killt den Worker-Prozess mitten im Run; der Run setzt aus seinem dauerhaften Memo fort und veröffentlicht nie erneut.
  • Stundenlange menschliche Freigabectx.waitFor parkt ohne Kosten; ResolveRun setzt fort.
  • Sichere wackelige Integrationen — transiente Retries ohne Verlust bereits erledigter Arbeit.
  • Wiederkehrende Jobs, keine Cron-Infrastruktur — self-rescheduling Runs, dedupe-sicher.
  • Führt fremden Code sicher aus — ein Script beweist, dass es nur seine deklarierten allow_net-Hosts erreichen kann; alles andere wird abgelehnt.

Jede Zeile oben wird von der Beacon-Akzeptanz-Suite geprüft — 19 von 19 bestehen gegen die laufende Engine: der Prüf-Flow, das menschlich freigegebene Veröffentlichen, der wiederkehrende Monitor, ein echter Worker-Absturz und eine Sandbox-Egress-Probe.


Bereit, deinen eigenen zu bauen? Die kyrie-App öffnen.