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 Schwierige | Normalerweise | Auf kyrie |
|---|---|---|
| Bei Retry nicht doppelt abbuchen / veröffentlichen | selbstgebaute Idempotenz + Dedupe-Tabellen | ctx.step(...) — läuft genau einmal |
| Einen Absturz mitten im Workflow überstehen | eine Saga / State-Machine + Recovery-Code | der Run setzt beim letzten Schritt fort |
| Stundenlang auf einen Menschen warten | eine Queue + eine „Warte“-Tabelle + ein Resume-Worker | ctx.waitFor(key) → ResolveRun |
| Wackelige HTTP-Aufrufe sicher wiederholen | Backoff + Max-Versuche + Poison-Handling | transiente Schritte wiederholen; Memo behält den Rest |
| Alle X wiederholen, ohne Drift | Cron + Locking + Overlap-Schutz | ein self-rescheduling Run + idempotency_key |
Drei Primitive, jedes am richtigen Ort
| Primitiv | Aufgabe in Beacon | Warum dieses Primitiv |
|---|---|---|
customer.http | den Entwurf holen; den KI-Dienst zum Zusammenfassen aufrufen | die unordentliche Außenwelt — Drittanbieter-/LLM-APIs — und der natürliche Ort, an dem Wackeligkeit auftritt |
customer.wasm | das Markensicherheits-Guardrail: eine kompilierte Policy-Engine | Compliance will ein reproduzierbares, prüfbares, sandboxed Urteil — gleicher Input, gleiche Antwort |
customer.script | Signale zu einem Urteil zusammenführen; dauerhaft veröffentlichen; für die Redaktion pausieren | Orchestrierung 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
| Mechanismus | In Beacon | Liest sich als |
|---|---|---|
| Flow-Kurzschluss | verdict blockiert einen unsicheren Entwurf | „wenn unsicher → Pipeline stoppen“ |
| Event-Trigger | Refresh-Event nur für veraltete Beiträge ausgelöst | „wenn veraltet → die Re-Vet-Journey starten“ |
In-Script-if + ctx.waitFor | review → menschliches Gate; auto → veröffentlichen | „wenn grenzwertig → einen Menschen fragen“ |
Was es beweist
- Nie doppelt veröffentlichen —
ctx.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 Freigabe —
ctx.waitForparkt ohne Kosten;ResolveRunsetzt 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.