Skip to main content
BlogAI

Observabilitas AI: Cara Log, Trace, dan Monitor Aplikasi LLM

Observabilitas LLM produksi dengan Langfuse, pelacakan biaya token, pemantauan latensi, dan deteksi anomali — pelajaran dari menjalankan integrasi AI ERP.

Matthews Wong

Software Engineer

Juni 202511 menit baca
AI

Meluncurkan integrasi LLM tanpa observabilitas seperti mendeploy aplikasi web tanpa log — Anda akan menemukan masalah dari keluhan pengguna, bukan dari pemantauan Anda. Tantangannya adalah bahwa aplikasi LLM gagal dengan cara kualitatif yang melewatkan metrik tradisional: panggilan API berhasil dengan 200 OK, tetapi responsnya salah secara faktual, di luar topik, atau mengabaikan instruksi kritis. Setelah menjalankan integrasi LLM produksi selama 18 bulan, ini adalah stack observabilitas yang telah saya standarkan.

Apa yang Harus Diobservasi dalam Aplikasi LLM

Observabilitas tradisional (latensi, tingkat error, throughput) diperlukan tetapi tidak cukup untuk aplikasi LLM. Anda juga membutuhkan: logging prompt/respons (teks lengkap, bukan hanya metadata), konsumsi token per panggilan dan per pengguna, pelacakan versi model, sinyal kualitas (umpan balik pengguna, tingkat penyelesaian tugas, deteksi halusinasi), atribusi biaya, dan deteksi anomali untuk upaya injeksi.

Langfuse: Lapisan Observabilitas LLM

Langfuse adalah platform observabilitas LLM open-source yang saya host sendiri di infrastruktur DigitalOcean kami. Ini menyediakan: logging trace (prompt lengkap, respons, model, latensi per panggilan), pelacakan biaya dengan kalkulasi harga token otomatis, pengelompokan sesi, alur kerja evaluasi, dan manajemen dataset untuk pengujian.

┌─────────────────────────────────────────────────────────────┐
│              LLM Observability Stack                         │
│                                                             │
│  Application                                                │
│  ┌─────────────────────────────────────────────┐           │
│  │  NestJS API  →  LLM Service  →  Langfuse    │           │
│  │                    │            SDK          │           │
│  │                    ▼                         │           │
│  │             Anthropic / OpenAI               │           │
│  └─────────────────────────────────────────────┘           │
│                    │                                        │
│                    ▼                                        │
│  ┌──────────────────────────────────────────────┐          │
│  │  Langfuse (self-hosted)                      │          │
│  │  - Traces: prompt + response + latency       │          │
│  │  - Costs: tokens × price per model           │          │
│  │  - Sessions: linked conversation turns       │          │
│  │  - Evaluations: quality scores               │          │
│  └──────────────────────────────────────────────┘          │
│                    │                                        │
│                    ▼                                        │
│  ┌──────────────────────────────────────────────┐          │
│  │  Grafana Dashboard + PagerDuty Alerts        │          │
│  │  - Cost per feature per day                  │          │
│  │  - Latency p50/p95/p99                       │          │
│  │  - Error rate by model                       │          │
│  └──────────────────────────────────────────────┘          │
└─────────────────────────────────────────────────────────────┘

Dari pengalaman saya memantau integrasi LLM: atur peringatan biaya dari hari pertama, bukan setelah mendapat tagihan kejutan. Biaya token dapat melonjak secara dramatis jika ada bug yang menyebabkan sistem mengirim prompt masif atau memasuki loop panggilan LLM. Saya pernah mengalami insiden di mana loop retry menyebabkan 400K token dalam 10 menit — tertangkap oleh peringatan sebelum menjadi insiden ratusan dolar.

Mengimplementasikan Structured LLM Tracing

Kuncinya adalah menginstrumentasi setiap panggilan LLM dengan metadata yang konsisten: user ID, session ID, nama fitur, parameter model, dan prompt/respons lengkap. Gunakan library tracing yang menangani serialisasi dan batching untuk menghindari penambahan latensi ke aplikasi Anda.

Pola Atribusi Biaya Token

Implementasikan atribusi biaya di tingkat fitur, bukan hanya tingkat pengguna. Tandai setiap panggilan LLM dengan fitur yang memicunya (misalnya, invoice_summary, chat_support, document_extraction). Ini memungkinkan Anda mengidentifikasi fitur mana yang mendorong biaya dan mana yang tidak efisien.

import Anthropic from "@anthropic-ai/sdk"
import { Langfuse } from "langfuse"

const anthropic = new Anthropic()
const langfuse = new Langfuse({
  publicKey: process.env.LANGFUSE_PUBLIC_KEY,
  secretKey: process.env.LANGFUSE_SECRET_KEY,
  baseUrl: process.env.LANGFUSE_HOST, // your self-hosted instance
})

async function callLLM(params: {
  userId: string
  sessionId: string
  feature: string
  systemPrompt: string
  userMessage: string
}) {
  const trace = langfuse.trace({
    id: crypto.randomUUID(),
    userId: params.userId,
    sessionId: params.sessionId,
    tags: [params.feature],
    metadata: { feature: params.feature },
  })

  const generation = trace.generation({
    name: "claude-call",
    model: "claude-opus-4-5",
    input: [
      { role: "system", content: params.systemPrompt },
      { role: "user", content: params.userMessage },
    ],
    startTime: new Date(),
  })

  try {
    const response = await anthropic.messages.create({
      model: "claude-opus-4-5",
      max_tokens: 1024,
      system: params.systemPrompt,
      messages: [{ role: "user", content: params.userMessage }],
    })

    generation.end({
      output: response.content,
      usage: {
        input: response.usage.input_tokens,
        output: response.usage.output_tokens,
      },
      endTime: new Date(),
    })

    return response.content[0].type === "text" ? response.content[0].text : ""
  } catch (err) {
    generation.end({ level: "ERROR", statusMessage: String(err) })
    throw err
  } finally {
    await langfuse.flushAsync()
  }
}

