Zwei Fenster der Startseite von pacod-ap unter app.demo.pacod.io, hell und dunkel, überlappend, mit der Überschrift „Build and run your own AI agents“, Schaltflächen zum Einstieg und zu den Agenten und einem gezeichneten Chatfenster, das eine Frage nach dem Preis eines Tarifs aus einem Referenzfakt beantwortet.
Die eigene Website von pacod-ap, bei Tag und bei Nacht. Jedes Deployment hat eine öffentliche Startseite, die seine Agenten vorstellt, jeden mit einer eigenen Seite, von der aus man sich anmeldet und einen Chat beginnt.

pacod-ap betreibt beliebig viele eigenständige KI-Agenten auf einem Deployment. Jeder Agent antwortet aus seiner eigenen Wissensdatenbank und exakten Referenzfakten, nennt seine Quellen und wird anhand seiner eigenen Gespräche überprüft; alle teilen sich eine Anmeldung über pacod-id, eine Admin-Konsole und ein LLM-Gateway, pacod-gw.

Plattform für KI-Agenten

  • Lizenz: Apache-2.0
  • Version: 0.1.0 · Vorschau
  • Geschrieben in: Python, TypeScript
  • Tech-Stack: FastAPI, LangGraph, MCP, SvelteKit, PostgreSQL, Redis, Qdrant, Caddy, Grafana
  • Auf GitHub ansehen · Issue eröffnen

Funktionen

Agenten als Profile

Jeder Agent hat seine eigene Wissensdatenbank, Referenzfakten, Prompts, Direktiven, Einstellungen, Gespräche und Reviews, und die Trennung zwischen den Agenten erzwingt der Code.

Referenzfakten

Preise, Sätze, Limits und Termine sind typisierte Zeilen in PostgreSQL, gelesen über MCP, wobei der Code Agent und Jahr setzt — das Modell zitiert sie, statt sie aus dem Gedächtnis zu holen.

Wissen pro Agent

Zweistufige Suche in den eigenen Qdrant-Sammlungen des Agenten (bge-m3, Neusortierung durch einen Cross-Encoder, übergeordnete Passagen) und eine kuratierte Ebene, die Admins freigeben.

Visueller Agenten-Editor

Die Komponenten eines Agenten auf einer Arbeitsfläche schalten und einstellen, den Entwurf als Dev-Deployment erproben und veröffentlichen; jede Version bleibt erhalten, ein Rollback versetzt einen Zeiger.

Abgesicherter Streaming-Chat

Sprach-, Kontingent- und Themenprüfung antworten, bevor der Stream beginnt; die Antwort kommt mit ihren Quellen, und dieselben Agenten stehen über eine OpenAI-kompatible API bereit.

Review-Kreislauf

Ein Worker prüft die Gespräche jedes Agenten an dem, was er tatsächlich gelesen hat, schreibt die Korrektur, bündelt wiederkehrende Probleme und überlässt jede Änderung einem Menschen.

Eine Admin-Konsole

Agenten, Benutzer, Wissen, Fakten, Direktiven, Prompts, Modelle, Caches, Gespräche, eine schrittweise Debug-Konsole, Analysen und ein Newsletter — für alle Agenten oder für einen.

Mehrsprachig

Agenten antworten auf Bulgarisch und Englisch, festgelegt je Deployment und je Agent; die Oberfläche gibt es auf Englisch, Bulgarisch, Deutsch und Russisch.

Das Plattform-Diagramm mit hervorgehobenem pacod-ap und abgeblendeten übrigen Projekten, mit einer grauen Linie von den Menschen zu pacod-ap, einer grün gepunkteten Linie von pacod-ap zu pacod-gw und einer golden gepunkteten Linie von pacod-ap zu pacod-id.
Wo pacod-ap sitzt. Menschen nutzen es direkt (grau); jeder LLM-Aufruf seiner Agenten läuft über pacod-gw (grün), Anmeldung und Rollen kommen von pacod-id (gold).

Screenshots

Die Seite Agent editor der pacod-ap-Admin-Konsole mit einer Zeile, dem Starter Agent, einem dialogorientierten RAG-Agenten in Produktion mit geändertem Entwurf, und Schaltflächen für den KI-Assistenten, den Import, die Verwaltung aller Agenten im Editor und einen neuen Agenten.
Der Agenten-Editor. Jeder Agent mit seinem Typ, seinem Zustand und seinen Produktions-, Dev- und Entwurfsversionen; eine Änderung wird als Entwurf gespeichert, als Dev-Deployment erprobt, das nur Admins sehen, und mit einer Versionsgeschichte veröffentlicht.
Eine Tabelle mit Referenzfakten in der pacod-ap-Konsole, etwa 30 Tage Datenaufbewahrung nach einer Kündigung, ein Passwort von mindestens 12 Zeichen, eine Rückerstattungsfrist von 14 Tagen und Dateigrößen von 25 MB, 250 MB und 1 GB je Tarif, jeweils mit Kategorie, dem Jahr 2026 und einem Link zur Quelle.
Die Referenzfakten des Agenten starter. Jeder hat einen Schlüssel, eine Variante, eine Kategorie, ein Bezugsjahr, einen typisierten Wert und die Quelle, die eine Antwort zitiert; der Agent zitiert diese Zahlen, statt sie aus dem Gedächtnis zu holen.
Die dunkle Seite Review process der pacod-ap-Konsole mit einer Schaltfläche Run now und Optionen für einen Probelauf, eine erzwungene Neuanalyse und verworfene Runden, darunter die Einstellungen mit einem ausgeschalteten täglichen Zeitplan um 02:00 UTC, einem Rückblick von 24 Stunden, einer Parallelität von 4, den Triage- und Analysemodi und einem Hinweis zur Unabhängigkeit des Richters.
Der Review-Prozess, der findet, was in den eigenen Gesprächen eines Agenten schiefging. Ein Lauf startet von Hand oder nach einem täglichen Zeitplan; ein günstiges Modell wählt die Grenzfälle unter den Runden aus, die eine Analyse lohnen, zwei Analysten und ein Richter fällen das Urteil, und die Seite warnt, wenn sie nicht unabhängig sind.
Die Analytics-Seite von pacod-ap mit Filtern für Zeitraum, Domain und Agent, zehn Kennzahlkarten, die meisten auf null in einer frisch gestarteten Demo, und Diagrammen der Anfragen, der LLM-Aufrufe gegenüber Fehlern und der Tokens der letzten sieben Tage.
Analysen. Anfragen, Agenten-Runden, LLM-Aufrufe, Tokens, Kosten und Fehler je Domain, Agent, Modell und Person; die LLM-Zahlen stammen aus den Berichten von pacod-gw, und ein Link führt weiter in dessen Konsole.

Warum es das gibt

pacod-ap ist für Agenten gebaut, deren Aufgabe korrekte, belegte Antworten in einem Fachgebiet sind — dort, wo ein falscher Preis, Satz oder Termin schlimmer ist als gar keine Antwort. Drei Regeln prägen es:

  • Jede Zahl stammt aus einer strukturierten Quelle der Wahrheit, nie aus dem Gedächtnis des Modells.
  • Jede Aussage nennt eine Quelle: eine Passage aus der Wissensdatenbank, die source_url eines Fakts oder eine freigegebene Webseite.
  • Admins korrigieren einen Agenten ohne neues Deployment. Modelle, Prompts, Direktiven, Websuche und Caching gelten ab der nächsten Runde.

Die Plattform begann als bulgarischer Steuerassistent und behält dessen Aufbau. Der Steuerassistent liegt heute als fortgeschrittenes Beispiel bei, und der Standard-Agent ist ein allgemeiner, der kopiert werden soll.

Ein Deployment, viele Agenten

Ein Agent ist ein Profil: eine Zeile in der Tabelle profiles und alles, was dazugehört. Zwei liegen der Plattform bei:

  • starter, der Standard: der Helpdesk eines erfundenen Notizdienstes, „Nimbus Notes“, mit 29 Referenzfakten, einem kleinen Korpus auf Bulgarisch und Englisch und einem Goldstandard aus Testfragen. So hat jede Funktion etwas zu zeigen.
  • taxes, ein fortgeschrittenes Beispiel für bulgarische Steuern und Buchhaltung, mit eigenen Prompts, Fakten, einem Gesetzeskorpus und einer Liste erlaubter Websites für die Websuche (make seed-example PROFILE=taxes). Der Korpus zeigt die Suche in einem echten Rechtsbestand. Er wird nicht aktuell gehalten, und nichts, was der Agent sagt, ist Rechts- oder Steuerberatung.

