Squelch — moins de bruit, moins de tokens
L'essentiel de ce que lit un agent de code est de la sortie de commandes, et l'essentiel de la sortie de commandes est du bruit : des centaines de lignes PASSED autour du seul test qui a échoué, une barre de progression pour chaque paquet qu'une installation télécharge, une ligne Compiling pour chaque fichier d'une compilation, les compteurs d'objets de git. Le modèle lit tout cela, à chaque tour, et tout compte dans la fenêtre de contexte et dans la facture.
Squelch retire ce bruit avant que le modèle ne le lise. Il garde ce sur quoi l'agent agit — erreurs, échecs, avertissements, résumés — et laisse de côté le reste. Il fonctionne pour tous les agents (Claude Code, Codex, Kimi Code, Grok, omp) sans rien installer dans la machine : le proxy de votre Mac allège les résultats de commandes que porte chaque requête, de la même façon que la Protection des données personnelles remplace les données personnelles. Squelch se règle par machine (un espace de travail, dans l'éditeur de réglages) et est désactivé par défaut ; la référence des champs se trouve dans Réglages → Squelch.
Crédit : Squelch s'inspire de rtk (Rust Token Killer, github.com/rtk-ai/rtk, Apache-2.0), qui fait la même chose en réécrivant les commandes shell de l'agent sur votre machine. L'idée, ses stratégies de filtrage par famille et son rapport « tokens économisés » (
rtk gain) viennent de rtk ; les filtres de Bromure sont les siens et tournent dans le proxy, si bien qu'ils atteignent tous les agents sans hooks.
L'activer
Deux façons, toutes deux immédiates — la requête suivante des agents est allégée, rien ne redémarre :
- Dans l'en-tête d'une session, cliquez sur l'icône Squelch (trois lignes qui se rétrécissent, après le nombre de tokens) et basculez l'interrupteur dans la fenêtre contextuelle.
- Dans les réglages de la machine, sélectionnez Squelch sous Modèles, cochez Retirer le bruit de la sortie des commandes avant que le modèle ne la lise, puis cliquez sur Enregistrer.
Pour en faire le réglage par défaut des nouvelles machines, activez-le dans Bromure → Préférences… (le modèle Valeurs par défaut).
Ce qu'il retire
Squelch regarde la commande dont provient une sortie — la dernière commande d'une chaîne qui fait le travail, en traversant les préfixes sudo, timeout, env et VAR=value — et applique le filtre de sa famille :
| Famille | Commandes (exemples) | Laissé de côté | Toujours gardé |
|---|---|---|---|
| Tests | pytest, jest, vitest, mocha, go test, cargo test, swift test, xcodebuild test, npm test, dotnet test, rspec, phpunit | Une ligne par test réussi, les points de progression, la progression de compilation | Les échecs, les traces de pile, les diffs d'assertion, le résumé |
| Installations | npm/pnpm/yarn/bun install, pip/uv/poetry, apt, brew, cargo fetch, go mod download, docker pull | Les lignes de téléchargement, de décompression et « already satisfied », les barres de progression, les avis de dépréciation | Les erreurs, les conflits, la ligne de résultat |
| Compilations | cargo build, swift build, xcodebuild, make, cmake, gradle, mvn, tsc, docker build | Les lignes de compilation par fichier, les blocs d'étapes de xcodebuild, le bavardage de répertoires de make, le même avertissement imprimé à nouveau | Chaque erreur et chaque avertissement, avec son extrait de source |
| git | git push, pull, fetch, clone, status, commit | Les compteurs d'objets, les conseils (use "git add"…), les longues listes create mode | Les branches, les refs, les conflits, les fichiers |
| Journaux | docker logs, kubectl logs, journalctl | Les suites de lignes qui ne diffèrent que par leurs nombres (horodatages, identifiants) — la première est gardée, avec un compte | Tout ce qui diffère |
| Recherche | grep, rg, ag, git grep | La fin des lignes très longues (fichiers minifiés) | Chaque correspondance et son emplacement |
| Tout le reste | — | Les séquences d'échappement du terminal, les lignes de progression redessinées, les barres de progression, la même ligne six fois ou plus de suite | Le reste |
Une ligne qui nomme une erreur, un échec, un avertissement, une panique ou un délai dépassé n'est jamais laissée de côté, quel que soit le motif auquel elle correspond.
Une désinstallation (pip uninstall, uv pip uninstall, npm remove, brew uninstall, apt remove…) n'est pas une installation : ce qu'elle affiche est la liste de ce qui est parti, elle n'a donc droit qu'au nettoyage générique de « tout le reste ».
Certaines sorties ne sont jamais touchées, parce que l'agent les lit comme la chose elle-même — en général pour en copier des passages dans une modification : cat, head, tail, sed, less, jq, awk, diff, git diff, git show, git log, git blame (quelles que soient les options placées avant : git --no-pager diff, git -C repo log), gh pr diff, gh api, hg diff, curl, python -c et consorts. Pas plus qu'un pipeline que l'agent a façonné lui-même (pytest -v | tail -40) : il a déjà choisi ce qu'il veut voir. Les résultats des outils de fichiers propres aux agents (outils Read, Edit, Grep) ne sont jamais touchés non plus — seulement les commandes shell.
Une sortie de moins d'environ 300 octets, ou qui rétrécirait de moins de 10 %, passe sans changement.
Ce que voit le modèle
Une sortie allégée se termine par une ligne qui dit ce qui a été laissé de côté et comment tout obtenir :
FAILED tests/test_api.py::test_retry_budget - assert 2 == 3
========================= 1 failed, 120 passed in 4.12s =========================
[Bromure Squelch left out 120 noise lines (passing tests 120). Run the command again prefixed with BROMURE_FULL_OUTPUT=1 to see all of it.]
Quand l'agent a besoin de la sortie complète, il relance la commande avec BROMURE_FULL_OUTPUT=1 devant — sans effet pour le shell, et Squelch laisse alors passer la sortie de cette commande en entier.
Seul le modèle de l'agent voit le texte allégé. La transcription de l'agent lui-même, la vue de chat et votre terminal gardent la sortie complète. Squelch modifie la requête chaîne par chaîne et laisse chaque autre octet tel que l'agent l'a envoyé, et une même sortie est toujours allégée de la même façon : une conversation renvoyée tour après tour garde donc son cache de prompt. (Activer ou désactiver Squelch en pleine conversation modifie une fois les tours précédents, si bien que la requête suivante rate le cache.)
Voir ce qu'il a économisé
L'en-tête de chaque session montre ce que Squelch a économisé dans cette conversation (12K économisés). Cliquez dessus pour la fenêtre contextuelle :
- Cette conversation — les tokens économisés, la part de la sortie de commandes laissée de côté, le nombre de sorties de commandes envoyées au modèle et le nombre de celles qui ont été allégées.
- Tout « … » (toute la machine) — la même chose, pour toutes les conversations de la machine.
- D’où ça vient — les commandes qui ont le plus économisé (
pytest,npm install, …). - Deux dernières semaines — les tokens économisés par jour.
Le volet de réglages Squelch de la machine montre la liste complète des commandes et le même graphique.
Les tokens sont estimés à caractères ÷ 4, comme le fait rtk — il n'y a pas de tokeniseur dans la boucle, donc la part économisée est fiable et le nombre absolu approximatif. Chaque sortie de commande compte une seule fois, la première fois qu'une requête la porte, même si l'agent renvoie toute la conversation à chaque tour — les économies réelles sur une longue session sont plus grandes que le nombre affiché.
Les économies sont conservées par machine dans ~/Library/Application Support/BromureAC/squelch/ledger.json (par conversation, commande, famille et jour, pour les 90 derniers jours). Sur un client lourd (un Mac, un iPhone ou un iPad connecté à un autre Mac), les nombres viennent du serveur qui fait tourner la machine, et l'interrupteur de la fenêtre contextuelle active ou désactive Squelch là-bas.
Limites
- Machines seulement. Squelch vit dans le proxy par lequel passe tout le trafic IA de chaque machine. Une machine native (un Mac qui exécute Bromure Sidecar) envoie le trafic de ses agents directement au fournisseur : Squelch ne s'y applique donc pas.
- Des motifs, pas du jugement. Les filtres reconnaissent les formats de sortie des outils courants. Un lanceur de tests inhabituel ou un script de compilation maison n'a droit qu'au nettoyage générique (séquences d'échappement, barres de progression, lignes répétées).
- Une commande que la requête ne nomme pas. Quand un tour de Codex poursuit un tour précédent sur le serveur, un résultat peut arriver sans l'appel qui l'a produit. Squelch l'associe à l'appel que le modèle a annoncé dans sa réponse ; un résultat dont il n'a jamais vu l'appel — après un redémarrage de Bromure, par exemple — est laissé tel quel, car son texte seul ne permet pas de distinguer une exécution de tests d'un
catd'un journal de tests.