# mitho AI Agent – Developer README Enterprise Hybrid RAG System (Symfony + NDJSON + FAISS) Stand: Februar 2026 Status: Produktiv stabil – Job-basierte Ingest-Architektur vollständig integriert --- # 1. Systemüberblick Dieses System implementiert eine deterministische, governance-stabile Hybrid-RAG-Architektur mit: - Symfony (PHP Backend) - NDJSON als Single Source of Truth - FAISS als Vektorindex (immer Full Rebuild) - Hybrid Retrieval (Keyword + Vektor) - Versioniertes Dokumentmodell - Job-basierte Ingest-Pipeline - Lock-geschützte Reindex-Operationen - SSE-Streaming im Frontend Grundprinzip: Keine inkrementellen Vektor-Updates. FAISS wird immer vollständig aus index.ndjson neu gebaut. --- # 2. Architekturprinzipien Determinismus: - Gleiche Dokumente + gleiche Konfiguration → identisches index.ndjson - Gleiches index.ndjson → identisches FAISS - Gleiche Query → identisches Retrieval-Ergebnis Governance: - Eine aktive Version pro Dokument - Keine impliziten Index-Änderungen - Strukturänderungen erzwingen Global Reindex - Keine Selbstmodifikation durch KI Skalierbarkeit: - NDJSON (streamingfähig) - Keine RAM-basierte JSON-Arrays - Zielgröße > 200k Chunks --- # 3. Wissensspeicher ## 3.1 index.ndjson Single Source of Truth. - 1 JSON-Objekt pro Zeile - Streaming-Append - Deterministische Compaction by document_id Beispielstruktur: { "chunk_id": "uuid", "document_id": "uuid", "document_version_id": "uuid", "text": "...", "meta": {...} } Keine JSON-Array-Datei. Keine Mutation einzelner Chunks. Nur Append + deterministische Entfernung per document_id. --- ## 3.2 index_meta.json Enthält Strukturparameter: - index_version - embedding_model - embedding_dimension - chunk_size - chunk_overlap - scoring_version - index_format - vector_backend Wenn einer dieser Werte sich ändert: → Global Reindex zwingend erforderlich. --- ## 3.3 FAISS Dateien: - vector.index - vector_meta.json (Chunk-ID Mapping) FAISS wird IMMER vollständig aus index.ndjson gebaut. Keine Partial Updates. --- # 4. Dokument- & Versionsmodell Document → enthält mehrere DocumentVersion → genau eine Version ist aktiv Regel: Es darf immer nur eine aktive Version pro Dokument existieren. Beim Aktivieren einer Version: - Alle anderen Versionen werden inaktiv - IngestStatus → PENDING - Re-Ingest via Job --- # 5. Ingest-Architektur (vollständig Job-basiert) Ingest läuft NIEMALS synchron im HTTP-Request. Jede Mutation am Index läuft über: IngestJob → CLI Runner → IngestOrchestrator → IngestFlow --- ## 5.1 Job-Typen DOCUMENT_VERSION_ACTIVATE - Wird genutzt für: - Version aktivieren - Neue Datei hochladen (Auto-Ingest) DOCUMENT - Manuelles Ingest einer Version GLOBAL_REINDEX - Strukturänderungen --- ## 5.2 Job-Status - QUEUED - RUNNING - COMPLETED - FAILED - ABORTED Jobs werden über CLI ausgeführt: php bin/console mto:agent:ingest:run Start erfolgt asynchron per exec() aus dem Controller. --- # 6. Admin-Flows (aktueller Stand) ## 6.1 Neue Datei hochladen (NEU: Auto-Ingest) Beim Upload: 1. Datei speichern 2. Document + Version 1 erzeugen 3. Version 1 aktiv setzen 4. IngestJob vom Typ DOCUMENT_VERSION_ACTIVATE anlegen 5. Job asynchron starten 6. Redirect auf Job-Detailseite Ergebnis: Neue Dokumente werden automatisch indexiert. --- ## 6.2 Version aktivieren 1. DB-Status anpassen 2. IngestStatus → PENDING 3. DOCUMENT_VERSION_ACTIVATE Job erzeugen 4. Async Runner starten 5. Redirect zur Job-Seite --- ## 6.3 Manuelles Ingest 1. DOCUMENT Job erzeugen 2. Async Runner starten 3. Redirect zur Job-Seite --- ## 6.4 Reset Reset löscht: - index.ndjson - vector.index - vector_meta.json - Upload-Verzeichnis - Tabellen: - document - document_version - ingest_job Nur möglich, wenn exec() aktiv ist. --- # 7. Ingest-Flow Details Local Ingest (ein Dokument): 1. Extract 2. Normalize 3. Chunk deterministisch 4. Entferne alte Chunks per document_id 5. Append neue Chunks 6. Full FAISS Rebuild Global Reindex: 1. Alle aktiven Versionen neu verarbeiten 2. Komplettes index.ndjson neu schreiben 3. FAISS neu bauen 4. index_version++ --- # 8. Hybrid Retrieval Ablauf: User Query → Keyword Retrieval → FAISS Vector Retrieval → Score Fusion → NDJSON Chunk Lookup → Context Builder → LLM → SSE Streaming Keyword ist Primärsignal. Vector ergänzt Semantik. --- # 9. Locking & Concurrency LockService verhindert: - parallelen Ingest - gleichzeitige Reindex-Vorgänge - NDJSON-Korruption Keine gleichzeitigen Mutationen erlaubt. --- # 10. CLI Commands mto:agent:ingest:run mto:agent:vector:ingest mto:agent:vector:search Alle Commands unter: mto:agent:* --- # 11. Failure Modes - Vector index fehlt → vector ingest ausführen - index_meta mismatch → Global Reindex - exec deaktiviert → Async-Start schlägt fehl - Lock aktiv → Parallel-Ingest blockiert --- # 12. Non-Goals - Kein Online-Learning - Keine inkrementellen FAISS Updates - Keine selbstverändernden Prompts - Kein Auto-Merging von Chunks Strukturänderungen → explizit + reindex. --- # 13. Zusammenfassung Dieses System ist: - deterministisch - reproduzierbar - drift-sicher - governance-stabil - enterprise-ready - job-basiert - versionssicher Wichtige Neuerung: Neue Dokumente lösen jetzt automatisch einen IngestJob aus (exakt derselbe Mechanismus wie bei Version-Aktivierung). Kein HTTP-Ingest mehr. Keine Inline-Rebuilds. Alles läuft über das Job-System.