J’ai ajusté chaque ligne de config.yaml Hermes — 3 paramètres qui empêchent les tâches longues de se bloquer

Ce qu’il y a de plus frustrant avec Hermes Agent sur des tâches complexes, ce n’est pas d’obtenir une mauvaise réponse — c’est de voir le travail se figer à mi-parcours : les appels API restent en suspens, la taille du contexte explose après de nombreux tours, ou un outil en échec reste coincé dans une boucle de réessais sans fin. La plupart du temps, ce ne sont pas des problèmes de modèle. Ce sont des valeurs par défaut dans ~/.hermes/config.yaml qui n’ont pas été ajustées pour les travaux longs.
Après avoir exécuté des centaines de tâches longues, j’ai passé ma configuration ligne par ligne et j’ai découvert que seuls trois paramètres déterminent vraiment si une tâche longue se termine en douceur. Réglez-les en fonction de votre charge de travail, et la plupart des tâches complexes se termineront sans intervention manuelle.
Ci-dessous, chaque section suit le schéma : symptôme → cause → correction → valeurs recommandées, avec des extraits YAML prêts à copier-coller.
Paramètre 1 : Mettre un harnais serré aux appels API — Délais d’attente des fournisseurs
Les symptômes
- La tâche atteint 50 %, le terminal devient silencieux, et après trente secondes s’affiche « Connection timed out. »
- Un travail en arrière-plan ou un cron affiche
running, mais le journal n’a pas bougé depuis plusieurs minutes. - Après avoir changé de fournisseur OpenRouter, les réponses deviennent erratiques et s’interrompent parfois complètement.
La cause
Par défaut, les appels API d’Hermes se basent sur deux variables d’environnement : HERMES_API_TIMEOUT (1800 s) et HERMES_API_CALL_STALE_TIMEOUT (90 s). Cependant, les clés request_timeout_seconds et stale_timeout_seconds sous le bloc providers dans config.yaml sont prioritaires ; les variables d’environnement ne sont utilisées que lorsque aucune configuration n’est définie.
Sans ajustement par fournisseur :
- Les modèles cloud avec réflexion longue (Claude Opus, o1, deep-research) peuvent être interrompus avant d’avoir fini.
- Les points de terminaison locaux (LM Studio, Ollama, vLLM) peuvent mettre plusieurs dizaines de secondes à démarrer à froid, mais les délais d’attente par défaut sont beaucoup plus courts.
- Un seul fournisseur défaillant peut bloquer toute l’exécution car il n’y a pas de délai d’attente explicite.
La correction
Ajoutez un bloc providers en haut de config.yaml et ajustez-le par fournisseur :
providers:
anthropic:
request_timeout_seconds: 600 # tolérer 10 min pour une réflexion lente
stale_timeout_seconds: 300 # appels non-streaming uniquement
openrouter:
request_timeout_seconds: 300
stale_timeout_seconds: 120
lmstudio:
request_timeout_seconds: 300 # le démarrage à froid local est lent
stale_timeout_seconds: 900 # réactiver explicitement la détection de stale
ollama-local:
request_timeout_seconds: 300
stale_timeout_seconds: 900
Si vous utilisez principalement un seul fournisseur, configurer uniquement ce fournisseur suffit. request_timeout_seconds est passé directement au SDK sous la forme timeout=, écrasant la variable d’environnement héritée.
Valeurs recommandées
| Scénario | request_timeout_seconds | stale_timeout_seconds |
|---|---|---|
| Modèles cloud rapides (Claude 3.5 Sonnet, GPT-4o mini) | 60–120 | 60–90 |
| Modèles à réflexion longue (Claude Opus, o1, deep-research) | 300–600 | 120–300 |
| Modèles locaux (LM Studio / Ollama / vLLM) | 180–300 | 600–900 |
| Travaux en arrière-plan / cron | 300–600 | 120–300 |
Note :
stale_timeout_secondsne s’applique qu’aux appels non-streaming. Les appels en streaming sont considérés comme vivants tant que les tokens continuent d’arriver.
Paramètre 2 : Ne laissez pas le contexte exploser en premier — Stratégie de compression
Les symptômes
- Après de nombreux tours d’outils, le modèle commence à répondre hors sujet ou renvoie « context length exceeded. »
- La compression se déclenche trop tard, à 80 % de la fenêtre, et compresse déjà des résultats intermédiaires importants.
- Après compression, l’agent « oublie » des éléments que vous venez de confirmer : clés API, chemins de fichiers, contraintes.
La cause
Le bloc compression d’Hermes se déclenche lorsque l’utilisation des tokens atteint threshold × context_length. Les valeurs par défaut peuvent ne pas convenir à votre charge de travail :
threshold: 0.50est agressif pour un contexte de 200K mais trop tardif pour un contexte de 32K.protect_last_n: 20ne conserve que les 20 derniers messages, ce qui ne couvre peut-être que 2 à 3 tours critiques dans une tâche longue.target_ratio: 0.20détermine la quantité de queue récente à conserver ; trop petit perd des détails, trop grand gaspille de l’espace.
Il existe aussi une règle cachée dans le code : pour les modèles dont les fenêtres de contexte sont inférieures à 512K, le seuil est plafonné à 0,75. Ainsi, les modèles à petite fenêtre ne se déclenchent pas du tout à 50 % — ils se déclenchent à 75 %. Savoir cela vous aide à estimer le point de compression réel.
La correction
compression:
enabled: true
threshold: 0.65 # se déclencher plus tôt que la valeur par défaut
target_ratio: 0.25 # conserver 25 % de la queue récente
protect_last_n: 30 # ~15 tours complets
protect_first_n: 1 # uniquement le prompt système + premier message utilisateur
codex_app_server_auto: native
Si votre tâche nécessite un contexte précoce fréquent (par exemple, « utilisez toujours Python 3.11 », « ce projet utilise pnpm »), augmentez protect_first_n à 3. Sinon, gardez-le à 1 pour économiser de l’espace.
Valeurs recommandées
| Contexte du modèle | threshold | target_ratio | protect_last_n |
|---|---|---|---|
| ≤ 32K (Claude 3.5 Sonnet, GPT-4o) | 0.75 (plancher par défaut) | 0.25 | 30–40 |
| 128K–200K | 0.60–0.65 | 0.20–0.25 | 20–30 |
| ≥ 1M (Gemini, Kimi k1.5) | 0.50–0.55 | 0.15–0.20 | 20 |
Astuce : le résumé de compression utilise par défaut Gemini Flash, qui est rapide et bon marché. Pour les tâches très orientées code, vous pouvez fixer un autre modèle sous
auxiliary.compression, mais la valeur par défaut est généralement suffisante.
Paramètre 3 : Verrouiller la boucle d’outils — agent.max_turns
Les symptômes
- Une tâche simple invoque 50 tours d’outils et l’agent répète encore « laissez-moi vérifier. »
- Un petit accroc réseau fait qu’un outil échoue plusieurs fois, plongeant l’agent dans une spirale de réessais et faisant grimper votre facture.
- Un travail en arrière-plan tourne pendant une demi-heure et s’avère coincé dans une boucle.
La cause
agent.max_turns limite le nombre d’itérations d’appels d’outils que l’agent peut effectuer dans une seule requête utilisateur. La valeur par défaut de 60 suffit pour des questions-réponses occasionnelles, mais elle est rapidement épuisée par le débogage complexe, le traitement par lots ou les confirmations itératives. Sans limite, un outil en échec peut réessayer indéfiniment.
Associer max_turns avec tool_loop_guardrails.hard_stop_enabled crée un disjoncteur pour les boucles anormales.
La correction
agent:
max_turns: 100 # marge pour les tâches complexes
api_max_retries: 2 # échouer vite et laisser le fallback prendre le relais
reasoning_effort: medium
tool_loop_guardrails:
warnings_enabled: true
hard_stop_enabled: true # disjoncteur pour les boucles anormales
warn_after:
exact_failure: 2
same_tool_failure: 3
idempotent_no_progress: 2
hard_stop_after:
exact_failure: 5
same_tool_failure: 8
idempotent_no_progress: 5
Valeurs recommandées
| Type de tâche | max_turns | hard_stop_enabled |
|---|---|---|
| Questions-réponses simples / requêtes en une étape | 30–40 | false |
| Débogage de code / complexité moyenne | 60–80 | true |
| Traitement par lots / travaux longs en arrière-plan | 100–150 | true |
| Recherche exploratoire / refactoring multi-fichiers | 100–200 | true |
Note :
max_turnsest la limite d’itérations d’outils par requête, et non la limite de messages sur toute la durée de vie de la session. Vous pouvez réinitialiser le contexte à tout moment avec/newou d’autres commandes de gestion de session présentées dans notre panorama des commandes Hermes v0.18.
Référence complète : Un extrait de config.yaml prêt à l’emploi
Voici un extrait consolidé pour la configuration courante : OpenRouter comme fournisseur principal + modèles locaux occasionnels + tâches longues fréquentes :
model:
default: "anthropic/claude-opus-4.6"
provider: "auto"
base_url: "https://openrouter.ai/api/v1"
providers:
anthropic:
request_timeout_seconds: 600
stale_timeout_seconds: 300
openrouter:
request_timeout_seconds: 300
stale_timeout_seconds: 120
lmstudio:
request_timeout_seconds: 300
stale_timeout_seconds: 900
compression:
enabled: true
threshold: 0.65
target_ratio: 0.25
protect_last_n: 30
protect_first_n: 1
codex_app_server_auto: native
codex_gpt55_autoraise: true
agent:
max_turns: 100
api_max_retries: 2
reasoning_effort: medium
tool_loop_guardrails:
warnings_enabled: true
hard_stop_enabled: true
warn_after:
exact_failure: 2
same_tool_failure: 3
idempotent_no_progress: 2
hard_stop_after:
exact_failure: 5
same_tool_failure: 8
idempotent_no_progress: 5
Enregistrez dans ~/.hermes/config.yaml. Les nouvelles sessions le prennent en compte immédiatement ; les sessions déjà en cours nécessitent /new pour le recharger.
Vérification : Est-ce que ça a vraiment aidé ?
Trois vérifications rapides :
- Déclenchez délibérément une longue réflexion. Demandez à l’agent de traiter un fichier journal de 500 lignes ou de lire dix fichiers source à la fois. Vous ne devriez plus rencontrer
context length exceeded. - Simulez des à-coups API. Bloquez brièvement l’IP du fournisseur avec
timeoutouiptableset confirmez que l’agent échoue dans le délai configuré et tente le fallback, au lieu de rester bloqué indéfiniment. - Inspectez la compression. Pendant une tâche longue, exécutez
/compressou attendez la compression automatique, puis vérifiez que les ~30 derniers messages et le prompt système sont toujours présents.
Pour les modes de défaillance plus complexes, consultez notre approfondissement sur la gestion des erreurs et la récupération d’Hermes, qui combine délais d’attente, fallbacks et réessais en une seule stratégie de résilience.
Résumé
Les tâches longues se bloquent généralement non pas parce que le modèle est devenu plus stupide, mais parce que les délais d’attente API, la compression du contexte et les limites de boucle d’outils ne sont pas alignés. Après avoir réglé ces trois paramètres :
- Les appels API expirent proprement et passent à un autre fournisseur au lieu de rester en suspens.
- Le contexte se compresse au bon moment, préservant les détails récents sans atteindre la limite de la fenêtre.
- Les appels d’outils ont un plafond dur, empêchant les spirales de réessais et les factures incontrôlables.
Si vous débutez, lisez d’abord le guide d’installation pour vous assurer que votre environnement est solide, puis conservez cet extrait comme un « modèle de tâche longue » à copier pour les travaux exigeants.
Références : cet article est basé sur l’exemple officiel Hermes Agent cli-config.yaml.example et la documentation officielle.