mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-08 18:24:42 +02:00
docs: synchroniser la doc avec l'état réel du cluster (revue Ansible + incident Qdrant)
- ops/ansible.md : tableau complet des rôles par playbook (15 storage-01, 6 gpu-01),
caveat hermes_agent, note lm_studio inutilisé
- ia/hermes-auto-improve.md : NOUVEAU — doc du worker déployé (trigger :9095,
modes du script, endpoints, PR squash, pièges connus)
- k8s/n8n.md : workflow 3 "Hermes Doc Worker" documenté (22h, /trigger/all,
boucle de polling), clé API → vault
- incidents.md : Qdrant crash-loop depuis 2026-06-05 (segment funk-docs corrompu,
invisible dans --state=failed) + procédure de réparation
- ia/rag.md : bandeau RAG HS
- CLAUDE.md : état 2026-06-10, rôle hermes_auto_improve, 3 workflows n8n,
vault complet (n8n_api_key, Gmail au lieu de Brevo), section auto-improve
- README.md : lien admin/ops/cluster.md corrigé, arborescence complète
(tools/, admin/, progress/, skills), roadmap à jour
- PROGRESS.md : entrée 2026-05-29 (migration NVMe) qui existait sans être référencée
- ansible : suppression effective des templates daily timer (cleanup b9be63c)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
ddff71a0fb
commit
40fd7f0868
10 changed files with 270 additions and 42 deletions
94
admin/ia/hermes-auto-improve.md
Normal file
94
admin/ia/hermes-auto-improve.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# hermes-auto-improve — Analyse quotidienne de la documentation
|
||||
|
||||
Hermes analyse chaque jour la base de connaissance `admin/`, écrit ses rapports dans
|
||||
`admin/hermes/builtin/` et pousse le tout sur la branche `hermes/daily-work`.
|
||||
Une PR squash-only vers `main` est créée (ou mise à jour) automatiquement.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
n8n « Hermes Doc Worker » (22h00)
|
||||
│ POST http://192.168.10.1:9095/trigger/all
|
||||
▼
|
||||
trigger server (storage-01:9095, systemd hermes-auto-improve)
|
||||
│ lance en background thread
|
||||
▼
|
||||
/usr/local/bin/hermes-auto-improve --all
|
||||
│ pour chaque .md de admin/ (sauf hermes/builtin/) :
|
||||
│ prompt → Hermes (profil funk-ai, Qwen3-8B sur gpu-01)
|
||||
│ → rapport JSON (statut, score, problèmes, suggestions)
|
||||
▼
|
||||
admin/hermes/builtin/YYYY-MM-DD_HH-MM.md (rapport consolidé)
|
||||
│ git commit + push → hermes/daily-work
|
||||
▼
|
||||
n8n poll GET :9095/status (toutes les 5 min jusqu'à running=false)
|
||||
│
|
||||
▼
|
||||
Email récap + PR GitHub (POST :9095/trigger/daily-pr)
|
||||
```
|
||||
|
||||
## Composants
|
||||
|
||||
| Élément | Emplacement | Géré par |
|
||||
|---|---|---|
|
||||
| Script d'analyse | `/usr/local/bin/hermes-auto-improve` | rôle `hermes_auto_improve` (source `tools/hermes-auto-improve/auto-improve.py`) |
|
||||
| Trigger server | `/usr/local/bin/hermes-auto-improve-server` (`:9095`) | rôle `hermes_auto_improve` (source `tools/hermes-auto-improve/trigger-server.py`) |
|
||||
| Service systemd | `hermes-auto-improve.service` (le serveur HTTP, pas de timer) | rôle `hermes_auto_improve` |
|
||||
| Scheduling | workflow n8n `CX72UUOempE1YtNL` — Schedule 22h00 | n8n (voir `admin/k8s/n8n.md`) |
|
||||
| État de rotation | `/var/lib/hermes-auto-improve/state.json` | script |
|
||||
| Log des runs | `/var/log/hermes-auto-improve.log` | trigger server |
|
||||
| Clone de travail | `/srv/data/lab/Funk-lab` (branche `hermes/daily-work`) | script (git_sync au début de chaque run) |
|
||||
|
||||
## Modes du script
|
||||
|
||||
```bash
|
||||
hermes-auto-improve # batch de 5 fichiers (rotation via state.json)
|
||||
hermes-auto-improve --all # tous les docs en une passe (~60-90 min pour 28 fichiers)
|
||||
hermes-auto-improve --subdir ia # un sous-dossier admin/ uniquement
|
||||
hermes-auto-improve --dry-run # analyse sans écrire ni push
|
||||
hermes-auto-improve --daily-pr # crée la PR GitHub (ou met à jour celle ouverte)
|
||||
```
|
||||
|
||||
## Endpoints du trigger server (`:9095`)
|
||||
|
||||
| Endpoint | Action |
|
||||
|---|---|
|
||||
| `POST /trigger` | run standard (batch de 5) |
|
||||
| `POST /trigger/all` | run complet `--all` |
|
||||
| `POST /trigger/subdir` | body `{"subdir": "ia"}` |
|
||||
| `POST /trigger/dry-run` | analyse sans commit |
|
||||
| `POST /trigger/daily-pr` | crée/met à jour la PR |
|
||||
| `GET /status` | `{running, last_result, state}` |
|
||||
| `GET /health` | healthcheck |
|
||||
|
||||
Un seul run à la fois (`already_running` sinon). Timeout interne : 7200 s.
|
||||
|
||||
## PR GitHub
|
||||
|
||||
- Branche : `hermes/daily-work` → `main`, **squash merge uniquement** (forcé côté repo GitHub)
|
||||
- S'il existe déjà une PR ouverte pour la branche, le script **met à jour** titre + corps au lieu d'en créer une nouvelle
|
||||
- Identité des commits : `Hermes Bot <hermes@funk.lab>`
|
||||
- Le push utilise les credentials `gh` de root sur storage-01 (`HOME=/root` dans le service)
|
||||
|
||||
## Vérifications rapides
|
||||
|
||||
```bash
|
||||
# Le serveur tourne ?
|
||||
curl -s http://192.168.10.1:9095/health
|
||||
|
||||
# Un run est en cours ? Dernier résultat ?
|
||||
curl -s http://192.168.10.1:9095/status | python3 -m json.tool
|
||||
|
||||
# Suivre un run en direct (le log n'est écrit qu'en fin de run — vérifier le process)
|
||||
ssh storage-01 'ps aux | grep "hermes-auto-improve --" | grep -v grep'
|
||||
ssh storage-01 'sudo tail -50 /var/log/hermes-auto-improve.log'
|
||||
```
|
||||
|
||||
## Pièges connus
|
||||
|
||||
- **Le log n'est flushé qu'à la fin du run** — un run `--all` peut sembler silencieux pendant une heure. Vérifier le process ou compter les `POST /v1/chat/completions` dans `journalctl -u litellm`.
|
||||
- **`git pull --rebase` dans git_sync** : si on réécrit l'historique de `hermes/daily-work` (force push), il faut aussi reset le clone `/srv/data/lab/Funk-lab` sur storage-01, sinon le prochain run réincorpore les anciens commits.
|
||||
- **rag-ingest en fin de run** : échoue tant que Qdrant est HS (incident 2026-06-05) — le run reste valide, seule la ré-indexation est sautée.
|
||||
- Les rapports `admin/hermes/builtin/` sont indexés dans le RAG par `rag-ingest` (qui parcourt tout `admin/`) — pollution potentielle des résultats `rag-query`, exclusion à prévoir.
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
# RAG — Documentation Funk
|
||||
|
||||
> ⚠️ **HS depuis 2026-06-05** — Qdrant en crash-loop (segment `funk-docs` corrompu).
|
||||
> Procédure de réparation dans `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.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,48 @@
|
|||
# Incidents — Historique et résolutions
|
||||
|
||||
## 2026-06-05 — Qdrant en crash-loop : segment funk-docs corrompu (EN COURS)
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `rag-query` et `rag-ingest` → `Connection refused` (port 6333 fermé)
|
||||
- `systemctl status qdrant` → `activating (auto-restart)` en boucle, exit code 101
|
||||
- **Invisible dans `systemctl --state=failed`** (l'unité reste en `activating`, jamais `failed`) — l'incident est passé inaperçu 5 jours
|
||||
|
||||
### Cause
|
||||
|
||||
Panic au démarrage de Qdrant 1.13.4 :
|
||||
|
||||
```
|
||||
Failed to load local shard "/srv/data/qdrant/storage/collections/funk-docs/0":
|
||||
Can't parse version from ".../segments/784eab54-.../version.info",
|
||||
error: unexpected character 'D' while parsing minor version number
|
||||
```
|
||||
|
||||
Le fichier `version.info` du segment contient `0.D\0` au lieu d'un numéro de version — corruption de données (première occurrence le 2026-06-05 à 21h10).
|
||||
|
||||
### Résolution (à appliquer)
|
||||
|
||||
La collection `funk-docs` est entièrement reconstructible depuis `admin/` :
|
||||
|
||||
```bash
|
||||
sudo systemctl stop qdrant
|
||||
sudo rm -rf /srv/data/qdrant/storage/collections/funk-docs
|
||||
sudo systemctl start qdrant
|
||||
curl -s http://127.0.0.1:6333/collections # doit répondre
|
||||
/usr/local/bin/rag-ingest # ré-indexe /srv/data/rag/docs
|
||||
```
|
||||
|
||||
### Prévention
|
||||
|
||||
- Ajouter une alerte Prometheus sur les unités systemd en `activating` prolongé (`node_systemd_unit_state`) — un crash-loop n'apparaît ni dans `failed` ni dans les alertes actuelles
|
||||
|
||||
---
|
||||
|
||||
## Index
|
||||
|
||||
| Date | Composant | Résumé | Sévérité |
|
||||
|---|---|---|---|
|
||||
| 2026-06-05 | Qdrant | **EN COURS** — crash-loop : segment `funk-docs` corrompu, RAG HS | Important |
|
||||
| 2026-05-29 | RAID5 / sdb + storage-01 | sdb ATA bus errors sous I/O — migration /srv/data du RAID vers NVMe | Important |
|
||||
| 2026-05-27 | RAID5 / sdd | Disque sdd défaillant (44 secteurs morts) — corruptions multiples en cascade | Critique |
|
||||
| 2026-05-14 | Grafana | OOMKilled — limite 256Mi trop serrée pour Grafana 13 | Warning |
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ n8n est le moteur d'automatisation du lab. Il orchestre les tâches récurrentes
|
|||
|---|---|
|
||||
| Namespace k8s | `ai` |
|
||||
| Port interne | `5678` |
|
||||
| API key | générée dans Settings → n8n API |
|
||||
| API key | générée dans Settings → n8n API — stockée dans le vault Ansible (`vault_n8n_api_key`) |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -161,6 +161,52 @@ Envoyer Rapport (SMTP)
|
|||
|
||||
---
|
||||
|
||||
### 3. Hermes Doc Worker — Funk-lab
|
||||
|
||||
**ID** : `CX72UUOempE1YtNL`
|
||||
**Déclencheurs** : Schedule quotidien **22h00** · webhook manuel `POST /webhook/hermes-doc-run` · (un ancien Schedule 30min existe mais est **désactivé**)
|
||||
|
||||
**Pipeline** :
|
||||
```
|
||||
Schedule 22h (ou webhook manuel)
|
||||
│
|
||||
▼
|
||||
Déclencher run (HTTP POST storage-01:9095/trigger/all)
|
||||
→ lance hermes-auto-improve --all (28 docs, ~60-90 min)
|
||||
│
|
||||
▼
|
||||
┌── Attendre run (5 min) ◄────────────┐
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Status run (GET :9095/status) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Run terminé ? (IF running=false) ─┘ false → reboucle
|
||||
│ │ true
|
||||
└───────▼
|
||||
Format Run → LLM Run (résumé) → Email Run → Envoyer Run
|
||||
│
|
||||
▼
|
||||
Est 22h ? (IF heure courante = 22)
|
||||
│ true
|
||||
▼
|
||||
Déclencher PR (POST :9095/trigger/daily-pr)
|
||||
→ crée ou met à jour la PR hermes/daily-work → main (squash-only)
|
||||
│
|
||||
▼
|
||||
Attendre PR (5 min) → Status PR → Format PR → LLM PR → Email PR → Envoyer PR
|
||||
```
|
||||
|
||||
**Backend** : trigger server `hermes-auto-improve` sur storage-01 (`:9095`), déployé par le rôle Ansible `hermes_auto_improve`. Voir `admin/ia/hermes-auto-improve.md`.
|
||||
|
||||
**Gestion via API** : la clé API n8n est dans le vault Ansible (`vault_n8n_api_key`) :
|
||||
```bash
|
||||
make vault-view | grep n8n_api_key
|
||||
curl -s -H "X-N8N-API-KEY: $KEY" http://n8n.lab.local/api/v1/workflows
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflows à ajouter
|
||||
|
||||
### Court terme
|
||||
|
|
|
|||
|
|
@ -1,10 +1,53 @@
|
|||
# Ansible — Commandes d'administration
|
||||
|
||||
Toutes les commandes se lancent depuis la racine du repo (`lab-infra/`).
|
||||
Toutes les commandes se lancent depuis la racine du repo (`Funk-lab/`).
|
||||
Le venv est dans `.venv/`, le `Makefile` fournit les raccourcis.
|
||||
|
||||
---
|
||||
|
||||
## Playbooks et rôles
|
||||
|
||||
Deux playbooks, un par machine (le `site.yml` les enchaîne) :
|
||||
|
||||
### `playbooks/storage-01.yml` — hosts `gateway` (15 rôles)
|
||||
|
||||
| Rôle | Tag | Ce qu'il gère |
|
||||
|---|---|---|
|
||||
| `hermes_user` | `hermes_user` | User `hermes` + clés SSH partagées entre hosts |
|
||||
| `common` | `common` | Paquets de base, sécurité, NTP |
|
||||
| `gateway` | `gateway` | nftables + NAT (routeur du LAN cluster) |
|
||||
| `dnsmasq` | `dnsmasq` | DNS local `lab.local` + wildcard → Traefik |
|
||||
| `nfs_server` | `nfs_server` | Exports NFS (modèles LLM, volumes k8s) |
|
||||
| `qdrant` | `qdrant` | Base vectorielle (RAG) — `:6333` |
|
||||
| `postgresql` | `postgresql` | PG 16 — bases hermes, litellm, n8n, openwebui, grafana |
|
||||
| `minio` | `minio` | Stockage objet S3 |
|
||||
| `litellm` | `litellm` | Proxy LLM `:4000` + script `ask-agent` |
|
||||
| `hermes_agent` | `hermes_agent` | Agent Hermes + skills + souls |
|
||||
| `rag` | `rag` | Scripts `rag-ingest` / `rag-query` + docs RAG |
|
||||
| `node_exporter` | `node_exporter` | Métriques Prometheus |
|
||||
| `alertmanager_webhook` | `alertmanager_webhook` | Pont AlertManager → ask-agent `:9093` |
|
||||
| `postfix_relay` | `postfix_relay` | SMTP sortant via Gmail (App Password) |
|
||||
| `hermes_auto_improve` | `hermes_auto_improve` | Worker analyse doc + trigger server `:9095` (schedulé par n8n à 22h) |
|
||||
|
||||
### `playbooks/gpu-01.yml` — hosts `gpu_hosts` (6 rôles)
|
||||
|
||||
| Rôle | Tag | Ce qu'il gère |
|
||||
|---|---|---|
|
||||
| `hermes_user` | `hermes_user` | User `hermes` (clé partagée avec storage-01) |
|
||||
| `common` | `common` | Paquets de base, sécurité, NTP |
|
||||
| `rocm` | `rocm` | Stack GPU AMD (ROCm 7.x, `HSA_OVERRIDE_GFX_VERSION=10.3.0`) |
|
||||
| `nfs_client` | `nfs_client` | Montage `/mnt/models` depuis storage-01 |
|
||||
| `llama_server` | `llama_server` | llama-server ×3 : GPU `:1234`, CPU `:1236`/`:1237` |
|
||||
| `node_exporter` | `node_exporter` | Métriques Prometheus (+ rocm power) |
|
||||
|
||||
> ⚠️ Le rôle `lm_studio` existe encore dans `ansible/roles/` mais n'est référencé par **aucun** playbook (remplacé par `llama_server` en mai 2026). Candidat à la suppression.
|
||||
|
||||
### Caveat premier déploiement — `hermes_agent`
|
||||
|
||||
Sur un hôte vierge, il faut **deux runs consécutifs** : le premier installe le binaire (`curl | bash`), le second applique la config (conditionnelle à l'existence du binaire).
|
||||
|
||||
---
|
||||
|
||||
## Raccourcis Makefile
|
||||
|
||||
```bash
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue