← Semua pembelajaran / AI Engineer Nol → Production
Fase 7 · Deployment ke Production

Observability aplikasi AI — logging, tracing, metrik

Observability aplikasi biasa sudah cukup rumit — request, response, latency. Aplikasi AI menambah dimensi baru: isi prompt, jumlah token, langkah-langkah internal agent, dan biaya yang menumpuk per panggilan.

Sumber asli opentelemetry.io Resmi Rangkuman ~8 menit baca

Intisari

  • Log HTTP standar (status code, latency) tidak cukup untuk debug aplikasi AI — kamu perlu tahu prompt apa yang dikirim, model apa yang dipakai, dan berapa token masuk/keluar.
  • OpenTelemetry GenAI semantic conventions adalah standar terbuka (vendor-neutral) untuk atribut yang harus dicatat di setiap panggilan LLM — supaya tooling observability apa pun bisa membacanya konsisten.
  • Untuk sistem dengan banyak langkah (agent Fase 3, RAG Fase 5, tool use Fase 2), tracing — bukan cuma logging — dibutuhkan untuk melihat urutan & durasi tiap langkah dalam satu request.
  • Metrik kunci yang wajib dipantau: latency (termasuk time-to-first-token untuk streaming), token terpakai (input/output terpisah), error rate, dan tingkat penolakan/fallback (berapa sering guardrails Fase 6 terpicu).
  • Simpan prompt & respons untuk debugging, tapi sadari implikasi privasi — data sensitif yang masuk prompt (Fase 2) juga ikut masuk log kalau tidak disaring.

Kenapa observability biasa tidak cukup

Log tradisional ("GET /api/chat 200 OK 340ms") memberitahu request berhasil dan berapa lama — tapi tidak menjawab pertanyaan yang paling sering muncul saat debug aplikasi AI: prompt apa persisnya yang dikirim? model mana yang dipakai? kenapa jawabannya aneh untuk input ini? Aplikasi AI butuh dimensi tambahan yang tidak ada di observability HTTP biasa.

Atribut standar: OpenTelemetry GenAI conventions

Alih-alih setiap tim menciptakan format logging sendiri, OpenTelemetry — standar observability vendor-neutral yang sudah dipakai luas untuk tracing/metrics aplikasi biasa — punya konvensi khusus untuk panggilan LLM. Memakainya berarti tooling observability apa pun (Grafana, Datadog, dll.) bisa membaca data ini secara konsisten.

import logging

def catat_panggilan_llm(model: str, response, durasi_ms: float, konteks: dict):
    logging.info("llm_call", extra={
        "gen_ai.request.model": model,
        "gen_ai.usage.input_tokens": response.usage.input_tokens,
        "gen_ai.usage.output_tokens": response.usage.output_tokens,
        "gen_ai.response.finish_reason": response.stop_reason,
        "duration_ms": durasi_ms,
        "conversation_id": konteks.get("conversation_id"),
    })
AtributKenapa penting
gen_ai.request.modelModel routing (materi berikutnya) berarti model bisa berbeda tiap request — perlu tahu mana yang dipakai
gen_ai.usage.input_tokens / output_tokensDasar perhitungan biaya per request — input dan output biasanya beda harga per token
gen_ai.response.finish_reasonMembedakan respons selesai normal vs terpotong (max_tokens kena) vs berhenti karena tool call

Tracing: melihat urutan langkah, bukan cuma hasil akhir

Untuk sistem dengan banyak langkah internal — agent loop (Fase 3), RAG (Fase 5), tool use (Fase 2) — satu "request" pengguna sebenarnya terdiri dari beberapa panggilan LLM & operasi lain yang berurutan. Logging datar (satu baris per event) membuat sulit melihat hubungan antar langkah. Tracing menyelesaikan ini dengan struktur span bersarang.

Trace: satu percakapan chatbot (trace_id: abc123)
├── Span: retrieval RAG (120ms)
│     └── query pgvector, 3 chunk ditemukan
├── Span: panggilan LLM #1 (890ms)
│     └── model minta tool "cek_stok"
├── Span: eksekusi tool cek_stok (45ms)
├── Span: panggilan LLM #2 — jawaban final (650ms)
└── Total: 1705ms, 1240 token, $0.008

Ini persis kebutuhan yang sama seperti debugging microservice — satu request yang melintasi banyak service butuh trace_id yang sama di semua log-nya supaya bisa direkonstruksi urutannya. Bedanya, di sini "service"-nya adalah langkah-langkah internal agent/RAG, dan setiap span membawa metrik yang khas AI: token, model, biaya.

Metrik yang wajib dipantau

MetrikKenapa dipantau
Latency (p50, p95, p99)Rata-rata bisa terlihat baik padahal sebagian kecil pengguna mengalami timeout — p95/p99 menangkap ini
Time-to-first-token (untuk streaming, Fase 1)Metrik pengalaman pengguna yang sebenarnya, beda dari total durasi
Token input/output per requestDasar pemantauan biaya (materi berikutnya) dan deteksi anomali (prompt yang membengkak tanpa sadar)
Error rate per jenis errorBedakan rate limit (Fase 2), timeout, vs error validasi — masing-masing butuh respons berbeda
Tingkat fallback/eskalasi (Fase 6)Naik tiba-tiba bisa menandakan regresi kualitas (mis. setelah ubah prompt) sebelum pengguna ramai komplain

Simpan prompt & respons — dengan hati-hati

Menyimpan isi prompt & respons lengkap sangat membantu debugging ("kenapa user ini dapat jawaban aneh?"), tapi ingat dari Fase 2: data sensitif yang masuk prompt ikut masuk log. Terapkan kebijakan retensi & akses yang sama ketatnya dengan log yang berisi data pengguna lain di sistemmu.

Latihan: tambahkan logging gen_ai.* ke fungsi kirim_pesan dari Fase 6, catat durasi tiap panggilan dengan time.perf_counter(). Jalankan 5 percakapan berbeda, lalu dari log yang terkumpul, hitung manual: total token terpakai, dan latency rata-rata per panggilan.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.