> ## 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 de agentes en Laravel AI SDK

> Explica, en el AI SDK de Laravel 13, el orden de ejecución del middleware en cada llamada al modelo, el procesamiento tras la respuesta y la detención según los tokens acumulados.

Cuando un agente utiliza varias herramientas, a veces quieres **comprobar el uso antes de llamar al modelo y registrar la respuesta de cada paso**. El middleware de Laravel AI SDK no envuelve el agente completo una sola vez, sino que se ejecuta en cada paso de la generación. Basándose en la documentación oficial de Laravel 13 y en la implementación de `laravel/ai` `v1.3.0`, esta página va un paso más allá de las [operaciones básicas del AI SDK](/es/ai-sdk) y organiza el orden de ejecución y las condiciones de detención.

## La unidad en la que se ejecuta el middleware

Cuando el agente recibe la respuesta del modelo, ejecuta herramientas y vuelve a llamar al modelo, la siguiente llamada al modelo es **un paso distinto**. Justo antes de cada paso, se pasa por el middleware devuelto en `HasMiddleware::middleware()` en el orden en que se declaró.

El `PendingStep` que se pasa a `handle(PendingStep $step, Closure $next)` del middleware contiene el array de pasos ya ejecutados `steps`, su uso acumulado `usage` y el número del paso actual, empezando en cero, `number`. En el primer paso, `usage` todavía no incluye el uso de la llamada al modelo actual.

```mermaid theme={null}
flowchart TD
    A["Siguiente PendingStep<br>usage acumulado de los pasos completados"] --> B["Evaluar en el orden declarado en middleware()"]
    B --> C{"¿Se cumple la condición de Stop?"}
    C -->|Sí| D["Terminar sin llamar al modelo en este paso"]
    C -->|No| E["Llamar al modelo"]
    E --> F["Recibir StepResponse"]
    F --> G["Ejecutar el callback de then()"]
    G --> H["Ejecutar herramientas si es necesario"]
    H --> I{"¿Hace falta otro paso?"}
    I -->|Sí| A
    I -->|No| J["Finalizar la respuesta del agente"]
```

El `then()` encadenado al resultado de `$next($step)` se ejecuta **después de que el modelo responda y antes de que se ejecuten las llamadas a herramientas**. No es un hook que se llame solo después de ejecutar las herramientas. Además, el `usage` en ese momento es la suma de los pasos completados anteriormente y no predice el número de tokens de la petición en curso.

## Registrar procesamiento por paso

Este ejemplo solo registra en el log el número de paso y el número de tokens de entrada utilizados hasta el momento. Evita guardar sin condiciones el texto del prompt o la salida del modelo en los 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]);
        });
    }
}
```

Implementa `HasMiddleware` en el agente y devuelve las instancias desde `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,
        ];
    }
}
```

En el orden de `middleware()`, coloca `Stop` primero. Cuando se supera el límite y **no se inicia el siguiente paso**, el `LogAgentSteps` posterior no se ejecuta en ese paso. Si inviertes el orden, puede que solo se registre el "inicio" en el log y no "el modelo respondió". Devuelve el resultado de `$next($step)` desde `handle()`; el callback de `then()` no necesita devolver la respuesta.

## Stop detiene la siguiente llamada al modelo

`Stop::when(...)` termina el procesamiento antes de ese paso cuando la condición es true, y `Stop::unless(...)` cuando la condición es false. El ejemplo anterior no realiza la siguiente llamada cuando los tokens de entrada acumulados de los **pasos completados** llegan a 50,000 o más. No es un límite estricto que detenga a la fuerza una llamada al modelo antes de que supere el umbral.

| Momento de la evaluación | Resultado cuando se cumple la condición |
| - | - |
| Antes de llamar al primer paso | No se llama al modelo; los pasos completados y el texto de la respuesta quedan vacíos |
| Antes de llamar al siguiente paso tras ejecutar herramientas | Termina conservando los pasos completados hasta ese momento y su uso |
| Antes de llamar al siguiente paso en streaming | El motivo de finalización del stream pasa a ser `cancelled` |

> [!WARNING]
>
> `Stop` no interrumpe una petición en curso al proveedor. Si necesitas garantizar estrictamente un límite de uso, no dependas solo de la evaluación del siguiente paso y considera también los límites del modelo o del proveedor.

Un middleware que quiera detenerse con una condición propia también puede devolver `Laravel\Ai\Gateway\StepResult::stop()`. Desde `handle()` se devuelve el resultado de `$next($step)`, un `StepResponse` o `StepResult::stop()`. Devolver un tipo no relacionado provoca una excepción.

## Verificar el orden de ejecución

Para no confundir la respuesta del modelo con la ejecución de herramientas, comprueba al menos los siguientes casos.

* En una generación de un solo paso, el log de inicio y el log de respuesta del modelo aparecen una vez cada uno.
* En los pasos adicionales que siguen a una herramienta, el número aumenta desde 0 y el `usage` de los pasos posteriores incluye el uso de los pasos anteriores.
* Si la condición de detención se cumple desde el principio, no se producen ni la llamada al modelo ni los logs de `LogAgentSteps`.
* Si la condición se alcanza a mitad de camino, los pasos anteriores se conservan y no se produce la llamada al modelo del siguiente paso.

Separa la ruta normal de la ruta que se detiene y comprueba cuántas veces se ejecuta cada paso. Aunque `then()` necesite efectos secundarios, diséñalo partiendo de que no se llamará en las rutas que fallan o se detienen antes de obtener la respuesta del modelo.

## Fuentes primarias consultadas

* [Documentación oficial de Laravel 13: middleware del AI SDK](https://github.com/laravel/docs/blob/13.x/ai-sdk.md)
* [Laravel AI SDK v1.3.0: valores de PendingStep](https://github.com/laravel/ai/blob/v1.3.0/src/PendingStep.php#L18-L46)
* [Laravel AI SDK v1.3.0: bucle de generación](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/TextGenerationLoop.php#L133-L188) · [orden de ejecución del middleware](https://github.com/laravel/ai/blob/v1.3.0/src/Gateway/TextGenerationLoop.php#L441-L468)
* [Laravel AI SDK v1.3.0: StepResult::stop() y 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: pruebas de detención de pasos](https://github.com/laravel/ai/blob/v1.3.0/tests/Feature/AgentMiddlewareTest.php#L300-L345)


## Related topics

- [Temas avanzados](/es/advanced/index.md)
- [Los agentes de IA de Laravel ahora soportan MCP](/es/blog/ai-sdk-mcp-client.md)
- [Laravel Agent Detector — Paquete de detección de agentes de IA](/es/blog/agent-detector-introduction.md)
- [Laravel AI SDK](/es/ai-sdk.md)
- [Crear un proveedor personalizado del AI SDK](/es/advanced/ai-sdk-custom-provider.md)


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