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

# Middleware degli agenti del Laravel AI SDK

> Spiega, per l'AI SDK di Laravel 13, l'ordine di esecuzione dei middleware a ogni chiamata al modello, l'elaborazione dopo la risposta e l'arresto in base ai token cumulativi.

Quando un agente usa più tool, può capitare di voler **controllare l'utilizzo prima di chiamare il modello e registrare la risposta di ogni step**. I middleware del Laravel AI SDK non avvolgono l'intero agente una sola volta: vengono eseguiti a ogni step della generazione. Basandosi sulla documentazione ufficiale di Laravel 13 e sull'implementazione di `laravel/ai` `v1.3.0`, questa pagina va un passo oltre le [operazioni di base dell'AI SDK](/it/ai-sdk) e mette in ordine la sequenza di esecuzione e le condizioni di arresto.

## L'unità di esecuzione dei middleware

Quando l'agente riceve la risposta del modello, esegue i tool e poi chiama di nuovo il modello, la chiamata successiva costituisce **uno step separato**. Subito prima di ogni step, vengono attraversati i middleware restituiti da `HasMiddleware::middleware()` nell'ordine in cui sono dichiarati.

Il `PendingStep` passato a `handle(PendingStep $step, Closure $next)` del middleware contiene l'array degli step già eseguiti `steps`, il loro utilizzo cumulativo `usage` e il numero dello step corrente a partire da zero `number`. Al primo step, `usage` non include ancora l'utilizzo della chiamata al modello in corso.

```mermaid theme={null}
flowchart TD
    A["PendingStep successivo<br>usage cumulativo degli step completati"] --> B["Valutazione nell'ordine dichiarato in middleware()"]
    B --> C{"Corrisponde alla condizione di Stop?"}
    C -->|Sì| D["Termina senza chiamare il modello per questo step"]
    C -->|No| E["Chiama il modello"]
    E --> F["Riceve lo StepResponse"]
    F --> G["Esegue la callback then()"]
    G --> H["Esegue i tool se necessario"]
    H --> I{"Serve uno step successivo?"}
    I -->|Sì| A
    I -->|No| J["Finalizza la risposta dell'agente"]
```

Il `then()` agganciato al risultato di `$next($step)` viene eseguito **dopo la risposta del modello e prima dell'esecuzione delle chiamate ai tool**. Non è un hook chiamato solo dopo l'esecuzione dei tool. Inoltre, `usage` in quel momento è la somma degli step completati in precedenza e non stima il numero di token della richiesta in corso.

## Registrare l'elaborazione per ogni step

Ecco un esempio che registra nel log solo il numero dello step e i token di input usati fino a quel momento. Evita di salvare incondizionatamente nel log il testo del prompt o l'output del modello.

```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]);
        });
    }
}
```

Implementa `HasMiddleware` nell'agente e restituisci le istanze da `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,
        ];
    }
}
```

Nell'ordine di `middleware()`, metti `Stop` per primo. Se il limite viene superato e **lo step successivo non viene avviato**, il `LogAgentSteps` che segue non viene eseguito per quello step. Invertendo l'ordine, può succedere che nel log venga registrato solo l'"inizio" e non "il modello ha risposto". Restituisci da `handle()` il risultato di `$next($step)`; la callback di `then()` non deve restituire la risposta.

## Stop blocca la chiamata successiva al modello

`Stop::when(...)` termina l'elaborazione prima dello step quando la condizione diventa true, `Stop::unless(...)` quando la condizione diventa false. L'esempio sopra non esegue la chiamata successiva quando i token di input cumulativi degli **step completati** raggiungono o superano 50.000. Non è un limite rigido che interrompe forzatamente una singola chiamata al modello prima che superi la soglia.

| Momento della verifica | Risultato quando la condizione è soddisfatta |
| - | - |
| Prima di chiamare il primo step | Il modello non viene chiamato e sia gli step completati sia il testo della risposta sono vuoti |
| Prima di chiamare lo step successivo dopo l'esecuzione dei tool | Termina conservando gli step completati fino a quel momento e il relativo utilizzo |
| Prima di chiamare lo step successivo in streaming | Il motivo di chiusura dello stream diventa `cancelled` |

> [!WARNING]
>
> `Stop` non interrompe una richiesta al provider già in corso. Se devi garantire rigorosamente un limite di utilizzo, non affidarti solo alla verifica dello step successivo e valuta anche i limiti lato modello o provider.

Un middleware che vuole fermarsi con una condizione personalizzata può anche restituire `Laravel\Ai\Gateway\StepResult::stop()`. Da `handle()` restituisci il risultato di `$next($step)`, uno `StepResponse` oppure `StepResult::stop()`. Restituire un tipo diverso genera un'eccezione.

## Verificare l'ordine di esecuzione

Per non confondere la risposta del modello con l'esecuzione dei tool, verifica almeno i casi seguenti.

* In una generazione con un solo step, il log di inizio e quello di risposta del modello compaiono una volta ciascuno.
* Negli step aggiuntivi che seguono i tool, il numero cresce a partire da 0 e lo `usage` degli step successivi include l'utilizzo degli step precedenti.
* Se la condizione di arresto è soddisfatta fin dall'inizio, non avvengono né la chiamata al modello né i log di `LogAgentSteps`.
* Se la condizione viene raggiunta a metà, gli step precedenti restano e la chiamata al modello per lo step successivo non avviene.

Separa il percorso normale da quello che si interrompe e controlla quante volte viene eseguito ogni step. Anche quando `then()` richiede effetti collaterali, progettalo presupponendo che non venga chiamato nei percorsi che falliscono o si fermano prima di ottenere la risposta del modello.

## Fonti primarie consultate

* [Documentazione ufficiale di Laravel 13: middleware dell'AI SDK](https://github.com/laravel/docs/blob/13.x/ai-sdk.md)
* [Laravel AI SDK v1.3.0: valori di PendingStep](https://github.com/laravel/ai/blob/v1.3.0/src/PendingStep.php#L18-L46)
* [Laravel AI SDK v1.3.0: loop di generazione](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/TextGenerationLoop.php#L133-L188) e [ordine di esecuzione dei middleware](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/TextGenerationLoop.php#L441-L468)
* [Laravel AI SDK v1.3.0: StepResult::stop() e then()](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/StepResult.php#L37-L59)
* [Laravel AI SDK v1.3.0: middleware Stop](https://github.com/laravel/ai/blob/v1.3.0/src/Middleware/Stop.php)
* [Laravel AI SDK v1.3.0: test dell'arresto degli step](https://github.com/laravel/ai/blob/v1.3.0/tests/Feature/AgentMiddlewareTest.php#L300-L345)


## Related topics

- [Argomenti avanzati](/it/advanced/index.md)
- [Laravel AI SDK](/it/ai-sdk.md)
- [Laravel Agent Detector — pacchetto per rilevare gli agenti AI](/it/blog/agent-detector-introduction.md)
- [Laravel PAO — strumento di ottimizzazione dell'output per agenti AI](/it/blog/pao-introduction.md)
- [Blog](/it/blog/index.md)


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