Observabilitas API LLM adalah praktik mengubah setiap panggilan model menjadi bukti terstruktur yang cukup untuk menjawab empat pertanyaan produksi:
- Apakah permintaan berhasil?
- Berapa lama pengguna menunggu?
- Apa yang dikonsumsi dan berapa biayanya?
- Mengapa sistem memilih model, retry, atau fallback itu?
Monitoring HTTP biasa memang perlu, tetapi tidak cukup. Sebuah 200 OK masih bisa berisi JSON yang tidak valid, jawaban kosong, respons yang ditolak, panggilan tool yang rusak, atau output yang melanggar kontrak aplikasi. Sebuah permintaan juga bisa berhasil setelah tiga percobaan dan diam-diam menghabiskan biaya empat kali lebih besar dari yang diharapkan.
Tujuan praktisnya bukan mencatat setiap prompt. Tujuannya adalah membuat kontrak telemetry kecil dan konsisten yang menghubungkan hasil aplikasi dengan model, provider, route, latensi, penggunaan token, retry, dan biaya—tanpa membocorkan data pengguna.
Panduan ini menunjukkan cara membangun kontrak itu dengan metrics, traces, structured logs, service-level objectives, dashboard, dan alert.
Apa yang harus dijelaskan oleh observabilitas API LLM
Sistem observabilitas yang berguna memungkinkan engineer on-call berpindah dari gejala ke penyebab dengan cepat.
| Pertanyaan produksi | Bukti yang Anda butuhkan |
|---|---|
| Mengapa latensi melonjak? | Durasi end-to-end, durasi provider, waktu antre, waktu ke token pertama, model, region, jumlah retry |
| Mengapa biaya naik? | Input token, output token, cached token jika tersedia, snapshot harga model, percobaan, tingkat task yang diterima |
| Mengapa pengguna melihat hasil yang buruk? | Hasil validator output, error schema, status penolakan, hasil panggilan tool, skor evaluasi, versi prompt |
| Mengapa traffic berpindah ke model lain? | Kebijakan route, target yang dipilih, alasan fallback, status circuit breaker, error provider |
| Apakah insiden ini spesifik pada provider? | Provider, model, akun atau deployment, region, status code, ID request provider |
| Bisakah kita mereproduksi satu permintaan? | ID permintaan internal, trace ID, fingerprint input yang disanitasi, versi prompt, parameter model |
Aturan desain pertama sederhana: ukur kontrak aplikasi, bukan hanya kontrak transport.
Kelima lapisan telemetry
Monitoring API LLM menjadi lebih mudah ketika Anda memisahkan lima lapisan alih-alih memaksa semua sinyal ke satu dashboard.
1. Metrik permintaan
Metrik menunjukkan tren dan mendukung alert. Catat counter dan histogram untuk:
- Jumlah permintaan
- Latensi end-to-end
- Waktu ke token pertama untuk respons streaming
- Latensi provider atau panggilan model
- Permintaan yang berhasil, gagal, dibatalkan, dan timeout
- Respons HTTP 429 dan 5xx
- Percobaan retry dan fallback
- Input, output, dan cached token
- Estimasi dan rekonsiliasi biaya
Metrik harus memiliki label yang terbatas. Label yang baik mencakup provider, model, route, environment, status, dan error_type. Hindari label dengan kardinalitas tinggi seperti ID pengguna, ID permintaan, teks prompt, atau URL lengkap.
2. Traces terdistribusi
Trace menjelaskan jalur satu permintaan melintasi API, antrean, lapisan retrieval, panggilan alat, gateway, dan penyedia model Anda.
Hierarki trace yang praktis terlihat seperti ini:
POST /support/reply
├── retrieve_customer_context
├── llm.route
│ ├── llm.attempt provider_a/model_primary
│ └── llm.attempt provider_b/model_fallback
├── validate_structured_output
└── persist_draft
Setiap percobaan model sebaiknya menjadi span tersendiri. Jika dua penyedia dicoba, trace harus menampilkan dua percobaan, bukan menyembunyikan keduanya di dalam satu span llm.call yang buram.
Konvensi semantik Generative AI dari OpenTelemetry menyediakan kosakata bersama yang berguna untuk span, metrik, dan event generatif-AI. Perlakukan versi konvensi sebagai bagian dari skema telemetri Anda sehingga Anda dapat bermigrasi secara sengaja ketika atribut berkembang.
3. Log terstruktur
Log menangkap keputusan diskret dan konteks diagnostik yang terlalu mahal atau terlalu rinci jika dijadikan label metrik.
Event yang berguna meliputi:
llm.request.startedllm.route.selectedllm.retry.scheduledllm.fallback.selectedllm.response.validatedllm.request.completedllm.request.failed
Setiap event harus menyertakan field korelasi yang sama: request_id, trace_id, route, model, provider, prompt_version, dan attempt.
4. Sinyal kualitas dan kontrak
Kualitas tidak dapat disimpulkan dari kode status. Tambahkan validator deterministik di mana pun memungkinkan:
- JSON berhasil diparse
- Field skema yang diwajibkan ada
- Nama dan argumen alat diizinkan
- Daftar sitasi ada saat diperlukan
- Panjang output berada dalam batas produk
- Keadaan penolakan atau keamanan dikenali
- Pemeriksaan aturan bisnis lulus
Untuk tugas subjektif, lampirkan hasil evaluasi sampel nanti. Jaga agar telemetri permintaan online dan evaluasi offline tetap terhubung melalui request atau sample ID yang stabil.
Sebelum mengganti model produksi, gunakan workflow evaluasi model AI yang dapat diulang, alih-alih hanya mengandalkan latensi agregat dan harga token.
5. Biaya dan hasil bisnis
Jumlah token adalah sinyal penggunaan, bukan hasil bisnis. Hubungkan penggunaan model ke unit yang penting bagi produk Anda:
- Biaya per balasan dukungan yang diterima
- Biaya per tugas coding yang selesai
- Biaya per gambar produk yang dihasilkan yang disetujui oleh peninjau
- Biaya per lead berkualitas yang diperkaya
- Biaya per ekstraksi terstruktur yang berhasil
Rumus yang paling berguna adalah:
biaya efektif per tugas yang diterima = total biaya model / tugas yang diterima
Ini mengungkap penghematan palsu. Model yang lebih murah tetapi menyebabkan lebih banyak retry, kegagalan validasi, atau pengerjaan ulang oleh manusia dapat meningkatkan biaya efektif.
Kontrak telemetri minimum untuk setiap panggilan model
Mulailah dengan skema event yang diberi versi. Nama field yang tepat dapat mengikuti stack observability Anda, tetapi konsepnya harus tetap stabil.
{
"schema_version": "llm-observability.v1",
"timestamp": "2026-07-30T09:00:00Z",
"request_id": "req_internal_01",
"trace_id": "7c4b...",
"environment": "production",
"feature": "support_reply",
"route": "support-default",
"provider": "provider-a",
"model": "model-primary",
"prompt_version": "support-reply-v12",
"attempt": 1,
"stream": true,
"status": "success",
"http_status": 200,
"latency_ms": 1840,
"time_to_first_token_ms": 410,
"input_tokens": 1640,
"output_tokens": 284,
"cached_input_tokens": 900,
"estimated_cost_usd": 0.0068,
"validator": "passed",
"fallback_reason": null,
"provider_request_id": "redacted-or-scoped-value"
}
Jangan jadikan prompt dan respons mentah sebagai field wajib. Simpan hanya ketika ada kebutuhan yang jelas, kebijakan retensi yang disetujui, kontrol akses yang sesuai, dan jalur redaksi yang aman.
Metrik yang harus ada di dashboard pertama
Jangan mulai dengan 40 panel. Bangun satu dashboard operasional yang menjawab apakah pengguna menerima hasil yang valid dalam batas latensi dan biaya.
Lalu lintas dan keberhasilan
- Permintaan per menit
- Tingkat keberhasilan transport
- Tingkat keberhasilan tervalidasi
- Tingkat pembatalan
- Tingkat timeout
- Rasio amplifikasi retry
- Tingkat fallback
Tingkat keberhasilan tervalidasi harus menjadi sinyal ketersediaan utama:
validated success rate = requests that pass the application contract / eligible requests
Ini lebih ketat dan lebih berguna daripada respons 2xx / permintaan.
Latensi
Lacak distribusi, bukan rata-rata:
- Latensi end-to-end p50, p95, dan p99
- Latensi panggilan provider p50, p95, dan p99
- Waktu ke token pertama p50 dan p95
- Waktu tunggu antrean p95
- Eksekusi alat p95
- Durasi validasi p95
Pisahkan rute streaming dan non-streaming. Permintaan streaming dapat terasa responsif dengan time to first token yang baik meskipun waktu penyelesaian totalnya lama.
Keandalan
- Tingkat 429 berdasarkan provider dan model
- Tingkat 5xx berdasarkan provider dan model
- Tingkat error jaringan
- Tingkat respons cacat atau tidak valid secara skema
- Tingkat kegagalan tool-call
- Status terbuka circuit-breaker
- Tingkat anggaran retry yang habis
Jika pembatasan rate menjadi penyebab yang sering, gunakan strategi retry LLM untuk batas RPM dan TPM yang dibatasi, alih-alih retry yang tidak terkoordinasi di setiap worker aplikasi.
Penggunaan dan biaya
- Token input dan output berdasarkan fitur
- Token per tugas yang diterima
- Estimasi biaya per permintaan
- Biaya per tugas yang diterima
- Biaya retry
- Selisih biaya fallback
- Belanja harian versus anggaran
- Estimasi biaya versus invoice provider atau ekspor penggunaan
Pertahankan estimated_cost dan reconciled_cost sekaligus. Yang pertama memungkinkan pemantauan hampir real-time; yang kedua mengoreksi estimasi setelah data penagihan resmi tersedia.
Cara melacak retry dan fallback routing
Retry dan fallback adalah titik di mana monitoring dasar biasanya gagal. Jika semua percobaan berbagi satu field status, request yang mahal dan mengalami degradasi bisa terlihat sehat.
Catat field berikut untuk setiap percobaan:
| Field | Mengapa penting |
|---|---|
attempt |
Menunjukkan amplifikasi dan urutan keputusan |
target_id |
Mengidentifikasi provider, deployment, region, dan model tanpa rahasia |
reason |
Membedakan timeout, 429, 5xx, kegagalan validasi, dan routing kebijakan |
remaining_budget_ms |
Membuktikan router menghormati batas waktu yang terlihat oleh pengguna |
safe_to_repeat |
Membuat keputusan idempotensi menjadi eksplisit |
output_started |
Mencegah fallback yang tidak aman setelah output streaming mencapai klien |
contract_compatible |
Mengonfirmasi target berikutnya mendukung skema, tools, dan modality yang diperlukan |
Sebuah LLM API fallback routing playbook produksi harus mendefinisikan kebijakan keputusan. Observability kemudian harus membuktikan bahwa router mengikutinya.
Pola instrumentasi TypeScript
Contoh berikut menjaga telemetry tetap independen dari SDK model tertentu. Ini merekam satu parent route span dan satu child span untuk setiap percobaan.
import { context, SpanStatusCode, trace } from "@opentelemetry/api";
const tracer = trace.getTracer("ai-gateway");
type ModelAttempt = {
provider: string;
model: string;
reason: "primary" | "retry" | "fallback";
};
export async function runModelRoute(
attempts: ModelAttempt[],
callModel: (attempt: ModelAttempt) => Promise<{
text: string;
usage?: { inputTokens?: number; outputTokens?: number };
providerRequestId?: string;
}>,
) {
return tracer.startActiveSpan("llm.route", async (routeSpan) => {
routeSpan.setAttribute("app.llm.route", "support-default");
routeSpan.setAttribute("app.llm.attempt_limit", attempts.length);
try {
for (const [index, attempt] of attempts.entries()) {
const result = await tracer.startActiveSpan(
"llm.attempt",
{ attributes: {
"gen_ai.system": attempt.provider,
"gen_ai.request.model": attempt.model,
"app.llm.attempt": index + 1,
"app.llm.reason": attempt.reason,
} },
context.active(),
async (attemptSpan) => {
const startedAt = performance.now();
try {
const response = await callModel(attempt);
const valid = response.text.trim().length > 0;
attemptSpan.setAttribute("app.llm.validated", valid);
attemptSpan.setAttribute(
"gen_ai.usage.input_tokens",
response.usage?.inputTokens ?? 0,
);
attemptSpan.setAttribute(
"gen_ai.usage.output_tokens",
response.usage?.outputTokens ?? 0,
);
attemptSpan.setAttribute(
"app.llm.latency_ms",
performance.now() - startedAt,
);
if (!valid) {
throw new Error("response_validation_failed");
}
attemptSpan.setStatus({ code: SpanStatusCode.OK });
return response;
} catch (error) {
attemptSpan.recordException(error as Error);
attemptSpan.setStatus({
code: SpanStatusCode.ERROR,
message: (error as Error).message,
});
return null;
} finally {
attemptSpan.end();
}
},
);
if (result) {
routeSpan.setAttribute("app.llm.selected_attempt", index + 1);
routeSpan.setStatus({ code: SpanStatusCode.OK });
return result;
}
}
throw new Error("llm_route_exhausted");
} catch (error) {
routeSpan.recordException(error as Error);
routeSpan.setStatus({
code: SpanStatusCode.ERROR,
message: (error as Error).message,
});
throw error;
} finally {
routeSpan.end();
}
});
}
Di produksi, tambahkan penghitung metrik dan event log terstruktur Anda di samping span. Juga tangkap pengenal request provider saat tersedia; identifier tersebut sering kali penting ketika mengeskalasi insiden ke penyedia model. Jauhkan identifier itu dari pesan error publik.
Log tanpa kebocoran prompt
Default teraman adalah logging berbasis metadata terlebih dahulu.
Log secara default
- ID request internal dan trace
- ID request dari provider
- Nama fitur dan route
- Provider, model, dan alias deployment
- Versi template prompt
- Parameter seperti temperature dan maximum output tokens
- Penggunaan token
- Latensi dan waktu ke token pertama
- Kelas error dan keputusan retry
- Hasil validator
- Nama tool yang sudah disanitasi
Jangan log secara default
- Prompt atau respons mentah
- API key atau header otorisasi
- Rahasia pelanggan
- Dokumen yang diambil
- Argumen tool yang mengandung data pribadi atau data yang diatur regulasi
- Path file lengkap atau record database
- Signed URL
Ketika penangkapan konten diperlukan untuk debugging atau evaluasi, ambil sampelnya secara terpisah, lakukan redaksi sebelum penyimpanan, batasi akses, enkripsi, dan tetapkan periode retensi yang singkat. panduan manajemen API key yang aman mencakup kontrol terkait untuk rahasia, logging, rotasi, dan respons insiden.
SLO untuk fitur yang didukung LLM
Objective level service LLM harus mendeskripsikan fitur yang terlihat oleh pengguna, bukan akun provider.
Contoh SLO untuk fitur balasan dukungan terstruktur:
| SLO | Target contoh |
|---|---|
| Ketersediaan tervalidasi | 99,5% request yang memenuhi syarat menghasilkan output yang valid sesuai kontrak |
| Latensi interaktif | 95% menghasilkan token pertama dalam 1,5 detik |
| Latensi penyelesaian | 95% selesai dalam 8 detik |
| Guardrail biaya | 99% tetap di bawah batas biaya per request |
| Kontainmen fallback | Kurang dari 3% memerlukan fallback selama satu jam bergulir |
Angka-angka ini adalah contoh, bukan target universal. Tetapkan berdasarkan ekspektasi pengguna, kompleksitas tugas, perilaku provider, dan ekonomi unit.
Gunakan error budget untuk memutuskan kapan harus memperlambat rilis fitur, memperketat kebijakan route, atau mengalihkan traffic. Provider dapat memenuhi target ketersediaannya sendiri sementara produk Anda gagal mencapai SLO karena antrean, tool, validasi, atau perilaku fallback menambah kegagalan.
Alert pada gejala, diagnosis dengan penyebab
Page operator untuk dampak pada pengguna. Gunakan alert dengan severity lebih rendah atau anotasi dashboard untuk kemungkinan penyebab.
Gejala yang layak dipage
- Validated success rate melampaui SLO
- p95 waktu ke token pertama melebihi ambang batas yang terlihat oleh pengguna
- Tingkat route yang kehabisan kapasitas meningkat tajam
- Biaya per tugas yang diterima melebihi guardrail
- Fitur kritis tidak memiliki target yang sehat dan kompatibel dengan kontrak
Sinyal diagnostik
- Rasio 429 dari satu provider meningkat
- Rasio kegagalan schema dari satu model berubah
- Amplifikasi retry meningkat
- Waktu tunggu antrean bertambah
- Circuit breaker terbuka
- Penggunaan token bergeser setelah rilis prompt
Hindari mempage untuk setiap 5xx dari provider. Jika fallback bekerja dan pengguna masih menerima respons valid dalam batas latensi, peristiwa tersebut mungkin memerlukan investigasi tanpa membangunkan engineer on-call.
Model operasi tiga dashboard
Dashboard 1: Pengalaman pengguna
Tampilkan ketersediaan tervalidasi, latensi, waktu ke token pertama, penyelesaian tugas, dan error yang terlihat oleh pengguna berdasarkan fitur.
Dashboard 2: Routing and providers
Tampilkan porsi traffic, error provider, retry, fallback, circuit breaker, kehabisan route, dan latensi menurut model dan target.
Dashboard 3: Usage and economics
Tampilkan token, estimasi pengeluaran, pengeluaran yang direkonsiliasi, biaya per tugas yang diterima, selisih anggaran, dan fitur teratas berdasarkan biaya.
Pertahankan anotasi deployment dan versi prompt pada ketiganya. Jika tidak, regresi yang dimulai tepat setelah rilis bisa terlihat seperti variansi provider acak.
Rollout checklist
- Tentukan satu skema event yang berversi.
- Hasilkan internal request ID di batas produk.
- Propagasikan trace context melalui antrean, tool, dan panggilan model.
- Buat child span untuk setiap percobaan model.
- Catat provider request ID saat dikembalikan.
- Tambahkan validasi output deterministik.
- Lacak alasan retry dan fallback secara eksplisit.
- Hitung estimasi biaya dari tabel harga berversi.
- Rekonsiliasikan estimasi dengan usage resmi atau ekspor penagihan.
- Bangun satu dashboard hasil pengguna sebelum dashboard provider.
- Tetapkan SLO untuk keberhasilan tervalidasi dan latensi.
- Redaksi atau kecualikan prompt, respons, secret, dan data tool sensitif.
- Jalankan pengujian kegagalan untuk timeout, 429, 5xx, output tidak valid, dan kehabisan route.
- Tinjau cardinality label sebelum mengaktifkan metrik di production.
- Sampling trace berdasarkan risiko: pertahankan error dan request lambat lebih banyak daripada keberhasilan rutin.
Common observability mistakes
Menganggap setiap 200 sebagai sukses
Tambahkan validator kontrak dan laporkan keberhasilan tervalidasi secara terpisah.
Melog prompt mentah untuk setiap request
Ini menimbulkan masalah privasi, keamanan, retensi, dan biaya. Lebih baik gunakan metadata dan sampling terkontrol.
Menyembunyikan retry di dalam satu durasi
Buat satu span dan satu event untuk setiap percobaan agar operator dapat melihat amplifikasinya.
Menggunakan nama model sebagai satu-satunya identitas route
Lacak provider, deployment atau alias akun, region, dan kebijakan route. Model yang sama dapat berperilaku berbeda di berbagai target.
Memberi alert berdasarkan latensi rata-rata
Rata-rata menyembunyikan masalah di ekor distribusi. Gunakan p95 dan p99, dan pisahkan time to first token dari total completion time.
Mempercayai estimasi biaya selamanya
Tabel harga, perlakuan cache, dan accounting provider bisa berubah. Rekonsiliasikan estimasi terhadap data penagihan dan catat versi tabel harga.
Membiarkan label telemetry tumbuh tanpa batas
Request ID dan identifier pelanggan harus berada di trace atau log, bukan di label metrik.
Where an AI API gateway helps
Aplikasi multi-provider selain itu memerlukan adapter terpisah untuk autentikasi, penamaan model, retry, field usage, error, dan ekspor penagihan. Sebuah gateway dapat mengurangi permukaan integrasi itu dengan memberi aplikasi satu batas API yang stabil sambil mempertahankan detail provider dan model dalam telemetry internal.
Flatkey menyediakan satu API key, satu endpoint yang kompatibel dengan OpenAI, dan akses ke model di berbagai provider besar. Itu membuatnya mungkin untuk memusatkan kontrak telemetry di sisi aplikasi bahkan ketika workload menggunakan model teks, gambar, atau video yang berbeda. Gateway tidak menggantikan observabilitas di level produk: aplikasi Anda tetap harus mencatat fitur, versi prompt, hasil validasi, latensi yang terlihat pengguna, dan outcome tugas yang diterima.
Jika tim Anda sedang mengonsolidasikan provider, mulailah dengan panduan arsitektur AI API gateway, lalu tambahkan kontrak telemetri dalam artikel ini sebelum memindahkan traffic produksi.
Pertanyaan yang sering diajukan
Apa itu observabilitas API LLM?
Observabilitas API LLM adalah pengumpulan dan korelasi metrics, traces, logs, pemeriksaan kualitas, penggunaan, dan data biaya untuk fitur yang didukung model. Ini menjelaskan perilaku provider sekaligus apakah aplikasi mengembalikan hasil pengguna yang valid.
Apa yang harus saya pantau untuk API LLM?
Pantau tingkat keberhasilan yang tervalidasi, latensi end-to-end, waktu ke token pertama, latensi provider, tingkat 429 dan 5xx, percobaan ulang, fallback, penggunaan token, estimasi biaya, biaya per tugas yang diterima, dan kegagalan kontrak output.
Apakah prompt dan respons harus disimpan dalam traces?
Tidak secara default. Simpan metadata terlebih dahulu. Tangkap konten hanya untuk tujuan debugging atau evaluasi yang ditentukan, dengan redaksi, kontrol akses, enkripsi, sampling, dan kebijakan retensi.
Apa perbedaan antara monitoring LLM dan observabilitas LLM?
Monitoring memberi tahu Anda bahwa metrik yang sudah dikenal melewati ambang batas. Observabilitas memberi Anda cukup bukti yang berkorelasi untuk menyelidiki mode kegagalan baru di seluruh aplikasi, rute, provider, model, tools, dan kontrak output.
Bagaimana cara menghitung biaya LLM per request?
Kalikan unit input yang dapat ditagih, output, cached-input, media, atau unit penggunaan lainnya dengan tabel harga yang berversi, lalu tambahkan biaya percobaan ulang dan percobaan fallback. Rekonsiliasikan estimasi tersebut dengan data penagihan provider atau gateway.
ID request mana yang harus saya simpan?
Buat ID request internal dan trace ID Anda sendiri, lalu simpan juga ID request provider saat API mengembalikannya. ID internal menghubungkan sistem Anda; ID provider membantu dukungan eksternal dan eskalasi insiden.
Bangun kontrak telemetri sebelum insiden terjadi
Waktu terbaik untuk memutuskan apa yang harus dicatat oleh panggilan model adalah sebelum traffic produksi datang. Mulailah dengan keberhasilan yang tervalidasi, distribusi latensi, satu span per percobaan, label metrik yang dibatasi, log berbasis metadata terlebih dahulu, dan biaya per tugas yang diterima. Lalu uji sistem dengan memaksa kegagalan yang Anda harapkan akan ditangani oleh router.
Fondasi itu mengubah laporan yang samar—“fitur AI lambat dan mahal”—menjadi keputusan yang dapat dilacak: fitur mana, rute mana, model mana, percobaan mana, kegagalan mana, berapa banyak penundaan, dan berapa banyak biaya.
Jelajahi harga Flatkey saat Anda siap membandingkan rute multi-model di balik satu API yang kompatibel dengan OpenAI.



