Ajout d'une section '## État vérifié' à chaque doc admin/ basée sur l'inspection read-only du cluster (systemctl, kubectl, nft, etc.). Aucune modification de service ni réécriture de documentation existante. Co-Authored-By: Hermes <hermes@funk.lab>
14 KiB
Hermes Agent
Hermes Agent tourne en deux services systemd sur storage-01 :
hermes-agent— gateway (messagerie, inférence, outils)hermes-dashboard— interface web (port 9119)
Il passe par LiteLLM (:4000) pour toute inférence — Qwen local ou Claude API.
Les données persistantes sont dans /srv/data/hermes (NVMe bind-mount depuis 2026-05-29, plus RAID5).
Architecture
Profils Hermes → LiteLLM Proxy (:4000) → llama-server / API Anthropic
├── qwen3-8b → gpu-01:1234 (GPU RX 6700XT)
├── qwen3-1.7b-system → gpu-01:1236 (CPU 14 threads)
├── qwen3-1.7b-monitor → gpu-01:1237 (CPU 14 threads)
├── claude-sonnet-4-6 → api.anthropic.com
└── claude-opus-4-7 → api.anthropic.com
Depuis Hermes (TUI ou ask-agent) :
funk-ai (principal) ──┐
brain ├── LM_BASE_URL=http://127.0.0.1:4000/v1
system │
monitor ──┘
Profils
| Profil | Alias CLI | Modèle | Usage |
|---|---|---|---|
funk-ai ◆ |
funk-ai |
qwen3-8b (GPU, ~35 tok/s) | Principal — par défaut |
brain |
brain |
claude-sonnet-4-6 (API) | Analyse complexe — facturé |
system |
system |
qwen3-1.7b-system (CPU, ~21 tok/s) | Traitement texte rapide |
monitor |
monitor |
qwen3-1.7b-monitor (CPU, ~21 tok/s) | Évaluation état services |
◆ = profil actif par défaut
# Lancer un profil (nouvelle session TUI)
funk-ai # Qwen3-8B GPU
brain # Claude Sonnet
system # Qwen3-1.7B CPU
monitor # Qwen3-1.7B CPU
# Oneshot
sudo -i -u hermes bash -c 'HERMES_HOME=/srv/data/hermes hermes --profile system -z "ta question"'
# Changer le profil par défaut
sudo -i -u hermes bash -c 'HERMES_HOME=/srv/data/hermes hermes profile use funk-ai'
# Lister les profils
sudo -i -u hermes bash -c 'HERMES_HOME=/srv/data/hermes hermes profile list'
Pas de changement de profil à chaud dans le TUI — ouvrir une nouvelle session.
Service systemd
sudo systemctl status hermes-agent
sudo systemctl restart hermes-agent
sudo journalctl -u hermes-agent -f
sudo journalctl -u hermes-agent -n 50
TUI (chat interactif)
Le TUI nécessite un TTY et doit tourner sous le compte hermes :
ssh storage-01
sudo -i -u hermes
cd /srv/data/hermes
hermes --tui
Lancer depuis un autre compte génère des "gateway error" — toujours utiliser le compte hermes.
Dashboard Web
Accessible depuis le poste admin uniquement (192.168.1.10) :
http://192.168.1.200:9119
sudo systemctl status hermes-dashboard
sudo systemctl restart hermes-dashboard
sudo journalctl -u hermes-dashboard -f
L'onglet Chat (TUI via WebSocket) ne fonctionne pas dans le dashboard. Utiliser le TUI SSH.
CLI
# Chat interactif (depuis storage-01, compte hermes)
cd /srv/data/hermes && hermes chat
# Question one-shot
cd /srv/data/hermes && hermes -z "ta question"
# Statut global
hermes status
# Diagnostics
hermes doctor
Configuration
config.yaml (/srv/data/hermes/config.yaml)
model:
provider: lmstudio
base_url: "http://127.0.0.1:4000/v1"
default: "hermes-default"
context_length: 65536
gateway:
host: "0.0.0.0"
port: 8080
.env (/srv/data/hermes/.env)
LM_BASE_URL=http://127.0.0.1:4000/v1
LM_API_KEY=lm-studio # valeur exacte obligatoire
Variables d'environnement (service systemd)
| Variable | Valeur |
|---|---|
HOME |
/opt/hermes |
HERMES_HOME |
/srv/data/hermes |
LM_BASE_URL |
http://127.0.0.1:4000/v1 |
LM_API_KEY |
lm-studio |
SOUL.md — Identité des profils
Chaque profil peut avoir un fichier SOUL.md chargé en slot #1 du system prompt.
Il définit l'identité de l'agent, son environnement, ses outils et son comportement.
Rechargé à chaque message sans redémarrage du service.
/srv/data/hermes/profiles/<profil>/SOUL.md
Sources versionnées dans le repo :
hermes-skills/souls/funk-ai.md → profil funk-ai
hermes-skills/souls/system.md → profil system
hermes-skills/souls/monitor.md → profil monitor
hermes-skills/souls/brain.md → profil brain
Le SOUL.md de funk-ai contient : environnement cluster (IPs, machines, services),
accès SSH gpu-01, règles ask-agent, routing system/monitor/brain, style de réponse.
# Déployer un SOUL.md depuis le repo
scp hermes-skills/souls/funk-ai.md storage-01:/tmp/soul.md
ssh storage-01 "sudo cp /tmp/soul.md /srv/data/hermes/profiles/funk-ai/SOUL.md"
# Pas de redémarrage nécessaire — rechargé automatiquement
Skills
Les skills sont des fichiers SKILL.md chargés en contexte dans chaque session Hermes.
Règle critique : un skill doit être présent dans deux endroits :
$HERMES_HOME/skills/<cat>/<nom>/SKILL.md— répertoire global (référence)$HERMES_HOME/profiles/<profil>/skills/<cat>/<nom>/SKILL.md— chargé par le profilPlacer un skill uniquement dans le global ne suffit pas.
# Lister les skills actifs du profil courant
sudo -u hermes env HERMES_HOME=/srv/data/hermes hermes skills list
# Vérifier qu'un skill est dans le profil funk-ai
sudo ls /srv/data/hermes/profiles/funk-ai/skills/funk/
Skills custom Funk
| Skill | Catégorie | Usage |
|---|---|---|
agent-delegation |
funk |
Déléguer des sous-tâches aux agents system/monitor/brain via ask-agent |
Ajouter un skill custom
# 1. Créer dans le repo (versionné)
mkdir -p hermes-skills/funk/<nom-skill>
vim hermes-skills/funk/<nom-skill>/SKILL.md
# 2. Déployer dans le répertoire global
sudo mkdir -p /srv/data/hermes/skills/funk/<nom-skill>
sudo cp hermes-skills/funk/<nom-skill>/SKILL.md /srv/data/hermes/skills/funk/<nom-skill>/
# 3. Copier dans le profil cible
sudo mkdir -p /srv/data/hermes/profiles/funk-ai/skills/funk/<nom-skill>
sudo cp /srv/data/hermes/skills/funk/<nom-skill>/SKILL.md \
/srv/data/hermes/profiles/funk-ai/skills/funk/<nom-skill>/
sudo chown -R hermes:hermes /srv/data/hermes/profiles/funk-ai/skills/funk
# 4. Redémarrer + vérifier
sudo systemctl restart hermes-agent
sudo -u hermes env HERMES_HOME=/srv/data/hermes hermes skills list | grep funk
Mettre à jour un skill existant
vim hermes-skills/funk/agent-delegation/SKILL.md
sudo cp hermes-skills/funk/agent-delegation/SKILL.md \
/srv/data/hermes/skills/funk/agent-delegation/SKILL.md
sudo cp hermes-skills/funk/agent-delegation/SKILL.md \
/srv/data/hermes/profiles/funk-ai/skills/funk/agent-delegation/SKILL.md
sudo chown hermes:hermes \
/srv/data/hermes/profiles/funk-ai/skills/funk/agent-delegation/SKILL.md
sudo systemctl restart hermes-agent
ask-agent — Délégation inter-agents
ask-agent permet à Hermes (profil funk-ai) de déléguer des sous-tâches
aux agents spécialisés. Le skill funk/agent-delegation lui enseigne quand et comment.
funk-ai (Qwen3-8B GPU)
│
│ Terminal: ask-agent <agent> "question"
▼
ask-agent (/usr/local/bin/ask-agent)
│ POST http://127.0.0.1:4000/v1/chat/completions
▼
LiteLLM Proxy (:4000)
├── ask-agent system → qwen3-1.7b-system (CPU :1236)
├── ask-agent monitor → qwen3-1.7b-monitor (CPU :1237)
├── ask-agent brain → claude-sonnet-4-6 (API Anthropic)
└── ask-agent funk-ai → qwen3-8b (GPU :1234)
Agents disponibles
| Agent | Modèle | Usage idéal |
|---|---|---|
system |
Qwen3-1.7B CPU (:1236) | Traitement texte : résumés, formatage, parsing, calculs Linux |
monitor |
Qwen3-1.7B CPU (:1237) | Évaluation santé : logs systemd, métriques, état des services |
brain |
Claude Sonnet 4.6 (API) | Raisonnement complexe, architecture — facturé |
funk-ai |
Qwen3-8B GPU (:1234) | Tâches générales (agent principal lui-même) |
system vs monitor
| Critère | system |
monitor |
|---|---|---|
| Type de question | "Qu'est-ce que ça signifie ?" / "Résume ça" | "Y a-t-il des erreurs ?" / "Ce service est-il sain ?" |
| Output | Réponse directe, liste de faits | Verdict OK/WARNING/ERROR + actions correctives |
Utilisation
# system : traitement de texte
ask-agent system "que signifie cette sortie df -h : <texte>"
ask-agent system "convertis 8192 MiB en GiB"
# monitor : évaluation santé
ask-agent monitor "logs litellm : <texte> — erreurs ?"
ask-agent monitor "status llama-server : <texte> — service sain ?"
# brain : analyse complexe
ask-agent brain "architecture optimale pour ce schéma k8s : <contexte>" --max-tokens 3000
# Avec prompt système personnalisé
ask-agent monitor "est-ce normal ?" --system "Tu es expert Linux, réponds en 1 phrase max."
Pattern typique — Hermes collecte en local, délègue l'analyse :
Terminal: systemctl --state=failed --no-pager
Terminal: ask-agent monitor "voici les services en erreur : <résultat> — résume les problèmes"
Paramètres du script
Déployé sur storage-01 : /usr/local/bin/ask-agent
Source versionnée : ansible/roles/litellm/files/ask-agent
| Paramètre | Valeur |
|---|---|
| LiteLLM URL | http://127.0.0.1:4000/v1/chat/completions |
| API key | lm-studio |
| Timeout | 120s (curl) |
/no_think |
Préfixé automatiquement pour system et monitor (évite la surconsommation de tokens) |
# Redéployer via Ansible
ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags litellm
Arborescence
Depuis l'incident 2026-05-13, le code est sur le SSD OS. Depuis l'incident 2026-05-29, les données sont sur NVMe (/home/data bind-monté sur /srv/data), plus sur le RAID5.
/opt/hermes/ → home utilisateur hermes (SSD OS)
├── .local/bin/hermes → wrapper bash → venv hermes-agent
└── .hermes/hermes-agent/ → code source + venv Python
├── venv/ → environnement Python (uv)
├── hermes_cli/ → source CLI
└── web/ → source frontend dashboard
/srv/data/hermes/ → HERMES_HOME (NVMe bind-mount) — données persistantes
├── config.yaml → configuration profil par défaut (géré Ansible)
├── .env → LM_BASE_URL, LM_API_KEY (géré Ansible)
├── memories/ → mémoire persistante profil par défaut
├── sessions/ → historique sessions
├── logs/ → logs
├── skills/ → skills installées
├── state.db → base SQLite état agent
└── profiles/ → profils isolés
├── funk-ai/ → config.yaml, memories/, sessions/, state.db, SOUL.md
├── brain/
├── system/
└── monitor/
Mise à jour de Hermes
sudo systemctl stop hermes-dashboard hermes-agent
sudo -i -u hermes bash -c 'HOME=/opt/hermes HERMES_HOME=/srv/data/hermes hermes update'
sudo systemctl start hermes-agent hermes-dashboard
sudo systemctl status hermes-agent hermes-dashboard --no-pager
Si rebuild frontend nécessaire après mise à jour majeure :
sudo -u hermes bash -c \
'HOME=/opt/hermes && cd /opt/hermes/.hermes/hermes-agent/web && npm install && npm run build'
sudo systemctl restart hermes-dashboard
Dépannage
ask-agent retourne du garbage
Modèle GGUF potentiellement corrompu (signe d'erreur disque).
ssh g01 "sudo systemctl status llama-server-system"
ssh g01 "md5sum /mnt/models/<chemin-gguf>"
ask-agent timeout
LiteLLM ou llama-server ne répond pas.
ssh s01 "curl -s http://localhost:4000/health -H 'Authorization: Bearer lm-studio'"
ssh g01 "systemctl status llama-server-system llama-server-monitor"
Le skill n'est pas chargé
sudo ls /srv/data/hermes/profiles/funk-ai/skills/funk/agent-delegation/
Si absent → copier depuis /srv/data/hermes/skills/funk/agent-delegation/ et redémarrer.
Hermes fait SSH vers storage-01
Le skill lui dit "tu es déjà sur storage-01". Une session déjà ouverte charge l'ancien skill. Fermer le TUI et en ouvrir un nouveau après chaque modification.
Points d'attention
| Sujet | Détail |
|---|---|
| Code vs données | Code + venv : /opt/hermes/.hermes/hermes-agent/ (SSD OS) — Profils/données : /srv/data/hermes/ (NVMe) |
HERMES_HOME |
Toujours préfixer les commandes hermes avec HERMES_HOME=/srv/data/hermes |
LM_API_KEY |
Doit valoir lm-studio exactement |
context_length |
Hermes exige 64k minimum — override via model.context_length: 65536 dans config.yaml |
hermes -z path |
Toujours lancer depuis /srv/data/hermes (cherche .git en remontant) |
| LiteLLM requis | litellm.service doit tourner avant hermes-agent |
| Skills double emplacement | Tout skill custom doit être dans skills/ ET dans profiles/funk-ai/skills/ |
| Restart après skill | systemctl restart hermes-agent obligatoire après ajout ou modification d'un skill |
| brain coûteux | Claude Sonnet API — réserver aux analyses que system/monitor ne peuvent pas faire |
| Gemma 4 interdit | Crash ROCm sur prompts >800 tokens |
| Dashboard | Accessible uniquement depuis 192.168.1.10:9119 (restreint nftables) |
| TUI | hermes --tui nécessite un TTY — utiliser SSH interactif sous le compte hermes |
systemd-journal |
Le service inclut ce groupe — journalctl fonctionne sans sudo dans le Terminal de Hermes |
État vérifié — 2026-06-05
- Service
hermesintrouvable (commandesystemctl status hermesretourne erreur 2) - Fichier de configuration existant :
model: qwen3-8b provider: lmstudio base_url: "http://127.0.0.1:4000/v1" default: "hermes-default" context_length: 65536 - Aucune divergence notée avec la documentation existante
- Configuration du gateway actif sur
0.0.0.0:8080sans anomalies déclarées