Use Laravel AI SDK Middleware for Automatic Request Recording

📖 2 minutes read

If you’re using Laravel AI SDK and need to log or track every AI agent call (costs, tokens, timing), you might be tempted to manually call your tracking service after every prompt():

// ❌ Repetitive - you'll forget this somewhere
$response = $agent->prompt($message);
UsageLogger::record($response);

Instead, use the HasMiddleware interface to automatically intercept all agent responses. Create a middleware that runs after every agent call:

// app/Ai/Middleware/LogUsage.php
namespace App\Ai\Middleware;

use Closure;
use Laravel\Ai\Prompts\AgentPrompt;

class LogUsage
{
    public function handle(AgentPrompt $prompt, Closure $next): mixed
    {
        $response = $next($prompt);

        // Automatic logging for ALL agents
        UsageLogger::record(
            response: $response,
            model: $response->meta->model,
            tag: class_basename($prompt->agent::class)
        );

        return $response;
    }
}

Then create a BaseAgent class that all your agents extend:

// app/Ai/Agents/BaseAgent.php
abstract class BaseAgent implements Agent, HasMiddleware
{
    use Promptable;

    public function middleware(): array
    {
        return [
            \App\Ai\Middleware\LogUsage::class,
        ];
    }
}

Now every agent that extends BaseAgent gets automatic logging:

// app/Ai/Agents/ReportGenerator.php
class ReportGenerator extends BaseAgent
{
    // Zero extra code - logging happens automatically
}

Why this matters: You have 20 agents and want to add cost tracking. Without middleware, you’re manually adding UsageLogger::record() after 20+ prompt() calls. With middleware, it’s one line in BaseAgent.

Bonus: Need authentication, rate limiting, or retries? Add more middleware to the BaseAgent::middleware() array. All agents inherit the behavior.

Daryle De Silva

VP of Technology

11+ years building and scaling web applications. Writing about what I learn in the trenches.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *