Passer au contenu principal
Quand un agent a besoin d’une personne, d’une tâche externe ou d’un outil exécuté par votre application, l’exécution se termine normalement (pas en erreur) avec le statut waiting_for_human et tout ce qu’il faut pour reprendre. Enregistrez le résultat complet, recueillez la décision dans votre application, puis passez le résultat enregistré et la décision à la méthode de reprise de l’agent.
Phaseo ne stocke pas les exécutions du SDK Agent. Enregistrez l’état reprenable dans votre propre application quand il doit survivre à une requête ou à un redémarrage du processus.

Approuver ou rejeter des appels d’outils

Les outils soumis à approbation, manuels et à humain dans la boucle mettent l’exécution en pause avant de s’exécuter. Chaque appel en attente contient le call du modèle (avec son id) et un kind : approval, manual ou hitl. Répondez à chaque appel par son ID d’appel exact, et non par le nom de l’outil, pour que deux appels au même outil restent distincts. Un appel approuvé exécute son outil. Un appel rejeté envoie {"error": "<reason>"} au modèle comme résultat de l’outil, avec la raison par défaut Tool call rejected.
Où se trouvent les appels en attente, et ce qui se passe quand une décision manque : La pause elle-même a aussi un kind. Go et C# le définissent à tool_approval pour toute pause d’outil. PHP, Ruby et Java définissent tool_approval quand au moins un appel en attente exige une approbation, sinon le kind du premier appel. Rust utilise tool_approval pour les appels à approuver, external_output quand tous les appels en attente exigent un résultat externe, et tool_input pour un mélange des deux.
Rust 0.2 n’a ni type de rejet ni champ rejections. Laissez en pause un appel non approuvé, ou appliquez la politique de rejet de votre application avant de reprendre.
Pour exiger une approbation pour chaque appel d’outil plutôt qu’outil par outil, définissez requireApproval sur la définition de l’agent (require_approval en Python et Ruby, RequireApproval en Go et C#). En TypeScript, c’est une fonction requireApproval(call, context). Rust ne prend en charge que l’approbation par outil, avec Tool::require_approval(). Outils montre comment chaque type d’outil est défini.

Fournir les résultats des outils manuels et à humain dans la boucle

Pour les appels manual et hitl, passez le résultat produit par votre application, indexé par ID d’appel. En Rust, il s’agit des outils construits avec Tool::external(...).
Une sortie manquante fait échouer la reprise avec Missing output for tool call <id> (missing en minuscules en Go, une ValueError en Python, une AgentError en Rust). Un message de saisie humaine ne remplace pas une sortie d’outil.

Mettre en pause pour une revue humaine

Définissez un callback de revue humaine sur la définition de l’agent pour vérifier chaque réponse du modèle avant que l’exécution continue. Renvoyez une demande de revue avec un reason (et éventuellement un payload) pour mettre en pause, ou rien pour continuer. Le kind de la pause est human_review. Le callback reçoit l’ID d’exécution, l’index de l’étape, les messages, la réponse du modèle et la sortie analysée (en Rust : les ID d’exécution et d’agent, l’index de l’étape, les messages, la réponse et le contexte applicatif).
Reprenez avec une saisie humaine, qui est ajoutée à la conversation comme message utilisateur :
Reprendre une pause de revue sans saisie humaine échoue avec Run <id> is waiting for human input (Go : run <id> is waiting for human input ; Java : Run is waiting for human input). Rust exige un human_input non vide. TypeScript accepte aussi des humanMessages structurés.

Enregistrer l’état de l’exécution entre les requêtes

Le résultat d’exécution est une simple donnée : stockez-le dans votre base de données, votre stockage d’objets ou l’enregistrement de votre tâche, et gardez le context applicatif sérialisable. Seul un agent ayant le même ID peut reprendre une exécution. La recette de boucle d’agent durable montre un flux complet d’enregistrement et de reprise. Pour laisser le SDK enregistrer et charger les exécutions à votre place, passez un accesseur d’état avec load(runId) et save(result). Le SDK enregistre alors après chaque exécution et chaque reprise, et vous pouvez reprendre par ID d’exécution au lieu de faire transiter l’enregistrement à travers chaque couche.
En Rust, recréez la même définition d’agent et les mêmes outils avant de reprendre : les closures et AgentDefinition ne font pas partie de l’exécution sérialisée. Le modèle effectif et la limite d’étapes sont stockés dans RunRecord, donc les surcharges par exécution restent actives après la reprise. Quoi que vous stockiez, votre application est responsable du chiffrement et de la conservation des exécutions enregistrées, de l’autorisation des approbations et des saisies humaines, et de l’idempotence des effets de bord qui se rejouent après une reprise.
Dernière modification le 5 novembre 2026