Skip to content

Latest commit

 

History

History
292 lines (212 loc) · 27.4 KB

File metadata and controls

292 lines (212 loc) · 27.4 KB
Bernstein
Bernstein - the open-source governance layer for AI agents

"To achieve great things, two things are needed: a plan and not quite enough time." - attributed to Leonard Bernstein

die Open-Source-Governance-Schicht für KI-Agenten

CI PyPI GHCR Python 3.12+ License OpenSSF Scorecard CodeQL Open in Codespaces MCP Toplist Ask DeepWiki

website · docs · install · first run · glossary · limitations · name policy · sponsor

简体中文 · 繁體中文 · 日本語 · 한국어 · हिन्दी · বাংলা · Русский · Español · Português · Deutsch · Français · Italiano · Nederlands · Polski · Svenska · Suomi · Українська · Türkçe · العربية · עברית · Bahasa Indonesia · Tiếng Việt · ไทย


Status: Beta. Von einer Einzelperson gepflegt, in aktiver Entwicklung. Die Versionsnummer zählt Releases, nicht Reife – Minor-Versionen können Schnittstellen ändern. Versionen für produktive Abhängigkeiten fixieren; Regressionen werden zügig behoben, Fehler bitte melden.

Bernstein ist die Open-Source-Governance-Schicht für KI-Agenten. Es läuft auf policy as code: Du schreibst die Policy - wer was tun darf, was eine Freigabe braucht, was protokolliert werden muss -, und Bernstein setzt sie durch und erzeugt den verifizierbaren Nachweis. Ein deterministischer Scheduler - kein Modell in der Koordinationsschleife - führt Agenten parallel aus, prüft ihre Ergebnisse an Gates und protokolliert jeden Schritt, sodass sich ein Lauf im Nachhinein verifizieren lässt: offline, allein aus den Artefakten. CLI-Coding-Agenten laufen ab Werk (Claude Code, Codex, Gemini CLI und 40+ weitere), und dieselbe Schicht governt jede Agenten-Workload: das Ergebnis kann ein Diff sein, ein Forschungsbericht, ein Datensatz oder ein Audit-Evidence-Pack. Air-Gap-Installationsprofil inklusive. Apache-2.0.

auf einen Blick

Vier Eigenschaften zeichnen es aus; alles Weitere sind Details.

  • Kein LLM in der Koordinationsschleife. Das Scheduling ist reines Python, wodurch ein Durchlauf durchgängig reproduzierbar ist. Gestern geplanten Ablauf erneut abspielen und exakt denselben Task-Graphen erhalten.
  • Nachträglich überprüfbar. Das Replay-Journal zeichnet jeden Lauf auf, und das durchgehend aktive Lineage-Rückgrat registriert jeden schrittweisen Herkunftsnachweis; das optionale HMAC-verkettete Audit-Log (BERNSTEIN_AUDIT=1) ergänzt Belege (Receipts), die offline verifiziert werden können. Nichtdeterminismus zeigt sich als Hash-Abweichung am exakten Einzelschritt statt als sporadischer Testfehler. Nicht-Code-Ergebnisse erhalten dieselbe Behandlung: Ein Task kann einen Artefakt-Vertrag (Report, Datensatz, Aktionsprotokoll, Ops-Ergebnis) definieren und schließt mit einem signierten Lineage-Receipt statt einem Git-Commit ab.
  • Von Grund auf isoliert. Jeder Programmier-Task erhält ein eigenes Git-Worktree hinter Merge-Gates; Artefakt-Modus-Tasks erhalten ein Arbeitsverzeichnis unter .sdd/workspaces/. Agenten teilen standardmäßig keinen veränderlichen Workspace; der einzige gemeinsame Zustand ist das Task-Backlog, das atomar beansprucht wird. Strengere Dateisystembeschränkungen sind optional über Sandbox-Backends verfügbar. Werden Worktrees deaktiviert, läuft jeder Task im geteilten Checkout.
  • Umfassend und lokal. Über 40 CLI-Agenten-Adapter plus ein generischer --prompt-Wrapper, dateibasierter Zustand, kein SaaS-Umweg, keine externe Datenebene.

