Evals
blume eval gibt deiner Doku eine Testsuite – ein KI-Agent beantwortet die Fragen deiner Nutzer ausschließlich anhand der Dokumentation, ein Judge bewertet die Antworten, und CI schlägt fehl, wenn die Doku keine Antwort liefert.
blume audit sagt dir, ob Crawler deine Doku finden können. blume eval sagt dir, ob überhaupt jemand sie tatsächlich nutzen kann: Ein KI-Agent liest deine Dokumentation so, wie es eine fremde Person tun würde, und versucht, echte Nutzerfragen damit zu beantworten. Wenn die Doku die Antwort nicht enthält, schlägt der Lauf fehl und nennt die Seite, auf der sie stehen sollte.
blume eval
blume eval 4 question(s) · Claude Code
✔ install-node-version pass 1.00 14.2s $0.14
✔ custom-domain pass 0.92 21.3s $0.19
✖ deploy-vercel fail 0.40 38.9s $0.31
missing: deployment: vercel() from blume/deploy
⊘ search-providers skipped
fix: content/docs/deployment.mdx Docs could not answer: "How do I deploy to Vercel?" — missing: deployment: vercel() from blume/deploy
2 passed · 1 failed · 1 skipped · 1m 42s · $0.64
So funktioniert es
Jede Frage durchläuft zwei Agent-Sessions, und zwar mit einer Agent-CLI, die du bereits installiert hast – standardmäßig Claude Code oder mit --agent codex Codex. Blume speichert keine API-Keys und ruft selbst kein Modell auf. Mit --agent codex laufen beide Sessions außerdem ohne die Shell-, Befehls- und Bild-Tools von Codex und erben keine deiner Umgebungsvariablen.
- Der Reader beantwortet die Frage ausschließlich anhand deiner Dokumentation. Er läuft in einem leeren Verzeichnis mit deaktivierten Datei-, Shell- und Web-Tools und ist mit einem privaten MCP-Server verbunden, der deine Doku bereitstellt – mit denselben
search_docs/get_page-Tools, die ein echter Agent auf deiner deployten Seite verwendet. Er kann dein Repo nicht lesen und erlebt die Doku daher genau wie ein neuer Nutzer: Was nicht dasteht, existiert nicht. - Der Judge bewertet die Antwort anhand der Fakten, die du aufgeführt hast, und hat dabei gar keine Tools. Umschreibungen bestehen; ein fehlender oder widersprochener Fakt fällt durch – genau wie „die Dokumentation sagt dazu nichts“.
Der MCP-Snapshot wird direkt aus deinen Content-Quellen erstellt. Du musst also vorher kein blume build ausführen, und nichts wird irgendwo deployt oder hochgeladen.
Eine Antwort, die die Doku nicht belegen kann, fällt durch, selbst wenn das Vorwissen des Agenten zufällig stimmt – genau darum geht es. Deine Doku ist die einzige Quelle, die du tatsächlich auslieferst.
Evals schreiben
Fragen liegen in evals.yaml im Stammverzeichnis des Projekts. So lässt du einen Agenten aus deiner bestehenden Doku eine erste Datei entwerfen:
blume eval init
Oder schreib sie von Hand:
questions:
- id: install-node-version
question: What is the minimum Node.js version required?
expected:
- Node 22.12 or newer
routes: /docs/quickstart
- id: deploy-vercel
question: How do I deploy to Vercel?
expected:
- run blume build
- "server features need deployment: vercel() from blume/deploy"
routes:
- /docs/deployment
- id: search-providers
question: Which search providers are supported?
expected:
- Orama is the default, with no hosted service
severity: warning # a miss warns instead of failing CI
skip: true # temporarily excluded, reported as skipped
expectedlistet die Fakten auf, die eine korrekte Antwort inhaltlich nennen muss – der Judge akzeptiert Umschreibungen und lehnt Widersprüche ab.routesnennt die Seite(n), die die Frage beantworten sollen. Ein Fehlschlag wird dann im Report der Quelldatei dieser Seite zugeordnet. Passt ein solcher Hinweis zu keiner Seite mehr, bekommst du eine Warnung, statt dass er stillschweigend ignoriert wird.severity: warningbehält eine Frage im Report, ohne CI fehlschlagen zu lassen;skip: truenimmt eine Frage komplett heraus.
Schreib Fragen, die deine Nutzer wirklich stellen – die aus Support-Threads, GitHub-Issues und Onboarding-Calls. Die besten Evals verwandeln ein Versprechen deiner Doku („Deploys ohne Konfiguration“) in eine Frage, die fehlschlägt, sobald ein PR dieses Versprechen bricht.
CI fehlschlagen lassen
Der Exit-Code ist der Vertrag: Jede fehlgeschlagene Frage führt zu einem Exit-Code ungleich null. Wenn der Agent-Lauf selbst fehlschlägt – Reader oder Judge brechen mit einem Fehler ab, statt eine Antwort zu bewerten –, zeigt der Report run failed: an. Er verweist dann auf die Frage in deiner Evals-Datei, statt eine Doku-Seite zum Korrigieren zu nennen, weil die Doku gar nicht bewertet wurde. Wenn du gerade einen Rückstau abarbeitest, lockerst du mit --threshold die Hürde, sodass nur noch ein bestimmter Anteil der Fragen bestehen muss:
blume eval # every question must pass
blume eval --threshold 0.8 # at least 80% must pass
blume eval --json # machine-readable report on stdout
Der JSON-Report hat dieselbe Struktur aus diagnostics + summary wie blume validate --json und blume audit --json und enthält zusätzlich die Ergebnisse pro Frage (Antwort, Score, fehlende Fakten, Kosten).
Da jede Frage zwei Modell-Sessions umfasst, kostet ein Eval-Lauf echtes Geld und Zeit – die Kosten pro Frage werden während des Laufs angezeigt. Ein sinnvolles CI-Setup führt blume eval bei Änderungen an der Doku aus, nicht bei jedem Push.
Befunde beheben
Jeder Fehlschlag nennt die fehlenden Fakten und die Seite, auf der sie stehen sollten. Du kannst den ganzen Report stattdessen auch an den Agenten übergeben:
blume eval --fix
Das schreibt den vollständigen JSON-Report in eine Datei und öffnet den Agenten interaktiv mit einem Prompt, der ihn durch jede fehlgeschlagene Frage führt: die genannte Seite lesen, die fehlenden Fakten im Stil der Seite ergänzen und blume eval erneut ausführen, bis alles besteht. Die Session ist bewusst interaktiv – du prüfst die Änderungen über den Berechtigungsablauf des Agenten selbst. Außerdem wird der Agent angewiesen, niemals Fragen zu löschen oder erwartete Fakten abzuschwächen, nur um auf Grün zu kommen.
Flags
--agent claude|codex– welche Agent-CLI den Reader und den Judge ausführt. Standardmäßigclaude.--file <path>– die Evals-Datei. Standardmäßigevals.yaml.--threshold <0..1>– Mindestanteil bestandener Fragen. Liegt der Anteil darunter, endet der Lauf mit einem Exit-Code ungleich null. Standardmäßig1.--timeout <seconds>– Zeitlimit des Readers pro Frage. Standardmäßig180.--json– gibt den Report als JSON auf stdout aus.--fix– übergibt nach einem fehlgeschlagenen Lauf den Report an den Agenten, der die Doku dann interaktiv korrigiert.--verbose– zeigt unter jedem Fehlschlag die vollständige Antwort des Readers an.