Cycle de vie d’exécution de l’outil
Les outils ZeroClaw sont des capacités que le modèle peut invoquer pendant un tour. Le catalogue d’outils indique ce qui peut être appelé ; le cycle de vie d’exécution indique comment un appel devient sûr, observable, annulable et visible par le fournisseur.
Utilisez cette page lorsqu’une modification touche les outils intégrés, l’activation d’outils MCP, la boucle de l’agent, la politique d’approbation, les événements de streaming des appels d’outils, les reçus, les événements d’observateur, l’historique des résultats d’outils, l’annulation, ou la frontière entre l’entrée de canal et l’action côté agent.
Chemin d’exécution
| Étape | Propriétaire | Examiner le contrat |
|---|---|---|
| Définition de l’outil | zeroclaw-api::tool::Tool | Un outil possède un nom stable, une description, un schéma JSON, execute asynchrone et une attribution. |
| Assemblage d’outil | Fabrique d’outils Runtime et registre à portée | L’agent ne reçoit que les outils admis par les bundles, la config MCP, le profil de risque et le rétrécissement par exécution. |
| Résolution du contexte de tour | ResolvedAgentExecution | Le tour commence avec un bundle résolu : accès au modèle, registre, gestionnaire d’approbation, observateur, réglages d’exécution, handle d’activation MCP et générateur de reçus. |
| Requête du fournisseur | agent::turn::tool_specs et appel au fournisseur | Les fournisseurs d’outils natifs reçoivent des spécifications structurées ; les fournisseurs de protocole texte reçoivent des instructions de prompt à moins que le parsing strict ne les masque. |
| Analyse des appels d’outils | agent::turn::parse_response et helpers de parseur | Les appels d’outils natifs et textuels sont normalisés en appels parsés avec des ids de provider lorsqu’ils sont disponibles. |
| Préparation | agent::turn::call_prep | Les Hooks, les valeurs par défaut de livraison, l’approbation, les gardes anti-doublon requiérant une invite et les gardes anti-doublon standards s’exécutent avant le dispatch. |
| Exécution | agent::tool_execution | Les appels s’exécutent séquentiellement ou en parallèle selon la politique, l’annulation et les contraintes d’activation. |
| Enregistrement des résultats | post_exec, results_collect et history_append | Les résultats sont ordonnés, journalisés, observés, optionnellement accusés de réception, bornés et rajoutés à l’historique du fournisseur. |
| Contrôle de boucle | run_tool_call_loop | Le modèle voit les résultats des outils et peut continuer jusqu’à ce qu’il renvoie le texte final, rencontre une annulation ou atteigne la limite d’itérations. |
Le runtime sépare ces étapes afin qu’une revue puisse demander quelle frontière a changé. Ajouter un outil n’est pas la même chose qu’élargir la politique d’approbation, modifier les spécifications d’outils du fournisseur, altérer les charges utiles de l’observateur ou persister un résultat.
Définitions et enregistrement des outils
Chaque outil implémente le trait Tool :
#![allow(unused)]
fn main() {
#[async_trait]
pub trait Tool: Send + Sync + Attributable {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn parameters_schema(&self) -> serde_json::Value;
async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult>;
}
}
ToolResult est petit : success, output et error. Les implémentations d’outils ne devraient pas inventer chacune leur propre journalisation ou chemin d’approbation. Le dispatcher gère les événements start/result communs, les reçus, les enregistrements d’observateur, les messages de progression et la conversion d’historique.
Les specs d’outils sont reconstruites pour les requêtes aux providers. Le ToolSpec actuel partage de grands schémas via Arc afin que le format de transmission reste le même tout en évitant les clones profonds à chaque itération.
Contexte d’exécution résolu
Les points d’entrée ne doivent pas construire un tour en recalculant la politique inline. Le moteur de tour reçoit un bundle ResolvedAgentExecution pour les dépendances par agent stables : liaison de modèle, registre des outils effectif, gestionnaires d’observateur et d’approbation, paramètres d’exécution résolus, ensemble d’activation MCP différé, rappel de changement de modèle et générateur de reçu optionnel.
L’état par message reste en dehors de ce bundle : historique, sinks de streaming, canaux d’événements, messages de pilotage, jeton d’annulation, état d’injection de mémoire et l’enveloppe d’ingress.
Lorsqu’une PR ajoute une nouvelle entrée d’exécution, préférez la faire passer via ce contexte résolu ou l’état ToolLoop explicite par tour. Évitez les globals cachés ou de reconsulter la config à l’intérieur d’un chemin d’outil.
Disponibilité et activation MCP
Le modèle ne peut appeler que les outils efficaces pour le tour en cours :
- les outils statiques proviennent du registre scopé ;
excluded_toolssupprime les noms avant l’exposition du prompt/spec et avant l’exécution ;- les fournisseurs d’outils natifs reçoivent des spécifications structurées pour des outils efficaces ;
- les fournisseurs de protocole texte reçoivent des instructions d’outils uniquement lorsque l’appel d’outils textuel est autorisé ;
- le parsing strict peut masquer entièrement le protocole de l’outil texte ;
tool_filter_groupsdécident quels schémas d’outils MCP sont visibles pour le tour actuel. Les groupesmode = "always"peuvent pré-activer les wrappers MCP différés éligibles, tandis que les groupesdynamicexposent les outils uniquement lorsque le message utilisateur actuel correspond à leurs mots-clés ;- MCP différé peut exposer un stub
tool_searchau lieu de chaque wrapper MCP.
L’activation différée de MCP conserve son état au sein du tour. tool_search résout les stubs MCP correspondants en ActivatedToolSet partagé ; les appels suivants peuvent exécuter ces wrappers activés. Les groupes de filtres ne confèrent pas de capacités par eux-mêmes : le registre d’étendue, la politique MCP et la liste d’interdiction déterminent toujours quels wrappers peuvent exister.
Ne pas exécuter tool_search en parallèle avec les outils qu’il active. Le dispatcher force tout lot contenant tool_search à s’exécuter de manière séquentielle, afin qu’une recherche ne concurrence pas l’activation. Les chemins de délégation/sous-agent doivent transmettre l’ensemble des outils activés qui leur ont été accordés ; sinon, un tour délégué peut annoncer ou tenter un outil que son exécutant ne peut pas résoudre.
Approbation et préparation
La préparation a lieu avant que l’exécuteur n’exécute un outil :
- Les hooks
before_tool_callpeuvent annuler ou réécrire le nom/arguments. - Les paramètres par défaut de livraison des canaux peuvent être injectés pour les outils sensibles aux canaux.
- Le runtime efface tout marqueur “approved” dans les arguments.
- La porte d’approbation évalue l’outil par rapport à l’
ApprovalManager. - Les appels approuvés se voient restaurer le marqueur d’approbation du runtime.
- Les gardes anti-appels en double suppriment les appels identiques répétés, sauf si l’outil est exempté.
L’approbation dispose de différentes portes d’entrée :
- Les gestionnaires CLI invitent l’opérateur et prennent en charge
yes,noetalways. - Les gestionnaires de canaux non interactifs refusent automatiquement les outils nécessitant une invite sauf si le canal fournit un backchannel d’approbation en ligne.
- Les canaux de rétroaction ACP/web peuvent transmettre la demande d’approbation à un opérateur réel, même si le tour de parole en soi n’est pas interactif.
DenyWithEdit/ les réponses de remplacement sont assainies et deviennent des résultats d’outil synthétiques ; l’outil d’origine ne s’exécute pas.
L’approbation est un contrôle pré-exécution. Elle ne constitue pas un accusé de réception et n’est pas la preuve qu’un outil a été exécuté. Les entrées d’audit enregistrent la décision et le canal de décision ou le canal secondaire.
Les appels shell requis par le prompt ont une protection de boucle supplémentaire : si l’agent répète le même appel shell requis par le prompt avant approbation, la boucle s’interrompt au lieu de demander en boucle.
Dispatching, annulation et ordonnancement
L’exécuteur émet un TurnEvent::ToolCall en attente immédiatement avant d’exécuter l’outil afin que les clients de streaming puissent afficher une carte d’exécution en direct. Lorsque l’outil se termine, il émet le TurnEvent::ToolResult correspondant en utilisant le même identifiant de corrélation.
L’exécution parallèle n’est autorisée que lorsque :
- le réglage d’exécution active les outils parallèles ;
- le batch a plus d’un appel exécutable ;
- aucun appel dans le lot ne nécessite d’approbation ;
- le lot ne contient pas
tool_search.
Sinon, les appels s’exécutent séquentiellement. Le dispatch séquentiel vérifie l’annulation avant chaque appel et arrête de dispatcher la suite en cas d’annulation. Le dispatch parallèle peut terminer certains frères tandis que d’autres sont interrompus ; les appels terminés conservent leur résultat terminal réel, et seuls les appels non terminés obtiennent un résultat interrompu.
Le vecteur de résultats ordonné conserve un emplacement par appel de modèle d’origine. La préparation remplit les emplacements pour les appels annulés, refusés, remplacés ou dédupliqués ; l’exécution remplit les emplacements restants. Cela préserve l’ordre de l’historique du fournisseur même lorsque certains appels ne s’exécutent jamais ou lorsque des appels parallèles se terminent dans le désordre.
Résultats, reçus et historique
Les exécutions d’outils réussies normalisent une sortie vide en (no output). Lorsque [agent.tool_receipts] enabled = true, les exécutions réussies peuvent recevoir un reçu de la portée de reçu active avant que le résultat ne soit ajouté à l’historique. Les chemins channel-runtime et direct-turn ont des durées de vie de portée différentes ; la page Tool receipts détient les détails exacts du format HMAC et de la durée de vie des clés.
Les reçus sont des preuves de résultat. Ils ne sont pas des décisions d’approbation, pas des enregistrements d’audit durables, pas une chaîne, et ne sont pas générés pour les appels refusés, remplacés, bloqués, échoués ou interrompus.
Après exécution :
- les événements
ToolCallStartde l’observateur contiennent le nom de l’outil, l’id d’appel d’outil du fournisseur lorsqu’il est disponible, les arguments, le canal, l’alias de l’agent et l’id de tour ; - les événements
ToolCallde l’observateur de terminal ajoutent la durée, l’indicateur de succès et le résultat nettoyé tout en répétant les champs de corrélation nécessaires aux backends orientés span ; - les flux de progression affichent les lignes de début/achèvement avec le texte d’échec nettoyé ;
- Les hooks
after_tool_calls’exécutent pour les appels exécutés ; - les résultats sont bornés par
max_tool_result_charsavant d’être ajoutés à l’historique visible par le modèle ; - la détection de boucles utilise le contenu du résultat sauf pour les outils ignorés configurés ;
- la prochaine requête du provider voit le tour d’appel d’outil de l’assistant plus les résultats d’outils ordonnés.
Les résultats d’outils ne constituent pas une mémoire à long terme sauf si une écriture en mémoire se produit. Ils peuvent être un contexte de tour actuel, un historique de session persisté, un événement d’interface utilisateur streamé, un enregistrement d’observateur/journal, ou un résultat portant un reçu. Nommez la surface précisément dans les PR et les revues.
Ce que cette page ne possède pas
Les adaptateurs de canal et les passerelles prennent en charge le transport entrant, l’authentification, l’appariement, le décodage des webhooks et la livraison des réponses. L’exécution des outils commence après qu’un tour a atteint la boucle agent et qu’un modèle a émis un appel d’outil.
Le cycle de vie de la configuration gère le chargement, la sauvegarde, l’écrasement et le rechargement des paramètres liés à l’outil. Cette page ne couvre que les valeurs résolues après leur entrée dans le cycle.
Les docs de sécurité et d’autonomie détiennent le vocabulaire des politiques. Cette page montre où cette politique est appliquée à un appel d’outil concret.
Le cycle de vie de la mémoire et des payloads gère les périmètres de durabilité et de confidentialité pour l’historique, les fichiers, les médias et la mémoire. Cette page couvre le parcours des résultats d’outils qui alimente ces surfaces.
Background work lifecycle possède le contrat de plus longue durée lorsqu’un outil démarre un travail délégué ou un sous-agent. Un outil renvoyant un ID de tâche ne rend pas son exécution reprise après redémarrage.
Liste de contrôle du relecteur
Pour les modifications liées à l’exécution des outils, répondez à ces points avant la validation du réviseur :
- Quelle frontière a changé : définition d’outil, assemblage du registre, approbation, exécution, reçus, événements d’observateur, historique ou streaming de l’UI ?
- L’outil reste-t-il attribuable et enregistré via le chemin d’usine standard ?
- Le modèle voit-il uniquement les outils autorisés pour cet agent/run/itération ?
- Les
excluded_tools, la restriction par exécution,tool_filter_groupset l’activation différée de MCP sont-ils toujours cohérents ? - Un appel nécessitant une invite s’exécute-t-il séquentiellement et interroge-t-il la surface d’approbation correcte ?
- L’exécution non interactive refuse-t-elle ou utilise-t-elle un canal de liaison réel plutôt que d’approuver silencieusement ?
- Les gardes duplicate-call et repeated-prompt sont-ils conservés ?
- L’annulation ferme-t-elle uniquement les cartes/résultats d’outils non terminés ?
- Les surfaces d’observateur, de journalisation et de suivi sont-elles assainies et bornées là où des charges utiles utilisateur ou secrètes peuvent apparaître ?
- Les reçus sont-ils décrits comme une preuve d’exécution réussie, et non comme une approbation, une persistance ou une preuve à divulgation nulle de connaissance ?
- La PR inclut-elle une validation aux limites de la surface visible par l’utilisateur qu’elle modifie : CLI, canal, ACP/WS, passerelle, cron ou délégué/sous-agent ?
Pointeurs source
Documentation Canonical :
- Aperçu des outils
- Inventaire des outils intégrés
- MCP
- Niveaux d’autonomie
- Reçus d’outils
- Cycle de vie des requêtes
- Cycle de vie de la mémoire et du payload
- Cycle de vie de la configuration
- ADR-002: Extensibilité pilotée par les traits
- ADR-004: Propriété de l’état partagé des outils
Principaux points d’entrée du code :
- Trait Tool et forme du résultat :
crates/zeroclaw-api/src/tool.rs - Observer les événements d’outils :
crates/zeroclaw-api/src/observability_traits.rs - Contexte d’exécution du tour :
crates/zeroclaw-runtime/src/agent/turn/execution.rs - Fiche d’exécution et boucle du moteur de tour :
crates/zeroclaw-runtime/src/agent/turn/mod.rs - Préparation et approbation des appels d’outils :
crates/zeroclaw-runtime/src/agent/turn/call_prep.rsetcrates/zeroclaw-runtime/src/agent/turn/approval_gate.rs - Dispatch d’outil :
crates/zeroclaw-runtime/src/agent/tool_execution.rs - Reçus d’outils :
crates/zeroclaw-runtime/src/agent/tool_receipts.rs - Collecte des résultats/ajout à l’historique :
crates/zeroclaw-runtime/src/agent/turn/results_collect.rsetcrates/zeroclaw-runtime/src/agent/turn/history_append.rs - Gestionnaire d’approbation :
crates/zeroclaw-runtime/src/approval/mod.rs - Assemblage d’outils à portée limitée et activation MCP différée :
crates/zeroclaw-runtime/src/tools/scoped.rs