Faisalaffan Blog
Faisalaffan Blog
Rekayasa Perangkat Lunak26 menit baca

Arsitektur AI Modern: End-to-End

Dari query user pertama hingga response tersimpan ke database. Panduan lengkap layer, tools, request flow, learning roadmap, dan penerapan nyata di production โ€” termasuk Google ADK yang baru rilis.

Faisal Affan
Faisal Affan
Diterbitkan
Galeri
1 / 3

Arsitektur AI Modern: End-to-End

Dari query user pertama hingga response tersimpan ke database. Panduan lengkap layer, tools, request flow, learning roadmap, dan penerapan nyata di production โ€” termasuk Google ADK yang baru rilis.

PRINSIP UTAMA

Yang membuat AI sistem production-grade bukan kualitas model โ€” tapi kualitas arsitektur di sekitar model. Model bisa diganti kapan saja. Arsitektur yang baik tetap solid.


Mengapa Perlu Memahami Ini?

LLM hanya bisa melakukan satu hal: text in โ†’ text out. Ia tidak bisa ingat percakapan sebelumnya, akses database, eksekusi kode, atau ambil keputusan multi-step. Semua "kecanggihan" AI yang kamu lihat di production bukan karena model-nya pintar sendirian โ€” tapi karena ada arsitektur di sekitar model yang mengkoordinasikan semua kemampuan itu.

Memahami arsitektur ini memberi kamu kemampuan untuk: memilih tool yang tepat untuk problem yang tepat, mendesain sistem AI yang bisa di-maintain, dan debug ketika sesuatu tidak bekerja seperti yang diharapkan.


Layer Stack โ€” 8 Lapisan Arsitektur

Sistem AI modern terdiri dari 8 layer yang bekerja bersama. Klik setiap layer di bawah ini untuk melihat detail penjelasan dan tools-nya.

๐Ÿ‘ค Layer 1 โ€” User / Consumer (Entry Point)

Cara pengguna berinteraksi dengan sistem AI. Ada tiga jalur: via API (developer), UI (end user), atau CLI (developer tooling). Semua bermuara ke HTTP request yang sama โ€” hanya lapisan presentasinya yang berbeda.

CATATAN

Semua jalur ini akhirnya mengirim satu hal yang sama: messages[] array ke LLM. Bedanya hanya di bagaimana stream di-handle dan di-render ke user.

๐Ÿ”Œ Layer 2 โ€” Model Gateway (Routing & Fallback)

Abstraksi di atas semua LLM provider. Satu interface, ganti model tanpa ubah kode. Handle retry, fallback ke provider lain kalau down, cost tracking terpusat, dan load balancing antar API key.

Python
# Tanpa gateway โ€” kode berbeda per provider
client.chat.completions.create(model="gpt-4o", ...)      # OpenAI
client.messages.create(model="claude-sonnet-4-6", ...) # Anthropic

# Dengan LiteLLM โ€” satu interface semua provider
litellm.completion(model="gpt-4o", messages=[...])
litellm.completion(model="claude-sonnet-4-6", messages=[...])
litellm.completion(model="gemini/gemini-2.0-flash", messages=[...])

# Fallback otomatis kalau provider down
litellm.completion(
  model="gpt-4o",
  fallbacks=["claude-sonnet-4-6", "gemini/gemini-2.0-flash"]
)
๐Ÿ”— Layer 3 โ€” Orchestration & Agent (Core Logic)

Otak dari sistem AI. Koordinasi tools, memory, RAG, dan reasoning multi-step. Ini layer yang paling perlu dipelajari. Pola dasarnya adalah ReAct Loop: Reason โ†’ Act โ†’ Observe โ†’ ulang sampai selesai.

๐Ÿ“„ Layer 4 โ€” Data & Knowledge / RAG (RAG Pipeline)

Ingest dokumen โ†’ parse โ†’ chunk โ†’ embed โ†’ store โ†’ retrieve. Fondasi RAG. Pipeline ini berjalan offline (indexing) dan online (retrieval per request). Kualitas di step ini menentukan kualitas jawaban AI.

๐Ÿงฐ Layer 5 โ€” Tools & External Systems (Agent Capabilities)

