RAG-Erweiterung
Text einlesen, eingebettet, Top-K abrufen und fundierte Fragen beantworten – alles in einer PHP-Klasse.
Das RAG-Plugin ist die Killerfunktion des KI-Moduls für Produktbauer. Es verwandelt jede Menge Text – Ihre Hilfedokumentationen, Ihre Fehlerprotokolle, Ihre Stripe-Rechnungen, Ihre Kundensupport-Tickets – in eine abfragbare Wissensbasis in etwa vier Zeilen PHP.
Drei Minuten, von Anfang bis Ende
Abschnitt betitelt „Drei Minuten, von Anfang bis Ende“use Nibiru\Module\Ai\Ai;
$ai = new Ai();$rag = $ai->rag('product-help'); / a named collection
$rag->ingestDir(__DIR__ . '/help/'); / walks .md/.txt/.php under help/$rag->ingestText('FAQ entry…', ['source' => 'faq-12']);
echo $rag->ask('How do I cancel my subscription?');// → grounded answer, citing chunks like [1] [2] [3]Das ist alles. Keine Vektordatenbank. Kein SDK. Kein Python-Sidecar.
Wie es funktioniert
Abschnitt betitelt „Wie es funktioniert“ingestText / ingestFile / ingestDir ↓ chunk → embed (Ollama nomic-embed-text) ↓ pack vectors → JSON file at cache/rag/<collection>.json ↓ask(question) → embed question → cosine top-K → chat with chunks as contextSpeicherung erfolgt durch eine JSON-Datei pro Sammlung. Jeder Chunk ist ein Objekt mit text und metadata; Vektoren sind als base64-gepackte Float32Array gespeichert – etwa 3 KB pro Chunk. ~10.000 Chunks passen komfortabel in den Speicher.
Mehrere Sammlungen
Abschnitt betitelt „Mehrere Sammlungen“Sie können eine beliebige Anzahl von Sammlungen in der gleichen App haben. Jede hat ihre eigene JSON-Datei. Sie teilen das Einbettungsmodell und das Chatmodell aus der [AI]-Konfiguration.
$docs = $ai->rag('docs');$tickets = $ai->rag('support-tickets');$logs = $ai->rag('error-logs');
$docs->ingestDir(__DIR__ . '/help/');$tickets->ingestText($ticket->body, ['ticket_id' => $ticket->id]);$logs->ingestText($exception->__toString(), ['ts' => time()]);API-Referenz
Abschnitt betitelt „API-Referenz“$rag = $ai->rag('name'); / get/create a named collection
// --- Ingestion ---$rag->ingestText($text, $metadata = []); / single chunk$count = $rag->ingestFile('path'); / returns chunks added$count = $rag->ingestDir('dir', ['md','txt','php']); / recursive
// --- Querying ---$hits = $rag->search('query', $k = null); / [{score, text, metadata}, …]$answer = $rag->ask('question', $k = null); / top-K → chat call
// --- Maintenance ---$rag->reset(); / forget everything (deletes file)$n = $rag->size(); / number of chunksEinstellungsregler
Abschnitt betitelt „Einstellungsregler“In application/module/ai/settings/ai.ini:
[AI]embed.model = "nomic-embed-text" ; or mxbai-embed-large for higher qualityrag.top_k = 6 ; chunks injected into the chat callrag.chunk_target = 600 ; tokens per chunk (target)rag.chunk_min = 120 ; smaller chunks mergedrag.chunk_max = 900 ; larger paragraphs split on sentencesrag.storage_path = "/../../application/module/ai/cache/rag/"Wann es verwendet werden sollte
Abschnitt betitelt „Wann es verwendet werden sollte“- Hilfe / FAQ Chat — Laden Sie Ihre Hilfesätze ein und stellen Sie einen
/askEndpunkt zur Verfügung. - In-app Code-Suche — Laden Sie
application/module/ein und fragen Sie sich “Wo berechnen wir die Mehrwertsteuer?” - Assistent für interne Dokumente — Laden Sie den Wiki-Dump Ihres Teams ein.
- Kundengeschichtensuchungen — Laden Sie Tickets ein und fragen Sie sich “Haben wir diesen Fehler schon einmal gesehen?”
Wann es NICHT verwendet werden sollte
Abschnitt betitelt „Wann es NICHT verwendet werden sollte“- Echtzeit, schreibintensive Daten — RAG ist ein Snapshot. Für lebende Daten schreiben Sie ein Tool, das der Agent aufrufen kann.
- Massive Korpora (> 100k Chunks) — Die Speicherung in JSON-Dateien beginnt zu knarzen. Wechseln Sie zu Qdrant / pgvector / Weaviate; wir veröffentlichen einen Adapter, sobald wir einen für uns selbst benötigen.
- Alles, wo Sie genaue Antworten benötigen und nicht nur wahrscheinliche Antworten. RAG ist probabilistisch. Verwenden Sie es nicht als Datenbankabfrageebene.
Häufige Fallen
Abschnitt betitelt „Häufige Fallen“nomic-embed-textwurde nicht abgerufen. Der erste Aufruf voningestTextschlägt mit einem klaren Fehler fehl, der Sie auf den Pull-Befehl hinweist.- Modellkonflikt beim Einbetten. Verwenden Sie keine
nomic-embed-text-Blöcke zusammen mitmxbai-embed-large-Abfragen – unterschiedliche Vektorräume. Wenn Sieembed.modeländern, führen Sie zuerst$rag->reset()aus. - Veraltete Sammlungen. Das erneute Ausführen von
ingestDirentfernt keine Duplikate. Verwenden Siereset()und fügen Sie dann erneut ein, oder überprüfen Sie selbst eine Inhalts-Hash-Erkennung. - Kleine Blöcke. Unter etwa 80 Token werden die Einbettungen störend. Der Standardwert von
rag.chunk_min = 120führt kleine benachbarte Blöcke zusammen.
Was kommt als nächstes?
Abschnitt betitelt „Was kommt als nächstes?“- Agent-Plugin → für Werkzeuge, nicht für Abruf.
- Trainingsnibiru-coder → um den Chat so zu gestalten, dass er halb in der Stimme des Frameworks antwortet.