Die Trennung der Agenten ist eine Sicherheitsgrenze: Jede Zeile eines Agenten trägt eine profile_id, jeder Agent hat eigene Qdrant-Sammlungen, und eine Runde eines Agenten erreicht nur dessen Daten.

Pro Agent Gemeinsam im Deployment
Referenzfakten, Direktiven, Prompts, eingelesene Quellen Konten und Rollen (pacod-id)
Modell je Rolle; Einstellungen für Websuche, Cache, Review und Newsletter LLM-Vorlagen und Schlüssel für die Websuche
Gespräche, Audit-Zeilen, Suchspuren, Debug-Schritte Der Embedding-Dienst: ein Raum mit 1024 Dimensionen
Review-Befunde, wiederkehrende Probleme, Goldtests, Editor-Versionen Anbieter, Modelle, Preise und Token-Limits (pacod-gw)

Menschen sehen nur die ihnen zugewiesenen Agenten, und wer neu ist, bekommt bei der ersten Anfrage alle freigegebenen Agenten. Admins arbeiten über alle Agenten hinweg oder mit einem, den sie oben in der Konsole wählen. Kontingente zählen je Person über alle Agenten. Ein Agent ist in einem von drei Zuständen, prod, dev oder archived, und nur ein Agent in prod ist für Nicht-Admins sichtbar.

Die Bausteine

Container Aufgabe
pacod-caddy Der einzige öffentliche Zugang: TLS und Reverse Proxy, mit Sites für die App, pacod-id und die Gateway-Konsole
ap-frontend SvelteKit-Backend-for-Frontend: die öffentliche Website, der Chat und die Admin-Konsole; Anmelde-Tokens bleiben auf dem Server
ap-api Die Chat-API und der LangGraph-Agent, dazu ein OpenAI-kompatibles /v1
ap-admin-api Die Steuerungsebene: Agenten, Zuweisungen, Einstellungen je Agent und Fassaden zu pacod-id und dem Gateway
ap-ingestion oder ap-ingestion-cpu Zerlegt, bettet ein und speichert Dokumente in den Sammlungen eines Agenten
ap-mcp Die Werkzeuge für Referenzfakten, get_fact und list_facts
pacod-embeddings bge-m3-Embeddings und ein bge-reranker-Cross-Encoder, gemeinsam für alle Agenten
ap-improvement-loop-worker, ap-newsletter-worker Dauerhaft laufende Worker, die Warteschlangen in PostgreSQL abarbeiten, einen Auftrag nach dem anderen
ap-redis, ap-pgbouncer Caches, Kontingente und die Sitzungen des Frontends; der Verbindungspool vor PostgreSQL
pacod-postgres, pacod-qdrant, pacod-id Gemeinsame Komponenten: PostgreSQL 18.6, der Vektorspeicher und der Identitätsanbieter

Jeder Container hat einen Namen im gemeinsamen Docker-Netz pacod-net: ap-* für die eigenen Dienste von pacod-ap, pacod-* für die Komponenten, die es mit den anderen pacod-Projekten teilt. Die Listener, die nur Server erreichen dürfen — die Management-API des Gateways und der interne Listener von pacod-id —, liegen in einem zweiten Netz, pacod-admin-net. Es ist intern, ohne Weg nach draußen, und nur ihre Aufrufer treten ihm bei.

Wie eine Chat-Runde abläuft