Tool yang bisa dipanggil agent: search web, baca/tulis database, eksekusi kode, akses API eksternal. Semakin banyak tool berkualitas tinggi, semakin powerful agent. Tool calling bukan magic โ€” LLM output JSON descriptor, orchestration layer yang eksekusi fungsinya.

Python
# Tool calling: bukan magic, tapi mekanisme sederhana

# 1. Daftarkan tool ke agent
@tool
def check_inventory(product_id: str) -> dict:
    """Cek stok produk dari database"""
    return db.query("SELECT stock FROM products WHERE id = ?", product_id)

# 2. LLM OUTPUT (bukan eksekusi langsung):
# { "tool_call": { "name": "check_inventory", "args": {"product_id": "A"} } }

# 3. Orchestration layer eksekusi fungsi, inject hasil ke context
# 4. LLM dipanggil lagi dengan context yang sudah diperkaya
๐Ÿงฉ Layer 6 โ€” Memory & State (Context Persistence)

LLM stateless by default โ€” setiap request berdiri sendiri. Memory layer memberi agent kemampuan "ingat" lintas sesi. Ada 4 jenis: in-context (conversation history), external DB (Redis), episodic (what happened), semantic (what is known).

๐Ÿ“Š Layer 7 โ€” Eval & Observability (Production Quality)

Tanpa observability, kamu blind di production. Trace setiap LLM call, ukur latency/cost/kualitas output, detect regresi prompt. LangFuse adalah wajib di setiap AI feature yang masuk production.

๐Ÿš€ Layer 8 โ€” Deployment & Infra (Production Serving)

Serve model sendiri (vLLM) atau managed API. K8s untuk orkestrasi container. FastAPI sebagai lapisan API. LGTM stack untuk observability infra. LangFuse untuk observability AI layer.


Request Flow โ€” Perjalanan Satu Query

Berikut adalah perjalanan lengkap satu query user dari awal hingga response diterima. Tidak ada step yang terjadi secara ajaib โ€” semuanya eksplisit dan bisa di-trace.

๐Ÿ‘ค User query REST / UI / Voice / CLI ๐Ÿ”Œ Model Gateway LiteLLM โ€” routing, fallback, cost tracking ๐Ÿ”— Orchestration / Agent LangGraph ยท LlamaIndex ยท Google ADK ยท CrewAI ๐Ÿ“„ RAG Pipeline Retrieve โ†’ Rerank โ†’ Inject ๐Ÿงฉ Memory Mem0 ยท Zep ยท Redis ๐Ÿงฐ Tools Search ยท SQL ยท Browser ยท API โšก LLM Inference Context: query + docs + memory + tool results ๐Ÿ“Š LangFuse trace + eval ๐ŸŽฏ Structured Output Instructor + Pydantic validation + retry โœ… Response JSON / stream / markdown โ‘  ENTRY โ‘ก ROUTING โ‘ข ORCHESTRATION โ‘ฃ INFERENCE โ‘ค OUTPUT
Request flow end-to-end โ€” setiap step bisa di-trace via LangFuse

Konsep Fundamental

Sebelum masuk ke framework spesifik, ini 6 konsep yang harus benar-benar dipahami. Semua framework โ€” LangGraph, Google ADK, CrewAI โ€” dibangun di atas konsep ini.

4.1 ReAct Loop โ€” Pola Dasar Semua Agent

ReAct (Reason + Act) adalah pola fundamental yang dipakai semua agentic framework. Agent loop ini terus berulang sampai agent yakin jawabannya cukup.

User query masuk ke agent loop โ‘  Reason LLM pikirkan langkah berikutnya Done? Cukup info? Ya โ†’ Final Response generate jawaban ke user Tidak โ‘ก Act Panggil tool / query DB / search web Tool eksekusi โ‘ข Observe inject ke context loop kembali
ReAct loop โ€” semua agentic framework mengimplementasikan pola ini
POIN KUNCI

Tool calling bukan magic. LLM output JSON descriptor {"name": "check_stock", "args": {...}}. Orchestration layer yang eksekusi Python function-nya, inject hasilnya kembali ke context, lalu LLM dipanggil lagi. Ini satu cycle ReAct.

