* fix(rag): ubatch=2048 pour llama-embed + retry rag-ingest + nettoie defaults rag L'instance llama-embed (:1238) tournait avec l'ubatch llama.cpp par défaut (512). En mode --embeddings + pooling, toute l'entrée doit tenir dans un seul ubatch → tout chunk > 512 tokens échouait en HTTP 500 « input too large to process. increase the physical batch size ». ~46 chunks du RAG (CHUNK_MAX=2000 chars ≈ 700 tokens) n'étaient pas indexés. - llama_server : ajoute llama_embed_ubatch_size (2048 = ctx) + flags --batch-size/--ubatch-size dans le template llama-embed.service. - rag-ingest : retry (5×, backoff) sur erreurs transitoires 5xx/réseau de l'embed. - rag/defaults : aligne embed_url/embed_model sur nomic :1238 (étaient des vars mortes pointant encore qwen3-8b :1234 — trompeuses). Résultat : ré-ingestion 436/436 chunks, 0 erreur. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(cluster): aligne la doc sur l'état réel (relevé 2026-06-21) + snapshot Passe de vérification terrain (SSH s01/g01 + kubectl) pour corriger les écarts doc↔réalité, et ajout d'un document de référence vérifié. - admin/ops/etat-cluster.md (nouveau) : snapshot daté — machines, services+ports par hôte, workloads k8s, namespaces, IngressRoute, bases PG, modèles LiteLLM, RAG/Qdrant, + procédure pour régénérer le relevé. - OS AlmaLinux 9.7 → 9.8 (s01/g01) ; précise k8s v1.33.1 (CLAUDE/README/install/talos). - RAG funk-docs : retire le warning périmé « supprimée 2026-06-17 / à re-ingérer » → reconstruite (436 chunks, nomic-embed-text :1238 dim 768, CPU). Maj rag.md, incidents.md, stt.md. - Namespace sacrifice (hors-repo, hors ArgoCD) + bases PG grafana/sacrifice + services ai via IngressRoute + registry in-cluster (CLAUDE.md, k9s.md). - Services de résilience (llm-heartbeat, llama-watchdog/embed) et instances CPU manuelles :1236/:1237 (souvent éteintes) documentés. - Journal progress/2026-06-21.md : section relevé + RAG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
6.6 KiB
RAG — Documentation Funk
✅ Opérationnel (relevé 2026-06-21) —
funk-docsreconstruite après l'incident Qdrant du 2026-06-17 : 436 chunks, statut 🟢 green, embeddings nomic-embed-text (:1238, dim 768).rag-queryfonctionne. Détails de l'incident :admin/incidents.md(entrée 2026-06-05).
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:1238/v1/embeddings (nomic-embed-text)
│ 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 |
436 chunks, 🟢 green, dim 768 Cosine (nomic-embed-text) |
Modèle d'embedding utilisé
nomic-embed-text via l'instance dédiée llama-server llama-embed sur gpu-01 (:1238, CPU,
dim 768). C'est un vrai modèle d'embedding — les scripts déployés rag-ingest et rag-query
le hardcodent (EMBED_URL=http://192.168.10.20:1238/v1/embeddings, EMBED_MODEL=nomic-embed-text).
Historique : le RAG utilisait au départ Qwen3-8B (modèle de chat,
:1234, dim 4096) réutilisé pour les embeddings → scores cosinus saturés (0.90–0.95), peu discriminants. La migration vers nomic (dim 768) étale les scores → tri par pertinence réel. La collection a été recréée à dim 768.
⚠️ Drift IaC :
ansible/roles/rag/defaults/main.ymla longtemps gardéembed_url: :1234/embed_model: qwen3-8b— variables mortes (le handler lancerag-ingestsans passer d'env → le défaut hardcodé nomic du script gagne). Aligné sur nomic dans le même lot que ce relevé.
L'instance llama-embed est gérée par le rôle llama_server (llama_embed_enabled, voir son README).
# (re)déployer l'instance embeddings sur gpu-01
ansible-playbook -i inventory.yml playbooks/gpu-01.yml --tags llama_server
Alternative envisagée
| Modèle | Taille | Dimension | Notes |
|---|---|---|---|
nomic-embed-text |
~274 MB | 768 | En service — rapide, bon équilibre qualité/taille |
bge-m3 |
~1.2 GB | 1024 | Multilingue (français natif) — option si la qualité FR doit monter |
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
# 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é)
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
# 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 quelques minutes pour ~436 chunks (embeddings via l'instance nomic :1238, CPU).
Elle est idempotente — re-lancer ne crée pas de doublons (IDs stables basés sur MD5 du fichier+section).
Administration Qdrant
# 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 | nomic-embed-text (modèle dédié) — scores cosinus discriminants, tri par pertinence réel |
| Embeddings CPU | llama-embed (:1238) tourne en CPU (découplé du slot chat GPU) — rag-ingest ne contend pas le GPU. ubatch=2048 requis (sinon 500 sur chunks > 512 tokens) |
| 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 dans rag-query ajusté pour nomic (scores plus étalés que qwen3-8b) |