# 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 ```bash # 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 ```bash 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` : ```bash 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 ``` ```bash 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 ```bash # 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`) ```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`) ```bash 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//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. ```bash # 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///SKILL.md` — répertoire global (référence) > - `$HERMES_HOME/profiles//skills///SKILL.md` — chargé par le profil > > Placer un skill uniquement dans le global ne suffit pas. ```bash # 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 ```bash # 1. Créer dans le repo (versionné) mkdir -p hermes-skills/funk/ vim hermes-skills/funk//SKILL.md # 2. Déployer dans le répertoire global sudo mkdir -p /srv/data/hermes/skills/funk/ sudo cp hermes-skills/funk//SKILL.md /srv/data/hermes/skills/funk// # 3. Copier dans le profil cible sudo mkdir -p /srv/data/hermes/profiles/funk-ai/skills/funk/ sudo cp /srv/data/hermes/skills/funk//SKILL.md \ /srv/data/hermes/profiles/funk-ai/skills/funk// 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 ```bash 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 "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 ```bash # system : traitement de texte ask-agent system "que signifie cette sortie df -h : " ask-agent system "convertis 8192 MiB en GiB" # monitor : évaluation santé ask-agent monitor "logs litellm : — erreurs ?" ask-agent monitor "status llama-server : — service sain ?" # brain : analyse complexe ask-agent brain "architecture optimale pour ce schéma k8s : " --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é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) | ```bash # 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 ```bash 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 : ```bash 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). ```bash ssh g01 "sudo systemctl status llama-server-system" ssh g01 "md5sum /mnt/models/" ``` ### ask-agent timeout LiteLLM ou llama-server ne répond pas. ```bash 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é ```bash 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 `hermes` introuvable (commande `systemctl status hermes` retourne erreur 2) - Fichier de configuration existant : ```yaml 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:8080` sans anomalies déclarées