Funk-lab/admin/ia/rag.md
alkatrazz 529bb66ebd docs: mise à jour documentation — NVMe, Qwen3, gaps IaC
- CLAUDE.md : /srv/data NVMe (plus RAID5), structure k8s/ expliquée,
  namespace ai ajouté, Hermes data code/données séparés
- README.md : roadmap complète (n8n/Open WebUI/monitoring opérationnels),
  Talos v1.13, vault vars complètes, rôles Ansible manquants, RAID5→NVMe
- admin/ia/rag.md : 284→339 chunks, RAID5→NVMe
- admin/ia/hermes.md : RAID5→NVMe (incidents 2026-05-13 et 2026-05-29)
- admin/ia/litellm.md : qwen2.5→qwen3-8b, gap IaC CPU models documenté
- admin/ia/llama_server.md : gap IaC instances CPU documenté
- admin/index_knowledge.py : 5 chunks RAG mis à jour (Qwen2.5→Qwen3,
  RAID5→NVMe, vault vars + rôles complets)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 22:58:24 +02:00

194 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# RAG — Documentation Funk
Le RAG (Retrieval-Augmented Generation) permet à Hermes de répondre en s'appuyant
sur la documentation du repo (`admin/`) plutôt que sur sa seule mémoire de modèle.
---
## Architecture
```
Hermes (funk-ai)
│ terminal: rag-query "comment relancer dnsmasq ?"
/usr/local/bin/rag-query (storage-01)
│ 1. Embed la question → POST http://192.168.10.20:1234/v1/embeddings
│ 2. Recherche vectorielle → POST http://127.0.0.1:6333/collections/funk-docs/points/search
Qdrant (storage-01:6333)
│ Retourne les N chunks les plus proches sémantiquement
rag-query affiche les extraits + fichier source + score
Hermes formule sa réponse en citant les sources
```
---
## Composants déployés
| Composant | Emplacement | Rôle |
|---|---|---|
| Qdrant | storage-01:6333/6334 | Base vectorielle — stocke les embeddings |
| `rag-ingest` | `/usr/local/bin/rag-ingest` | Indexe les docs dans Qdrant |
| `rag-query` | `/usr/local/bin/rag-query` | Interroge Qdrant depuis la ligne de commande |
| Skill `rag-docs` | Profil `funk-ai` Hermes | Enseigne à Hermes comment utiliser `rag-query` |
| Docs indexées | `/srv/data/rag/docs/` (NVMe) | Copie locale du dossier `admin/` |
| Collection Qdrant | `funk-docs` | 339 chunks — dimension 4096 (Cosine) |
---
## Modèle d'embedding utilisé
**Qwen3-8B** via llama-server GPU (port 1234), avec les flags `--embeddings --pooling mean`.
C'est le modèle de chat principal, réutilisé pour les embeddings.
### Limitation connue
Qwen3-8B est un modèle génératif, **pas un modèle d'embedding dédié**.
Ses représentations vectorielles ont peu de discrimination sémantique :
les scores de similarité cosinus sont uniformément hauts (0.900.95)
quelle que soit la pertinence du résultat.
Conséquence : les résultats retournés ne sont pas triés par pertinence réelle —
le fichier avec le plus de tokens (ex : `incidents.md`) remonte souvent en premier.
### Quand améliorer
Pour une recherche sémantique précise, utiliser un modèle d'embedding dédié :
| Modèle | Taille | Dimension | Notes |
|---|---|---|---|
| `nomic-embed-text-v1.5` | ~274 MB | 768 | Rapide, bon équilibre qualité/taille |
| `bge-m3` | ~1.2 GB | 1024 | Multilingue (français natif) — meilleur choix pour ce repo |
Déploiement si besoin :
```bash
# Sur gpu-01 — télécharger le modèle
ssh gpu-01 "lms get nomic-ai/nomic-embed-text-v1.5-GGUF"
# Ajouter une instance llama-server sur port 1238 (CPU, embedding only)
# Modifier ansible/roles/rag/defaults/main.yml :
# embed_url: "http://192.168.10.20:1238/v1/embeddings"
# embed_model: "nomic-embed-text-v1.5"
# Puis re-indexer : rag-ingest /srv/data/rag/docs/
```
---
## Utilisation
### Via Hermes (funk-ai)
Le skill `rag-docs` est chargé dans le profil `funk-ai`. Hermes l'utilise
automatiquement pour les questions sur le cluster :
```
# Dans le TUI Hermes :
"Comment je relance dnsmasq ?"
→ Hermes appelle rag-query en interne et cite les sources
```
### En ligne de commande
```bash
# Depuis storage-01
rag-query "ma question"
rag-query "ma question" --top 3 # limiter les résultats (défaut: 5)
# Exemples
rag-query "comment relancer llama-server gpu"
rag-query "nftables firewall port cluster"
rag-query "hermes profils configuration"
rag-query "alertmanager webhook pipeline"
rag-query "monitoring grafana dashboard"
```
---
## Mise à jour de l'index
L'index doit être re-généré après chaque modification de la doc `admin/`.
### Via Ansible (recommandé)
```bash
cd ansible/
../.venv/bin/ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags rag
```
Ansible synchronise `admin/` vers `/srv/data/rag/docs/` puis relance automatiquement
`rag-ingest` (handler Ansible).
### Manuellement
```bash
# Synchroniser les docs (depuis le poste perso)
rsync -av --delete admin/ storage-01:/srv/data/rag/docs/
# Ré-indexer (depuis storage-01)
ssh storage-01 "rag-ingest /srv/data/rag/docs/"
```
L'ingestion prend ~5-10 minutes pour 339 chunks (embeddings via GPU).
Elle est idempotente — re-lancer ne crée pas de doublons (IDs stables basés sur MD5 du fichier+section).
---
## Administration Qdrant
```bash
# Collections existantes
curl -s http://storage-01:6333/collections | python3 -m json.tool
# Stats de la collection funk-docs
curl -s http://storage-01:6333/collections/funk-docs | python3 -m json.tool
# Nombre de points indexés
curl -s http://storage-01:6333/collections/funk-docs \
| python3 -c "import sys,json; print(json.load(sys.stdin)['result']['points_count'])"
# Vider et re-créer la collection (si re-indexation propre nécessaire)
curl -s -X DELETE http://storage-01:6333/collections/funk-docs
rag-ingest /srv/data/rag/docs/
# Statut du service
ssh storage-01 "systemctl status qdrant --no-pager"
```
---
## Structure des fichiers
```
ansible/roles/rag/
├── defaults/main.yml # URLs Qdrant/embed, collection, répertoires
├── tasks/main.yml # Déploiement scripts + docs + skill Hermes
├── handlers/main.yml # Handler : Run rag-ingest + Restart hermes-agent
└── files/
├── rag-ingest # Script Python d'ingestion
├── rag-query # Script Python de requête
└── rag-docs/SKILL.md # Skill Hermes
hermes-skills/funk/rag-docs/
└── SKILL.md # Source versionnée du skill (copié dans files/)
/srv/data/rag/ (NVMe storage-01 — bind-mount /home/data)
├── docs/ # Copie de admin/ — source des chunks
└── (Qdrant stocke dans /srv/data/qdrant/)
```
---
## Points d'attention
| Sujet | Détail |
|---|---|
| Qualité embeddings | Qwen3-8B = modèle chat réutilisé — scores peu discriminants. Fonctionnel mais pas optimal. |
| Modèle dédié | `nomic-embed-text` ou `bge-m3` diviseraient les faux positifs par ~3 |
| Contention GPU | `rag-ingest` sollicite le GPU (port 1234) pendant ~5-10 min — éviter pendant une session d'inférence active |
| Re-indexation | Obligatoire après modification de `admin/` — pas de sync automatique |
| Qdrant persistance | Données dans `/srv/data/qdrant/` sur NVMe — survivent aux redémarrages |
| Score minimum | `MIN_SCORE = 0.60` dans `rag-query` — tous les résultats sont au-dessus avec ce modèle |