Die Prüfungen laufen, bevor etwas gestreamt wird, sodass eine Ablehnung ein echter HTTP-Status ist und kein Fehler mitten im Stream:

  1. Anmeldung. Das Token von pacod-id wird geprüft. Eine beendete Sitzung oder ein deaktiviertes Konto wird abgewiesen (401); sind die Signaturschlüssel von pacod-id nicht lesbar, lautet die Antwort 503.
  2. Agent. Der angefragte Agent muss der Person zugewiesen und freigegeben sein (sonst 403). Wer keinen nennt, bekommt seine einzige Zuweisung, nie eine Vermutung.
  3. Sprache. Wird in jeder Runde erkannt und mit den Sprachen des Agenten abgeglichen (400).
  4. Kontingent. Das tägliche Token-Limit je Person im Gateway, standardmäßig 100.000 Tokens, dazu eine Drosselung pro Minute und ein optionales Anfrage-Kontingent in Redis (429). Antwortet das Gateway nicht, lässt die Token-Prüfung die Runde durch und protokolliert es.
  5. Thema. Ein fester Filter für illegale Formulierungen (403), dann ein günstiger Klassifikator: Eine themenfremde Frage wird abgewiesen (400), eine unklare bekommt Rückfragen.

Dann öffnet sich der Stream aus Server-Sent Events. Eine erste Frage kann aus dem semantischen Antwort-Cache des Agenten beantwortet werden. Sonst läuft ein kleiner LangGraph-Graph:

  • plan: Der Planer liefert JSON mit den aufzurufenden Werkzeugen und ob die Frage komplex ist.
  • execute tools: Alle geplanten Aufrufe laufen gleichzeitig: kb_search, get_fact und list_facts sowie web_search.
  • synthesize: Das Hauptmodell streamt die Antwort aus diesem Kontext, bei komplexen Fragen mit erweitertem Denken, und danach folgen drei vorgeschlagene Anschlussfragen.

Der Client sieht die Runde als Folge von Ereignissen:

tool_call … citation … [thinking] … token … token … suggestions … done {turn_id, usage, quota}

Standardmäßig bleiben die letzten vier Wechsel wörtlich erhalten, ältere werden zu einer laufenden Zusammenfassung verdichtet, sodass ein langes Gespräch nicht sein ganzes Protokoll erneut sendet. Das OpenAI-kompatible /v1 durchläuft dieselben Prüfungen und denselben Agenten, ohne den Antwort-Cache: Jeder Agent erscheint als Modell, und <slug>@dev erreicht für Admins das Dev-Deployment eines Agenten. Es wird nicht über den öffentlichen Zugang geleitet; Clients erreichen es im internen Netz mit dem Token einer Person oder dem pidt_-Token eines Dienstkontos von pacod-id.

Wissen, Fakten und das Web

Der Planer wählt die Quelle nach der Art der Aussage:

  • Zahlen, Preise, Sätze, Limits und Termine kommen nur aus Referenzfakten: typisierten Zeilen in PostgreSQL, bereitgestellt über MCP von ap-mcp. Der Code, nicht das Modell, setzt bei jedem Aufruf den Agenten und das Bezugsjahr, sodass der Planer die Fakten eines anderen Agenten nicht erreichen kann. Eine Zahl, nach der jemand ausdrücklich fragt, wird zusätzlich mit der Wissensdatenbank abgeglichen und, wo erlaubt, mit dem Web: Der Fakt gilt, und ein Widerspruch wird benannt.
  • Erklärungen kommen aus der Wissensdatenbank: dichte bge-m3-Suche in Qdrant (standardmäßig 20 Kandidaten), eine Neusortierung durch einen Cross-Encoder, die die besten fünf behält, dann werden kleine Abschnitte zu ihrer übergeordneten Passage erweitert. Eine eigene, schwächer gewichtete kuratierte Sammlung enthält die Notizen, die Admins von Hand geschrieben, aus einem Gespräch übernommen oder aus der Review-Warteschlange freigegeben haben.
  • Aktuelles kommt aus der Websuche, immer zusammen mit der Wissensdatenbank und beschränkt auf eine Liste erlaubter Domains je Agent, die bei der Anfrage und noch einmal bei den zurückgegebenen Adressen geprüft wird. Für starter ist sie aus.

Ein Fakt hat eine allgemeine Form, sodass die Preise eines Helpdesks und die Fristen eines Steueragenten dieselbe Tabelle teilen. Ein neues Fachgebiet ist Daten, kein Schema:

{"fact_key": "plan_price_monthly", "variant": "plus", "category": "pricing",
 "legal_year": 2026, "value_type": "money", "value_num": 6, "unit": "EUR",
 "label_en": "Plus plan — price per user per month (billed monthly)",
 "source_url": "https://nimbus-notes.example/pricing"}

Die Werttypen sind number, percent, count, money, range, date, annual_date (ein Tag in jedem Jahr), monthly_day, text und boolean. Admins bearbeiten die Fakten je Agent in der Konsole, mit JSON-Export und -Import. Ein optionaler Prüfer, standardmäßig aus, gleicht Zahlen und Aussagen des Entwurfs mit den Werkzeugergebnissen ab, bevor die Antwort hinausgeht.

Der Agenten-Editor

Superuser bauen und ändern Agenten in einem visuellen Editor. Ein Agent ist ein Graph aus Komponenten einer Bibliothek, angeordnet auf einer Arbeitsfläche: die Chat-Eingabe, die Sprach-, Kontingent- und Themenprüfung, der semantische Antwort-Cache, das Gesprächsgedächtnis, der Planer, die drei Werkzeuge, der Synthesizer, der Prüfer, die Anschlussfragen und der Chat-Stream. Bisher folgt jeder Graph einer Vorlage, dem dialogorientierten RAG-Agenten (rag_chat_v1), mit einem festen Platz für jede Komponente; Komponenten werden also ein- und ausgeschaltet und eingestellt, nicht frei verdrahtet.

  • Erben oder überschreiben. Jede Einstellung einer Komponente erbt entweder den aktuellen Wert des Agenten oder überschreibt ihn. Das Formular entsteht aus dem Schema der Komponente.
  • Entwurf, Dev, Produktion. Eine Änderung wird als Entwurf gespeichert, als Dev-Version bereitgestellt, mit der nur Admins chatten können (im Testbereich des Editors oder mit einem PROD/DEV-Schalter im Chat), und veröffentlicht, wenn sie fertig ist. Versionen werden nur angefügt, sodass Veröffentlichen und Zurückrollen nur einen Zeiger versetzen, und beides leert die Antwort-Caches des Agenten.
  • Ein KI-Assistent entwirft die Texte einer Komponente, etwa ihre Prompts, nach der Anweisung des Autors. Er rührt nie Modelle, Zahlen oder Schalter an, sein Vorschlag wird wie ein Entwurf geprüft, und nichts ändert sich, bevor der Autor ihn übernimmt.
  • Eine öffentliche Seite. Der Editor hält auch den Text des Agenten für die öffentliche Website: seine Karte auf der Startseite und seine eigene Seite unter /agents/<slug>.

Eine Einstellung, die eine veröffentlichte Version verwaltet, ist auf den älteren Einstellungsseiten gesperrt: Sie zeigen ihren Wert und lehnen Änderungen ab, sodass beide Stellen nie auseinanderlaufen.

Der Verbesserungskreislauf

Jeder Agent verbessert sich aus seinem eigenen Verkehr. Ein Worker prüft die jüngsten Gespräche eines Agenten, wenn ein Admin auf Run now drückt, täglich, sobald der Zeitplan eingeschaltet ist (standardmäßig ist er aus), oder für eine einzelne Runde, die auf der Seite Conversations gewählt wird. Die Protokolle werden zuerst geschwärzt: E-Mail-Adressen, IBANs, Karten- und Telefonnummern und mit dem Paket bg auch bulgarische Personen- und Firmennummern. Danach hat ein Lauf fünf Stufen:

  1. Triage. Runden, die die Person bewertet hat, werden immer analysiert; leere, themenfremde, rückfragende und aus dem Cache bediente fallen immer weg. Über den Rest entscheidet standardmäßig ein günstiges Modell; man kann auch alle analysieren oder alle verwerfen lassen.
  2. Belege. Der Prüfer liest, was der Assistent tatsächlich gelesen hat: den wörtlichen Kontext der Antwort mit ihren Fakten und Passagen, die geltenden Direktiven, das bisherige Gespräch, die Werkzeugaufrufe und die Passagen, die die Suche gefunden und verworfen hat.
  3. Analyse. Zwei unabhängige Analysten und ein Richter oder ein Analyst und ein Kritiker. Ein Gremium, das nicht wirklich unabhängig ist, sagt das vor und nach dem Lauf und gilt nie als volle Übereinstimmung.
  4. Zuordnung und Abhilfe. Jeder Befund geht dorthin, wo er behoben werden kann, mit ausgeschriebener Korrektur: der Antwort, die richtig gewesen wäre, und den Fakten, die ein Test prüfen kann.
  5. Bündelung. Ähnliche Befunde werden zu wiederkehrenden Problemen gruppiert. Ein wiederkehrendes Problem ist das Ticket, an dem ein Prüfer arbeitet: offen, in Arbeit, gelöst oder verworfen.
