> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Les middlewares d'agent de Laravel AI SDK

> Découvrez, avec l'AI SDK de Laravel 13, l'ordre d'exécution des middlewares à chaque appel au modèle, le traitement après la réponse et l'arrêt en fonction des tokens cumulés.

Lorsqu'un agent utilise plusieurs outils, vous pouvez avoir besoin de **vérifier la consommation avant d'appeler le modèle et de journaliser la réponse de chaque étape**. Les middlewares de Laravel AI SDK n'enveloppent pas l'agent entier une seule fois : ils s'exécutent à chaque étape de la génération. En s'appuyant sur la documentation officielle de Laravel 13 et sur l'implémentation de `laravel/ai` `v1.3.0`, cette page va un peu plus loin que les [opérations de base de l'AI SDK](/fr/ai-sdk) et détaille l'ordre d'exécution et les conditions d'arrêt.

## L'unité d'exécution des middlewares

Lorsqu'un agent reçoit la réponse du modèle, exécute des outils puis rappelle le modèle, ce nouvel appel au modèle constitue une **étape distincte**. Juste avant chaque étape, les middlewares retournés par `HasMiddleware::middleware()` sont traversés dans l'ordre de leur déclaration.

Le `PendingStep` transmis à la méthode `handle(PendingStep $step, Closure $next)` du middleware contient le tableau des étapes déjà exécutées `steps`, leur consommation cumulée `usage` et le numéro de l'étape courante `number`, qui commence à zéro. Lors de la première étape, `usage` n'inclut pas encore la consommation de l'appel au modèle en cours.

```mermaid theme={null}
flowchart TD
    A["PendingStep suivant<br>usage cumulé des étapes terminées"] --> B["Évaluation dans l'ordre de déclaration de middleware()"]
    B --> C{"Condition Stop remplie ?"}
    C -->|Oui| D["Fin sans appeler le modèle pour cette étape"]
    C -->|Non| E["Appel au modèle"]
    E --> F["Réception du StepResponse"]
    F --> G["Exécution du callback then()"]
    G --> H["Exécution des outils si nécessaire"]
    H --> I{"Étape suivante nécessaire ?"}
    I -->|Oui| A
    I -->|Non| J["Finalisation de la réponse de l'agent"]
```

Le `then()` chaîné au résultat de `$next($step)` s'exécute **après la réponse du modèle et avant l'exécution des appels d'outils**. Ce n'est pas un hook appelé uniquement après l'exécution des outils. De plus, à ce stade, `usage` correspond au total des étapes précédemment terminées et ne prédit pas le nombre de tokens de la requête en cours.

## Enregistrer un traitement pour chaque étape

Voici un exemple qui journalise uniquement le numéro de l'étape et le nombre de tokens d'entrée consommés jusque-là. Évitez d'enregistrer systématiquement le texte du prompt ou la sortie du modèle dans les logs.

```php theme={null}
<?php

namespace App\Ai\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;
use Laravel\Ai\Gateway\StepResponse;
use Laravel\Ai\PendingStep;

final class LogAgentSteps
{
    public function handle(PendingStep $step, Closure $next)
    {
        Log::info('AI step starting', [
            'step' => $step->number,
            'input_tokens_used' => $step->usage->inputTokens,
        ]);

        return $next($step)->then(function (StepResponse $response) use ($step): void {
            Log::info('AI model responded', ['step' => $step->number]);
        });
    }
}
```

Faites implémenter `HasMiddleware` à l'agent et retournez les instances depuis `middleware()`.

```php theme={null}
<?php

namespace App\Ai\Agents;

use App\Ai\Middleware\LogAgentSteps;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasMiddleware;
use Laravel\Ai\Middleware\Stop;
use Laravel\Ai\PendingStep;
use Laravel\Ai\Promptable;

class SupportAgent implements Agent, HasMiddleware
{
    use Promptable;

    public function instructions(): string
    {
        return 'Answer support questions concisely.';
    }

    public function middleware(): array
    {
        return [
            Stop::when(fn (PendingStep $step): bool => $step->usage->inputTokens >= 50_000),
            new LogAgentSteps,
        ];
    }
}
```