4.2 Context Window โ€” Apa yang Dilihat LLM

LLM adalah fungsi matematika: f(tokens_in)โ†’probability_distribution(tokens_out)f(\text{tokens\_in}) \rightarrow \text{probability\_distribution}(\text{tokens\_out}). Tidak ada memori, tidak ada state. Setiap call, ia membaca seluruh context dari awal. Semua "pengetahuan" LLM dalam satu request ada di dalam context window ini.

Komponen Isi Token Budget Sumber
System prompt Identitas, aturan, format output, batasan 200โ€“2.000 hardcoded oleh developer
Retrieved docs Chunk relevan dari vector DB 500โ€“4.000 RAG pipeline
Memory Fakta dari sesi sebelumnya 100โ€“500 Mem0 / Redis
Tool schema JSON descriptor semua tool yang tersedia 200โ€“800 tool registry
History Turn percakapan sebelumnya 500โ€“8.000 conversation state
User query Query saat ini 50โ€“200 user input
Total โ€” ~4kโ€“15k โ€”
LOST-IN-THE-MIDDLE PROBLEM

LLM lebih "perhatian" ke awal dan akhir context. Taruh instruksi penting di system prompt (awal) dan user query tepat sebelum generate (akhir). Retrieved chunks di tengah rawan diabaikan kalau terlalu banyak.

4.3 RAG Pipeline โ€” Cara Kerja Detail

RAG terdiri dari dua fase yang terpisah: Indexing (offline, sekali jalan) dan Retrieval (online, setiap request).

INDEXING (Offline โ€” Sekali Jalan)

๐Ÿ“ฅ Load dokumen โ†’\rightarrow ๐Ÿ” Parse (Docling) โ†’\rightarrow โœ‚๏ธ Chunk (~512 token, 50 overlap) โ†’\rightarrow ๐Ÿงฎ Embed (OpenAI / Jina) โ†’\rightarrow ๐Ÿ’พ Store (pgvector / Qdrant)


RETRIEVAL (Online โ€” Setiap Request)

๐Ÿ—ฃ๏ธ User query โ†’\rightarrow ๐Ÿงฎ Embed query โ†’\rightarrow ๐Ÿ” Similarity search (top-100) โ†’\rightarrow ๐Ÿ“Š Rerank (Cohere) โ†’\rightarrow top-5 โ†’\rightarrow ๐Ÿ’‰ Inject ke context

Situasi Pakai RAG? Alasan
Q&A atas dokumen internal (SOP, katalog) Ya (Hijau) Data tidak ada di training LLM
Data real-time (harga, stok sekarang) Tool call (Kuning) Perlu query DB langsung, bukan RAG
Pertanyaan umum (cara pakai Python) Tidak (Abu-abu) LLM sudah tahu
Compliance & audit trail Ya (Hijau) Harus bisa cite sumber spesifik
Inventory forecasting + live data Hybrid (Biru) RAG untuk historical docs, tool call untuk data live

4.4 Tool Calling โ€” Mekanisme Lengkap

Ini yang membuat LLM bisa berinteraksi dengan dunia nyata. Bukan magic โ€” ini sequence yang eksplisit dan deterministic dari sisi orchestration.

Python
# Step 1: Define tool sebagai Python function biasa
@tool
def check_inventory(product_id: str) -> dict:
    """Cek stok produk dari database. Args: product_id (str)"""
    return db.query("SELECT * FROM products WHERE id = %s", product_id)

# Step 2: LLM menerima tool schema di context
# {"name": "check_inventory", "description": "Cek stok...", "parameters": {...}}

# Step 3: LLM output (bukan eksekusi!) โ€” JSON tool call
# {"type": "tool_call", "name": "check_inventory", "args": {"product_id": "A"}}

# Step 4: Orchestration layer eksekusi fungsi Python
result = check_inventory(product_id="A")  # {"stock": 142, "safety_stock": 200}

# Step 5: Inject hasil sebagai tool_result ke context
# {"type": "tool_result", "content": {"stock": 142, "safety_stock": 200}}

