---
title: "plugin RAG"
description: "Intégrez le texte, intégrez-le, récupérez les K premiers éléments et répondez aux questions fondées — tout cela dans une seule classe PHP."
---

Le plugin RAG est la fonctionnalité clé du module IA pour les constructeurs de produits. Il transforme n'importe quel amoncellement de texte — vos documents d'aide, vos journaux d'erreurs, vos factures Stripe, vos tickets de support client — en une base de connaissances interrogeable en environ quatre lignes de PHP.

## Trois minutes, de bout en bout
```php
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]
```
Voilà. Aucune base de données vectorielle. Aucun SDK. Pas de conteneur latéral en Python.

## Comment ça fonctionne
```
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 context
```
Le stockage se fait par fichier JSON par collection. Chaque morceau est un objet avec `texte` + `métadonnées`; les vecteurs sont des Float32Array empaquetés en base64 — environ 3 Ko par morceau. Environ 10 000 morceaux s'adaptent confortablement à la mémoire.

## Collections multiples

Vous pouvez avoir un nombre quelconque de collections dans la même application. Chacune a son propre fichier JSON. Elles partagent le modèle d'incrustation et le modèle de conversation à partir de la configuration `[AI]`.
```php
$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()]);
```
## Référence de l'API
```php
$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 chunks
```
## Réglages

Dans `application/module/ai/settings/ai.ini`:
```ini
[AI]
embed.model        = "nomic-embed-text"   ; or mxbai-embed-large for higher quality
rag.top_k          = 6                    ; chunks injected into the chat call
rag.chunk_target   = 600                  ; tokens per chunk (target)
rag.chunk_min      = 120                  ; smaller chunks merged
rag.chunk_max      = 900                  ; larger paragraphs split on sentences
rag.storage_path   = "/../../application/module/ai/cache/rag/"
```
## Quand l'utiliser

- **Aide / FAQ chat** — intégrez vos articles d'aide, exposez un point de terminaison `/ask`.
- **Recherche de code dans l'application** — intégrez `application/module/`, posez la question "où calculons-nous la TVA ?"
- **Assistant des documents internes** — intégrez le vidage wiki de votre équipe.
- **Recherches d'historique clients** — intégrez les tickets, posez la question "avons-nous déjà vu cette erreur ?"

## Quand ne PAS l'utiliser

- **Données en temps réel et à forte écriture** — RAG est une capture instantanée. Pour les données en direct, écrivez un [Outil](/en/ai/module/agent/) que l'agent puisse appeler.
- **Corpus massifs (> 100k morceaux)** — Le stockage dans des fichiers JSON commence à s'affaiblir. Passez à Qdrant / pgvector / Weaviate ; nous publierons un adaptateur une fois que nous en aurons besoin nous-mêmes.
- **Tout ce dont vous avez besoin de *réponses exactes*, pas de *probabilités*.** RAG est probabiliste. Ne l'utilisez pas comme une couche de requêtes de base de données.

## Trépieds communs

- **`nomic-embed-text` non récupéré.** Le premier appel à `ingestText` échouera avec une erreur claire vous indiquant la commande de récupération.
- **Modèle d'incrustation incompatible.** Ne mélangez pas les morceaux `nomic-embed-text` avec les requêtes `mxbai-embed-large` — espaces vectoriels différents. Si vous changez `embed.model`, exécutez `$rag->reset()` en premier.
- **Collections obsolètes.** Réexécuter `ingestDir` ne supprime pas les doublons. Utilisez `reset()` puis ré-ingestez, ou maintenez un contrôle de hachage du contenu vous-même.
- **Petits morceaux.** En dessous de ~80 jetons, les incrustations deviennent bruitées. Le `rag.chunk_min` par défaut à 120 fusionne les petits morceaux adjacents.

## ¿Qué sigue?

- [Plugin agent →](/fr/ia/module/agent/) pour les outils, pas la récupération.
- [Formation nibiru-coder →](/fr/ia/module/formation/) pour faire répondre le chat à moitié dans la voix du framework.
