Laravel Filament Yönetim Paneli Kurma Rehberi
AI geliştirme sürecinde, genellikle unutulan ancak büyük önem taşıyan bir özellik, yönetim panellerinin oluşturulmasıdır. Bu makalede, Laravel Filament ile AI uygulamaları için bir yönetim paneli nasıl oluşturulacağını öğreneceksiniz. Bu panel, token maliyetlerinin izlenmesi, kullanım analitiği, prompt sürüm yönetimi ve ajans denetim günlüklerini içerecektir.
Neden Filament ve Şimdi?
Laravel ekosisteminde yönetim arayüzleri oluşturmak için ciddi bir rekabet yok. Filament v3, kapsamlı bir panel sistemi, Livewire destekli tablolar, istatistik widget’ları ve rol tabanlı yetkilendirme katmanı ile gelmektedir. Mevcut Laravel uygulamanız içine entegre edilebilir ve ayrı bir işlem veya Node frontend’i gerektirmez.
Kurulum ve Panel Ayarları
Filament’i yüklemek için aşağıdaki komutları kullanabilirsiniz:
composer require filament/filament:"^3.0" -W
php artisan filament:install --panelsBu komut, app/Providers/Filament/AdminPanelProvider.php dosyasını oluşturur ve bunu bootstrap/app.php üzerinden kaydeder. İşte başlangıç yapılandırmasının bir örneği:
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login()
->colors(['primary' => Color::Violet])
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([Authenticate::class])
->authorization(fn () => auth()->user()?->is_admin ?? false);
}
}Yetkilendirme kontrolünü ilk günden ayarlamak önemlidir; aksi halde herhangi bir kimliği doğrulanmış kullanıcı yönetim paneline ulaşabilir.
Panele Sunulacak Verilerin Modellemesi
İlk önce veri toplamanız gereken alanlar üzerinde karar vermeniz gerekiyor. Üretimdeki bir AI uygulamasında, iki ana günlük türü dikkate alınmalıdır:
- AI Kullanım Günlükleri: Hangi sağlayıcı, hangi model, ne kadar token kullanıldı vb. bilgileri içerir.
- Ajan Denetim Günlükleri: Hangi ajan sınıfı hangi işlevi çağırdı, giriş ve çıkış neydi gibi verileri kaydeder.
Her ikisi de Eloquent modeller olarak oluşturulmalıdır. İşte kullanım günlüğüne ilişkin bir göç dosyasının örneği:
Schema::create('ai_usage_logs', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
$table->string('provider'); // 'anthropic', 'openai'
$table->string('model');
$table->string('feature')->nullable(); // 'chat', 'summarize', 'agent'
$table->integer('prompt_tokens');
$table->integer('completion_tokens');
$table->integer('total_tokens');
$table->decimal('cost_usd', 10, 6)->nullable();
$table->string('prompt_version')->nullable();
$table->json('metadata')->nullable();
$table->boolean('success')->default(true);
$table->text('error_message')->nullable();
$table->timestamps();
$table->index(['user_id', 'created_at']);
$table->index(['provider', 'model', 'created_at']);
$table->index(['feature', 'created_at']);
});Token Maliyeti İzleme: İstatistik Genel Bakış Widget’ı
Panele ilk giriş yaptığınızda görmeniz gereken şey, AI katmanının son 24 saatteki maliyetini özetleyen bir genel bakıştır. Filament’in StatsOverviewWidget bu işlemi kolayca yapar:
php artisan make:filament-widget AiStatsOverview --stats-overviewOluşan widget tanımını şuna benzeyecek şekilde güncelleyebilirsiniz:
namespace App\Filament\Widgets;
use App\Models\AiUsageLog;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
class AiStatsOverview extends BaseWidget
{
protected static ?int $sort = 1;
protected function getStats(): array
{
$today = AiUsageLog::whereDate('created_at', today());
$month = AiUsageLog::whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year);
return [
Stat::make("Today's Tokens", number_format($today->sum('total_tokens')))
->description('Across all providers and models')
->color('primary'),
Stat::make("Today's Cost", '$' . number_format($today->sum('cost_usd'), 4))
->description('USD — live tally')
->color('warning'),
Stat::make('Monthly Spend', '$' . number_format($month->sum('cost_usd'), 2))
->description(now()->format('F Y'))
->color('danger'),
Stat::make('Failures Today', number_format($today->where('success', false)->count()))
->description('Inference errors across all features')
->color('gray'),
];
}
}Bu widget’i panel sağlayıcısındaki ->widgets() dizisine kaydedin. Widget’ınız zaten Livewire’in polling mekanizmasını kullanarak belirli aralıklarla güncellenebilir.
Günlük Token Kullanımı: Grafik Widget’ı
Brüt toplamlar faydalıdır. Ancak, eğilim çizgileri aslında sorunları sergiler. Böylece, problemi teşhis edebilmek için bir grafik widget’ı ekleyin:
php artisan make:filament-widget TokenUsageChart --chartOluşan widget ile ilgili veri alım mantığını aşağıdaki şekilde güncelleyebilirsiniz:
namespace App\Filament\Widgets;
use App\Models\AiUsageLog;
use Filament\Widgets\ChartWidget;
class TokenUsageChart extends ChartWidget
{
protected static ?string $heading = 'Daily Token Usage — Last 30 Days';
protected static ?int $sort = 2;
public ?string $filter = 'tokens';
protected function getFilters(): ?array
{
return [
'tokens' => 'Total Tokens',
'cost' => 'Cost (USD)',
];
}
protected function getData(): array
{
$column = $this->filter === 'cost' ? 'cost_usd' : 'total_tokens';
$label = $this->filter === 'cost' ? 'Cost (USD)' : 'Total Tokens';
$data = AiUsageLog::selectRaw("DATE(created_at) as date, SUM({$column}) as value")
->where('created_at', '>=', now()->subDays(30))
->groupBy('date')
->orderBy('date')
->get();
return [
'datasets' => [
[
'label' => $label,
'data' => $data->pluck('value')->toArray(),
'borderColor' => '#8b5cf6',
'tension' => 0.3,
'fill' => false,
],
],
'labels' => $data->pluck('date')->toArray(),
];
}
protected function getType(): string
{
return 'line';
}
}Kullanım Günlüğü Kaynağı: Kullanıcı ve Model Bazında Analiz
İstatistikler ve grafikler özeti sağlasa da, detaylı inceleme için sıralanabilir ve filtrelenebilir bir tablo gereklidir. Bunun için:
php artisan make:filament-resource AiUsageLog --generateOluşan kaynak tanımını güncelleyin:
namespace App\Filament\Resources;
use App\Filament\Resources\AiUsageLogResource\Pages;
use App\Models\AiUsageLog;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class AiUsageLogResource extends Resource
{
protected static ?string $model = AiUsageLog::class;
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';
protected static ?string $navigationGroup = 'AI Governance';
protected static ?string $navigationLabel = 'Usage Logs';
public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('user.name')
->label('User')
->searchable()
->sortable()
->placeholder('—'),
TextColumn::make('provider')
->badge()
->sortable(),
TextColumn::make('model')
->searchable()
->copyable(),
TextColumn::make('feature')
->badge()
->color('info')
->placeholder('—'),
TextColumn::make('total_tokens')
->numeric()
->sortable()
->summarize(Tables\Columns\Summarizers\Sum::make()->label('Total')),
TextColumn::make('cost_usd')
->money('usd')
->sortable()
->summarize(Tables\Columns\Summarizers\Sum::make()->label('Total')),
TextColumn::make('prompt_version')
->badge()
->color('warning')
->placeholder('—'),
IconColumn::make('success')
->boolean(),
TextColumn::make('created_at')
->dateTime()
->sortable()
->since()
->toggleable(),
])
->filters([
SelectFilter::make('provider')
->options([
'anthropic' => 'Anthropic',
'openai' => 'OpenAI',
]),
SelectFilter::make('success')
->options([
'1' => 'Successful',
'0' => 'Failed',
]),
Filter::make('today')
->label('Today only')
->query(fn (Builder $query) => $query->whereDate('created_at', today())),
])
->defaultSort('created_at', 'desc')
->paginated([25, 50, 100]);
}
public static function getPages(): array
{
return [
'index' => Pages\ListAiUsageLogs::route("https://dev.to/"),
];
}
public static function canCreate(): bool
{
return false;
}
}Koşul Kısıtlaması
Yönetim panelinizi güvenli bir hale getirmek için, kullanıcıların erişimi üzerinde sıkı kontrol sağlamalısınız. ->authorization() çağrısı panel sağlayıcısında sizin ilk savunma hattınızdır. Ayrıca, daha ince ayar için Laravel Politikaları kullanabilirsiniz:
->authorization(fn () => auth()->user()?->hasRole('admin') ?? false)Sonuç
Bu makalede, Laravel kullanarak bir AI yönetim paneli kurma adımlarını açıkladık. Sağlam bir yazılım mimarisi ve etkili bir yönetişim yapısıyla, sisteminizin verimliliğini artırabilir ve oluşturduğunuz hizmetleri daha iyi yönetebilirsiniz. Geliştirmeye devam edin ve sisteminizi geliştirmek için yeni özellikler ekleyin!
Kaynak: Orijinal Makale


