tlr-rag — bundle cœur RAG L0
tlr-rag est la fondation retrieval de l'écosystème Telaria. Il transforme des documents Markdown en une base interrogeable par similarité sémantique, sans aucune dépendance à un LLM — la génération est du ressort des surfaces (L2 : chat, veille).
| Champ | Valeur |
|---|---|
| Package Composer | telaria/rag-bundle |
| Namespace | Telaria\Rag\ |
| Pilote | telaria-app (même release flow) |
| Version en prod | v0.1.3 — 200 docs / 2 528 chunks indexés |
Spec fonctionnelle complète :
specs/ia-coeur.mdTuto pas-à -pas :../tutos/ia/rag-bout-en-bout.mdDéploiement VPS :../vps/09-ia-embeddings.md
Pipeline
Indexation (batch, hors-ligne)
*.md ──▶ IngestionService ──▶ ChunkerInterface ──▶ EmbeddingClient HTTP ──▶ VectorStore
(walk + filtre (size=512 tok POST /embed (sqlite-vec
.aiignore) overlap=64) passages → float[768]) upsert)
Requête (à la demande)
question ──▶ EmbeddingClient HTTP ──▶ VectorStore.search ──▶ Hit[] (chunk + score + source)
POST /embed query kNN cosinus
Réindexation incrémentale : content_hash par chunk — seuls les chunks modifiés sont ré-embeddés.
Zéro clé IA en L0 — le cœur ne génère rien. L'embedding est délégué au microservice Python tlr-embeddings.
Schéma SQLite (index vectoriel)
Fichier : var/rag/index.sqlite (artefact dérivé, non sauvegardé — régénérable via app:rag:ingest).
| Table | Colonnes clés | Rôle |
|---|---|---|
document |
id, path, title, content_hash, indexed_at |
métadonnées par document |
chunk |
id, document_id, section, anchor, position, content, token_count, content_hash |
fragment de texte indexé |
chunk_vector |
table virtuelle sqlite-vec — chunk_id ↔ embedding float[768] |
recherche kNN cosinus |
ingest_run |
id, source_root, started_at, finished_at, docs, chunks, status |
traçabilité des indexations |
Extension requise : vec0.so chargée par PHP via Pdo\Sqlite::loadExtension(RAG_SQLITE_VEC_PATH).
Microservice d'embeddings (contrat HTTP)
Le microservice Python tlr-embeddings (FastAPI, port 8001, modèle intfloat/multilingual-e5-base, dim 768).
GET /health
→ { "status": "ok", "model": "intfloat/multilingual-e5-base", "dim": 768 }
POST /embed
→ requête : { "type": "query" | "passage", "texts": ["..."] }
→ réponse : { "model": "...", "dim": 768, "vectors": [[0.012, ...], ...] }
→ 422 si type hors {query, passage} ou texts vide (erreur d'entrée, pas de fallback silencieux)
Convention e5 : les préfixes query: / passage: sont gérés côté service selon le type — le bundle PHP envoie le texte brut.
Interfaces Symfony (bundle)
Signatures figées en v0.1.x :
ChunkerInterface::chunk(Document $document): Chunk[] EmbeddingClientInterface::embed(string $type, string[] $texts): float[][] EmbeddingClientInterface::health(): array{status, model, dim} VectorStoreInterface::initialize(): void VectorStoreInterface::upsertDocument(Document $doc, Chunk[] $chunks, float[][] $vectors): void VectorStoreInterface::documentHash(string $path): ?string VectorStoreInterface::search(float[] $vector, int $k): Hit[] VectorStoreInterface::stats(): array{documents, chunks, last_indexed_at} RetrievalService::retrieve(string $query, ?int $k = null): Hit[] IngestionService::ingest(?string $sourceRoot = null, bool $incremental = true): IngestReport
Modèles : Chunk{documentPath, documentTitle, section, anchor, position, content, tokenCount, contentHash} · Hit{chunk, score} avec score = 1 - distance_cosinus (∈ ~[0,1]).
Configuration (config/packages/telaria_rag.yaml)
| Variable d'env | Mappe vers | Défaut |
|---|---|---|
RAG_EMBEDDING_URL |
embedding.service_url |
http://127.0.0.1:8001 |
RAG_DB_PATH |
store.database_path |
%kernel.project_dir%/var/rag/index.sqlite |
RAG_SQLITE_VEC_PATH |
store.extension_path |
vec0 |
Paramètres YAML (dans telaria_rag.*) :
| Clé | Défaut | Notes |
|---|---|---|
source_root |
%kernel.project_dir%/docs |
racine des .md à indexer |
chunk.size |
512 |
tokens par chunk |
chunk.overlap |
64 |
chevauchement |
embedding.model |
intfloat/multilingual-e5-base |
|
embedding.dimension |
768 |
|
embedding.batch_size |
32 |
chunks par appel /embed |
retrieval.k |
5 |
top-k par défaut |
excluded_paths |
["SCRATCH.md", "inputs/legacy/"] |
jamais indexés |
Commandes CLI
# Indexation complète (supprime l'index existant) php bin/console app:rag:ingest --full # Indexation incrémentale (ne ré-embedde que ce qui a changé) php bin/console app:rag:ingest # ou php bin/console app:rag:reindex # Tester une requête php bin/console app:rag:search "sécurité VPS" --k=5 # État de l'index + santé du microservice php bin/console app:rag:stats
UI de diagnostic : /admin/rag (ROLE_ADMIN) — statistiques, dernier ingest, formulaire de test.
Dépannage
RAG vide — 0 document, 0 chunk
# 1. Microservice actif ? systemctl is-active telaria-embeddings curl http://127.0.0.1:8001/health # 2. Extension sqlite-vec chargée ? php -r "new PDO('sqlite::memory:'); echo 'ok';" php bin/console app:rag:stats # signale si extension absente # 3. Relancer l'indexation complète php bin/console app:rag:ingest --full
Microservice Python crashé après upgrade Python
Le venv Python (/var/www/telaria-embeddings/venv) est lié à la version de Python. Après un upgrade OS :
# Supprimer et reconstruire le venv rm -rf /var/www/telaria-embeddings/venv cd /var/www/telaria-embeddings python3 -m venv venv ./venv/bin/pip install -r requirements.txt sudo systemctl restart telaria-embeddings
Index corrompu (fichiers WAL non fermés)
Si index.sqlite-wal ou index.sqlite-shm existent et que PHP échoue à lire l'index :
# Réinitialiser proprement (artefact dérivé, pas de perte de donnée) rm -f var/rag/index.sqlite var/rag/index.sqlite-wal var/rag/index.sqlite-shm php bin/console app:rag:ingest --full
Score trop faible — mauvais résultats
- Vérifier le seuil
score_thresholddanschat_config(BO/admin) — recommandé ≥ 0.6 pourmultilingual-e5-base. - Vérifier les préfixes e5 : requêtes →
type=query, passages →type=passage. Une inversion donne de mauvais scores. - Chunk size : si les chunks sont trop courts (< 100 tokens), le contexte sémantique est insuffisant.
Voir aussi
specs/ia-coeur.md— spécification complète L0 (interfaces, decisions, tests)../tutos/ia/microservice-embeddings-python.md— code FastAPI + déploiement../tutos/ia/index-vectoriel-sqlite-vec.md— sqlite-vec, kNN, piège PDO::PARAM_INT../tutos/ia/rag-bout-en-bout.md— assemblage complet (ingest → retrieval → génération)../vps/09-ia-embeddings.md— configuration VPS complète