diff --git a/README.md b/README.md index f8ddce7..353137d 100644 --- a/README.md +++ b/README.md @@ -1,396 +1,321 @@ -# 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 +# RAG-System – Technische Projektdokumentation +**Version:** 1.0 +**Stand:** Februar 2026 +**Autor:** mitho +**Status:** Verbindliche Referenzarchitektur (System Freeze) --- -# 1. Systemüberblick +# 1. Ziel des Systems -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 +Das RAG-System dient der deterministischen, governance-stabilen Beantwortung von Nutzeranfragen auf Basis versionierter, kontrollierter Wissensquellen. Grundprinzip: +> „Wir nutzen KI nicht, um kreativ zu raten, sondern um verlässlich auf Basis Ihres Wissens zu antworten.“ -- 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) +Das System kombiniert: + +- Versionierte Dokumentverwaltung +- Deterministisches Chunking +- NDJSON als Single Source of Truth +- Vollständigen FAISS-Rebuild +- Hybrid Retrieval (Keyword + Vector + Tag) +- Job-basierte Orchestrierung +- Rollen- und Guardrail-Architektur +- SSE-Streaming --- -# 2. Architekturprinzipien +# 2. Architekturüberblick -## 2.1 Determinismus +## 2.1 Systemebenen -- Gleiche Dokumente + gleiche Konfiguration → identisches `index.ndjson` -- Gleiches `index.ndjson` → identisches FAISS -- Gleiche Query → identisches Retrieval-Ergebnis +### 1. Admin-Ebene (Symfony Backend) +- Dokumentverwaltung +- Versionierung +- Tag-Management +- Job-Steuerung +- System-Prompt-Verwaltung +- KI-Endpoint-Konfiguration -## 2.2 Governance +### 2. Wissensebene +- Dokumente (immutable) +- DocumentVersion +- Chunks +- index.ndjson +- index_meta.json -- Eine aktive Version pro Dokument -- Keine impliziten Index-Änderungen -- Strukturänderungen erzwingen Global Reindex -- Keine Selbstmodifikation durch KI +### 3. Vector-Ebene (Python) +- Embedding-Modell (lokal) +- FAISS-Index (Chunks) +- FAISS-Index (Tags) +- Persistenter Vector-Service +- CLI-Fallback -## 2.3 Skalierbarkeit - -- NDJSON (streamingfähig) -- Kein RAM-basiertes JSON-Array -- Zielgröße > 200k Chunks -- FAISS Full Rebuild ist deterministisch +### 4. Agent-Ebene +- Retrieval-Fusion +- PromptBuilder +- SSE-Streaming +- Chat-History-Verarbeitung --- -# 3. Wissensspeicher +# 3. Dokumentenarchitektur -## 3.1 index.ndjson +## 3.1 Primärquellen -Single Source of Truth. +- Dokumente sind immutable. +- Jede Änderung erzeugt eine neue DocumentVersion. +- Pro Dokument existiert genau eine aktive Version. -- 1 JSON-Objekt pro Zeile -- Streaming-Append -- Deterministische Compaction by `document_id` +## 3.2 Aktivierungsprozess -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` +1. Aktivierung einer Version +2. Erstellung eines IngestJob +3. Async-Start: + ``` + bin/console mto:agent:ingest:run + ``` +4. IngestOrchestrator: + - Guardrail-Validierung + - NDJSON Compaction by document_id + - Chunking + - Streaming Append + - Vollständiger FAISS-Rebuild + - index_meta.json Update + - Status COMPLETED/FAILED --- -## 3.2 index_meta.json +# 4. NDJSON-Architektur -Strukturparameter: +## 4.1 index.ndjson (Single Source of Truth) -- `index_version` -- `embedding_model` -- `embedding_dimension` -- `chunk_size` -- `chunk_overlap` -- `scoring_version` -- `index_format` -- `vector_backend` +- Streamingfähiges Format +- Kein JSON-Array +- Append-only mit Compaction +- Keine vollständige RAM-Verarbeitung +- Atomare Datei-Switches (.tmp → rename) -Wenn einer dieser Werte sich ändert: +## 4.2 index_meta.json -→ **Global Reindex zwingend erforderlich** +Enthält: + +- index_version +- embedding_model +- embedding_dimension +- chunk_size +- overlap +- scoring_version +- index_format + +### Guardrail-Mechanismus + +Bei strukturellen Änderungen (Embedding, Chunking, Scoring): +- Lokaler Ingest wird blockiert +- Global Reindex erforderlich --- -## 3.3 FAISS +# 5. Chunk-Management -Dateien: +Verantwortlich: ChunkManager -- `vector.index` -- `vector.index.meta.json` -- `vector_tags.index` -- `vector_tags.index.meta.json` +Eigenschaften: -FAISS wird IMMER vollständig aus `index.ndjson` gebaut. - -Keine Partial Updates. -Kein inkrementelles Vector-Append. +- Streaming-basiertes Schreiben +- Deterministische Reproduktion +- Hard Limit: 120.000 Chunks +- Warnlimit: 100.000 Chunks +- Kein vollständiger JSON-RAM-Load --- -# 4. Persistenter Vector-Service +# 6. Vector-Architektur -Retrieval läuft nicht mehr über: +## 6.1 Betriebsmodi -- Symfony Process -- `exec()` -- `python vector_search.py` pro Anfrage +### A) Persistenter Vector-Service (bevorzugt) +- Lädt Embedding-Modell einmal +- Lädt FAISS-Indizes in RAM +- REST-Endpunkte: + - /search-chunks + - /search-tags -Sondern über: +### B) CLI-Fallback +- Python-Skripte +- Wird genutzt, falls Service nicht verfügbar ist -**FastAPI + Uvicorn (persistent im RAM)** +## 6.2 Rebuild-Strategie -## 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. +- Immer vollständiger FAISS-Rebuild +- Kein inkrementelles Patchen +- Atomarer Index-Switch +- Deterministisch und drift-sicher --- -# 5. Score-Gates (Routing-Sicherheit) +# 7. Hybrid Retrieval -## 5.1 Tag-Gate +## 7.1 Retrieval-Komponenten -Tags steuern Routing. +1. Keyword-Retrieval (führend) +2. FAISS-Chunk-Retrieval (ergänzend) +3. Tag-Routing (Soft-Gate) -Empfohlener Mindestscore: +## 7.2 Score-Fusion -`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. +- Keyword hat Priorität +- Vector ergänzt semantische Nähe +- Tags dienen als Routing-Verstärker --- -# 6. Dokument- & Versionsmodell +# 8. Tag-System -Document -→ enthält mehrere `DocumentVersion` -→ genau eine Version ist aktiv +## 8.1 Entities -Regel: +- Tag +- DocumentTag +- TagRebuildJob -Es darf immer nur eine aktive Version pro Dokument existieren. +## 8.2 Trigger-Logik -Beim Aktivieren einer Version: +Ein Rebuild wird ausgelöst bei: -- Alle anderen Versionen werden inaktiv -- `IngestStatus → PENDING` -- Re-Ingest via Job +- Tag-Erstellung +- Tag-Löschung +- Tag-Zuweisung +- Tag-Entfernung + +## 8.3 Job-Mechanik + +- Async-Start via: + ``` + php bin/console mto:agent:tags:job:run + ``` +- Logfile unter: + ``` + var/log/tags/job_.log + ``` + +## 8.4 Stale-Protection + +- QUEUED-Jobs älter als 5 Minuten → FAILED +- System kann nicht dauerhaft blockieren +- Coalescing (max. 1 aktiver Job) + +## 8.5 Tag-Index + +- tags.ndjson +- vector_tags.index +- Vollständiger Rebuild bei Änderung --- -# 7. Ingest-Architektur (vollständig Job-basiert) +# 9. Job-Architektur -Ingest läuft NIEMALS synchron im HTTP-Request. +Statusmodell: -Jede Mutation am Index läuft über: +- QUEUED +- RUNNING +- COMPLETED +- FAILED -IngestJob → CLI Runner → IngestOrchestrator → IngestFlow +Eigenschaften: -## 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 -``` +- Async exec +- LockService gegen Parallel-Ausführung +- Self-Healing gegen blockierte Jobs +- Logging pro Job --- -# 8. Hybrid Retrieval +# 10. Governance & Guardrails -Flow: +## 10.1 Rollen -User Query -→ Keyword Retrieval -→ Tag Vector Search -→ Dokumentfilter -→ Chunk Vector Retrieval -→ Score Fusion -→ NDJSON Lookup -→ Context Builder -→ LLM -→ SSE Streaming +- Super Admin +- Knowledge Admin +- Redaktion +- Frontend-User -Keyword bleibt Primärsignal. -Vector ergänzt Semantik. +## 10.2 Schutzmechanismen + +- Dokumente immutable +- Keine manuelle Chunk-Manipulation +- Versionierte Ingest-Profile +- Versionierte System-Prompts +- Konfigurierbare KI-Endpunkte +- Logging & Audit-Fähigkeit --- -# 9. Locking & Concurrency +# 11. Agent-Architektur -LockService verhindert: - -- parallelen Ingest -- gleichzeitige Reindex-Vorgänge -- NDJSON-Korruption - -Keine gleichzeitigen Mutationen erlaubt. +- SSE-Streaming +- Historienverarbeitung korrekt implementiert +- Deterministischer PromptBuilder +- Retrieval-Kontext explizit eingebettet +- Kein Think-Mode-Leak --- -# 10. Vector Control (Production Safe) +# 12. Skalierbarkeit -Ein zentrales Kommando steuert: +Zielgröße: -- Dependency-Check -- Auto-Install (opt-in) -- Service Start -- Service Stop -- Reload -- Status -- Health-Check -- PID-Management +- >120.000 Chunks -## Command +Ermöglicht durch: -`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 +- NDJSON Streaming +- Kein Full-RAM-JSON +- Vollständiger FAISS-Rebuild +- Persistenter Vector-Service +- Atomare Switches +- Locking-Mechanismen --- -# 11. CLI Commands +# 13. Stabilitätsstatus (Freeze-Zustand) -- `mto:agent:ingest:run ` -- `mto:agent:vector:control` -- `mto:agent:test` -- `mto:agent:chat` - -Alle Commands unter: - -`mto:agent:*` +| Bereich | Status | +|----------|--------| +| Dokument-Ingest | Stabil | +| NDJSON-Architektur | Enterprise-Stabil | +| FAISS-Rebuild | Deterministisch | +| Tag-System | Stabil mit Stale-Recovery | +| Async-Jobs | Blockiersicher | +| Retrieval-Fusion | Funktional | +| SSE | Stabil | +| Governance | Aktiv | --- -# 12. Failure Modes +# 14. System-Freeze-Definition -Vector Service nicht erreichbar -→ `vector:control --start` +Dieses Dokument definiert den verbindlichen Referenzstand des Systems. -Reload Endpoint fehlt -→ falsche Service-Version +Ab diesem Punkt gilt: -index_meta mismatch -→ Global Reindex - -Lock aktiv -→ Parallel-Ingest blockiert +- Keine strukturellen Änderungen ohne explizite Freigabe. +- Erweiterungen nur inkrementell. +- Keine Architektur-Rewrites. +- Determinismus und Reproduzierbarkeit sind oberstes Prinzip. --- -# 13. Non-Goals +# 15. Zusammenfassung -- 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: +Das System ist: - deterministisch -- reproduzierbar - drift-sicher -- governance-stabil +- governance-konform +- skalierbar +- blockiersicher +- debugbar - 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 \ No newline at end of file +Es erfüllt die Anforderungen an ein kontrolliertes, reproduzierbares RAG-System mit klarer Trennung zwischen Wissensquelle, Index, Retrieval und Generierung. \ No newline at end of file