PHP code example of mubseoul / laravel-llm-observability

1. Go to this page and download the library: Download mubseoul/laravel-llm-observability library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mubseoul / laravel-llm-observability example snippets


'recording' => [
    'enabled' => true,
    'mode' => 'async', // 'sync' or 'async'
    'sampling_rate' => 1.0, // 1.0 = 100%, 0.1 = 10%
    'store_bodies' => false, // Privacy: store raw prompts/responses
],

'pricing' => [
    'openai' => [
        'gpt-4' => ['input' => 30.00, 'output' => 60.00],
        'gpt-4o' => ['input' => 5.00, 'output' => 15.00],
        // ... more models
    ],
    'anthropic' => [
        'claude-3-opus-20240229' => ['input' => 15.00, 'output' => 75.00],
        // ... more models
    ],
],

'quotas' => [
    'enabled' => true,
    'defaults' => [
        'user' => [
            'requests_per_day' => 1000,
            'cost_per_day' => 10.00,
        ],
    ],
],

use Mubseoul\LLMObservability\Facades\LLM;

$response = LLM::record([
    'provider' => 'openai',
    'model' => 'gpt-4',
    'prompt_tokens' => 150,
    'completion_tokens' => 75,
])->send(function () {
    return OpenAI::chat()->create([
        'model' => 'gpt-4',
        'messages' => [
            ['role' => 'user', 'content' => 'Hello!'],
        ],
    ]);
});

LLM::record([
    'provider' => 'anthropic',
    'model' => 'claude-3-sonnet-20240229',
])
->withUser(auth()->id())
->withTeam(auth()->user()->currentTeam->id)
->send(function () {
    return Anthropic::messages()->create([...]);
});

LLM::record([
    'provider' => 'openai',
    'model' => 'gpt-4',
])
->withMetadata([
    'feature' => 'chat',
    'session_id' => session()->getId(),
])
->send(function () {
    // Your LLM call
});

LLM::record([
    'provider' => 'openai',
    'model' => 'gpt-4',
    'prompt_tokens' => 100,
    'completion_tokens' => 50,
    'latency_ms' => 1250,
    'status' => 'success',
])->recordRequest([
    'request_id' => 'custom-id',
]);

Route::middleware(['llm.quota'])->group(function () {
    Route::post('/api/chat', [ChatController::class, 'send']);
});

use Mubseoul\LLMObservability\Services\QuotaEnforcer;

$enforcer = app(QuotaEnforcer::class);

$result = $enforcer->checkQuota(
    userId: auth()->id(),
    estimatedTokens: 1000,
    estimatedCost: 0.05
);

if (!$result['allowed']) {
    throw new Exception($result['reason']);
}

use Mubseoul\LLMObservability\Models\LLMQuota;

// Create a custom quota for a user
LLMQuota::create([
    'scope' => 'user',
    'scope_id' => '123',
    'requests_per_day' => 500,
    'cost_per_month' => 50.00,
    'enabled' => true,
]);

// Get or create quota with defaults
$quota = app(QuotaEnforcer::class)->getOrCreateQuota('user', '123');

use Mubseoul\LLMObservability\Models\LLMAlertRule;

LLMAlertRule::create([
    'name' => 'High Daily Cost Alert',
    'type' => 'cost_threshold',
    'scope' => 'global',
    'threshold_config' => [
        'cost_usd' => 100.00,
        'period' => 'day',
    ],
    'send_webhook' => true,
    'webhook_url' => 'https://your-app.com/webhooks/llm-alert',
    'enabled' => true,
]);

'dashboard' => [
    'enabled' => true,
    'prefix' => 'llm-observability',
    'middleware' => ['web', 'auth'],
],

use OpenAI\Laravel\Facades\OpenAI;
use Mubseoul\LLMObservability\Facades\LLM;

$result = LLM::record([
    'provider' => 'openai',
    'model' => 'gpt-4',
])->send(function () {
    $response = OpenAI::chat()->create([
        'model' => 'gpt-4',
        'messages' => [
            ['role' => 'user', 'content' => 'Tell me a joke'],
        ],
    ]);

    return $response;
});

// Extract tokens from response if available
$tokens = $result->usage->totalTokens ?? null;

use Illuminate\Support\Facades\Http;
use Mubseoul\LLMObservability\Facades\LLM;

$result = LLM::record([
    'provider' => 'anthropic',
    'model' => 'claude-3-sonnet-20240229',
])->send(function () {
    $response = Http::withHeaders([
        'x-api-key' => config('services.anthropic.key'),
        'anthropic-version' => '2023-06-01',
    ])->post('https://api.anthropic.com/v1/messages', [
        'model' => 'claude-3-sonnet-20240229',
        'max_tokens' => 1024,
        'messages' => [
            ['role' => 'user', 'content' => 'Hello!'],
        ],
    ]);

    return $response->json();
});

LLM::record([
    'provider' => 'ollama',
    'model' => 'llama2',
    'input_chars' => strlen($prompt),
    'output_chars' => strlen($response),
])->send(function () use ($prompt) {
    return Http::post('http://localhost:11434/api/generate', [
        'model' => 'llama2',
        'prompt' => $prompt,
    ])->json();
});

'recording' => [
    'store_bodies' => false, // Keep disabled for production
    'redact_patterns' => [
        '/api[_-]?key["\s:=]+([a-zA-Z0-9_\-]+)/i',
        '/bearer\s+([a-zA-Z0-9_\-\.]+)/i',
    ],
],
bash
php artisan vendor:publish --tag="llm-observability-config"
bash
php artisan migrate
bash
# Recalculate last 90 days
php artisan llm:recalc-aggregates

# Custom date range
php artisan llm:recalc-aggregates --from=2024-01-01 --to=2024-12-31
bash
composer analyse