---
title: "Agent Tracing"
description: "Monitor Laravel agents with token usage, latency, tool execution, and error tracking."
url: https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing/
---

# Set Up Agent Tracing for Laravel

This feature is currently in Beta. Beta features are still in progress and may have bugs. We recognize the irony.

With [Sentry Agent Tracing](https://docs.sentry.io/product/agents/dashboards.md), you can monitor and debug your Laravel agents with full-stack context. You'll be able to track key insights like token usage, latency, tool usage, and error rates. Agent Tracing data is connected to your other Sentry data like logs, errors, and traces.

## [Requirements](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#requirements)

* `sentry/sentry-laravel` version `4.27.0` or later
* Laravel 12.x or later
* [`laravel/ai`](https://laravel.com/docs/13.x/ai-sdk#installation) installed and configured
* [Tracing](https://docs.sentry.io/platforms/php/guides/laravel/tracing.md) enabled in your Sentry configuration

## [Configure](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#configure)

Laravel AI tracing is enabled by default when `laravel/ai` is installed and tracing is active.

```shell
SENTRY_TRACES_SAMPLE_RATE=1.0
```

You can opt out of all AI spans, or individual AI span types, in `config/sentry.php`:

```php
'tracing' => [
    // Master switch for all AI spans (requires laravel/ai)
    'gen_ai' => env('SENTRY_TRACE_GEN_AI_ENABLED', true),

    // Individual span types
    'gen_ai_invoke_agent' => env('SENTRY_TRACE_GEN_AI_INVOKE_AGENT_ENABLED', true),
    'gen_ai_chat' => env('SENTRY_TRACE_GEN_AI_CHAT_ENABLED', true),
    'gen_ai_execute_tool' => env('SENTRY_TRACE_GEN_AI_EXECUTE_TOOL_ENABLED', true),
    'gen_ai_embeddings' => env('SENTRY_TRACE_GEN_AI_EMBEDDINGS_ENABLED', true),
    'gen_ai_evaluate' => env('SENTRY_TRACE_GEN_AI_EVALUATE_ENABLED', true),
],
```

Sentry considers LLM and tool inputs/outputs as PII and doesn't include them by default. To capture this data for debugging, set `SENTRY_SEND_DEFAULT_PII=true`. See [Data Collected](https://docs.sentry.io/platforms/php/guides/laravel/data-management/data-collected.md) for details.

## [Automatic Instrumentation](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#automatic-instrumentation)

The Laravel SDK automatically instruments the [Laravel AI](https://laravel.com/docs/13.x/ai-sdk) package. Once enabled, Sentry captures:

* Agent invocations
* LLM requests
* Tool executions
* Embeddings
* Classifications, such as [Jev evaluations](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#trace-jev-evaluations)
* Token usage
* Model and provider metadata

For package-specific details, see the [Laravel AI integration](https://docs.sentry.io/platforms/php/guides/laravel/integrations/laravel-ai.md).

## [Supported Providers and Custom URLs](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#supported-providers-and-custom-urls)

Sentry creates `gen_ai.chat` spans by matching Laravel AI's outgoing HTTP requests to the provider URL. Built-in URL detection supports these Laravel AI provider drivers:

* Anthropic
* DeepSeek
* Gemini
* Groq
* Mistral
* Ollama
* OpenAI
* OpenRouter
* Voyage AI
* xAI

If you use a custom provider, or override a provider's endpoint, include a `url` value in `config/ai.php` so Sentry can identify those requests:

```php
'providers' => [
    'my-llm' => [
        'driver' => 'openai-compatible',
        'url' => env('MY_LLM_URL'),
        'key' => env('MY_LLM_API_KEY'),
    ],
],
```

The provider key (`my-llm` in this example) is what Laravel AI passes to Sentry as the provider name. Sentry looks for `ai.providers.my-llm.url` and uses that value as the URL prefix for chat span detection.

## [Trace Jev Evaluations](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#trace-jev-evaluations)

Available since: `v4.29.0`

Classifications made with `laravel/ai` 1.0 or later, such as calls to TypeSafe's Jev model, are traced automatically. No additional setup is needed:

```php
use Laravel\Ai\Classification;
use Laravel\Ai\Classification\Boolean;
use Laravel\Ai\Classification\Choice;

$response = Classification::of('I was charged twice. Please refund the extra charge.')
    ->questions([
        'is_urgent' => new Boolean('Does this message convey urgency?'),
        'department' => new Choice('Which team should handle this?', [
            'billing' => 'Charges and refunds',
            'technical' => 'Bugs and outages',
        ]),
    ])
    ->classify('typesafe');
```

Each classification creates a `gen_ai.evaluate` span named `evaluate <model>`, with the provider, the response model (for example, `jev-1.13.0`), latency, and token usage. If the provider returns an error, the span is marked as failed. When recording is enabled, Sentry captures the classified text and the questions as input messages and the answers as output messages. Sentry shows these spans as [evaluation spans](https://docs.sentry.io/product/agents/conversations.md#evaluation-spans).

Classified text and answers can contain sensitive data, so Sentry only records them if `send_default_pii` is enabled. With the [`data_collection` option](https://docs.sentry.io/platforms/php/guides/laravel/configuration/options.md#data_collection), use the `gen_ai` key's `inputs` and `outputs` instead.

To stop creating these spans, set `tracing.gen_ai_evaluate` to `false` in `config/sentry.php`.

## [Verify](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#verify)

Prompt one of your Laravel agents. For example, from a route:

```php
use App\Ai\Agents\TimeAgent;

Route::get('/debug-ai', function () {
    $response = (new TimeAgent)->prompt('What time is it?');

    return $response->text;
});
```

Visiting this route triggers an agent invocation that Sentry captures. It may take a couple of moments for the data to appear in [sentry.io](https://sentry.io).

## [Conversations](https://docs.sentry.io/platforms/php/guides/laravel/agent-tracing.md#conversations)

If your agent uses Laravel AI's [remembering conversations](https://laravel.com/docs/13.x/ai-sdk#remembering-conversations) feature, Sentry automatically tracks the `conversationId` returned by Laravel AI. The integration adds it to AI spans as `gen_ai.conversation.id`, which lets Sentry group multiple prompts into the same conversation in **Explore > Agents**.

To keep later prompts in the same Sentry conversation, the agent must implement `Conversational` and use `RemembersConversations`. Store the first response's `conversationId`, then pass it to `continue()` for each later prompt:

```php
use App\Ai\Agents\TimeAgent;
use App\Models\User;

$user = User::firstOrFail();
$conversationId = null;

foreach (["Hello", "What did I just ask you?"] as $message) {
    $agent = $conversationId
        ? (new TimeAgent)->continue($conversationId, as: $user)
        : (new TimeAgent)->forUser($user);

    $response = $agent->prompt($message);
    $conversationId = $response->conversationId;
}
```

Starting a new agent without passing the previous ID creates a separate conversation in Sentry.

Classifications don't have a conversation ID of their own. They're added to the conversation of an agent in the same trace, including classifications made while the agent runs, for example, from a tool. To set the conversation ID yourself, for example, for a classification that runs without an agent or for AI calls that span multiple requests, call `Integration::setConversationId()` before making the call:

```php
use Sentry\Laravel\Integration;

Integration::setConversationId($conversationId);
```

The ID applies to the AI spans started afterwards in the current trace, so a transaction must be active. Pass `null` to stop adding it.

For CLI commands and other non-HTTP entry points, create a transaction around each agent call so the AI spans are captured.
