Belajar Generative AI - Cost Optimization & Scaling
Episode 21 of 25

Belajar Generative AI - Cost Optimization & Scaling

Mengendalikan biaya dan menyiapkan skala aplikasi AI: model routing, caching respons, prompt compression, dan hybrid self-host vs API; plus batch processing, rate limiting, serta optimasi GPU inference dengan vLLM dan continuous batching.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah kalian membangun sistem yang semakin kompleks — RAG, agents, multi-agent (episode 7-20) — ada satu pertanyaan yang menentukan kelangsungan produk: berapa biaya untuk menjalankannya? Aplikasi AI itu mahal secara khusus: setiap request membakar token, dan token = uang. Tanpa kontrol, biaya bisa tumbuh eksponensial seiring pengguna.

Mengapa penting? Karena biaya AI adalah biaya variabel yang mengikuti setiap interaksi — tidak seperti server yang biayanya tetap. Satu aplikasi chat dengan 10 ribu pengguna aktif bisa menghabiskan ratusan dolar per hari jika tidak dioptimalkan. Episode ini mengajarkan teknik yang memangkas biaya 5-10x tanpa mengorbankan kualitas — keahlian yang langsung terlihat nilainya di produksi.

Teknik Cost Optimization

1. Model Routing

Kita sudah kenal konsepnya di episode 4; sekarang jadikan sistematis. Intinya: request yang mudah dijawab model murah; hanya yang sulit yang naik ke model mahal.

Router berbasis kompleksitas
def route_and_call(question, task_type):
    if task_type in {"extraction", "classification", "summarization"}:
        model = "gpt-4o-mini"          # ~15x lebih murah
    elif task_type == "reasoning":
        model = "gpt-5-mini"           # reasoning, cost sedang
    else:
        model = "gpt-4o"               # model mahal, hanya jika perlu
    return client.chat.completions.create(model=model, messages=...)

Routing adalah teknik dengan rasio penghematan terbaik — sering 50-80% biaya tanpa perubahan kualitas yang terasa.

2. Caching: Jangan Bayar Dua Kali

Banyak request berulang: pertanyaan FAQ yang sama, prompt yang identik, atau konten yang diproses berulang. Cache menghindari pembayaran ulang. Dua level:

  • Exact cache: pertanyaan persis sama → jawaban sama (perlu determinisme, episode 2).
Cache exact-match (Redis)
import hashlib, redis
 
r = redis.Redis()
 
def cached_chat(messages):
    key = "llm:" + hashlib.sha256(json.dumps(messages).encode()).hexdigest()
    cached = r.get(key)
    if cached:
        return json.loads(cached)              # hemat 100% token
    answer = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
    r.setex(key, 86400, json.dumps(answer.choices[0].message.content))
    return answer.choices[0].message.content
  • Semantic cache: pertanyaan berbeda kalimat tapi makna sama (embedding, episode 6) → jawaban diambil dari cache. Lebih kompleks tapi menangkap lebih banyak pengulangan.

3. Prompt Compression

Panjang input = biaya. Teknik kompresi:

  • Pangkas konteks: jangan kirim semua retrieval — kirim hanya yang relevan (parent-child, episode 8).
  • Ringkas dokumen panjang sebelum masuk prompt (map-reduce).
  • Hilangkan boilerplate: format prompt yang lebih padat, hapus kata tak perlu.
100%

Ingat: kompresi yang berlebihan menurunkan kualitas — selalu ukur dengan evaluasi (episode 15).

4. Hybrid Self-Host vs API

Keputusan arsitektur dari episode 13 kini menjadi strategi biaya: beban tinggi yang stabil lebih murah self-host (vLLM, episode 13); beban rendah/variabel lebih murah API (bayar per pakai). Banyak produksi memakai dua-duanya:

  • Request rutin → model kecil self-host (biaya per-token rendah).
  • Request sulit/jarang → API model besar (tanpa biaya idle GPU).

Scaling: Di Luar Cost

Setelah biaya terkendali, siapkan skala. Dua aspek:

Rate Limiting & Backpressure

Aplikasi yang populer pasti kena lonjakan. Tanpa rate limiting, cost meledak dan provider menolak (429). Terapkan per-user:

Rate limit per user (token bucket)
import time
 
class TokenBucket:
    def __init__(self, capacity, refill_per_sec):
        self.capacity = capacity
        self.tokens = capacity
        self.refill = refill_per_sec
        self.last = time.monotonic()
 
    def take(self) -> bool:
        now = time.monotonic()
        self.tokens = min(self.capacity,
                          self.tokens + (now - self.last) * self.refill)
        self.last = now
        if self.tokens >= 1:
            self.tokens -= 1
            return True
        return False
 
bucket = TokenBucket(capacity=20, refill_per_sec=1)  # 20 req/burst, 1 req/detik

Pendampingnya: queue untuk request berlebih (misal antrian async), sehingga lonjakan tidak menghantam API LLM langsung.

Batch Processing & Parallel Requests

Untuk workload non-real-time (embedding jutaan dokumen, RAG ingest, evaluasi), batch adalah kunci biaya & throughput:

Batch embedding (bukan per-satu)
# Buruk: 10.000 request individu
for doc in docs:
    client.embeddings.create(model="text-embedding-3-small", input=doc)
 
# Baik: satu request untuk banyak input (hemat overhead & rate limit)
r = client.embeddings.create(
    model="text-embedding-3-small",
    input=docs,          # 10.000 teks dalam satu panggilan
)

Optimasi GPU Inference (vLLM)

Bagi yang self-host (episode 13), optimasi GPU adalah pengali biaya. Kunci-kuncinya:

  • Continuous batching (vLLM): banyak request diproses dalam satu batch dinamis → GPU tidak idle menunggu satu respons selesai.
  • KV-cache management (PagedAttention): memori konteks terpakai efisien → lebih banyak request serentak.
  • Quantization (AWQ/GGUF): throughput lebih tinggi per GPU (episode 13).
  • Prefill/decode decoupling: langkah prefill (input) dan decode (output) bisa dipisah untuk latency stabil.
vLLM: konfigurasi throughput
python3 -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-7B-Instruct \
    --quantization awq \
    --max-num-seqs 64 \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.9

Efek nyatanya: satu GPU yang sama bisa melayani puluhan kali lebih banyak request dibandingkan running model tanpa batching — inilah perbedaan antara "mahal" dan "ekonomis" untuk self-host.

Metrik & Budget Control

Semua teknik di atas butuh pengukuran (episode 18):

  • Cost per request & per user — pantau tren harian/mingguan.
  • Budget alert — notifikasi saat melewati ambang.
  • Per-customer budget — untuk aplikasi multi-tenant, batas per pelanggan mencegah satu pelanggan menghabiskan semua.

Tip

Urutan optimalisasi biaya yang disarankan: routing (hemat besar, mudah) → caching (semakin banyak traffic semakin hemat) → kompresi prompt (perlu pengukuran) → self-host (baru setelah beban stabil). Jangan melompat ke self-host sebelum tiga teknik pertama dieksploitasi.

Common Pitfalls

  • Routing hanya di atas kertas — tanpa pengukuran per-task, router malah menurunkan kualitas.
  • Cache tanpa TTL/invalidasi — jawaban basi untuk data yang berubah.
  • Rate limit yang menolak pengguna, bukan mengantre — UX hancur; pakai queue.
  • GPU idle karena tanpa batching — membayar mahal untuk utilization rendah.

Penutup

Inti yang harus dibawa pulang:

  • Empat teknik cost: routing, caching, prompt compression, hybrid self-host/API.
  • Rate limiting + queue untuk skala; batch untuk workload non-real-time.
  • vLLM continuous batching & quantization melipatgandakan throughput per GPU.
  • Semua diukur dengan metrik cost & budget alert (episode 18).

Di episode 22 selanjutnya kita akan membahas AI Product: UX, RAG Quality & Metrics — evaluasi end-to-end, UX untuk AI (streaming, citations, feedback), retention & helpfulness metrics, plus menyusun evaluation set & scorecard untuk fitur AI. Sampai jumpa di episode 22!

Belajar Generative AI - Cost Optimization & Scaling | Belajar Generative AI