
Pourquoi ça échoue ? Donnez des faits au modèle, et une machine qui se souvient
« Pourquoi ce service échoue-t-il ? » Un modèle muni d'un shell lancera des commandes au hasard, citera des lignes de journal qui n'existent pas et accusera des fichiers inventés. Le problème n'est pas son intelligence : il lui manque les faits, et les rassembler n'est pas son fort. Alors on les rassemble avec du code, et on les lui donne.
Comment ces chiffres ont été obtenus. Mesurés sur nos propres machines (voir le protocole), en général en un seul passage, vitesses relevées par le serveur lui-même ; nous ne publions pas les journaux bruts. Ce sont des ordres de grandeur sur ce matériel, pas des garanties sur le vôtre. Les chiffres extérieurs sont accompagnés de leur source.
Ce que vous y gagnez. Sur quatre pannes posées exprès, notre modèle de 27B en a trouvé 5 sur 5 en 72 secondes avec l'outil de faits, contre 2,75 sur 5 en 9 minutes sans lui. Même modèle, mêmes pannes : seuls les faits ont changé.
1. Un outil de faits : fh-why
fh-why unit nginx.service # ses derniers mots, depuis quand, ce qui a changé juste avant
fh-why unit --failed # chaque unité en échec, système et utilisateur
fh-why container mon-modele # contrôles de santé, redémarrages, tués par manque de mémoire, dernières erreurs
fh-why run 4182 # un run d'agent : état final et lignes en échec
fh-why unit --failed --json # un objet par ligne, pour un modèle ou un script
Un seul fichier, bibliothèque standard Python seulement, aucun modèle dedans. Sa règle : ce qui ne peut pas être lu est dit, jamais sauté. « Impossible de lire le journal : permission refusée » est un fait ; le silence n'en est pas un.
2. Une machine qui se souvient : fh-probes
Un run d'agent échoue à 3 h du matin. Était-ce le code, ou la machine qui suffoquait ? Sans enregistrement, impossible de savoir. Un petit échantillonneur écrit, une fois par seconde, une ligne sur les cartes, la mémoire, la pression mémoire et les serveurs de modèles. Une seconde commande joint cette série à la fenêtre de temps de chaque run :
fh-history 4182
# « ce run a échoué pendant que la pression mémoire montait à 91 et que la lecture du prompt tombait à 20 jetons/s »
Il garde les extrêmes, pas les moyennes, et dit quand deux runs se sont chevauchés et partagent donc les mêmes chiffres.
3. Des règles apprises d'un gel
Le jour où notre serveur a gelé, l'ancien collecteur était passé de 3 à 20 secondes par passe, et dix copies tournaient côte à côte, chacune lançant ses propres sous-processus : la supervision a contribué au gel qu'elle aurait dû voir venir. L'échantillonneur a été réécrit avec trois règles :
- Aucun sous-processus : la bibliothèque de la carte appelée directement,
/proc, deux requêtes HTTP locales. - Une seule instance : un verrou exclusif ; une seconde copie s'arrête.
- Sauter, jamais rattraper : un tour en retard est noté sauté, jamais remboursé en rafale.
Surveillez la pression mémoire (/proc/pressure/memory), pas la « mémoire disponible ». Trois minutes avant le gel, la mémoire disponible disait que tout allait bien ; la pression était à 99. Ce sont les poids des modèles, résidents en mémoire partagée, qui remplissaient la machine.
Pièges
Une panne vue assez souvent mérite une page écrite, pas un nouveau diagnostic à chaque fois. Tenez une liste des signatures de pannes récurrentes et de leur remède.
Un index de recherche qui répond encore mais a quarante heures de retard est pire qu'un index en panne. Vérifiez sa fraîcheur, pas seulement son code de réponse.
Utile ? Dites-nous ce qu'il faut mesurer ensuite.