Fehler Wohin er geht
Inhaltslücke Ein Kandidat für die Wissensdatenbank in der Review-Warteschlange, den ein Mensch bearbeitet und freigibt
Suchfehler Die Suchspur der Runde, zum Nachjustieren
Halluzination, Ton, Verhalten Eine korrigierte Antwort und eine vorgeschlagene Regel, die auf Wunsch zur inaktiven Direktive wird
Eine saubere Antwort Ein Goldtest mit den Fakten, die die Antwort enthalten muss

Nichts gelangt in die kuratierte Sammlung, bevor ein Admin es freigibt — außer ein Schalter für automatisches Einfügen, standardmäßig aus, ist an und alle strengen Prüfungen sind bestanden: volle Übereinstimmung, vollständige Belege, eine gestützte Aussage mit geringer Tragweite und hohe Sicherheit. Eine Aussage, der die Quellen widersprechen, wird nie eingefügt. Prüfer markieren jeden Befund als nützlich, verworfen, Duplikat oder behoben, und die Verwerfungsquote ist das eigene Maß des Kreislaufs dafür, wie gut er arbeitet. Zwei abschließende Durchgänge prüfen die Abhilfen: eine Meta-Auswertung, höchstens einmal am Tag nach einem vollen Lauf, ob die kuratierten Notizen genutzt werden, und auf Wunsch das erneute Stellen der Fragen hinter gemeldeten Korrekturen über den laufenden Agenten (standardmäßig aus, da jeder Fall eine volle Runde ist).

Sicherheit und Isolation

  • Identität ist ausgelagert. Konten, Passwörter, Sitzungen und Rollen liegen in pacod-id. Das Frontend meldet Menschen als vertraulicher Client an und hält ihre Tokens in Redis; der Browser hat nur eine undurchsichtige Sitzungs-ID. Die API folgt dem Ereignis-Feed von pacod-id, sodass eine beendete Sitzung oder ein deaktiviertes Konto binnen Sekunden abgewiesen wird, und die Admin-Seiten handeln nicht auf Grundlage einer Rollenkopie, die älter als 60 Sekunden ist. Konto- und Rollenänderungen geschehen in pacod-id im Namen des aufrufenden Admins: Nur ein Superuser macht jemanden zum Superuser, und der letzte Admin lässt sich nicht entfernen.
  • Agenten sind im Code eingezäunt. Der Agent wird vor jeder Arbeit autorisiert, Werkzeugargumente, die Agentendaten betreffen, setzt der Code, /v1/models listet nur die Agenten des Aufrufers, und jeder Cache-Schlüssel eines Agenten trägt dessen ID.
  • Innere Türen sind verschlossen. Die MCP-Werkzeuge und der Endpunkt, der die Telemetrie des Frontends annimmt, verlangen ein gemeinsames Token und lehnen jeden Aufruf ab, solange es leer ist. Entwicklungs-Tokens brauchen zwei getrennte Schalter. Die Management-API des Gateways und der interne Listener von pacod-id sind nur in pacod-admin-net erreichbar.
  • Geheimnisse bleiben, wo sie sind. LLM-Anbieterschlüssel liegen nur im Gateway. Schlüssel für die Websuche sind in der Datenbank verschlüsselt. Geheimnis-Dateien werden erzeugt, haben die Rechte 0600 und stehen in gitignore, und die Skripte, die sie schreiben, geben Namen aus, nie Werte. Das Zugriffsprotokoll des öffentlichen Zugangs lässt Anmeldecodes, Tokens und Schlüssel weg.
  • Sichere Prompts. Die Ablehnung illegaler Anfragen steht ganz oben in den Prompts von Planer und Synthesizer und hat Vorrang vor den Direktiven der Admins, und ein fester Formulierungsfilter läuft vor dem Klassifikator. Text von Admins und Nutzern wird immer als Wert eingesetzt, nie als Vorlage.

