Memilih arsitektur produk AI tidak seharusnya dimulai dari tren, melainkan dari bentuk beban kerja, batasan data, pola latensi, dan kemampuan tim mengoperasikan sistem. Untuk banyak tim, monolit modular adalah pilihan paling tepat di fase awal karena lebih cepat dikirim, lebih mudah di-debug, dan belum memecah kompleksitas ke jaringan, deployment, serta observabilitas lintas service.
Masalahnya, produk AI jarang berhenti di fase awal. Ketika pipeline inferensi makin berat, kebutuhan asynchronous job bertambah, model berubah lebih cepat daripada aplikasi utama, atau tim bertambah banyak, arsitektur yang tadinya efisien bisa menjadi hambatan. Di titik itu, pilihan antara monolith, service terpisah, atau hybrid harus didasarkan pada trade-off teknik yang jelas, bukan asumsi bahwa microservices selalu lebih modern.
Sebagai konteks, opini industri AI beberapa waktu terakhir banyak bergerak ke arah produk yang lebih pragmatis: fokus ke distribusi nilai, biaya inferensi, integrasi workflow, dan reliability operasional, bukan sekadar demo model. Itu berarti keputusan arsitektur juga harus pragmatis. Pertanyaan utamanya bukan “arsitektur mana yang paling keren?”, tetapi “arsitektur mana yang paling murah untuk dioperasikan, cukup cepat, aman terhadap perubahan, dan masih bisa berkembang 12-24 bulan ke depan?”
Definisikan dulu: apa yang sedang dibangun?
Sebelum membahas bentuk arsitektur, penting membedakan tipe beban kerja AI karena ini sangat memengaruhi desain sistem:
- AI sebagai fitur sinkron: misalnya ringkasan teks, klasifikasi tiket, ekstraksi field dokumen, saran balasan chat.
- AI sebagai pipeline asinkron: misalnya indexing dokumen, embedding, evaluasi batch, fine-tuning pipeline, enrichment data.
- AI sebagai produk inti: misalnya copilot, search semantik, agen berbasis tool, analitik berbasis model.
Jika AI hanya satu fitur kecil dalam aplikasi bisnis, arsitektur yang terlalu terdistribusi sering menjadi beban. Jika AI sudah menjadi inti nilai produk, maka pemisahan concern, isolasi scaling, dan pengelolaan model biasanya mulai penting.
Pilihan 1: monolit modular saat AI masih bagian dari aplikasi
Monolit modular berarti aplikasi tetap satu unit deployment utama, tetapi dibagi jelas per domain: API, auth, billing, orchestrator AI, storage, job worker, dan observability. Ini bukan monolit berantakan; ini monolit yang disiplin.
Kapan monolit modular cukup?
- Tim masih kecil, misalnya 2-8 engineer.
- Produk masih mencari bentuk dan banyak eksperimen.
- Perubahan domain bisnis lebih cepat daripada perubahan arsitektur.
- Inference bisa dipanggil lewat provider eksternal atau worker internal tanpa kebutuhan scaling ekstrem.
- Data access masih terpusat dan belum ada kebutuhan isolasi ketat antar domain.
- Pipeline AI belum membutuhkan lifecycle terpisah dari aplikasi utama.
Kenapa pendekatan ini sering paling efektif?
- Latensi lebih sederhana: pemanggilan antar modul tidak perlu hop jaringan internal.
- Debugging lebih mudah: request trace tidak tersebar ke banyak service.
- Deployment lebih murah secara operasional: lebih sedikit artifact, pipeline CI/CD, dan surface area failure.
- Refactor domain lebih cepat: ketika kebutuhan produk masih berubah, memecah service terlalu cepat justru mengunci boundary yang belum matang.
Contoh struktur monolit modular
app/
api/
controllers/
routes/
domains/
documents/
chat/
billing/
ai/
prompts/
inference/
embeddings/
safety/
evaluation/
jobs/
workers/
infra/
storage/
queue/
telemetry/
Poin pentingnya: modul AI diperlakukan sebagai domain internal yang jelas, bukan potongan utilitas acak yang tersebar di seluruh kode.
Praktik implementasi yang disarankan
- Buat interface untuk provider model, agar mudah berpindah provider atau menambah fallback.
- Pisahkan alur request sinkron dan job asinkron sejak awal.
- Simpan metadata inference: model, prompt version, token usage, latency, error type.
- Tambahkan idempotency key untuk job AI yang bisa terpicu ulang.
- Jangan biarkan route/controller langsung memanggil provider model; gunakan service layer atau orchestrator.
Contoh abstraksi sederhana untuk inference
interface LLMClient {
generate(input: {
prompt: string;
temperature?: number;
maxTokens?: number;
userId?: string;
}): Promise<{
output: string;
usage?: { inputTokens?: number; outputTokens?: number };
model?: string;
}>;
}
class AIOrchestrator {
constructor(
private readonly llmClient: LLMClient,
private readonly usageLogger: UsageLogger
) {}
async summarizeTicket(ticketText: string, userId: string) {
const prompt = buildTicketSummaryPrompt(ticketText);
const startedAt = Date.now();
const result = await this.llmClient.generate({
prompt,
userId,
maxTokens: 300
});
await this.usageLogger.log({
userId,
task: 'ticket_summary',
latencyMs: Date.now() - startedAt,
model: result.model,
usage: result.usage
});
return result.output;
}
}
Kode seperti ini membantu karena batas antara domain aplikasi dan provider AI tetap bersih. Saat nanti ingin memindahkan inference ke service terpisah, kontraknya sudah terbentuk.
Keterbatasan monolit modular
- Scaling tidak selalu efisien: jika hanya worker AI yang berat, Anda tetap bisa ikut menaikkan resource aplikasi utama.
- Failure domain menyatu: bug pada modul AI bisa berdampak ke proses lain jika isolasi tidak disiplin.
- Lifecycle model, cache, dan dependency ML bisa mengganggu deployment aplikasi biasa.
- Jika tim bertambah besar, koordinasi dalam satu codebase dapat menjadi bottleneck.
Pilihan 2: service terpisah saat kebutuhan operasional mulai berbeda
Service terpisah masuk akal ketika beban kerja AI sudah cukup berbeda dari aplikasi utama, baik dari sisi compute, runtime, deployment cadence, maupun pola failure. Ini tidak harus berarti microservices yang sangat granular; satu atau dua service AI yang jelas sering sudah cukup.
Kapan service terpisah lebih tepat?
- Inference berat dan membutuhkan autoscaling berbeda dari web app.
- Ada pipeline background seperti embedding, ingestion, re-ranking, evaluasi, atau batch enrichment.
- Dependensi AI/ML berbeda jauh dari stack utama dan sering berubah.
- Tim mulai terbagi: tim platform/backend dan tim AI/ML punya ritme kerja berbeda.
- Perlu isolasi kegagalan agar timeout atau lonjakan traffic AI tidak menjatuhkan API inti.
- Perlu kontrol keamanan atau compliance yang lebih ketat pada data/model tertentu.
Bentuk service yang umum
- Inference service: menerima request terstandar, memanggil model/provider, mengembalikan hasil dan metadata.
- Embedding/indexing service: menangani chunking, embedding, upsert vector index, re-index.
- Evaluation service: mengukur kualitas output, regression check, prompt test, offline scoring.
- Agent/tool execution service: mengelola tool-call, retry, timeout, dan sandboxing.
Kenapa pemisahan ini bekerja?
Karena karakteristik operasional AI sering tidak cocok dengan aplikasi CRUD biasa. Web app umumnya sensitif terhadap latency p95/p99 pada request pendek, sedangkan inference bisa lebih mahal, lebih lama, dan lebih variatif. Dengan service terpisah, Anda bisa:
- Menetapkan timeout, retry, dan rate limit yang spesifik untuk AI.
- Menskalakan worker/GPU/CPU-intensive process tanpa ikut menskalakan seluruh aplikasi.
- Melakukan deploy model adapter atau pipeline baru tanpa menyentuh layanan utama.
- Mengisolasi dependency yang rawan konflik.
Trade-off yang sering diremehkan
- Latensi bertambah: setiap hop jaringan menambah overhead, terutama jika alur awalnya sinkron.
- Operasional lebih kompleks: service discovery, secret management, CI/CD, observability, dan rollback menjadi lebih banyak.
- Debugging lintas service lebih sulit: tanpa tracing yang baik, sulit tahu bottleneck ada di API gateway, queue, retriever, atau model call.
- Contract drift: schema request/response antar service bisa menyimpang jika governance lemah.
Pola komunikasi yang biasanya aman
- Sinkron via HTTP/gRPC untuk kebutuhan interaktif yang butuh respons cepat.
- Asinkron via queue untuk tugas berat, batch, atau proses yang tidak harus selesai di request yang sama.
Jangan memaksa semua proses AI menjadi sinkron hanya demi kesederhanaan API. Banyak fitur AI lebih sehat jika dijalankan sebagai job, lalu hasilnya dipolling, di-push via webhook, atau dibaca dari status endpoint.
Contoh kontrak API untuk inference service
POST /v1/inference/summarize
Content-Type: application/json
Idempotency-Key: 4b8a-req-123
{
"document_id": "doc_123",
"text": "...konten dokumen...",
"options": {
"max_tokens": 300,
"priority": "normal"
},
"trace_id": "trace-abc-123"
}
Response sebaiknya memuat metadata minimum yang berguna untuk audit dan debugging:
{
"result": "Ringkasan dokumen...",
"model": "provider/model-name",
"usage": {
"input_tokens": 1200,
"output_tokens": 180
},
"latency_ms": 1480,
"request_id": "inf_456"
}
Angka di atas hanya contoh struktur, bukan nilai baku. Yang penting adalah adanya metadata yang konsisten untuk observabilitas dan pengendalian biaya.
Pilihan 3: hybrid, biasanya paling realistis untuk produk AI
Untuk banyak produk, arsitektur hybrid adalah kompromi terbaik. Aplikasi inti tetap monolit modular, tetapi komponen AI tertentu dipisah menjadi service atau worker khusus. Pendekatan ini menjaga kecepatan pengembangan pada domain bisnis, sambil memisahkan bagian yang memang punya kebutuhan operasional berbeda.
Contoh bentuk hybrid yang sehat
- Web app, auth, billing, workspace, dan API utama tetap dalam monolit.
- Inference sinkron ringan tetap bisa dipanggil dari monolit melalui adapter.
- Embedding, indexing, ingestion dokumen, dan evaluasi prompt dipindahkan ke worker/service terpisah.
- Queue dipakai untuk proses berat dan retry yang aman.
- Object storage dan vector store dikelola sebagai komponen infrastruktur bersama.
Kapan hybrid lebih masuk akal?
- Produk sudah live, tetapi belum cukup besar untuk memecah semua domain.
- Ada satu atau dua hotspot AI yang butuh scaling sendiri.
- Tim ingin memisahkan risiko operasional tanpa membangun platform microservices penuh.
- Masih ada banyak iterasi produk, sehingga boundary belum final.
Keuntungan utama hybrid
- Biaya kompleksitas lebih terkendali daripada microservices penuh.
- Jalur evolusi lebih natural: hanya bagian yang terbukti bermasalah yang dipisahkan.
- Tim tidak dipaksa matang terlalu cepat dalam observability, platform engineering, dan service governance.
Decision matrix: monolit, service, atau hybrid?
Gunakan matriks berikut sebagai alat bantu awal. Nilainya bukan aturan mutlak, tetapi cukup baik untuk diskusi desain.
| Kriteria | Monolit Modular | Service Terpisah | Hybrid |
|---|---|---|---|
| Kecepatan bangun MVP | Sangat baik | Lambat | Baik |
| Kompleksitas deployment | Rendah | Tinggi | Sedang |
| Isolasi scaling AI | Terbatas | Sangat baik | Baik |
| Latensi request sinkron | Lebih sederhana | Bisa bertambah | Tergantung alur |
| Observabilitas awal | Lebih mudah | Lebih sulit | Sedang |
| Biaya operasional platform | Rendah | Tinggi | Sedang |
| Otonomi tim | Rendah-Sedang | Tinggi | Sedang-Tinggi |
| Cocok untuk pipeline AI berat | Kurang cocok | Sangat cocok | Cocok |
| Maintainability jangka menengah | Baik jika modular | Baik jika governance kuat | Sering paling seimbang |
Aturan praktis yang bisa dipakai
- Pilih monolit modular jika produk masih berubah cepat dan AI belum menjadi bottleneck operasional utama.
- Pilih service terpisah jika AI punya kebutuhan scaling, dependency, reliability, atau lifecycle yang sudah jelas berbeda.
- Pilih hybrid jika Anda ingin manfaat isolasi pada area tertentu tanpa membayar kompleksitas penuh microservices.
Trade-off teknis yang harus dihitung sejak awal
1. Latensi
Dalam produk AI, latensi bukan hanya soal jaringan. Ada beberapa komponen:
- Waktu serialisasi request/response.
- Queueing dan concurrency limit.
- Retrieval atau database lookup.
- Cold start worker/container.
- Waktu inferensi model atau respons provider.
Kesalahan umum adalah memecah service terlalu cepat, lalu heran kenapa UX menjadi lambat. Jika fitur harus terasa interaktif, minimalkan hop dan pindahkan proses non-esensial ke background.
Tip debugging: ukur latency per tahap, bukan hanya total request time. Tanpa breakdown, Anda tidak tahu apakah masalah berasal dari retriever, prompt assembly, network, atau model call.
2. Biaya inferensi
Biaya inferensi sering lebih dominan daripada biaya compute aplikasi biasa. Arsitektur memengaruhi biaya lewat:
- Jumlah panggilan model akibat retry yang tidak terkendali.
- Pemrosesan sinkron yang memaksa timeout tinggi dan kapasitas berlebih.
- Pemecahan service yang menambah duplikasi data atau pipeline.
- Kurangnya cache, batching, atau deduplication.
Jika AI dipanggil berkali-kali pada alur yang sama, pertimbangkan cache hasil, penyimpanan artefak intermediate, dan penjadwalan job agar tidak menghitung ulang tanpa perlu.
3. Kompleksitas deployment
Service terpisah berarti lebih banyak image, pipeline, secret, health check, rollback plan, dan compatibility contract. Jika tim belum siap mengelola itu, microservices bisa menurunkan delivery speed secara signifikan.
4. Observabilitas
Produk AI membutuhkan observabilitas yang lebih kaya daripada API biasa. Selain log dan metrics teknis, Anda biasanya perlu:
- Trace ID lintas request dan job.
- Model/provider yang dipakai.
- Prompt/template version.
- Token usage atau ukuran input/output.
- Error taxonomy: timeout, rate limit, validation, content filter, downstream failure.
- Hasil evaluasi kualitas jika ada.
Tanpa ini, sulit membedakan bug aplikasi dari degradasi model atau masalah provider.
5. Scaling tim
Arsitektur sebaiknya mengikuti struktur kerja tim, tetapi jangan terlalu literal. Dua tim kecil tidak otomatis membutuhkan dua belas microservice. Pemisahan service baru masuk akal jika benar-benar mengurangi koordinasi dan bukan hanya memindahkan kompleksitas ke integration layer.
6. Batasan data dan keamanan
Data AI sering menyentuh dokumen internal, percakapan pengguna, atau PII. Ini memengaruhi keputusan arsitektur:
- Apakah data boleh keluar ke provider eksternal?
- Apakah embedding dan raw document harus dipisah lokasinya?
- Apakah ada kebutuhan audit trail per inferensi?
- Apakah service tertentu perlu berjalan dalam boundary jaringan yang lebih ketat?
Dalam beberapa kasus, service terpisah dipilih bukan karena scaling, tetapi karena kebutuhan isolasi data dan kontrol akses.
7. Maintainability
Maintainability bukan hanya soal ukuran codebase. Yang lebih penting adalah kejelasan boundary, kontrak internal, dan kemampuan mengubah satu bagian tanpa merusak yang lain. Monolit bisa maintainable jika modular. Microservices bisa tidak maintainable jika boundary domain buruk dan observability lemah.
Tanda bahwa arsitektur sekarang mulai tidak cocok
Berikut beberapa sinyal praktis bahwa Anda perlu mengevaluasi ulang arsitektur saat ini:
- Deployment fitur kecil di aplikasi utama sering tertunda karena pipeline AI ikut berisiko.
- Worker AI yang berat memaksa scaling seluruh aplikasi, padahal traffic CRUD biasa rendah.
- Timeout dan retry mulai sulit dikendalikan dalam request sinkron.
- Insiden produksi sulit di-debug karena tidak ada pemisahan responsibility atau tracing.
- Tim AI dan tim aplikasi saling menghambat release cadence.
- Dependensi untuk fitur AI membuat image/container aplikasi utama membengkak atau rawan konflik.
- Biaya inference naik karena pipeline tidak bisa diisolasi, di-cache, atau di-batch dengan baik.
- Data governance menuntut boundary akses yang lebih jelas.
Jika baru satu atau dua gejala muncul, belum tentu perlu rewrite. Tetapi jika beberapa gejala terjadi berulang dan menghambat delivery atau reliability, itu tanda arsitektur perlu dievolusikan.
Contoh evolusi: dari MVP ke scale-up
Fase 1: MVP
Sebuah tim membangun aplikasi knowledge assistant untuk customer support. Fitur awalnya:
- Upload dokumen.
- Pencarian sederhana.
- Ringkasan tiket dan draft balasan.
Pada tahap ini, pendekatan yang sehat adalah:
- Satu monolit modular untuk API, auth, billing, dan orchestrator AI.
- Satu queue/worker untuk indexing dokumen dan job background.
- Satu adapter untuk provider LLM dan embedding.
- Penyimpanan metadata inference untuk audit biaya.
Kenapa? Karena tim masih memvalidasi use case, prompt, dan alur UX. Memecah banyak service di fase ini hanya memperlambat eksperimen.
Fase 2: product-market fit awal
Traffic mulai naik. Dokumen yang diindeks makin banyak. Beberapa pelanggan mengunggah file besar. Latensi chat masih penting, tetapi indexing dan re-embedding mulai mendominasi resource.
Evolusi yang masuk akal:
- Pindahkan ingestion/indexing pipeline ke worker atau service terpisah.
- Pertahankan API produk utama di monolit.
- Tambahkan queue prioritas untuk proses sinkron ringan vs batch berat.
- Tambahkan tracing lintas upload - chunking - embedding - upsert index.
Ini adalah tahap hybrid yang sangat umum.
Fase 3: scale-up
Perusahaan kini punya beberapa tim: aplikasi inti, platform data, dan AI. Ada kebutuhan evaluasi kualitas, fallback provider, rate limiting per tenant, dan compliance pelanggan enterprise.
Pada titik ini, masuk akal untuk memiliki:
- Inference gateway/service terpisah.
- Embedding/indexing pipeline terpisah.
- Evaluation pipeline terpisah.
- Kontrak API internal yang stabil.
- Observability dan cost attribution per tenant.
Perhatikan bahwa pemisahan ini terjadi setelah bottleneck-nya jelas, bukan sebagai asumsi awal.
Checklist evaluasi sebelum rewrite arsitektur
Sebelum memutuskan migrasi besar, jawab pertanyaan berikut. Jika mayoritas jawabannya belum jelas, kemungkinan Anda belum perlu rewrite.
- Apa bottleneck utama saat ini? Latensi, biaya, deploy, reliability, atau koordinasi tim?
- Bisakah masalah diselesaikan tanpa memecah service? Misalnya dengan queue, cache, modularisasi, atau isolasi worker.
- Boundary domain-nya sudah stabil? Jika belum, pemecahan service berisiko salah potong.
- Apakah tim punya observability yang cukup? Memecah service tanpa tracing/logging yang baik biasanya memperburuk debugging.
- Apakah ada kebutuhan scaling yang benar-benar berbeda? Bukan dugaan, tetapi pola beban nyata.
- Apakah deployment cadence domain AI berbeda dari aplikasi utama?
- Apakah ada alasan keamanan atau compliance untuk memisahkan komponen?
- Apakah kontrak request/response internal sudah cukup matang untuk dijadikan API service?
- Berapa biaya platform tambahan yang siap ditanggung? CI/CD, secrets, monitoring, on-call, dan incident response.
- Bisakah evolusi dilakukan bertahap? Misalnya memindahkan indexing dulu, bukan semua komponen sekaligus.
Kesalahan umum saat merancang arsitektur produk AI
- Terlalu cepat memilih microservices karena ingin terlihat siap skala, padahal bottleneck belum ada.
- Menggabungkan semua alur AI menjadi request sinkron sehingga latensi dan timeout sulit dikendalikan.
- Tidak menyimpan metadata inference, lalu bingung saat biaya naik atau output menurun.
- Menyatukan logic bisnis, prompt assembly, dan provider call dalam controller atau handler yang sama.
- Mengabaikan fallback dan idempotency pada job yang bisa terpicu ulang.
- Memecah service tanpa contract testing, sehingga perubahan kecil merusak alur downstream.
Rekomendasi praktis
Jika Anda sedang merancang produk AI di tengah hype pasar, aturan paling aman biasanya seperti ini:
- Mulai dari monolit modular bila AI masih bagian dari aplikasi dan tim masih mencari bentuk produk.
- Pisahkan worker atau service hanya untuk beban kerja yang memang berbeda: indexing, batch inference, evaluasi, atau agent execution.
- Gunakan hybrid sebagai jalur evolusi default, karena paling seimbang antara kecepatan delivery dan isolasi operasional.
- Jangan rewrite karena tren. Rewrite hanya jika bottleneck sudah terukur dan manfaatnya lebih besar daripada biaya migrasi.
Pada akhirnya, arsitektur produk AI yang baik bukan yang paling terdistribusi, melainkan yang paling sesuai dengan bentuk produk, pola traffic, batasan data, dan kemampuan tim untuk mengoperasikannya dengan tenang. Dalam banyak kasus, keputusan terbaik bukan memilih satu kubu secara ideologis, tetapi merancang jalur evolusi yang memungkinkan monolit tumbuh dengan rapi dan hanya memisahkan bagian yang benar-benar layak dipisah.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!