# Step 6: LLM dipanggil LAGI dengan context lengkap + tool result
# Kali ini LLM bisa generate jawaban final berdasarkan data nyata

4.5 Structured Output โ€” Dari Teks ke Data

Tanpa structured output, LLM adalah sumber teks. Dengan structured output, LLM menjadi fungsi yang bisa dipanggil seperti API โ€” output-nya langsung bisa diproses kode tanpa parsing manual.

Python
import instructor
from pydantic import BaseModel, Field
from typing import Literal

# 1. Define schema yang diinginkan
class InventoryAlert(BaseModel):
    product_id: str
    current_stock: int = Field(ge=0)
    status: Literal["ok", "low", "critical", "stockout"]
    reorder_suggested: bool
    suggested_quantity: int | None = None
    reason: str = Field(max_length=200)

# 2. Instructor wrap LLM client
client = instructor.from_anthropic(Anthropic())

# 3. Response langsung berupa Python object โ€” bukan string
alert = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=500,
    response_model=InventoryAlert,  # inject schema ke tool calling
    messages=[{"role": "user", "content": context}]
)

# alert.status == "low" โ€” type-safe, langsung pakai
if alert.reorder_suggested:
    trigger_purchase_order(alert.product_id, alert.suggested_quantity)
KENAPA INSTRUCTOR, BUKAN JSON MODE?

JSON mode hanya menjamin output adalah valid JSON โ€” schema field masih bisa hilang atau salah tipe. Instructor inject Pydantic schema ke tool calling mechanism, validasi output, dan auto-retry 3x kalau output tidak sesuai schema. Ini yang bikin reliable di production.

4.6 Observability dengan LangFuse

LangFuse adalah observability layer khusus AI โ€” analoginya Grafana untuk infra, tapi untuk LLM calls. Hierarki datanya: Trace (satu end-to-end request) โ†’\rightarrow Span (unit kerja) โ†’\rightarrow Generation (satu LLM call) โ†’\rightarrow Score (evaluasi).

Python
# Cara paling simple: LiteLLM integration (1 baris)
import os
os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-..."
os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-..."
litellm.success_callback = ["langfuse"]  # semua LLM call auto-traced

# Atau via decorator untuk custom spans
from langfuse.decorators import observe

@observe(name="inventory-analysis")
def analyze_inventory(query: str) -> str:
    chunks = retrieve_docs(query)     # jadi child span
    answer = generate_answer(query, chunks)  # jadi child span
    return answer

# Yang di-capture per generation:
# latency, input/output tokens, cost, faithfulness score, user feedback

Google ADK โ€” Framework Multi-Agent Baru

GOOGLE AGENT DEVELOPMENT KIT

Framework open-source dari Google untuk build, test, dan deploy AI agent. Native Gemini, tapi support model lain. Dirancang untuk multi-agent production use case dengan protocol A2A (Agent-to-Agent).

Komponen Fungsi Analogi ke LangGraph
Agent Unit dasar. LlmAgent (reasoning) atau WorkflowAgent (deterministic) Node dalam graph
Tools Python function yang bisa dipanggil agent. Auto-convert ke function calling schema Tool dalam LangGraph
Runner Engine yang eksekusi agent loop graph.invoke()
Session State per user conversation, persistent Checkpointer
A2A Protocol Agent-to-Agent communication. Sub-agent bisa dipanggil sebagai tool Subgraph
Deployment Local dev, Vertex AI (managed), atau self-hosted ADK server LangGraph Cloud / self-host
Python
from google.adk.agents import LlmAgent
from google.adk.tools import tool
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService

# 1. Define tool
@tool
def check_stock(product_id: str) -> dict:
    """Cek stok produk dari inventory database"""
    return db.get_stock(product_id)

# 2. Create agent
inventory_agent = LlmAgent(
    name="inventory-analyst",
    model="gemini-2.0-flash",
    tools=[check_stock],
    instruction="Kamu adalah analis inventory. Bantu user memahami kondisi stok."
)

# 3. Run
session_service = InMemorySessionService()
runner = Runner(agent=inventory_agent, session_service=session_service)