Betrieb

Drei Docker-Compose-Stacks starten in fester Reihenfolge, und make up-all erledigt das:

  1. Die App, in zwei Compose-Dateien. Die App-Datei enthält die eigenen Dienste von pacod-ap, Redis, PgBouncer und den Embedding-Dienst. Die Standalone-Datei enthält seine Kopien der gemeinsamen Komponenten: Caddy, PostgreSQL, Qdrant und pacod-id, lokal dazu mailpit.
  2. Das Gateway: die App-Datei von pacod-gw, aus einem Checkout neben diesem. Es meldet sich über dasselbe pacod-id an, hält seine Datenbank im selben PostgreSQL und wird vom selben Caddy ausgeliefert.
  3. Monitoring: Prometheus, Alertmanager und Grafana. Es ist optional, und make up-all startet es, wenn monitoring/.env vorhanden ist.

Auf dem Laptop liegt die App unter http://localhost:8080, pacod-id unter http://127.0.0.1:8070, die Gateway-Konsole unter http://127.0.0.1:13000 und jede Mail unter http://127.0.0.1:8025. Das Gateway antwortet mit seinen Mock-Anbietern: vorgegebene Antworten, keine Kosten. Docker braucht etwa 8 GB Speicher und 20 GB Platte; LOCAL_EMBEDDINGS_BACKEND=hash erspart das 2 GB große Embedding-Modell, um den Preis einer bedeutungslosen Suche.

Weil die gemeinsamen Komponenten in einer eigenen Datei liegen, lädt pacod-demo die App-Datei von pacod-ap neben den anderen pacod-Projekten und betreibt jede gemeinsame Komponente einmal; das Ergebnis läuft unter demo.pacod.io, mit pacod-ap unter app.demo.pacod.io. Eine Demo ohne Anbieterschlüssel antwortet mit dem Mock des Gateways, und ohne ihre optionale Ingestion-Komponente antwortet der Agent starter nur aus seinen Referenzfakten. Auf einem Host kann jede gemeinsame Komponente nur einmal laufen, daher läuft ein eigenständiges pacod-ap nicht neben einem anderen pacod-Stack.

  • Konfiguration liest zuerst einen Redis-Cache, dann eine Zeile in app_settings mit dem Agenten als Schlüssel, dann den Standardwert der Umgebung. Bei einem Ausfall gelten die Standardwerte, statt eine Runde zu blockieren.
  • LLM-Aufrufe werden Person, Sitzung, Runde, Agent und Zweck zugeordnet, sodass die Seiten für Nutzung, Kosten und Analysen die Berichte des Gateways lesen, statt ein eigenes Buch zu führen. Die Spur einer Runde im Gateway ist die Runde selbst. Ein Aufruf mit Zeitüberschreitung wird nie wiederholt, denn der Anbieter berechnet ihn trotzdem: Die Person fragt erneut.
  • Beobachtbarkeit. Eine Audit-Zeile je Anfrage, eine zuschaltbare schrittweise Debug-Konsole, strukturierte Logs im gemeinsamen pacod-Format und Prometheus-Metriken in jedem Dienst, mit Grafana-Dashboards für App, Infrastruktur, Webverkehr, Crawler und Nutzung, dazu die eigenen des Gateways.
  • Sicherung. make backup schreibt ein Archiv mit den PostgreSQL-Dumps, den Qdrant-Snapshots, den hochgeladenen Dokumenten, der Konfiguration und den Geheimnissen, die mit den Dumps reisen müssen; make restore kehrt es um. Die eigenen Speicher des Gateways werden mit den Werkzeugen von pacod-gw gesichert.

