Membangun dashboard admin untuk AI Agent PHP: tampilkan statistik penggunaan, monitor jumlah request dan token API, serta kelola riwayat percakapan user.
Daftar Isi
- Definisi: Apa itu Dashboard Admin AI Agent PHP?
- TL;DR (Ringkasan Cepat)
- Struktur Tabel Usage Statistics AI Agent
- Panduan Belajar AI-Agent-PHP: Query Agregasi Metrik Dashboard
- Implementasi Frontend View Template dan Chart.js
- Estimasi Biaya & Tabel Perbandingan Harga Model API LLM
- Komparasi Biaya & Harga Token Model AI Agent PHP (Per 1 Juta Token)
- Sistem Peringatan Dini: Slack & Discord Webhook Alert
- FAQ: Kendala Umum Saat Memonitor Request AI Agent
- 1. Bagaimana cara mencegah tabel log usage tumbuh terlalu besar?
- 2. Mengapa terjadi perbedaan perhitungan token antara dashboard dan tagihan OpenAI?
- 3. Bagaimana cara memantau latensi eksekusi tool yang lambat di dashboard?
Terakhir diperbarui:
Definisi: Apa itu Dashboard Admin AI Agent PHP?
Direct Answer:Dashboard Admin AI Agent PHP adalah antarmuka visual terpusat untuk memantau performa operasional agen kecerdasan buatan — meliputi agregasi jumlah request, total konsumsi token (prompt & completion), estimasi pengeluaran biaya API LLM, distribusi alat (tool usage frequency), serta riwayat log percakapan pengguna secara real-time.
Dalam modul belajar ai-agent-php tingkat lanjut, dashboard analitik mencegah developer dari lonjakan biaya token tak terduga (*runaway costs*) dan mempercepat identifikasi kegagalan eksekusi tool di lingkungan produksi.
TL;DR (Ringkasan Cepat)
- Pusat Pengawasan Biaya & Kualitas: Dashboard admin membantu Anda memantau biaya pengeluaran API, latensi respons, dan tingkat keberhasilan (*success rate*) AI Agent.
- Pencatatan Granular: Catat setiap sesi interaksi (prompt tokens, completion tokens, duration ms, tools used) ke database MySQL.
- Early Warning System: Pasang notifikasi otomatis Webhook ke Slack/Discord saat penggunaan token harian melampaui batas anggaran (*budget threshold*).
- Isolasi Hak Akses Admin: Pastikan endpoint dashboard diproteksi middleware otentikasi role
admin.

