Agents-outils sous 2B · N°1
Déclarer ses outils : comment un 1,5B passe de 6 % à 94,5 % Résumé exécutif Mes agents-outils tournent sur Qwen 2.5 3B + LoRA, sur CPU, sans GPU. En voulant réévaluer si ce socle était encore le bon en 2026, j’ai construit un banc d’exactitude d’appel d’outil : 214 cas figés, 40 fonctions OPNsense, plus 14 cas où la bonne réponse est de ne rien appeler.
Le premier chiffre m’a arrêté net.
Agents-outils sous 2B · N°2
Le refus : ce qu’aucun palmarès ne mesure Résumé exécutif Tous les bancs d’appel d’outil que j’ai croisés mesurent la même chose : le modèle appelle-t-il la bonne fonction avec les bons arguments ? Aucun ne mesure l’inverse — sait-il ne PAS appeler ?
Mon propre corpus d’entraînement ne le mesurait pas davantage : 1978 exemples, zéro sans appel d’outil. J’ai donc construit 14 cas où la bonne réponse est de se taire, répartis en quatre genres.
Agents-outils sous 2B · N°3
Entraîner le refus : 43 % → 93 %, et ce que ça coûte ailleurs Résumé exécutif Les deux premiers articles de cette série se terminaient sur la même réserve : « aucun LoRA n’a été mesuré ». Le second poussait plus loin — le refus ne se corrige pas par l’invite, il faut l’entraîner — en le présentant comme une hypothèse à éprouver.
Elle est éprouvée. 228 exemples de refus et vingt-deux minutes de GPU font passer le taux de refus correct de 42,9 % à 92,9 %, et les demandes dangereuses de 0/6 à 6/6, sans rien coûter à la sélection de fonction.
cyber-agent-engine
🇬🇧 English version 💻 Code source (AGPL) : github.com/patlegu/cyber-agent-engine
De « ça marche » à « déployable par un tiers » Les quatre premiers articles de cette série ont décrit des frontières : jetons plutôt que valeurs réelles (article 2), politique fail-closed et approbation humaine (article 3), LLM hors de l’équipement qu’il pilote (article 4). Chacune répond à la question « qu’est-ce que le système a le droit de faire, de voir, ou de laisser fuiter ?
cyber-agent-engine
🇬🇧 English version 💻 Code source (AGPL) : github.com/patlegu/cyber-agent-engine
La rigueur comme livrable Les cinq articles précédents de cette série ont décrit des frontières techniques : jetons plutôt que valeurs réelles, politique fail-closed, topologie hors-boîte, audit borné et packaging reproductible. Ce dernier article change d’angle. Il ne parle pas de ce que cyber-agent-engine fait, mais de comment il a été construit — et pourquoi ce comment fait partie du livrable au même titre que le code.
cyber-agent-engine
🇬🇧 English version 💻 Code source (AGPL) : github.com/patlegu/cyber-agent-engine
Une question de topologie, pas seulement de sécurité Les trois premiers articles de cette série ont détaillé comment cyber-agent-engine encadre un LLM qui pilote un pare-feu de production : jetons plutôt que valeurs réelles (article 2), politique fail-closed et approbation humaine (article 3). Celui-ci s’attaque à une question antérieure, presque architecturale avant d’être sécuritaire : où ce LLM doit-il physiquement s’exécuter ?
cyber-agent-engine
🇬🇧 English version 💻 Code source (AGPL) : github.com/patlegu/cyber-agent-engine
L’invariant Le premier article de cette série posait la thèse générale de cyber-agent-engine : un LLM qui pilote un pare-feu de production ne doit jamais franchir seul la frontière entre intention et exécution. Celui-ci descend dans le pilier le plus contre-intuitif de cette architecture, et probablement le plus simple à énoncer : le LLM de raisonnement ne voit jamais une IP réelle, un hostname réel ou un secret réel.
cyber-agent-engine
🇬🇧 English version 💻 Code source (AGPL) : github.com/patlegu/cyber-agent-engine
Le réflexe firewall, appliqué à une décision d’IA Le premier article de cette série posait la thèse générale : un LLM qui pilote un pare-feu de production ne doit jamais franchir seul la frontière entre intention et exécution. Le deuxième montrait comment cette frontière protège les données — le modèle ne voit que des jetons, jamais une IP réelle. Celui-ci s’attaque à l’autre moitié du problème : une fois que le LLM a proposé une action sur des jetons, qui décide si elle a le droit de se produire ?
cyber-agent-engine
🇬🇧 English version 💻 Code source (AGPL) : github.com/patlegu/cyber-agent-engine
Un LLM qui peut bloquer une IP Il y a quelque chose de vertigineux à donner à un modèle de langage la capacité d’appeler block_ip ou add_filter_rule sur un pare-feu de production. On lui tend une phrase — « bloque cette IP qui scanne le LAN » — et quelques centaines de millisecondes plus tard, une règle apparaît dans OPNsense. C’est exactement la promesse du DevSecOps assisté par IA : traduire l’intention en action, sans passer par une console, un ticket ou une CLI.
TL;DR J’ai dépensé 3,10 € de Claude Sonnet 4.6 (via OpenRouter) pour générer un corpus de distillation de 293 paires destiné au fine-tune d’un LoRA SOC. Sur ces 293 paires, 94 % étaient du bruit ambient SSH (sessions PAM, sshd auth success) et seulement 3 % du signal d’attaque réel (FIM sur fichiers sensibles). Le piège est subtil : plus l’attaquant qu’on utilise pour générer le corpus est scriptable (SSH-driven), plus il génère lui-même du bruit qui contamine le dataset.
Inférence LLM CPU · N°1
Benchmarker llama.cpp sur CPU : ce qu’on apprend en 50 runs Résumé Exécutif Pour les besoins d’un PoC SOC agentique CPU-only, j’ai fait tourner ~50 benchmarks llama-bench sur 4 plateformes différentes (un Ryzen 5 3600 bare-metal, sa contrepartie FreeBSD, un EPYC Milan dedicated chez Hetzner, un Xeon Skylake shared chez Hetzner). Modèle de référence : Qwen 2.5 3B Q4_K_M et son grand frère 7B. Builds comparés : llama.cpp (tag b3813 et b9165) et son fork agressif ik_llama.
Inférence LLM CPU · N°2
tg/s = MB/s : la formule empirique pour planifier la capacité d’un cluster LLM CPU TL;DR Sur 5 plateformes CPU (x86 AMD, x86 Intel, ARM Ampere Altra), la bande passante mémoire (mesurée par mbw) prédit le throughput de génération LLM (tg64 sur Qwen 3B Q4_K_M) à ±10 % près sur x86 et à ±25 % près si on inclut ARM. Le ratio empirique est ~470 MB par token/s sur x86, et ~650 MB par token/s sur ARM Ampere Altra — l’ARM est moins efficient par MB de BW pour des raisons développées plus loin.