mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-08 07:54:42 +02:00
fix: ask-agent /no_think + SKILL.md renforcé + tests 10/10
- ask-agent : ajout /no_think pour agents system et monitor (Qwen3-1.7B en mode thinking consommait tous les tokens sur le raisonnement interne, laissant content: "" vide) - SKILL.md v1.1.0 : règles OBLIGATOIRES de délégation, distinction ask-agent vs delegate_task, exemples concrets, syntaxe exacte - test.sh : suite 10 tests end-to-end — CLI disponible, LiteLLM, system/monitor/brain, données réelles, skill présence/activation, Hermes funk-ai appelle Terminal: ask-agent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bd7181b8db
commit
5e93c1d3d7
3 changed files with 240 additions and 49 deletions
|
|
@ -33,6 +33,13 @@ AGENT="$1"
|
|||
QUESTION="$2"
|
||||
shift 2
|
||||
|
||||
# Qwen3 thinking mode : les agents rapides (system/monitor) doivent répondre
|
||||
# directement sans passer du temps en raisonnement interne.
|
||||
# /no_think désactive le mode thinking pour system et monitor.
|
||||
case "$AGENT" in
|
||||
system|monitor) QUESTION="/no_think ${QUESTION}" ;;
|
||||
esac
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--max-tokens) MAX_TOKENS="$2"; shift 2 ;;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: agent-delegation
|
||||
description: "Délègue des sous-tâches aux agents spécialisés du cluster Funk. Utilise system/monitor pour les tâches rapides et légères, brain pour l'analyse complexe."
|
||||
version: 1.0.0
|
||||
description: "Délègue des sous-tâches aux agents spécialisés du cluster Funk via ask-agent. OBLIGATOIRE pour toute analyse de logs, métriques ou monitoring système."
|
||||
version: 1.1.0
|
||||
author: Funk Lab
|
||||
license: MIT
|
||||
platforms: [linux]
|
||||
|
|
@ -12,73 +12,88 @@ metadata:
|
|||
|
||||
# Délégation inter-agents — Cluster Funk
|
||||
|
||||
**Contexte important** : Tu tournes EN LOCAL sur `storage-01`. Ne jamais SSH vers `storage-01` depuis toi-même — lance les commandes directement via le terminal. `systemctl`, `journalctl`, `cat /proc/mdstat`, etc. s'exécutent localement sans SSH.
|
||||
## Contexte critique
|
||||
|
||||
Le cluster Funk dispose de 4 agents avec des capacités différentes. Utilise la commande shell `ask-agent` (disponible dans `/usr/local/bin/`) pour déléguer des sous-tâches aux agents spécialisés.
|
||||
Tu tournes **EN LOCAL sur `storage-01`**. Ne jamais SSH vers `storage-01` depuis toi-même — toutes les commandes locales (systemctl, journalctl, cat /proc/mdstat, etc.) s'exécutent directement via Terminal sans SSH.
|
||||
|
||||
## Règle de délégation OBLIGATOIRE
|
||||
|
||||
**Tu DOIS utiliser `ask-agent` via Terminal dans ces situations :**
|
||||
|
||||
| Situation | Agent à utiliser |
|
||||
|---|---|
|
||||
| Analyser des logs système ou service | `monitor` |
|
||||
| Évaluer l'état de santé de services | `monitor` |
|
||||
| Résumer des métriques, sorties de commandes | `system` |
|
||||
| Toute question de formatage ou calcul simple | `system` |
|
||||
| Architecture, revue de code, raisonnement complexe | `brain` |
|
||||
|
||||
**Ne réponds JAMAIS directement à une demande d'analyse** — collecte d'abord les données, puis délègue.
|
||||
|
||||
## Syntaxe exacte
|
||||
|
||||
`ask-agent` est une commande shell. Elle s'exécute toujours via l'outil `terminal` :
|
||||
|
||||
```
|
||||
terminal: ask-agent system "ta question courte"
|
||||
terminal: ask-agent monitor "analyse ces données : <données>"
|
||||
terminal: ask-agent brain "raisonnement complexe : <contexte>"
|
||||
```
|
||||
|
||||
**Ne jamais appeler `ask-agent` sans passer par le terminal.** `ask-agent` n'est pas un outil Hermes natif, c'est un binaire shell dans `/usr/local/bin/ask-agent`.
|
||||
|
||||
## Agents disponibles
|
||||
|
||||
| Agent | Modèle | Vitesse | Coût | Usage idéal |
|
||||
|---|---|---|---|---|
|
||||
| `system` | Qwen3-1.7B CPU (port 1236) | ~21 tok/s | Gratuit | Calculs rapides, parsing, formatage, résumés courts |
|
||||
| `monitor` | Qwen3-1.7B CPU (port 1237) | ~21 tok/s | Gratuit | Analyse métriques, logs, santé système, alertes |
|
||||
| `brain` | Claude Sonnet 4.6 (API) | Variable | Payant | Raisonnement complexe, architecture, revue de code |
|
||||
| `funk-ai` | Qwen3-8B GPU (port 1234) | ~35 tok/s | Gratuit | Tâches générales (toi-même) |
|
||||
| Agent | Modèle | Port | Usage |
|
||||
|---|---|---|---|
|
||||
| `system` | Qwen3-1.7B CPU | :1236 | Calculs, formatage, résumés courts, questions Linux |
|
||||
| `monitor` | Qwen3-1.7B CPU | :1237 | Analyse logs, métriques, santé système, alertes |
|
||||
| `brain` | Claude Sonnet 4.6 API | - | Raisonnement complexe, architecture, revue critique |
|
||||
| `funk-ai` | Qwen3-8B GPU | :1234 | Tâches générales (toi-même — rarement utile) |
|
||||
|
||||
## Règle fondamentale
|
||||
|
||||
**`ask-agent` est une commande shell.** Pour déléguer, utilise l'outil Terminal avec exactement cette syntaxe :
|
||||
|
||||
```
|
||||
Terminal: ask-agent system "ta question"
|
||||
Terminal: ask-agent monitor "ta question"
|
||||
Terminal: ask-agent brain "ta question"
|
||||
```
|
||||
|
||||
Ne jamais SSH vers storage-01 pour des commandes locales. Utilise `Terminal` directement.
|
||||
|
||||
## Pattern type : collecter + déléguer
|
||||
## Pattern OBLIGATOIRE : collecter → déléguer
|
||||
|
||||
```bash
|
||||
# 1. Collecter les données localement (PAS via SSH)
|
||||
Terminal: systemctl --state=failed --no-pager
|
||||
# ÉTAPE 1 — Collecter les données localement (Terminal direct, PAS via SSH)
|
||||
terminal: systemctl --state=failed --no-pager
|
||||
|
||||
# 2. Passer le résultat à un agent pour analyse
|
||||
Terminal: ask-agent monitor "voici les services en erreur systemd : <résultat> — résume les problèmes"
|
||||
# ÉTAPE 2 — Déléguer l'analyse à l'agent approprié
|
||||
terminal: ask-agent monitor "voici les services en erreur : <coller résultat étape 1> — identifie les causes et priorités"
|
||||
```
|
||||
|
||||
## Utilisation
|
||||
## Exemples concrets
|
||||
|
||||
```bash
|
||||
# Services en erreur sur storage-01 (LOCAL, pas SSH)
|
||||
Terminal: systemctl --state=failed --no-pager
|
||||
Terminal: ask-agent monitor "analyse ces services en erreur : <résultat>"
|
||||
# Monitoring services
|
||||
terminal: systemctl --state=failed --no-pager
|
||||
terminal: ask-agent monitor "services systemd en erreur : <résultat> — résume en 3 points"
|
||||
|
||||
# Déléguer une analyse de logs
|
||||
Terminal: journalctl -u hermes-agent -n 20 --no-pager
|
||||
Terminal: ask-agent system "résume ces logs en 3 points : <résultat>"
|
||||
# Analyse logs hermes
|
||||
terminal: journalctl -u hermes-agent -n 30 --no-pager
|
||||
terminal: ask-agent monitor "analyse ces logs hermes-agent : <résultat> — y a-t-il des erreurs ?"
|
||||
|
||||
# Question simple rapide
|
||||
Terminal: ask-agent system "quelle commande pour vider le cache DNS sous AlmaLinux ?"
|
||||
# Espace disque
|
||||
terminal: df -h /srv/data
|
||||
terminal: ask-agent system "est-ce que cette utilisation disque est critique : <résultat>"
|
||||
|
||||
# Analyse complexe
|
||||
Terminal: ask-agent brain "explique pourquoi ce log Kubernetes indique un crash : <log>"
|
||||
# Question Linux simple
|
||||
terminal: ask-agent system "quelle commande pour lister les connexions TCP actives sur AlmaLinux ?"
|
||||
|
||||
# Avec prompt système
|
||||
Terminal: ask-agent system "état du RAID normal ?" --system "Tu es expert Linux AlmaLinux, réponds en 1 phrase."
|
||||
# Analyse complexe k8s
|
||||
terminal: kubectl get nodes
|
||||
terminal: ask-agent brain "un nœud k8s est NotReady, que vérifier en priorité : <résultat>"
|
||||
```
|
||||
|
||||
## Quand déléguer à quel agent
|
||||
## Différence avec delegate_task
|
||||
|
||||
| Situation | Agent |
|
||||
|---|---|
|
||||
| Question Linux simple, formatage, résumé court | `system` |
|
||||
| Analyse logs, métriques, santé système | `monitor` |
|
||||
| Raisonnement complexe, revue critique, architecture | `brain` |
|
||||
- **`ask-agent`** : appel direct LiteLLM, réponse immédiate, pas besoin de gateway Hermes actif → pour analyses rapides et questions ponctuelles
|
||||
- **`delegate_task`** : spawn d'un agent Hermes complet avec sessions, mémoire, tools → pour tâches longues multi-étapes
|
||||
|
||||
Pour le monitoring et les analyses système, **toujours utiliser `ask-agent`**.
|
||||
|
||||
## Notes techniques
|
||||
|
||||
- `ask-agent` appelle LiteLLM sur `http://127.0.0.1:4000/v1` avec la clé `lm-studio`
|
||||
- `ask-agent` appelle `http://127.0.0.1:4000/v1/chat/completions` via LiteLLM
|
||||
- Timeout : 120s
|
||||
- Les agents `system` et `monitor` tournent sur des CPUs isolés (14 threads chacun) — ils ne bloquent pas le GPU
|
||||
- `brain` consomme des tokens API Anthropic — réserver aux cas qui le justifient
|
||||
- `system` et `monitor` tournent sur CPUs isolés — ils ne bloquent pas le GPU
|
||||
- `brain` consomme des tokens API Anthropic — réserver aux cas complexes
|
||||
|
|
|
|||
169
hermes-skills/funk/agent-delegation/test.sh
Executable file
169
hermes-skills/funk/agent-delegation/test.sh
Executable file
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env bash
|
||||
# test.sh — Validation end-to-end du skill agent-delegation et de ask-agent
|
||||
#
|
||||
# Usage : bash test.sh
|
||||
# Doit tourner sur storage-01 (ou depuis le poste perso via SSH)
|
||||
#
|
||||
# Vérifie :
|
||||
# 1. ask-agent CLI disponible et fonctionnel (system, monitor, brain)
|
||||
# 2. Skill agent-delegation présent dans le profil funk-ai
|
||||
# 3. Hermes funk-ai appelle réellement Terminal: ask-agent quand demandé
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
|
||||
green() { echo -e "\033[32m✓ $*\033[0m"; }
|
||||
red() { echo -e "\033[31m✗ $*\033[0m"; }
|
||||
yellow(){ echo -e "\033[33m~ $*\033[0m"; }
|
||||
|
||||
pass() { green "$1"; ((PASS++)); }
|
||||
fail() { red "$1"; ((FAIL++)); }
|
||||
skip() { yellow "$1 (SKIP)"; ((SKIP++)); }
|
||||
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
echo " Test agent-delegation + ask-agent — Funk Cluster"
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# ── Test 1 : ask-agent disponible ────────────────────────────────────────────
|
||||
echo "▸ [1] ask-agent CLI disponible sur storage-01"
|
||||
if command -v ask-agent &>/dev/null; then
|
||||
pass "ask-agent trouvé : $(which ask-agent)"
|
||||
else
|
||||
fail "ask-agent introuvable dans PATH"
|
||||
fi
|
||||
|
||||
# ── Test 2 : LiteLLM accessible ──────────────────────────────────────────────
|
||||
echo "▸ [2] LiteLLM proxy accessible (127.0.0.1:4000)"
|
||||
if curl -sf -o /dev/null http://127.0.0.1:4000/health -H "Authorization: Bearer lm-studio"; then
|
||||
pass "LiteLLM répond"
|
||||
else
|
||||
fail "LiteLLM inaccessible — vérifier : sudo systemctl status litellm"
|
||||
fi
|
||||
|
||||
# ── Test 3 : ask-agent system ─────────────────────────────────────────────────
|
||||
echo "▸ [3] ask-agent system — réponse non vide"
|
||||
RESP=$(ask-agent system "Réponds juste: OK" --max-tokens 200 2>&1) || true
|
||||
if [ -n "$RESP" ] && echo "$RESP" | grep -qiv "error\|failed\|curl"; then
|
||||
pass "ask-agent system répond : ${RESP:0:80}..."
|
||||
else
|
||||
fail "ask-agent system a échoué : $RESP"
|
||||
fi
|
||||
|
||||
# ── Test 4 : ask-agent monitor ────────────────────────────────────────────────
|
||||
echo "▸ [4] ask-agent monitor — réponse non vide"
|
||||
RESP=$(ask-agent monitor "Réponds juste: OK" --max-tokens 200 2>&1) || true
|
||||
if [ -n "$RESP" ] && echo "$RESP" | grep -qiv "error\|failed\|curl"; then
|
||||
pass "ask-agent monitor répond : ${RESP:0:80}..."
|
||||
else
|
||||
fail "ask-agent monitor a échoué : $RESP"
|
||||
fi
|
||||
|
||||
# ── Test 5 : ask-agent brain ──────────────────────────────────────────────────
|
||||
echo "▸ [5] ask-agent brain — réponse non vide"
|
||||
if curl -sf http://127.0.0.1:4000/v1/models -H "Authorization: Bearer lm-studio" | grep -q "claude"; then
|
||||
RESP=$(ask-agent brain "Réponds juste: OK" --max-tokens 200 2>&1) || true
|
||||
if [ -n "$RESP" ] && echo "$RESP" | grep -qiv "error\|failed\|curl"; then
|
||||
pass "ask-agent brain répond : ${RESP:0:80}..."
|
||||
else
|
||||
fail "ask-agent brain a échoué : $RESP"
|
||||
fi
|
||||
else
|
||||
skip "ask-agent brain — claude-sonnet non disponible dans LiteLLM"
|
||||
fi
|
||||
|
||||
# ── Test 6 : ask-agent avec données réelles ───────────────────────────────────
|
||||
echo "▸ [6] ask-agent monitor — analyse données système réelles"
|
||||
DISK=$(df -h /srv/data | tail -1)
|
||||
RESP=$(ask-agent monitor "Est-ce que cette utilisation disque est critique ? $DISK — réponds en une phrase." --max-tokens 100 2>&1) || true
|
||||
if [ -n "$RESP" ] && echo "$RESP" | grep -qiv "error\|failed\|curl"; then
|
||||
pass "ask-agent monitor analyse données réelles : ${RESP:0:120}..."
|
||||
else
|
||||
fail "ask-agent monitor analyse échouée : $RESP"
|
||||
fi
|
||||
|
||||
# ── Test 7 : Skill dans répertoire global HERMES_HOME ────────────────────────
|
||||
echo "▸ [7] Skill agent-delegation dans HERMES_HOME/skills/"
|
||||
SKILL_GLOBAL="${HERMES_HOME:-/srv/data/hermes}/skills/funk/agent-delegation/SKILL.md"
|
||||
if [ -f "$SKILL_GLOBAL" ]; then
|
||||
pass "Skill global : $SKILL_GLOBAL"
|
||||
else
|
||||
fail "Skill absent : $SKILL_GLOBAL"
|
||||
fi
|
||||
|
||||
# ── Test 8 : Skill dans le profil funk-ai ────────────────────────────────────
|
||||
echo "▸ [8] Skill agent-delegation dans profil funk-ai"
|
||||
SKILL_PROFILE="${HERMES_HOME:-/srv/data/hermes}/profiles/funk-ai/skills/funk/agent-delegation/SKILL.md"
|
||||
if [ -f "$SKILL_PROFILE" ]; then
|
||||
pass "Skill profil : $SKILL_PROFILE"
|
||||
else
|
||||
fail "Skill absent du profil — copier et redémarrer hermes-agent"
|
||||
fi
|
||||
|
||||
# ── Test 9 : Skill enabled dans hermes skills list ───────────────────────────
|
||||
echo "▸ [9] Skill agent-delegation enabled dans hermes skills list"
|
||||
HERMES_BIN="${HOME:-/opt/hermes}/.local/bin/hermes"
|
||||
if [ -x "$HERMES_BIN" ]; then
|
||||
STATUS=$(HERMES_HOME="${HERMES_HOME:-/srv/data/hermes}" "$HERMES_BIN" skills list 2>/dev/null | grep "agent-delegation" || echo "")
|
||||
if echo "$STATUS" | grep -q "enabled"; then
|
||||
pass "Skill enabled : $STATUS"
|
||||
else
|
||||
fail "Skill non trouvé ou disabled dans hermes skills list"
|
||||
fi
|
||||
else
|
||||
skip "hermes binaire introuvable : $HERMES_BIN"
|
||||
fi
|
||||
|
||||
# ── Test 10 : Hermes funk-ai appelle Terminal ask-agent ───────────────────────
|
||||
echo "▸ [10] Hermes funk-ai appelle Terminal: ask-agent (test fonctionnel)"
|
||||
if [ -x "$HERMES_BIN" ]; then
|
||||
RESP=$(HERMES_HOME="${HERMES_HOME:-/srv/data/hermes}" bash -c \
|
||||
"cd ${HERMES_HOME:-/srv/data/hermes} && $HERMES_BIN -z \
|
||||
'Exécute via ton outil terminal exactement cette commande et affiche le résultat brut : ask-agent system \"Réponds OK\"' \
|
||||
2>/dev/null") || true
|
||||
|
||||
# Vérifier dans la dernière session que le tool terminal a été appelé avec ask-agent
|
||||
LAST_SESSION=$(ls -t "${HERMES_HOME:-/srv/data/hermes}/profiles/funk-ai/sessions/session_"*.json 2>/dev/null | head -1)
|
||||
if [ -n "$LAST_SESSION" ]; then
|
||||
TOOL_CALL=$(python3 -c "
|
||||
import json
|
||||
with open('$LAST_SESSION') as f:
|
||||
data = json.load(f)
|
||||
for msg in data.get('messages', []):
|
||||
if msg.get('role') == 'tool':
|
||||
content = msg.get('content', '')
|
||||
if 'ask-agent' in content or 'OK' in content:
|
||||
print('FOUND')
|
||||
break
|
||||
" 2>/dev/null || echo "")
|
||||
if [ "$TOOL_CALL" = "FOUND" ]; then
|
||||
pass "Hermes a appelé Terminal: ask-agent et reçu une réponse"
|
||||
else
|
||||
# Fallback : vérifier juste que la réponse contient OK
|
||||
if echo "$RESP" | grep -qi "OK"; then
|
||||
pass "Hermes a obtenu la réponse ask-agent : ${RESP:0:100}"
|
||||
else
|
||||
fail "Hermes n'a pas appelé ask-agent via Terminal — réponse : ${RESP:0:200}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
skip "Impossible de lire la session — test de session ignoré"
|
||||
fi
|
||||
else
|
||||
skip "hermes binaire introuvable — test fonctionnel ignoré"
|
||||
fi
|
||||
|
||||
# ── Résumé ────────────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
echo " Résultats : ✓ $PASS passés ✗ $FAIL échoués ~ $SKIP ignorés"
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
if [ $FAIL -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue