À la Laracon US 2026 à Boston, l'équipe Laravel a annoncé une API human-in-the-loop (HITL) pour le Laravel AI SDK. Elle a été intégrée via laravel/ai#773 et publiée dans la v0.10.0 le 21 juillet. Jusqu'ici, une fois qu'un agent commençait à appeler des outils, il allait au bout sans supervision — acceptable pour des outils en lecture seule, mais risqué pour des actions comme supprimer un fichier, rembourser un paiement ou envoyer un e-mail à un client. Avec HITL, un agent peut se mettre en pause avant d'exécuter un outil et attendre qu'une personne approuve, rejette ou modifie ses arguments.
L'approbation est activable outil par outil. Un outil implémente le contrat Laravel\Ai\Contracts\Approvable et utilise le trait InteractsWithApprovals, ce qui rend l'approbation obligatoire par défaut. Pour un contrôle plus fin, une méthode needsApproval peut examiner les arguments et renvoyer un booléen ou une instance Approval avec un motif — par exemple n'exiger une validation que pour les remboursements supérieurs à 20 $. Les exigences peuvent aussi être redéfinies à l'enregistrement dans la méthode tools() de l'agent via withoutApproval() et requireApproval().
Quand le modèle appelle un outil soumis à approbation, l'agent s'arrête et expose les appels en attente dans la réponse via hasPendingApprovals() et pendingApprovals ; chaque entrée contient l'ID d'appel, le nom de l'outil, les arguments et le motif. Pour reprendre, on continue la conversation avec une instance Decisions indexée par ID d'appel, avec Decision::approve() ou Decision::reject() — true/false fonctionnent comme raccourcis. Chaque appel en attente exige une décision, sinon une ApprovalMismatchException est levée ; approveRemaining() et rejectRemaining() définissent une valeur par défaut pour le reste. Un rejet accompagné d'une chaîne de résultat est renvoyé au modèle pour qu'il poursuive, tandis qu'un rejet sans résultat arrête la boucle de génération.
Quelques détails comptent : l'agent doit être Conversational avec un historique persisté (trait RemembersConversations) pour pouvoir reprendre un appel en pause. L'approbation fonctionne avec prompt, stream, queue, broadcast, broadcastNow et broadcastOnQueue ; en streaming, elle apparaît comme événement tool_approval_request, avec des parts d'approbation natives dans le protocole de stream du Vercel AI SDK, et les agents en queue reçoivent la réponse dans le callback then avec un événement ToolApprovalRequested. Les pauses sont par appel, pas par étape — les outils non soumis à approbation d'une même étape s'exécutent immédiatement, donc les effets de bord doivent rester idempotents via $request->toolCallId(). Le résultat d'un outil approuvé est enregistré avant que le modèle ne continue ; si la génération échoue ensuite, il faut reprendre avec un prompt texte ordinaire plutôt que de resoumettre les décisions.
La mise à niveau vers 0.10 comporte des changements cassants : une nouvelle colonne nullable approval_state sur la table des messages de conversation, et une méthode storeApprovalResults() que les implémentations personnalisées de ConversationStore doivent fournir. La documentation propose un flux complet avec deux routes acceptant soit un nouveau message, soit un ensemble de décisions depuis un écran de chat.
Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
En attente de ton clic …
·