Die vollständige Liste befindet sich auf der Funktionsübersicht; die Feature-Matrix bietet den vollständigen Index.

wie ein Lauf aussieht

Eine einzige YAML-Datei deklariert den Lauf: Phasen, Rollen, Abhängigkeiten und die Bedingungen, unter denen ein Knoten überhaupt läuft. Der Scheduler führt sie als reines Python aus - nichts in der Datei ist ein Prompt, und kein Modell entscheidet, was als Nächstes passiert. Dieser Graph erzeugt ein Audit-Evidence-Pack; die vollständige Datei liegt unter .bernstein/workflows/audit-evidence-pack.yaml.

name: audit-evidence-pack
version: "1.0.0"

phases:
  - name: scope
    allowed_roles: [manager, architect]
  - name: collect
  - name: validate
    allowed_roles: [qa, security]
  - name: deliver
    allowed_roles: [security, manager]

nodes:
  define-control-inventory:
    phase: scope
    role: architect

  collect-audit-logs:
    phase: collect
    role: security
    depends_on: [define-control-inventory]

  # three more evidence streams collect in parallel:
  # collect-sboms-and-attestations, collect-runbooks-and-policies,
  # collect-eval-results

  assemble-pack:
    phase: validate
    role: docs
    depends_on:
      - collect-audit-logs
      - collect-sboms-and-attestations
      - collect-runbooks-and-policies
      - collect-eval-results

  mock-auditor-pass:
    phase: validate
    role: qa
    depends_on: [assemble-pack]

  remediate-findings:
    phase: collect
    role: docs
    depends_on:
      - source: mock-auditor-pass
        condition: "status == 'failed'"
    retry:
      max_attempts: 3
      until: "status == 'done'"

  sign-and-deliver:
    phase: deliver
    role: security
    depends_on:
      - source: mock-auditor-pass
        condition: "status == 'done'"
flowchart LR
    inv[define-control-inventory] --> logs[collect-audit-logs]
    inv --> sbom[collect-sboms-and-attestations]
    inv --> rb[collect-runbooks-and-policies]
    inv --> ev[collect-eval-results]
    logs --> pack[assemble-pack]
    sbom --> pack
    rb --> pack
    ev --> pack
    pack --> gate{mock-auditor-pass}
    gate -->|failed| fix["remediate-findings (retry x3)"]
    gate -->|done| sign[sign-and-deliver]
Loading

Jeden Knoten übernimmt ein Agent, dessen Rolle die Phase zulässt; Rollenzäune und Freigabe-Gates halten, egal was der Agent innerhalb der Aufgabe tut. Ein Code-Knoten endet hinter Merge-Gates im eigenen git worktree. Die Knoten oben enden anders: ein Artefaktvertrag benennt das Ergebnis (Bericht, Datensatz, Scan, Aktionslog), und der Knoten schließt mit einer signierten Lineage-Quittung statt eines Commits. Derselbe Scheduler, dasselbe Journal, dieselbe Offline-Verifikation - ob der Graph Code, Forschung, eine Ops-Änderung oder eine Mischung aus allen dreien liefert. Fertige Graphen für Software, Forschung, Doku, Enterprise und Contributor-Workflows liegen in .bernstein/scenarios/.

in 30 Sekunden installieren

uv tool install bernstein    # or: pipx install bernstein
bernstein init
bernstein doctor             # checks a CLI agent is installed and authenticated
bernstein -g "fix the failing test in tests/test_foo.py"

pipx, pip, brew, dnf, npm und Docker werden in der Installationsanleitung behandelt; das Air-Gap-Wheelhouse verfügt über einen eigenen Air-Gap-Leitfaden.

A real bernstein demo run: mock agents fix four seeded bugs, ending on the run's signed receipt verifying offline

Die obige Aufnahme zeigt einen realen Durchlauf und bringt ihren eigenen Nachweis mit. Die Aufzeichnung, der aus dem Journal dieses Laufs abgeleitete signierte Run-Receipt und der zugehörige öffentliche Schlüssel liegen in docs/assets/demo-run/. Verifizieren Sie den soeben gesehenen Durchlauf offline:

bernstein verify receipt docs/assets/demo-run/run-receipt.json \
    --public-key docs/assets/demo-run/run-receipt.pub.pem

Die CI prüft den committeten Receipt bei jedem Push auf main erneut – und belegt, dass manipulierte Kopien fehlschlagen –, damit publizierte Nachweise nicht zu dekorativen Dateien verkommen. scripts/record_demo.sh regeneriert Aufnahme, Receipt und Schlüssel aus einem frischen realen Durchlauf; im Terminal wird nichts synthetisiert.

Ein laufender Durchlauf kann über beide Bedienoberflächen beobachtet werden. Beide lesen dieselbe Task-API, sodass keine Oberfläche ein verzögertes Abbild der anderen ist. In bernstein live scrollen linke und rechte Spalte unabhängig als vollständige Bereiche, sodass Steuerelemente auch in kleineren Terminals erreichbar bleiben.

A two-column terminal dashboard - agents with their live logs on the left, the task board on the right - with a full-width activity feed and a cost line underneath A browser dashboard listing sixty-two tasks with eleven running, one of them opened to its working-tree diff
bernstein live — das Terminal-Dashboard bernstein gui serve — das Browser-Dashboard

einen Durchlauf nachweisen

Determinismus ist hier etwas, das Sie überprüfen, statt darauf zu vertrauen. Einmal mit aktiviertem Audit ausführen und die Aufzeichnungen verifizieren:

BERNSTEIN_AUDIT=1 bernstein -g "fix the failing test in tests/test_foo.py"
bernstein replay list                 # run ids recorded on disk
bernstein replay latest --verify      # recompute the journal head, name the first divergent step
bernstein lineage verify <run_id>     # recompute the always-on lineage spine
bernstein audit verify                # HMAC chain + Merkle seal (written because audit was enabled)
bernstein audit diagnose <run_id> --signal gate --sign-key KEY
                                      # name the exact step a failure entered the run, as a signed receipt
bernstein verify run <run_id> --signing-key-path key.pem   # sign one portable run receipt
bernstein verify receipt .sdd/runs/<run_id>/run-receipt.json  # verify it offline: file only

Das Journal wird bei jedem Lauf geschrieben; das Lineage-Rückgrat ist immer aktiv und erhält für jeden Schritt einen Eintrag, sodass ein kurzer Lauf mit einem gültigen, leeren Rückgrat enden kann. bernstein audit verify hat nur dann eine Kette zu prüfen, wenn der Lauf mit BERNSTEIN_AUDIT=1, einem Compliance-Preset oder bernstein run --audit gestartet wurde. Das Flag --audit gehört zu bernstein run; bei der obigen bernstein -g-Form setzen Sie die Umgebungsvariable.

Ein Run-Receipt bindet den Journal-Head, den Lineage-Head (sofern Einträge geschrieben wurden) und optional einen Audit-Kettenbereich unter einem einzigen Ed25519-signierten Subjekt mit eingebettetem öffentlichem Schlüssel. Ein Prüfer mit dieser Datei und dem öffentlichen Schlüssel des Betreibers kann bestätigen, dass Aktionen und Ketten unverändert sind: kein HMAC-Schlüssel, kein aktives .sdd/, und Exit-Code 2 mit Nennung des ersten abweichenden Schritts bei Manipulation. Dieser Receipt identifiziert den eingebetteten Journal-Zustand; um zu belegen, dass dieser Zustand dem vollständigen Journal entspricht, ist zusätzlich ein unabhängiges Head/Count-Siegel erforderlich. Mit der Datei allein ohne --public-key-Bindung dient die Prüfung nur der Integrität – sie belegt interne Konsistenz, nicht den Aussteller. Details unter deterministisches Replay.

Dieselbe Prüfbarkeit gilt für Evaluierungsmetriken. bernstein bench run <suite> --reliability k (auch bernstein eval --reliability k) führt jede Aufgabe k-mal unter fester Koordination aus und berichtet die Untergrenze pass^k (alle k Versuche müssen bestehen) neben der Obergrenze pass@1. Dieses Ergebnis wird in einem signierten Beleg versiegelt, den bernstein bench reliability-verify offline nachrechnet, sodass fingierte Werte die Verifikation nicht bestehen. Details: pass^k Zuverlässigkeits-Untergrenze.