Dans l'ordre de `middleware()`, placez `Stop` en premier. Si la limite est dépassée et que **l'étape suivante n'est pas lancée**, le `LogAgentSteps` qui suit n'est pas exécuté pour cette étape. Si vous inversez l'ordre, seul le log de « démarrage » peut être enregistré, sans le log « le modèle a répondu ». Retournez le résultat de `$next($step)` depuis `handle()` ; le callback de `then()` n'a pas besoin de retourner la réponse.

## Stop empêche l'appel suivant au modèle

`Stop::when(...)` termine le traitement avant l'étape lorsque la condition devient vraie, et `Stop::unless(...)` lorsque la condition devient fausse. Dans l'exemple ci-dessus, l'appel suivant n'est pas effectué dès que le cumul des tokens d'entrée des **étapes terminées** atteint 50 000 ou plus. Il ne s'agit pas d'une limite stricte qui interromprait de force un appel au modèle avant qu'il ne dépasse le seuil.

| Moment de l'évaluation | Résultat lorsque la condition est remplie |
| - | - |
| Avant d'appeler la première étape | Le modèle n'est pas appelé, et les étapes terminées comme le texte de réponse sont vides |
| Avant d'appeler l'étape suivante après l'exécution des outils | Le traitement se termine en conservant les étapes terminées jusque-là et leur consommation |
| Avant d'appeler l'étape suivante en streaming | La raison de fin du stream devient `cancelled` |

> [!WARNING]
>
> `Stop` n'interrompt pas une requête en cours auprès du fournisseur. Si vous devez garantir strictement une limite de consommation, ne vous reposez pas uniquement sur l'évaluation de l'étape suivante et envisagez également les limites côté modèle ou fournisseur.

Un middleware qui souhaite s'arrêter selon sa propre condition peut aussi retourner `Laravel\Ai\Gateway\StepResult::stop()`. Depuis `handle()`, retournez le résultat de `$next($step)`, un `StepResponse` ou `StepResult::stop()`. Retourner un type sans rapport lève une exception.

## Vérifier l'ordre d'exécution

Pour ne pas confondre réponse du modèle et exécution des outils, vérifiez au minimum les cas suivants.

* Pour une génération en une seule étape, le log de démarrage et le log de réponse du modèle apparaissent une fois chacun.
* Pour les étapes supplémentaires qui suivent un outil, le numéro augmente à partir de 0, et le `usage` des étapes suivantes inclut la consommation des étapes précédentes.
* Si la condition d'arrêt est remplie dès le départ, ni l'appel au modèle ni les logs de `LogAgentSteps` ne se produisent.
* Si la condition est atteinte en cours de route, les étapes précédentes sont conservées et l'appel au modèle de l'étape suivante n'a pas lieu.

Séparez le chemin normal du chemin d'arrêt et vérifiez le nombre d'exécutions de chaque étape. Si `then()` doit produire des effets de bord, concevez-le en partant du principe qu'il n'est pas appelé sur les chemins qui échouent ou s'arrêtent avant d'obtenir la réponse du modèle.

## Sources primaires consultées

* [Documentation officielle de Laravel 13 : les middlewares de l'AI SDK](https://github.com/laravel/docs/blob/13.x/ai-sdk.md)
* [Laravel AI SDK v1.3.0 : les valeurs de PendingStep](https://github.com/laravel/ai/blob/v1.3.0/src/PendingStep.php#L18-L46)
* [Laravel AI SDK v1.3.0 : la boucle de génération](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/TextGenerationLoop.php#L133-L188) et [l'ordre d'exécution des middlewares](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/TextGenerationLoop.php#L441-L468)
* [Laravel AI SDK v1.3.0 : StepResult::stop() et then()](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/StepResult.php#L37-L59)
* [Laravel AI SDK v1.3.0 : le middleware Stop](https://github.com/laravel/ai/blob/v1.3.0/src/Middleware/Stop.php)
* [Laravel AI SDK v1.3.0 : les tests d'arrêt d'étape](https://github.com/laravel/ai/blob/v1.3.0/tests/Feature/AgentMiddlewareTest.php#L300-L345)


## Related topics

- [Sujets avancés](/fr/advanced/index.md)
- [Laravel AI SDK](/fr/ai-sdk.md)
- [Boucle d'agent](/fr/packages/laravel-copilot-sdk/agent-loop.md)
- [Pilote Amazon Bedrock pour Laravel AI SDK](/fr/packages/laravel-amazon-bedrock.md)
- [Créer un fournisseur personnalisé pour l'AI SDK](/fr/advanced/ai-sdk-custom-provider.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.