response = runner.run(
    user_id="user_123",
    session_id="session_abc",
    message="Berapa stok produk A sekarang?"
)

ADK vs Framework Lain

Framework Kelebihan Trade-off Pilih kalau
Google ADK Multi-agent native, Vertex AI, A2A protocol Python only, community kecil Butuh multi-agent production-grade di Google Cloud
LangGraph Mature, graph state machine, checkpointing Abstraksi tebal, LangChain dep Complex stateful agent, human-in-the-loop
CrewAI Intuitive, role-based, cepat prototype Kurang fleksibel untuk complex flow Prototype cepat, workshop
Pydantic AI Type-safe, minimal, Pythonic Ekosistem terbatas Simple agent dengan type safety ketat

Format Response AI di Production

Format response yang baik bukan tentang estetika โ€” tapi tentang predictability, parsability, dan contract yang tidak berubah saat model di-update.

Untuk data pipeline, background job, analisis dokumen. Type-safe penuh via Instructor + Pydantic.

Python
class InventoryInsight(BaseModel):
    product_id: str
    action: Literal["reorder", "hold", "liquidate"]
    urgency: Literal["immediate", "this_week", "this_month"]
    confidence: float = Field(ge=0.0, le=1.0)
    suggested_quantity: int | None = None

insight = client.messages.create(
    response_model=InventoryInsight,
    messages=[{"role": "user", "content": context}]
)
# insight.action == "reorder" โ€” langsung gunakan, no parsing

Learning Roadmap โ€” 8 Minggu

Urutan belajar yang optimal berdasarkan dependency antar konsep. Tidak ada shortcut โ€” tiap minggu membangun fondasi untuk minggu berikutnya.

MINGGU 1: Fundamental: LLM API + Structured Output

Pahami cara panggil LLM via API, perbedaan model, token pricing. Kuasai Instructor + Pydantic โ€” ini fondasi semua tool AI lainnya. Tanpa ini, kamu tidak akan bisa debug masalah di layer atasnya.

MINGGU 2: FastAPI + LiteLLM: Serve AI sebagai Service

Bungkus LLM call dalam REST API pakai FastAPI. Tambah LiteLLM untuk routing multi-provider. Implement streaming endpoint. Deploy via Docker. Skill ini langsung masuk ke CV dan bisa langsung dipakai di project nyata.

MINGGU 3: RAG Pipeline: pgvector + LlamaIndex

Bangun sistem Q&A atas dokumen. Ingest PDF โ†’\rightarrow chunk โ†’\rightarrow embed โ†’\rightarrow store di pgvector โ†’\rightarrow retrieve โ†’\rightarrow rerank โ†’\rightarrow inject ke prompt. LlamaIndex handle orchestration pipeline-nya. Ini skill yang paling banyak dicari di job posting AI.

MINGGU 4: Agentic Loop: LangGraph

Bangun agent yang bisa reason, memanggil tool (search, SQL, API), dan loop sampai task selesai. LangGraph adalah graph state machine untuk agent workflow kompleks. Pelajari checkpointing dan human-in-the-loop pattern.

MINGGU 5: Observability: LangFuse

Integrasikan LangFuse ke semua LLM call. Track latency, token cost, kualitas output per request. Setup RAGAS untuk evaluasi RAG pipeline. Tanpa ini kamu buta di production. Self-hosted gratis, UI bagus, integrate dengan K8s.

MINGGU 6: Multi-Agent: Google ADK

Pelajari Google ADK untuk orchestrasi multi-agent di atas Gemini. Konsep: sub-agent, tool registry, session management, A2A protocol. Cocok untuk portofolio karena paling baru dan makin banyak dicari employer yang pakai Google Cloud.

MINGGU 7โ€“8: Demo Project: End-to-End AI Feature

Gabungkan semua konsep dalam satu project yang bisa di-demo. Contoh: inventory Q&A agent โ€” user tanya natural language โ†’\rightarrow agent RAG + query DB + generate insight โ†’\rightarrow stream response. Deploy ke K8s dengan LangFuse tracing aktif.

PRIORITY STACK V1

