# mitho AI Agent – Developer README Enterprise Hybrid RAG System (Symfony + NDJSON + FAISS + Persistent Vector Service) Stand: Februar 2026 Status: Produktiv stabil – Job-basierte Ingest-Architektur + Persistenter Vector-Service 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) - Persistenter Python Vector-Service (FastAPI + Uvicorn) - 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 - Retrieval läuft über einen persistenten Service (kein Python-Spawn pro Anfrage) --- # 2. Architekturprinzipien ## 2.1 Determinismus - Gleiche Dokumente + gleiche Konfiguration → identisches `index.ndjson` - Gleiches `index.ndjson` → identisches FAISS - Gleiche Query → identisches Retrieval-Ergebnis ## 2.2 Governance - Eine aktive Version pro Dokument - Keine impliziten Index-Änderungen - Strukturänderungen erzwingen Global Reindex - Keine Selbstmodifikation durch KI ## 2.3 Skalierbarkeit - NDJSON (streamingfähig) - Kein RAM-basiertes JSON-Array - Zielgröße > 200k Chunks - FAISS Full Rebuild ist deterministisch --- # 3. Wissensspeicher ## 3.1 index.ndjson Single Source of Truth. - 1 JSON-Objekt pro Zeile - Streaming-Append - Deterministische Compaction by `document_id` Beispielstruktur: ```json { "chunk_id": "uuid", "document_id": "uuid", "document_version_id": "uuid", "text": "...", "meta": { ... } } ``` Regeln: - Keine JSON-Array-Datei - Keine Mutation einzelner Chunks - Nur Append + deterministische Entfernung per `document_id` --- ## 3.2 index_meta.json 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.index.meta.json` - `vector_tags.index` - `vector_tags.index.meta.json` FAISS wird IMMER vollständig aus `index.ndjson` gebaut. Keine Partial Updates. Kein inkrementelles Vector-Append. --- # 4. Persistenter Vector-Service Retrieval läuft nicht mehr über: - Symfony Process - `exec()` - `python vector_search.py` pro Anfrage Sondern über: **FastAPI + Uvicorn (persistent im RAM)** ## 4.1 Eigenschaften Beim Start lädt der Service: - Embedding-Modell - Chunk-Index - Tag-Index - ID-Mappings Diese bleiben dauerhaft im RAM. Kein Modell-Reload pro Anfrage. Kein Disk-Reload pro Anfrage. Kein Python-Spawn pro Anfrage. ## 4.2 Endpoints - `GET /health` - `POST /search-chunks` - `POST /search-tags` - `POST /reload` ## 4.3 Reload-Mechanismus Nach Global Reindex: ```bash curl -X POST http://127.0.0.1:8090/reload ``` Lädt: - Chunk-Index neu - Tag-Index neu - Modell nur wenn `embedding_model` geändert wurde Kein Neustart nötig. Keine Downtime. --- # 5. Score-Gates (Routing-Sicherheit) ## 5.1 Tag-Gate Tags steuern Routing. Empfohlener Mindestscore: `MIN_SCORE ≈ 0.70` Schützt vor: - zufälligen semantischen Treffern - falschem Dokumentrouting ## 5.2 Chunk-Gate Chunks sind Kontext. Weicher Gate: `MIN_SCORE ≈ 0.50` Optional: relativer Score zum besten Treffer. --- # 6. 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 --- # 7. 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 ## 7.1 Job-Typen - `DOCUMENT_VERSION_ACTIVATE` - `DOCUMENT` - `GLOBAL_REINDEX` ## 7.2 Job-Status - `QUEUED` - `RUNNING` - `COMPLETED` - `FAILED` - `ABORTED` CLI-Ausführung: ```bash php bin/console mto:agent:ingest:run ``` --- # 8. Hybrid Retrieval Flow: User Query → Keyword Retrieval → Tag Vector Search → Dokumentfilter → Chunk Vector Retrieval → Score Fusion → NDJSON Lookup → Context Builder → LLM → SSE Streaming Keyword bleibt Primärsignal. Vector ergänzt Semantik. --- # 9. Locking & Concurrency LockService verhindert: - parallelen Ingest - gleichzeitige Reindex-Vorgänge - NDJSON-Korruption Keine gleichzeitigen Mutationen erlaubt. --- # 10. Vector Control (Production Safe) Ein zentrales Kommando steuert: - Dependency-Check - Auto-Install (opt-in) - Service Start - Service Stop - Reload - Status - Health-Check - PID-Management ## Command `mto:agent:vector:control` ## Beispiele Status: ```bash bin/console mto:agent:vector:control ``` Install + Start: ```bash bin/console mto:agent:vector:control --install --start ``` Stop: ```bash bin/console mto:agent:vector:control --stop ``` Reload: ```bash bin/console mto:agent:vector:control --reload ``` ## Production-Safety - PID-File unter `var/run/vector_service.pid` - SIGTERM Stop mit Timeout - Optional SIGKILL (`--force`) - Health-Check mit Retry-Mechanismus - Kein automatisches Install ohne Flag --- # 11. CLI Commands - `mto:agent:ingest:run ` - `mto:agent:vector:control` - `mto:agent:test` - `mto:agent:chat` Alle Commands unter: `mto:agent:*` --- # 12. Failure Modes Vector Service nicht erreichbar → `vector:control --start` Reload Endpoint fehlt → falsche Service-Version index_meta mismatch → Global Reindex Lock aktiv → Parallel-Ingest blockiert --- # 13. Non-Goals - Kein Online-Learning - Keine inkrementellen FAISS Updates - Keine selbstverändernden Prompts - Kein Auto-Merging von Chunks - Kein Vector-Append im Runtime Strukturänderungen → explizit + Reindex. --- # 14. Zusammenfassung Dieses System ist: - deterministisch - reproduzierbar - drift-sicher - governance-stabil - enterprise-ready - job-basiert - versionssicher - persistent im Retrieval - ohne Spawn-Overhead - reload-fähig ohne Downtime Wichtige Neuerungen: - Persistenter Vector-Service ersetzt CLI-Spawn - Score-Gates verhindern falsches Routing - Reload-Endpoint vermeidet Neustarts - Production-Safe Control Command integriert - Vollständige Trennung von Ingest und Runtime