wie es funktioniert

Jedes Ziel durchläuft vier Phasen:

  1. Zerlegen (Decompose). Der Manager teilt Ihr Ziel in Aufgaben mit Rollen, zugewiesenen Dateien und Abschlusskriterien auf. Ein LLM-Aufruf, danach reines Python.
  2. Starten (Spawn). Agenten starten in isolierten Git-Worktrees, einer pro Coding-Task; Artefakt-Tasks erhalten ein reguläres Arbeitsverzeichnis. Der Hauptbranch bleibt sauber.
  3. Verifizieren (Verify). Der Janitor prüft handfeste Kriterien: Tests erfolgreich, Dateien vorhanden, Linting fehlerfrei, Typen korrekt.
  4. Zusammenführen (Merge). Verifizierte Änderungen gelangen in den Main-Branch. Fehlgeschlagene Tasks werden wiederholt oder an ein anderes Modell übergeben.

Warum der Scheduler in reinem Python geschrieben ist und welche Vor- und Nachteile das bringt: Warum deterministisch.

alltägliche Befehle

cd your-project
bernstein init                    # creates .sdd/ workspace, bernstein.yaml + templates/
bernstein -g "Add rate limiting"  # agents spawn, work in parallel, verify, exit
bernstein live                    # watch progress in the TUI dashboard
bernstein run plan.yaml           # multi-stage plan: skip LLM planning, execute directly
bernstein stop                    # graceful shutdown with drain

Die vollständige Bedienoberfläche (PR-Automatisierung, Zeitpläne, Chat-Bridges, Autofix-Daemon) ist unter Operator-Befehle beschrieben.

bernstein workflow führt deklarative YAML-DAGs aus, die aus Agenten-, Befehls- und Schleifenknoten bestehen - mit Unterstützung für die Wiederaufnahme unterbrochener Läufe:

bernstein workflow run idea-to-pr -g "Add JWT auth"   # prints run_id
bernstein workflow resume <run_id>                    # picks up at the first non-completed node

Der Laufzustand wird bei jedem Knoten als Checkpoint unter .sdd/runs/<run_id>/ gesichert. Die Wiederaufnahme validiert den Manifest-Digest beim Start des Laufs, sodass eine geänderte Spezifikation abgelehnt wird, anstatt stillschweigend ein anderes Manifest auszuführen. Siehe Workflow-Manifeste.

Repository-Hygieneprüfungen: bernstein readme-l10n verify lässt PRs fehlschlagen, deren übersetzte READMEs von der englischen Quelle abweichen (mit Nennung des veralteten Abschnitts), bernstein readme-l10n sync aktualisiert die Bindungen nach englischen Änderungen. Siehe readme-l10n.

unterstützte Agenten

Claude Code, Codex CLI, Gemini CLI, GitHub Copilot CLI, Cursor, Aider, Goose, Muse Code, OpenAI Agents SDK, Amp, Cody, Continue, Devin Terminal, Junie, Kilo, Kiro, AWS Q Developer, Ollama, OpenCode, OpenHands, Open Interpreter, gptme, Plandex, AIChat, Letta Code, Qwen und mehr. Der Adapter-Index enthält Installationsbefehle für 30 davon. bernstein integrations list führt alle 54 angebundenen Integrationen aus src/bernstein/adapters/registry.py auf, der zentralen Quelle der Wahrheit. 52 davon sind wählbare Agentenadapter; die beiden anderen Zeilen sind der Test-Stub mock und das Endpunkt-Profil self-hosted-endpoints. Jedes andere Werkzeug mit --prompt-Flag funktioniert über den generischen Wrapper.

Kombinieren Sie Agenten im selben Lauf: Günstige lokale Modelle für Boilerplate-Code, leistungsfähigere Cloud-Modelle für Architekturfragen. bernstein integrations list --installed zeigt verfügbare Installationen auf Ihrem System.

freiwillige rechenleistung

