Pourquoi nous avons construit un orchestrateur, pas plus de règles de routage
Les règles statiques de déclencheur et de transformation passent mal à l'échelle une fois que votre canevas dépasse quelques agents. Voici pourquoi MadoHub route désormais via une vraie boucle d'appel d'outils — et quand vous devriez quand même utiliser des règles.
Pendant la majeure partie de la vie de MadoHub, le routage entre agents était un moteur de règles. Une connexion avait un déclencheur (on-idle, on-complete, on-keyword, always), une transformation (ai-routing, prompt-wrap, full-output, raw, summary) et des réglages de protection contre les boucles. Configurez-la une fois et elle se déclenche pareil à chaque fois. Ce modèle existe toujours — c'est ce que documentent Routage d'agents et Flows, et c'est encore la façon la plus rapide de câbler deux tiles pour un motif connu comme le peer review. Mais il a un problème de passage à l'échelle qui mérite d'être précisé.
Le problème n'est pas une règle en particulier. C'est le nombre.
Une connexion avec « on idle → prompt-wrap » est facile à raisonner : la source a-t-elle fini ? Si oui, transfère. Les ennuis commencent dès que le canevas dépasse quelques tiles et que les connexions cessent d'être indépendantes.
Avec cinq agents et huit connexions, chaque règle interagit avec toutes les autres. La sortie de A compte-t-elle comme une correspondance de mot-clé pour le déclencheur on-keyword de B ? C doit-il attendre le cooldown de D pour que la même cible ne soit pas touchée deux fois en une seconde ? Aucune de ces questions n'a de mauvaise réponse — vous pouvez résoudre chacune en ajoutant un autre type de déclencheur, une autre transformation ou un autre flag de priorité. Mais chaque réponse est une nouvelle règle, et les règles ne se composent pas, elles se multiplient. Une topologie avec N agents n'a pas besoin de N règles, mais de près de N² de traitement des cas particuliers, parce qu'une règle n'a pas de modèle de ce qui se passe ailleurs sur le canevas — elle pattern-matche sur le texte de sortie et se déclenche à l'aveugle.
C'est le véritable argument pour un orchestrateur : pas que les règles soient mauvaises, mais qu'une règle fixe ne peut pas regarder le reste de l'espace de travail avant de décider quoi faire, et qu'un espace de travail avec plus de quelques agents a de plus en plus besoin exactement de ça.
Comment MadoHub gère ça
Une boucle d'outils, pas une règle plus grosse
L'alternative n'est pas « ajoutez une transformation IA » — MadoHub l'avait déjà. C'est donner à la décision de routage l'accès à l'espace de travail. Par défaut, une connexion déclenchée ouvre désormais un sous-tour MadoAgent : une vraie boucle d'appel d'outils qui regarde un instantané de votre canevas — chaque tile, le déclencheur et la transformation et l'état du tour de chaque connexion, la sortie récente — et prend une décision de routage, puis s'arrête.
Cette décision est volontairement étroite : elle peut lire des fichiers, vérifier le statut git, lister les connexions, inspecter l'historique de routage, rechercher des sessions et rappeler de la mémoire, plus prendre exactement une action — transférer le message, ou l'ignorer. Elle ne peut pas réécrire votre canevas, muter les connexions ou exécuter des workflows. L'instruction est simple : transférer quand il y a du contenu substantiel (un plan, du code, une revue), ignorer quand la sortie source n'est qu'une question à l'utilisateur ou du bruit vide. Un jugement sur la conversation réelle, pas un pattern match.
La protection contre les boucles s'applique toujours, quel que soit le chemin
Remplacer un dispatcher déterministe par un appel de modèle n'est pas un changement qu'on fait en pleine confiance le jour 1, donc les garde-fous du système à règles sont conservés à l'identique. La protection contre les boucles plafonne combien de cycles une connexion peut tourner avant de s'auto-désactiver (défaut 5), applique un écart minimum entre les déclencheurs (défaut 3 secondes) et peut terminer la boucle dès qu'un mot-clé d'arrêt comme LGTM apparaît. Un sous-tour qui déciderait de transférer à chaque tour ne peut quand même pas s'emballer — le plafond et le cooldown sont appliqués indépendamment de sa décision.
Le mode shadow, pour construire la confiance
Si vous voulez essayer le nouveau chemin sans changer le comportement, le mode shadow exécute le routeur legacy en direct et sa décision est ce qui est transféré — le comportement perçu par l'utilisateur ne change pas — tandis qu'un sous-tour MadoAgent tourne en parallèle sur le même déclencheur, purement comme signal de comparaison. Vous pouvez voir où le nouveau chemin est d'accord avec l'ancien sur du trafic réel avant de lui confier l'appel en direct. Le chemin legacy reste sélectionnable dans les Paramètres aussi longtemps qu'il faut pour construire cette confiance.
Conseils pratiques
- Utilisez les Flows pour les formes éprouvées. Les trois intégrés (Peer review, Pipeline, Watcher) restent des ensembles de règles fixes, parce qu'un template déposé pour un motif reproductible ne devrait pas être remis en question par un modèle à chaque déclenchement.
- Utilisez l'orchestrateur pour les topologies sur mesure ou larges. Quand aucun ensemble de règles fixe ne décrit bien votre canevas, une boucle d'appel d'outils qui peut regarder le reste de l'espace de travail avant de décider généralise mieux qu'une règle de plus.
- Utilisez le câblage manuel pour la précision ponctuelle. Dessiner une connexion entre deux tiles reste le chemin le plus rapide quand vous voulez le contrôle total d'un seul lien et n'avez pas besoin d'un template ni d'une conversation.
- Gardez la protection contre les boucles activée. Un LLM dans la boucle de routage peut mal juger si une sortie est substantielle, ignorer quelque chose qu'une règle aurait transféré, et ajouter un aller-retour de latence et de tokens qu'un pattern match de template n'ajoute pas. La protection contre les boucles et la porte de livraison garantissent qu'une mauvaise décision ne peut pas déraper en boucle non bornée, et qu'un transfert ne peut pas être silencieusement avalé par un tile qui n'est plus là pour le recevoir.