Was getestet ist und wo die Grenzen liegen

  • Unit-Tests laufen ohne Datenbank, Redis oder Gateway und decken die Trennung der Agenten, den Gateway-Client anhand aufgezeichneter Antworten, die Identitätsprüfung und den Rollenkatalog ab. Integrationstests laufen gegen einen laufenden Stack: den MCP-Server mit den Fakten von starter, die Trennung eingeschlossen, und die Prüfungen des Chats.
  • make smoke-all prüft den Zustand der Dienste, schickt eine Chat-Runde durch den Mock des Gateways, prüft, dass die Spur dieser Runde im Gateway dasselbe kostet, wie die Runde in ihrem done-Ereignis meldet, und führt den eigenen Smoke-Test des Gateways aus.
  • Der Wechsel von einem LiteLLM-Proxy zu pacod-gw wurde gegen den Mock des Gateways geprüft: Reasoning-Deltas, Zitate der eingebauten Websuche, Tokens aus dem Cache, abgeschnittene Antworten, die Parameter für Denken und Prompt-Caching und die Form einer Zeitüberschreitung. Zwei Prüfungen sind offen, und beide brauchen Anbieterschlüssel: der Vergleich mit aufgezeichneten Antworten des alten Proxys und eine echte komplexe Runde.
  • Echte Anbieter. Der Wechsel zu echten Anbietern ist vorbereitet, aber noch nicht mit echten Schlüsseln durchgeführt.
  • Standardmäßig aus: der tägliche Review-Zeitplan, das automatische Einfügen in die kuratierte Ebene, das erneute Stellen behobener Fragen und der Prüfer. Das Nachtrainieren der Suche anhand von Rückmeldungen wird von Hand gestartet; nichts plant es ein.
  • Grenzen. Agenten sprechen zwei Sprachen, eine dritte ist eine Codeänderung, keine Einstellung. Der Editor hat eine Vorlage. Eine Runde mit Zeitüberschreitung ist verloren und muss neu gestellt werden.

Einen eigenen Agenten bauen

Es gibt zwei Wege:

  • In der Konsole. Ein Superuser legt einen Agenten auf der Seite Profiles oder im Agenten-Editor an. Ein neuer Agent beginnt in dev mit den allgemeinen Prompts; man erprobt ihn dort und veröffentlicht ihn, wenn er fertig ist.
  • Als Code. Eine ProfileSpec in pacod-api/scripts/profiles/<id>.py, mit den Daten in pacod-api/data/profiles/<id>/: Referenzfakten, ein Korpus und ein Goldstandard aus Fragen.
from scripts.seed_profile import ProfileSpec

SPEC = ProfileSpec(
    profile_id="helpdesk",
    slug="helpdesk",
    name="Acme Help Desk",
    description="Answers questions about Acme's products and plans.",
    topic_name="acme_helpdesk",
    topic_description_en="Questions about Acme's products: plans, prices, limits, accounts, support.",
    topic_description_bg="Въпроси за продуктите на Acme: планове, цени, лимити, акаунти, поддръжка.",
    legal_year=2026,  # the reference year the facts and the corpus are filed under
    languages="en,bg",
    settings_overrides={"websearch.enabled": "false"},
    assign_to_all_users=True,
)

make seed-example PROFILE=<id> installiert ihn: den Agenten, seine Sammlungen, seine überschriebenen Prompts und Einstellungen (nie über das, was ein Admin inzwischen eingestellt hat), seine Fakten und seinen Korpus. Die Themenbeschreibung ist wichtig: Die Themenprüfung misst jede Frage daran, und der Review-Kreislauf nutzt sie als Zuständigkeit des Agenten. Danach mit dem Agenten chatten, die Debug-Konsole und die Spur einer Runde im Gateway ansehen und make eval gegen den Goldstandard laufen lassen. Ab da übernimmt der Review-Kreislauf.

Weiterlesen

Schnellstart

Schnellstart auf dem Laptop

make secrets-init
make up-all
make bootstrap-local
make smoke-all
open http://localhost:8080

Funktioniert mit

  • pacod-gw: Jeder LLM-Aufruf läuft über das Gateway und wird Person, Runde, Agent und Zweck zugeordnet; Modelle, Preise, Anbieterschlüssel, Token-Limits, Nutzung und Kosten liegen beim Gateway.
  • pacod-id: Konten, Passwörter, Sitzungen und Rollen liegen in pacod-id; man meldet sich darüber an, und die App und die Gateway-Konsole teilen sich ein Konto.
  • pacod-kb: pacod-ap bringt pacod-embeddings mit, den gemeinsamen Dienst für Embeddings und Neusortierung mit bge-m3; daneben betrieben, kann pacod-kb ihn nutzen, statt das Modell selbst zu laden.