Struktur Tabel Usage Statistics AI Agent
Direct Answer:Tabel agent_usage_logs adalah skema relasional teroptimasi indeks untuk mencatat metadata pemanggilan model AI (prompt tokens, completion tokens, duration ms, tools JSON) guna menghasilkan metrik performa real-time tanpa membebani throughput backend.Tabel agent_usage_logs dirancang untuk menyimpan metadata setiap request agen secara granular guna kebutuhan kalkulasi analitik dan audit forensik:
CREATE TABLE agent_usage_logs (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NULL,
session_id VARCHAR(128) NOT NULL,
task TEXT NOT NULL,
tools_used JSON NULL,
prompt_tokens INT UNSIGNED DEFAULT 0,
completion_tokens INT UNSIGNED DEFAULT 0,
total_tokens INT UNSIGNED DEFAULT 0,
duration_ms INT UNSIGNED DEFAULT 0,
is_success TINYINT(1) DEFAULT 1,
error_message TEXT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_created_at (created_at),
INDEX idx_session (session_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Panduan Belajar AI-Agent-PHP: Query Agregasi Metrik Dashboard
Direct Answer:Agregasi metrik performa AI Agent dilakukan melalui query agregat SQL (COUNT,SUM,AVG, danJSON_EXTRACT) yang dibungkus dalam classDashboardServiceuntuk menyediakan data metrik 30 hari dan grafik tren harian.
Class DashboardService merangkum kueri agregasi performa 30 hari terakhir, tren pemakaian harian, serta frekuensi pemanggilan tool terpopuler:
<?php
namespace App\Admin;
use PDO;
class DashboardService
{
private PDO $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
/**
* Mengambil ringkasan metrik global 30 hari terakhir.
*/
public function getSummary(): array
{
$stmt = $this->pdo->query(
'SELECT
COUNT(*) AS total_requests,
COALESCE(SUM(total_tokens), 0) AS total_tokens_used,
COALESCE(AVG(total_tokens), 0) AS avg_tokens_per_request,
COALESCE(SUM(duration_ms) / 1000, 0) AS total_duration_seconds,
COALESCE(AVG(duration_ms), 0) AS avg_response_ms,
SUM(CASE WHEN is_success = 1 THEN 1 ELSE 0 END) AS success_count,
SUM(CASE WHEN is_success = 0 THEN 1 ELSE 0 END) AS error_count
FROM agent_usage_logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)'
);
return $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
}
/**
* Mengambil tren statistik request dan konsumsi token harian.
*/
public function getDailyStats(int $days = 7): array
{
$stmt = $this->pdo->prepare(
'SELECT
DATE(created_at) AS log_date,
COUNT(*) AS total_requests,
COALESCE(SUM(total_tokens), 0) AS tokens_used,
COALESCE(AVG(duration_ms), 0) AS avg_latency_ms
FROM agent_usage_logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY log_date ASC'
);
$stmt->execute([$days]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Mengurai distribusi pemanggilan tools dari kolom JSON.
*/
public function getMostUsedTools(): array
{
$stmt = $this->pdo->query(
'SELECT tool_name, COUNT(*) AS usage_count
FROM (
SELECT JSON_UNQUOTE(JSON_EXTRACT(tools_used, CONCAT("$[", n.n, "]"))) AS tool_name
FROM agent_usage_logs,
(SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) n
WHERE JSON_LENGTH(tools_used) > n.n
) t
WHERE tool_name IS NOT NULL AND tool_name != "null"
GROUP BY tool_name
ORDER BY usage_count DESC
LIMIT 10'
);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Mengambil 20 riwayat interaksi percakapan pengguna terbaru.
*/
public function getRecentConversations(int $limit = 20): array
{
$stmt = $this->pdo->prepare(
'SELECT l.*, u.name AS user_name, u.email
FROM agent_usage_logs l
LEFT JOIN users u ON l.user_id = u.id
ORDER BY l.created_at DESC
LIMIT ?'
);
$stmt->execute([$limit]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}Implementasi Frontend View Template dan Chart.js
Direct Answer:Template view admin mengonsumsi array data dari DashboardService untuk merender kartu metrik statistik dan menyuplai dataset JSON ke visualisasi diagram garis/batang Chart.js secara reaktif.Berikut adalah contoh kode implementasi antarmuka frontend (PHP Template / Laravel Blade) yang siap digunakan pada dashboard admin:
<!-- views/admin/dashboard.php atau resources/views/admin/dashboard.blade.php -->
<div class="container mx-auto p-6 space-y-6">
<h1 class="text-2xl font-bold text-white">AI Agent Analytics Overview</h1>
<!-- 1. Top Metrics Summary Cards -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-4 bg-slate-900 border border-slate-800 rounded-xl">
<span class="text-xs text-slate-400 font-mono uppercase">Total Requests</span>
<div class="text-2xl font-extrabold text-white mt-1"><?= number_format($summary['total_requests']) ?></div>
<span class="text-xs text-emerald-400 font-medium"><?= number_format($summary['success_count']) ?> Berhasil</span>
</div>
<div class="p-4 bg-slate-900 border border-slate-800 rounded-xl">
<span class="text-xs text-slate-400 font-mono uppercase">Total Token Usage</span>
<div class="text-2xl font-extrabold text-sky-400 mt-1"><?= number_format($summary['total_tokens_used']) ?></div>
<span class="text-xs text-slate-400">Rata-rata: <?= number_format($summary['avg_tokens_per_request']) ?> / req</span>
</div>
<div class="p-4 bg-slate-900 border border-slate-800 rounded-xl">
<span class="text-xs text-slate-400 font-mono uppercase">Avg Latency</span>
<div class="text-2xl font-extrabold text-amber-400 mt-1"><?= number_format($summary['avg_response_ms']) ?> ms</div>
<span class="text-xs text-emerald-400">Total: <?= number_format($summary['total_duration_seconds']) ?>s komputasi</span>
</div>
<div class="p-4 bg-slate-900 border border-slate-800 rounded-xl">
<span class="text-xs text-slate-400 font-mono uppercase">Error Count</span>
<div class="text-2xl font-extrabold text-rose-400 mt-1"><?= number_format($summary['error_count']) ?></div>
<span class="text-xs text-slate-400">Tingkat Error: <?= $summary['total_requests'] > 0 ? round(($summary['error_count'] / $summary['total_requests']) * 100, 2) : 0 ?>%</span>
</div>
</div>
<!-- 2. Chart.js Container -->
<div class="p-6 bg-slate-900 border border-slate-800 rounded-2xl">
<h2 class="text-lg font-semibold text-white mb-4">Tren Penggunaan Harian</h2>
<div class="relative w-full h-72">
<canvas id="usageChartCanvas"></canvas>
</div>
</div>
</div>
<!-- 3. Inisialisasi Script Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js" defer></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const dailyStats = <?= json_encode($dailyStats) ?>;
const labels = dailyStats.map(row => row.log_date);
const requests = dailyStats.map(row => row.total_requests);
const tokens = dailyStats.map(row => row.tokens_used / 1000);
const ctx = document.getElementById("usageChartCanvas").getContext("2d");
new Chart(ctx, {
type: "bar",
data: {
labels: labels,
datasets: [
{
label: "Volume Requests",
data: requests,
backgroundColor: "rgba(16, 185, 129, 0.7)",
borderRadius: 6
},
{
label: "Tokens Used (x1,000)",
data: tokens,
borderColor: "#38bdf8",
backgroundColor: "rgba(56, 189, 248, 0.2)",
type: "line",
tension: 0.3
}
]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
});
</script>Estimasi Biaya & Tabel Perbandingan Harga Model API LLM
Direct Answer:Kalkulasi biaya LLM dihitung berdasarkan tarif per 1 juta token dengan rumus: Cost = (Prompt Tokens / 1.000.000 × Input Rate) + (Completion Tokens / 1.000.000 × Output Rate).Gunakan fungsi pembantu di bawah ini untuk menghitung kalkulasi biaya dolar berdasarkan tarif per 1 juta token (1M tokens) pada masing-masing penyedia model kecerdasan buatan:
<?php
namespace App\Admin;
class CostCalculator
{
/**
* Tarif resmi per 1 Juta Token (USD).
*/
private static array $pricing = [
'gpt-4o-mini' => ['input' => 0.15, 'output' => 0.60],
'gpt-4o' => ['input' => 2.50, 'output' => 10.00],
'claude-3-5-sonnet' => ['input' => 3.00, 'output' => 15.00],
'gemini-1-5-pro' => ['input' => 1.25, 'output' => 5.00],
'gemini-1-5-flash' => ['input' => 0.075, 'output' => 0.30],
];
public static function calculate(int $promptTokens, int $completionTokens, string $model = 'gpt-4o-mini'): float
{
$rates = self::$pricing[$model] ?? self::$pricing['gpt-4o-mini'];
$inputCost = ($promptTokens / 1_000_000) * $rates['input'];
$outputCost = ($completionTokens / 1_000_000) * $rates['output'];
return round($inputCost + $outputCost, 6);
}
}Komparasi Biaya & Harga Token Model AI Agent PHP (Per 1 Juta Token)
| Nama Model AI | Provider Vendor | Input Price / 1M Tokens | Output Price / 1M Tokens | Rekomendasi Use Case |
|---|---|---|---|---|
| GPT-4o mini | OpenAI | $0.15 | $0.60 | Default Agent Tasks, tool routing, dan klasifikasi teks |
| GPT-4o | OpenAI | $2.50 | $10.00 | Penalaran kompleks, query SQL tingkat lanjut, dan coding |
| Claude 3.5 Sonnet | Anthropic | $3.00 | $15.00 | Ekstraksi dokumen panjang, penulisan esai, dan multimodal |
| Gemini 1.5 Pro | $1.25 | $5.00 | Context window super besar (hingga 2 juta token) | |
| Gemini 1.5 Flash | $0.075 | $0.30 | Tugas latensi super cepat dan pemrosesan bulk batch |
Cost Optimization Strategy: Gunakan model hemat seperti GPT-4o mini untuk loop identifikasi tool awal, dan hanya beralih ke GPT-4o ketika penalaran kompleks gagal.
Sistem Peringatan Dini: Slack & Discord Webhook Alert
Direct Answer:Sistem peringatan dini (Early Warning Alert System) mengevaluasi ambang batas anggaran harian (misal: $50/hari atau 500.000 token) dan mengirimkan payload darurat melalui Webhook cURL ke kanal Slack atau Discord untuk mencegah kerugian finansial saat terjadi loop tak terkendali (*infinite agent loop*).
Berikut adalah diagram alur kerja dan class WebhookAlertService untuk mengotomasi notifikasi darurat:

<?php
namespace App\Admin;
class WebhookAlertService
{
private string $slackWebhookUrl;
private string $discordWebhookUrl;
private float $dailyBudgetLimit;
public function __construct(string $slackUrl = '', string $discordUrl = '', float $budgetLimit = 50.0)
{
$this->slackWebhookUrl = $slackUrl;
$this->discordWebhookUrl = $discordUrl;
$this->dailyBudgetLimit = $budgetLimit;
}
/**
* Memeriksa apakah biaya harian melebihi ambang batas dan memicu alert.
*/
public function checkAndDispatchAlert(float $todayCost, int $todayTokens): void
{
if ($todayCost < $this->dailyBudgetLimit) {
return;
}
$message = sprintf(
"🚨 *AI AGENT BUDGET ALERT* 🚨\nBiaya harian telah mencapai: *$%.2f* (Batas: $%.2f)\nTotal Konsumsi Token: *%s tokens*\nStatus: _Throttling & Review Required_",
$todayCost,
$this->dailyBudgetLimit,
number_format($todayTokens)
);
if (!empty($this->slackWebhookUrl)) {
$this->sendCurlWebhook($this->slackWebhookUrl, ['text' => $message]);
}
if (!empty($this->discordWebhookUrl)) {
$this->sendCurlWebhook($this->discordWebhookUrl, ['content' => $message]);
}
}
private function sendCurlWebhook(string $url, array $payload): void
{
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
]);
curl_exec($ch);
curl_close($ch);
}
}FAQ: Kendala Umum Saat Memonitor Request AI Agent
1. Bagaimana cara mencegah tabel log usage tumbuh terlalu besar?
Ringkasan Jawaban:Jalankan scheduler cron harian untuk memindahkan data log berumur lebih dari 90 hari ke tabel arsip dingin (*cold storage* / file CSV terkompresi) atau hapus log sementara menggunakan perintah DELETE FROM agent_usage_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY).Dengan rotasi data berkala, indeks database MySQL tetap ramping dan performa kueri dashboard tetap di bawah 50 milidetik.
2. Mengapa terjadi perbedaan perhitungan token antara dashboard dan tagihan OpenAI?
Ringkasan Jawaban:Perbedaan biasanya timbul jika request gagal di tengah transmisi (misal: timeout soket jaringan atau error 400) sehingga token prompt tetap dihitung oleh OpenAI tetapi gagal tercatat di database lokal.
Selalu catat usage token dari blok $response['usage'] di dalam blok finally atau exception handler untuk meminimalisir deviasi pencatatan.
3. Bagaimana cara memantau latensi eksekusi tool yang lambat di dashboard?
Ringkasan Jawaban:Gunakan fungsimicrotime(true)sebelum dan sesudah$tool->execute(), lalu simpan durasi spesifik masing-masing tool ke dalam kolom JSONtools_used(misal:[{"name": "DatabaseTool", "duration_ms": 420}]).
Ini memudahkan administrator mengidentifikasi query database yang lambat atau endpoint REST API pihak ketiga yang mengalami lag.
- Monitoring Token Komprehensif: Mencatat token input dan output secara akurat untuk memprediksi biaya operasional LLM.
- Visualisasi Reaktif Frontend: Menggabungkan
DashboardServicedengan template view dan Chart.js untuk menampilkan tren request harian. - Early Warning Alert: Integrasi
WebhookAlertServiceuntuk memancarkan peringatan seketika saat konsumsi token melampaui batas. - Audit Jejak Penalaran: Meninjau riwayat percakapan pengguna dan pemanggilan alat untuk menyempurnakan system prompt agen.
Rusmawan Abdullah Sani
Lead Software Engineer & System Architect
Praktisi pengembangan backend PHP modern, arsitektur AI Agent, microservices, dan otomasi server Linux. Terhubung melalui profil LinkedIn.