Mengubah prototipe menjadi backend sungguhan: FastAPI dengan streaming, rate limiting, autentikasi, dan guardrail biaya. Kalian membangun API untuk aplikasi AI yang aman dipakai banyak pengguna, bukan sekadar script lokaltype: text

Selama lima belas episode, kalian membangun logika AI yang hebat — di dalam script yang berjalan di terminal kalian. Episode ini mengubahnya menjadi produk: API yang bisa dipanggil aplikasi web, mobile, atau integrasi lain, dengan keamanan dan batasan yang layak produksi.
Mengapa penting? Karena prototipe dan produk dipisahkan oleh satu hal: batasan (boundaries). Produk AI harus membatasi siapa yang boleh memanggil, berapa sering, berapa biaya, dan berapa lama waktu respons. Tanpa batasan ini, satu bug di frontend bisa menghabiskan ratusan dolar token dalam hitungan menit. Episode ini memasang batasan-batasan itu.
Backend AI yang baik memisahkan tiga lapisan:
Kunci utamanya: API layer tidak boleh tahu detail LLM, dan service layer tidak boleh menyentuh HTTP. Pemisahan ini membuat sistem bisa diuji dan di-scale.
Contoh API chat dengan streaming dan autentikasi sederhana:
import time
from fastapi import FastAPI, Depends, Header, HTTPException
from fastapi.responses import StreamingResponse
from openai import OpenAI
app = FastAPI()
client = OpenAI()
VALID_KEYS = {"dev_key_123"} # demo; pakai DB/secret manager di produksi
def verify_key(authorization: str | None = Header(None)) -> str:
if not authorization or not authorization.startswith("Bearer "):
raise HTTPException(401, "missing token")
token = authorization.removeprefix("Bearer ")
if token not in VALID_KEYS:
raise HTTPException(403, "invalid token")
return token
RATE: dict[str, list[float]] = {}
def rate_limit(api_key: str, max_req: int = 10, window: int = 60) -> None:
now = time.time()
RATE.setdefault(api_key, []).append(now)
RATE[api_key] = [t for t in RATE[api_key] if t > now - window]
if len(RATE[api_key]) > max_req:
raise HTTPException(429, "too many requests")
@app.post("/chat")
async def chat(prompt: str, api_key: str = Depends(verify_key)):
rate_limit(api_key)
def stream():
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
stream=True,
)
for chunk in r:
d = chunk.choices[0].delta.content
if d:
yield d
return StreamingResponse(stream(), media_type="text/plain")Empat komponen yang patut dicermati:
verify_key: setiap request wajib token; tanpa ini API terbuka untuk disalahgunakan.rate_limit: membatasi request per pengguna — ini juga guardrail biaya pertama.StreamingResponse: jawaban mengalir ke klien token demi token (episode 3).Streaming dari backend ke frontend butuh dua lapisan: (1) backend meng-stream dari LLM (di atas), dan (2) frontend membaca stream. Untuk aplikasi web, pola umum adalah Server-Sent Events (SSE) atau WebSocket:
import json
def stream_events():
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Jelaskan RAG."}],
stream=True,
)
for chunk in r:
d = chunk.choices[0].delta.content
if d:
yield f"data: {json.dumps({'delta': d})}\n\n"
yield "data: [DONE]\n\n"
@app.post("/chat/stream")
async def chat_stream(prompt: str, api_key: str = Depends(verify_key)):
return StreamingResponse(stream_events(), media_type="text/event-stream")SSE punya keunggulan dibanding polling: klien menerima delta secara real-time, dan koneksi bisa ditutup (cancel) kapan saja — yang juga menghemat token.
Untuk produksi, ganti VALID_KEYS di atas dengan sistem yang benar:
Caution
Jangan pernah memanggil LLM API dari frontend langsung (browser). Kunci LLM API kalian akan terekspos di network tab pengguna. Selalu lewatkan melalui backend — ini juga satu-satunya tempat di mana rate limit, biaya, dan audit bisa dikontrol.
Selain rate limit, pasang batas biaya eksplisit:
def check_budget(user_id: str, cost: float) -> None:
total = get_daily_spend(user_id) # dari DB / observability
if total + cost > BUDGET_HARIAN:
raise HTTPException(429, "budget harian tercapai, coba besok")Kombinasi rate limit + budget guard + auth adalah minimum untuk API AI produksi. Tanpa ketiganya, produk kalian satu request malang dari tagihan mengejutkan.
Inti yang harus dibawa pulang:
Di episode 17 selanjutnya kita memasang mata pada sistem: observability & monitoring AI — tracing langkah agent, tracking biaya per request, dan monitoring kualitas jawaban di produksi. Sampai jumpa di episode 17!