Ein Projekt kann Issues als offen für Freiwillige markieren, und jeder kann eines davon auf der eigenen Maschine ausführen - ohne Konto und ohne Koordinator. Was eine Aufgabe tun darf, erklärt das Projekt in einem volunteer.json-Manifest - Sandbox-Backend, erlaubte Netzwerkziele, Obergrenzen für Laufzeit und Speicher - und die eigenen Limits des Spenders können das nur enger ziehen, niemals weiter. Die Quittung einer abgeschlossenen Aufgabe bindet das Ergebnis an die Isolationsentscheidung, unter der es entstanden ist, sodass ein Maintainer noch Monate später prüfen kann, worauf die Arbeit tatsächlich zugreifen durfte.

bernstein volunteer verify .
bernstein volunteer browse --budget 60

Der Spenderleitfaden behandelt den Betrieb eines Workers und das Budget, das Sie setzen, der Projektleitfaden das Deklarieren eines Manifests, und das Bedrohungsmodell beschreibt, wovor jede Grenze schützt und wovor nicht. Der Runner mit einem einzigen Befehl ist noch nicht veröffentlicht: Heute sind verify, browse und hub die funktionierenden Unterbefehle.

hinter den Kulissen

Alle weiterführenden Details finden sich auf der Dokumentations-Website:

Seite Themenbereich
capabilities vollständige Funktionsliste: MCP-Server-Modus, signierte Agent-Cards, Sandbox-Backends, Artefakt-Sinks, regulatorische Abbildungen
who this is for wo der konkrete Nutzen liegt und wann Bernstein das falsche Werkzeug ist
workflows deklarative YAML-DAGs aus Agenten-, Befehls- und Schleifenknoten
web UI Browser-Dashboard auf Basis derselben API wie das TUI
cloud execution experimentell: Agenten auf Cloudflare Workers mit R2-Workspace-Synchronisation über das eigene Konto ausführen. Der gehostete Dienst api.bernstein.run ist noch nicht verfügbar
datasources Nur-Lese-Abfragebelege plus ein Abfragetreiber, der Ergebnisse an den jeweiligen Schema-Snapshot bindet
agent catalogs Rollen auf externe Agentendefinitionen verweisen lassen – generische YAML/SKILL.md-Verzeichnisse oder Claude Code Plugin-Layouts
security Scorecard, Fuzzing, Härtung
architecture technische Funktionsweise im Detail

warum dieser Name?

Bernstein ist nach Leonard Bernstein benannt, dem US-amerikanischen Dirigenten und Komponisten. Das Projekt koordiniert ein Ensemble von CLI-Coding-Agenten so, wie Bernstein die New Yorker Philharmoniker dirigierte: Jeder Musiker auf den Punkt, die Partitur deterministisch, der Dirigent für das Gesamtergebnis verantwortlich.

Ich habe Bernstein entwickelt, weil ich monatlich 400 $ für Claude-Rechnungen zahlte, während drei parallele Coding-Agenten nichtdeterministische Merge-Konflikte erzeugten. Apache 2.0, von einer Einzelperson gepflegt. Live-Statistiken: bernstein.run.

erwähnungen

Gelistet in vinta/awesome-python, besprochen in Augment Codes Übersicht Open-Source Agent Orchestrators und erwähnt in Python Weekly #742. Zudem haben wir das Konzept als Deterministic Zero-LLM Orchestration-Pattern in awesome-agentic-patterns veröffentlicht.

Alle Erwähnungen: Über 20 Awesome-Listen, Verzeichnisse, Newsletter und Zitate

Die vollständige Übersicht aller Awesome-List-Einträge, Katalogeinträge, Zitate und Newsletter-Erwähnungen befindet sich in docs/mentions.md. Neue Einträge werden fortlaufend ergänzt; Hinweise und Korrekturen sind per Issue oder PR willkommen.

mitwirken, support, lizenz

Pull Requests sind willkommen; CONTRIBUTING.md beschreibt Setup und Codestil. Sicherheitsberichte bitte über SECURITY.md einreichen. Wenn Bernstein Ihnen Zeit spart: GitHub Sponsors. Kontakt: forte@bernstein.run.

Zitiermetadaten finden sich in CITATION.cff. Lizenz: Apache-2.0; der Projektname ist separat in TRADEMARKS.md geschützt.


Alex Chernysh · GitHub · X · bernstein.run