2026-02-21 21:02:31 +01:00
2026-02-11 14:15:08 +01:00
2026-02-21 16:23:34 +01:00
2026-02-21 19:23:38 +01:00
2026-02-17 16:14:37 +01:00
2026-02-21 21:02:31 +01:00
2026-02-21 16:23:34 +01:00
2026-02-18 11:41:58 +01:00
2026-02-15 18:07:38 +01:00
2026-02-16 09:38:40 +01:00
2026-02-16 09:38:40 +01:00

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.

Description
No description provided
Readme 26 MiB
Languages
PHP 79%
Twig 13%
HTML 2.8%
Python 2.4%
JavaScript 1.8%
Other 1%