Routage
ZeroClaw utilise le routage pour deux décisions différentes :
- La distribution des agents sélectionne quel agent prend en charge un canal ou une requête. Chaque agent possède son propre profil de fournisseur et sa propre politique d’exécution.
- Le routage du fournisseur et du modèle sélectionne un profil de fournisseur configuré et un modèle pour un appel, puis applique la stratégie de nouvelle tentative et de basculement de ce profil.
Un service de routage externe tel qu’OpenRouter peut toujours effectuer la sélection du fournisseur derrière un profil de fournisseur unique. C’est facultatif : ZeroClaw prend également en charge les routes de suggestion natives, le basculement de modèle au sein d’un même profil et le basculement entre profils de fournisseurs.
Répartition par agent
Définissez chaque cible de routage comme son propre agent, puis dirigez les canaux vers l’agent qui doit gérer leur trafic.
Chaque canal est lié à un agent. Les canaux passent d’un agent à l’autre en modifiant channels = [...] sur l’agent qui doit les prendre en charge ; Config::validate() s’assure que les références sont résolues.
Pour le routage multi-étapes ad hoc au sein d’une même conversation, l’outil spawn_subagent permet à un agent d’exécuter un enfant éphémère sous sa propre identité. L’enfant hérite de l’enveloppe de permissions du parent (voir [risk_profiles.<alias>].allowed_tools) et renvoie sa réponse finale à la boucle d’outils du parent.
Routage de modèle basé sur des indications
Un mécanisme plus restreint : [[model_routes]] permet à un agent de remplacer le model_provider configuré pour les prompts marqués d’une chaîne d’indication. Utile lorsqu’un agent doit occasionnellement recourir à un modèle différent sans lancer un second agent. Chaque entrée de route comporte un hint (la chaîne qu’un prompt doit déclarer pour la déclencher), un model_provider (le profil en notation pointée <type>.<alias> vers lequel basculer, p. ex. deepseek.reasoner) et un model (l’identifiant de modèle local au fournisseur, p. ex. deepseek-reasoner). Configurez les routes via la passerelle, zerocode ou zeroclaw config set ; consultez la Config reference pour le schéma des champs.
Les routes se déclenchent normalement lorsqu’une invite contient explicitement l’indication correspondante. Un profil d’exécution de routage par effort, activé explicitement, peut également sélectionner automatiquement deux routes nommées avant l’exécution par le fournisseur.
Un hint:<name> inconnu journalise un avertissement et reste dans le domaine de fiabilité par défaut tout en conservant l’indication littérale comme modèle demandé. Une entrée par défaut épinglée continue d’utiliser sa valeur épinglée active/par défaut. Une entrée par défaut non épinglée transmet la valeur littérale, que le fournisseur peut rejeter avant que le mécanisme normal de repli ou de gestion des erreurs ne se poursuive.
model_provider est toujours une référence à un profil de fournisseur au format pointé <type>.<alias>, comme anthropic.sonnet ou openai.default. Le profil contient le point de terminaison, la référence aux informations d’authentification, le mode de compatibilité, la chaîne de secours et, éventuellement, le modèle par défaut. Le champ model contient l’état local du fournisseur pour ce profil.
Limitation actuelle : L’épinglage de route dépend du profil cible. La cible principale est épinglée au modèle actif/par défaut utilisé pour construire le routeur, y compris lorsqu’un indice reconnu renvoie vers le profil principal actif ; la valeur
model_routes[].modelde cet indice ne remplace pas l’épinglage principal. Une cible non principale avec un modèle de profil configuré est épinglée à ce modèle, de sorte que son modèle de route ne remplace pas non plus le modèle du profil. Une cible non principale sans modèle configuré reste non épinglée et reçoit le modèle de route ; sesfallback_modelsne sont pas matérialisés, bien que les profils de secours référencés soient tout de même parcourus. Maintenez le modèle de route aligné sur l’épinglage de la cible lorsqu’il en existe un.
Routage local/cloud selon l’effort
Un bloc effort_routing sur un profil d’exécution peut sélectionner une route locale pour les tours simples et ambigus, et une route cloud pour les tours complexes. La fonctionnalité est désactivée tant que le bloc n’est pas présent. Elle réutilise des valeurs [[model_routes]].hint exactes et sensibles à la casse, de sorte que les identifiants des fournisseurs et les ID de modèles restent gérés par la configuration existante des routes et des profils de fournisseur.
[[model_routes]]
hint = "local"
model_provider = "ollama.local"
model = "qwen3:8b"
[[model_routes]]
hint = "cloud"
model_provider = "anthropic.sonnet"
model = "claude-sonnet-4-5"
[runtime_profiles.local_first.effort_routing]
local_hint = "local"
cloud_hint = "cloud"
cloud_escalation = "auto"
La première implémentation utilise l’estimateur de complexité déterministe de ZeroClaw. Elle n’envoie pas le prompt à un autre modèle pour le classer. L’estimateur compte les octets UTF-8 : un texte de moins de 50 octets sans mot-clé de raisonnement est simple, un texte de plus de 200 octets, contenant un bloc de code délimité ou au moins deux mots-clés de raisonnement en anglais est complexe, et le reste est standard. Les tours simples et standard sélectionnent local_hint. Les tours complexes ne sélectionnent cloud_hint que si cloud_escalation = "auto" ; la valeur par défaut "never" maintient toutes les décisions automatiques en local. Pour les tours de canal, la classification porte sur le texte utilisateur d’avant enrichissement, les marqueurs de pièces jointes étant retirés, de sorte que les résumés de liens récupérés et les octets de médias encodés ne déclenchent pas d’escalade vers le cloud.
La décision de routage est prise à chaque tour. Les journaux incluent la cible sélectionnée, le niveau de complexité, la politique d’escalade et la longueur du message, mais pas le texte du message. Une décision locale restreint les tentatives auprès du fournisseur à celui configuré localement, y compris la récupération de stream à non-stream, afin qu’un repli de disponibilité ne puisse pas divulguer silencieusement ce tour au cloud. Une décision cloud autorise les références de fournisseur locale et cloud configurées.
Les choix de l’opérateur ont priorité sur le routage automatique de l’effort. Les substitutions CLI --provider ou --model le contournent. Un choix de canal /model <model-or-hint> reste sélectionné au lieu d’être remplacé au tour suivant pouvant être classifié. Utilisez /model auto pour effacer le choix de session de l’expéditeur et rétablir le routage automatique configuré ; /model --user auto et /model --agent auto effacent ces choix limités à leur portée. Les substitutions structurées de fournisseur ou de modèle au niveau de la session restent explicites pour cette session. Un model_switch émis par le modèle reste soumis à la politique d’effort active et ne peut sélectionner qu’un profil de fournisseur autorisé pour ce tour.
effort_routing remplace auto_classify et query_classification du canal pour cet agent. La validation de la configuration rejette un profil d’exécution qui définit à la fois effort_routing et auto_classify. Pour un agent avec effort_routing, les commandes du canal réservent auto pour rétablir le routage automatique. Les agents sans effort_routing conservent le comportement existant de sélection de modèle et de route, y compris un indice de modèle ou de route nommé auto.
Cette tranche ne fournit pas de mode de demande de confirmation avant recours au cloud, de limites de fréquence d’escalade ni de plafond de coût distinct. Utilisez cloud_escalation = "never" pour que les tentatives auprès des fournisseurs de modèles, routées selon l’effort, restent en local. Pour le contrôle des coûts, utilisez les budgets des fournisseurs et l’observabilité habituelle. Ce paramètre ne régit pas les appels réseau ou vers des fournisseurs effectués par des outils sans rapport ni par le prétraitement des médias.
Lorsque le fournisseur sélectionné ne prend pas en charge la vision et qu’un tour avec image nécessite le vision_model_provider configuré, ce fournisseur doit correspondre à l’une des références de fournisseur locales ou cloud autorisées pour le tour. Le tour échoue en mode fermé (fail closed) lorsque le fournisseur de vision dédié se situe en dehors de cet ensemble.
La gestion de l’effort a une relation volontairement restreinte avec les travaux connexes :
- Issue #5287 gère le comportement d’un modèle local ou de petite taille une fois qu’il a été sélectionné.
- Issue #7539 concerne le travail local de routage de modèles et de découverte ; le routage par effort consomme des alias configurés au lieu de découvrir des modèles.
- Issue #7431 concerne l’intention de livraison et de routage des outils, et non le choix entre modèle local et modèle cloud.
Solution de secours pour la fiabilité
Un profil de fournisseur peut déclarer fallback_models pour des modèles alternatifs sur le même endpoint et fallback pour d’autres profils de fournisseur en notation pointée. ZeroClaw ne matérialise fallback_models que lorsque le profil possède un modèle principal effectif ; sinon, ce profil contribue une entrée non épinglée. Il parcourt ensuite les profils de repli en profondeur d’abord. Chaque profil de repli conserve son propre endpoint, ses identifiants, ses en-têtes, son modèle facultatif et ses déclarations de repli imbriquées.
L’exécution effective peut différer après une limitation de débit : les entrées d’un même profil partagent une clé de temporisation, si bien qu’un 429 sur le modèle principal peut ignorer les modèles de secours restants de ce profil tant que la temporisation est active.
Configurez la chaîne via l’éditeur ZeroCode Config, le tableau de bord ou zeroclaw config set ; consultez Configuration du fournisseur. Le cycle de vie du routage des fournisseurs documente la construction, la classification des tentatives, la récupération du streaming, les limites de non-rejeu et la propriété de l’attribution.
Changement de modèle à l’exécution
Les commutateurs d’exécution utilisent le même contrat provider-profile que le routage basé sur la configuration :
/models <type>.<alias>sélectionne le profil de fournisseur actif pour la session de l’expéditeur. Les runtimes de canal peuvent également accepter le raccourci<type>seul lorsqu’il existe exactement un alias configuré pour cette famille de fournisseurs./model <model-id>sélectionne un modèle au sein du profil de fournisseur actif. Si la valeur est résolue via une entrée[[model_routes]], cette route peut sélectionner un autre profil de fournisseur. Une cible épinglée utilise son épinglage effectif plutôt que nécessairementmodel_routes[].model; une cible non épinglée sans modèle de profil configuré reçoit le modèle de la route.- L’outil
model_switchutilisemodel_provider = "<type>.<alias>"ainsi quemodel = "<provider-local-model-id>".
Les commutateurs d’exécution relèvent de l’état de session/d’exécution. Ils ne modifient pas config.toml ; les valeurs par défaut persistées nécessitent une écriture explicite dans la configuration. Pour les commutateurs pilotés par des outils, les noms de famille de fournisseurs seuls tels que openai ne sont pas des cibles de commutation, car ils n’identifient pas quel profil configuré, quelle information d’identification, quel point de terminaison ou quel mode de compatibilité doit être utilisé.
Observabilité
Les décisions de répartition par agent sont visibles dans les journaux de traçage :
INFO channel=telegram.home routed to agent=fast
INFO agent=fast model_provider=anthropic.haiku turn_id=...
INFO model_provider=anthropic.haiku stream complete tokens={input=512, output=128}
Pour les déploiements en production, connectez la sortie des journaux à Loki / Grafana. Consultez Opérations → Journaux et observabilité.
Voir aussi
- Overview : modèle de fournisseur et répartition par agent
- Configuration : schéma complet
[providers.*] - Cycle de vie du routage des fournisseurs : sélection, nouvelle tentative, solution de repli, reprise du streaming et responsabilité de l’attribution
- Catalogue des fournisseurs : chaque emplacement canonique