Metrik Kualitas dan Evaluasi

Metrik keberhasilan/kegagalan biner tidak menangkap kualitas output LLM. Bangun pipeline evaluasi kualitas: (1) Pengumpulan umpan balik pengguna — jempol atas/bawah pada respons. (2) Pemeriksaan format otomatis — verifikasi output terstruktur sesuai skema yang diharapkan. (3) Pemeriksaan kesetiaan untuk RAG. (4) Persentil latensi — lacak p50, p95, p99 secara terpisah.

Log trace LLM berisi teks lengkap input pengguna dan output model. Jika aplikasi Anda memproses data pribadi (nama, detail kontak, catatan keuangan), log trace Anda adalah data pribadi yang tunduk pada GDPR, UU PDP Indonesia, atau regulasi privasi lainnya. Implementasikan redaksi PII sebelum logging: gunakan regex atau model deteksi PII khusus untuk menghapus email, nomor telepon, nomor identitas, dan data keuangan dari trace.

Deteksi Anomali untuk Sistem LLM

Bangun detektor anomali khusus untuk mode kegagalan LLM: distribusi panjang output (perubahan mendadak dalam panjang output rata-rata mungkin mengindikasikan prompt injection), frekuensi tool call (lonjakan tool call per sesi menunjukkan loop atau injeksi), tingkat error per model, dan anomali spesifik pengguna.

Setup Observabilitas Produksi Saya

Stack lengkap yang saya jalankan: Langfuse (self-hosted, Docker Compose, PostgreSQL) untuk trace LLM dan pelacakan biaya. Metrik Prometheus kustom untuk infrastruktur. Dashboard Grafana menggabungkan data Prometheus dan Langfuse melalui API. Peringatan PagerDuty untuk lonjakan biaya, peningkatan tingkat error, dan pelanggaran latensi p99. Retensi: 90 hari untuk trace lengkap, metrik agregat disimpan selamanya.

Artikel Terkait

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Mengapa observabilitas tradisional (latensi, tingkat error, throughput) tidak cukup untuk aplikasi LLM?

Aplikasi LLM bisa gagal dengan cara kualitatif yang sama sekali tidak tertangkap oleh metrik standar: panggilan API mengembalikan 200 OK, tetapi responsnya salah secara faktual, di luar topik, atau mengabaikan instruksi kritis. Untuk mendeteksi kegagalan ini, Anda juga membutuhkan logging prompt dan respons, pelacakan konsumsi token, sinyal kualitas seperti umpan balik pengguna dan deteksi halusinasi, serta deteksi anomali — semuanya tidak tercakup oleh metrik infrastruktur tradisional.

Apa itu Langfuse dan mengapa artikel ini merekomendasikan self-hosting?

Langfuse adalah platform observabilitas LLM open-source yang menyediakan logging trace, kalkulasi biaya token otomatis, pengelompokan sesi, alur kerja evaluasi, dan manajemen dataset. Artikel ini merekomendasikan self-hosting menggunakan Docker Compose dengan PostgreSQL karena memberikan kendali penuh atas retensi data dan privasi, yang penting ketika trace berisi data pribadi pengguna. Tier hosted gratis hingga 50K observasi per bulan untuk proyek yang lebih kecil.

Mengapa peringatan biaya harus dipasang sejak hari pertama, dan berapa ambang batas yang disarankan?

Biaya token bisa melonjak drastis hanya dari satu bug — misalnya, loop retry pernah menyebabkan 400K token terpakai dalam 10 menit saja. Artikel ini merekomendasikan membuat peringatan biaya harian di Langfuse pada 120% dari pengeluaran harian yang diperkirakan, sehingga lonjakan bisa tertangkap sebelum menjadi insiden ratusan dolar, bukan baru diketahui dari tagihan yang mengejutkan.

Bagaimana sebaiknya biaya panggilan LLM diatribusikan, dan jebakan apa yang disorot artikel ini?

Artikel ini merekomendasikan atribusi biaya di tingkat fitur (misalnya, invoice_summary, chat_support, document_extraction) bukan hanya di tingkat pengguna, agar Anda bisa mengidentifikasi fitur mana yang mendorong biaya atau tidak efisien. Dalam satu audit, fitur document_extraction menggunakan 3x lebih banyak token dari yang diperlukan karena prompt menyertakan seluruh dokumen padahal hanya dua halaman pertama yang relevan — kodenya benar secara fungsional tetapi boros.

Kewajiban privasi apa yang berlaku untuk log trace LLM, dan apa rekomendasi artikel ini?

Log trace LLM berisi teks lengkap input pengguna dan output model, menjadikannya data pribadi yang tunduk pada GDPR, UU PDP Indonesia, dan regulasi privasi lainnya ketika aplikasi memproses nama, detail kontak, atau catatan keuangan. Artikel ini merekomendasikan implementasi redaksi PII sebelum logging — menggunakan regex atau model deteksi PII khusus untuk menghapus email, nomor telepon, nomor identitas, dan data keuangan — serta menerapkan batas retensi dan kontrol akses yang tepat pada trace yang tersimpan.