FastAPI + LiteLLM + LlamaIndex + LangGraph + pgvector + LangFuse + Instructor. Ini cukup untuk 90% job requirement AI engineer level mid. Kuasai 7 tool ini production-depth sebelum expand ke yang lain.


Production Readiness Checklist

Gunakan ini sebelum deploy AI feature ke production. Setiap item yang terlewat adalah potensi incident.

SCHEMA

  • Semua field typed, tidak ada dict atau Any
  • Field nullable di-mark Optional / None eksplisit
  • Field numerik punya constraint (ge=0, le=1.0, dll)
  • Literal atau Enum untuk field yang nilainya terbatas

DELIVERY

  • Batch endpoint untuk data pipeline (JSON + Pydantic)
  • Streaming endpoint untuk chat interface (SSE)
  • SSE header benar: Cache-Control: no-cache, X-Accel-Buffering: no
  • Timeout di-set (bukan infinite wait)
  • Max tokens di-set eksplisit di setiap LLM call

ERROR HANDLING

  • Validation error ter-catch sebelum masuk DB
  • Retry logic ada (Instructor 3x default, atau manual)
  • Error response punya retryable flag
  • request_id ada di setiap response untuk tracing
  • Fallback provider dikonfigurasi di LiteLLM

OBSERVABILITY

  • trace_id link ke LangFuse di setiap response
  • latency_ms di-log per request
  • Input/output tokens di-log untuk cost monitoring
  • context_sources (chunk ID dari RAG) di-log untuk audit trail
  • PII masking dikonfigurasi di LangFuse sebelum go-live

SECURITY

  • Prompt injection protection โ€” validasi input user sebelum masuk ke system prompt
  • Rate limiting per user / per endpoint
  • API key tidak hardcoded โ€” gunakan env var atau secret manager
  • Output validation โ€” AI output yang masuk ke DB harus melalui Pydantic

Artikel terkait

Rekayasa Perangkat Lunak

Search & Catalog 15k SKU Q-Commerce: Relevan + In-Stock Real-time

System design search dan catalog untuk quick commerce dengan 15.000+ SKU. Elasticsearch full-text search dengan multi-match query dan typo tolerance (fuzziness), filter ketersediaan per-hub via Redis pipeline query-time filtering, ranking berbasis relevansi, ketersediaan, margin, dan popularitas, index update via Kafka streaming, dan autocomplete handler. Implementasi Golang lengkap dengan worker concurrency pattern untuk index sync.
Faisal Affan
Faisal Affan
Diterbitkan

Real-time Order Tracking Q-Commerce: Driver Bergerak di Peta Live

System design real-time order tracking untuk quick commerce. Driver GPS ingestion via WebSocket dengan throttling dan validasi, Kalman filter untuk position smoothing, Redis pub/sub fan-out by order ID untuk scale ribuan driver concurrent, dan Server-Sent Events (SSE) push ke user client. Implementasi Golang dengan pattern WebSocket goroutine pool, pub/sub broker, dan concurrent connection management.
Faisal Affan
Faisal Affan
Diterbitkan
Rekayasa Perangkat Lunak
Real-time Inventory Dark Store: Cegah Oversell di Q-Commerce

Real-time Inventory Dark Store: Cegah Oversell di Q-Commerce

Desain inventory per-hub untuk Astro (instant grocery). Reservation pattern dengan Redis DECRBY atomic + TTL, async sync ke Postgres, stock partitioning untuk hot SKU, reaper job untuk reservation leak, dan cycle counting untuk stok fisik vs sistem. Implementasi Golang lengkap.
Faisal Affan
Faisal Affan
Diterbitkan

Promo & Voucher Engine Q-Commerce: Rule Engine Anti-Abuse

System design promo engine untuk quick commerce. Rule engine dengan kondisi komposable (min transaksi, first-N-order, area, kategori) ke efek (discount, free ongkir), atomic counter untuk limit penggunaan Redis Lua, anti-fraud device fingerprinting, stackable vs eksklusif promo resolution, dan budget cap. Implementasi Golang lengkap dengan composable condition interface, AND/OR composite tree, concurrent-safe redeem, serta Kafka event streaming untuk audit trail.
Faisal Affan
Faisal Affan
Diterbitkan