Episode ini membedah model data ChromaDB: Collection yang terdiri dari ids, embeddings, documents, dan metadatas, perbedaan embedded mode versus client-server, arsitektur server Python FastAPI lawas versus server Rust, serta alur index dan query berbasis HNSW.

Setelah memahami mengapa ChromaDB ada, episode 2 ini membawa kalian ke dalam mesinnya: konsep dasar dan arsitektur utama. Ini adalah episode paling penting untuk dipahami sebelum mulai ngoding, karena hampir semua kode di series ini berputar di sekitar satu primitif: Collection.
Kita akan membahas model data, dua mode penjalanan (embedded dan client-server), perbedaan server Python FastAPI lawas dengan server Rust modern, serta bagaimana query mengalir dari teks menjadi hasil. Jika kalian memahami episode ini dengan baik, episode 3 sampai 20 akan terasa seperti variasi dari satu tema besar.
Semua data di ChromaDB hidup di dalam Collection, semacam tabel di database relasional. Setiap collection punya nama unik, dan isinya mengikuti empat komponen utama:
Hubungan keempatnya sederhana: setiap id berpasangan dengan satu embedding, satu document, dan satu dict metadata. Kalian bisa mengisi semuanya sekaligus, atau membiarkan embedding dibangkitkan otomatis dari document.
collection = client.create_collection("berita")
collection.add(
ids=["berita-001", "berita-002"],
documents=["Inflasi naik dua persen", "Gunung meletus di Jawa Timur"],
metadatas=[{"kategori": "ekonomi"}, {"kategori": "alam"}],
)Perhatikan bahwa collection.add(...) tidak menerima argumen embeddings — ChromaDB membangkitkannya dari documents menggunakan embedding function bawaan. Cara ini paling mudah untuk memulai.
Model data ini fleksibel: kalian boleh menyimpan embeddings saja tanpa documents (misalnya untuk image embedding), atau sebaliknya. Pemisahan ini penting untuk kasus di episode 19: multimodal dan multi-vector. Untuk RAG teks biasa, kalian memerlukan documents karena itu yang menjadi konteks jawaban LLM.
ChromaDB punya dua cara berjalan yang sangat berbeda. Perbedaannya menentukan banyak keputusan arsitektur di series ini.
Dalam mode ini, ChromaDB berjalan di dalam proses aplikasi kalian. Tidak ada port, tidak ada jaringan, tidak ada server terpisah. Kalian cukup membuat klien dan mulai:
import chromadb
client = chromadb.PersistentClient(path="./chroma-data")Mode ini sempurna untuk development, prototipe, dan aplikasi single-process. Data disimpan ke direktori lokal (./chroma-data pada contoh di atas) lewat PersistentClient(path="./chroma-data"). Ada juga EphemeralClient yang datanya hilang begitu proses berakhir — cocok untuk test.
Dalam mode ini, ChromaDB berjalan sebagai server terpisah yang diakses banyak klien melalui HTTP. Di sinilah chroma run — server Rust — berperan:
chroma run --path ./chroma-data --port 8000Klien lalu terhubung lewat HTTP:
import chromadb
client = chromadb.HttpClient(host="localhost", port=8000)Mode ini wajib untuk production multi-process atau multi-service. chromadb.HttpClient(host="localhost", port=8000) adalah gerbang menuju arsitektur terdistribusi yang akan kita bahas dari episode 12 hingga 17.
Penting untuk membedakan dua era server ChromaDB, karena masih banyak tutorial lama yang memakai versi Python.
Server versi 0.x dan awal 1.x dibangun dengan Python FastAPI. Kelebihannya: mudah dikembangkan dan sama dengan library embedded. Namun ada kelemahan yang membuatnya tidak ideal untuk produksi: performa yang kurang deterministik, penggunaan memori lebih besar, dan — yang paling penting — riwayat celah keamanan, termasuk CVE-2026-45829 yang akan kita bedah di episode 14.
Sejak versi 1.x, ChromaDB memperkenalkan server Rust. Dengan perintah yang sama, chroma run, kini dijalankan binary Rust yang jauh lebih efisien. Keunggulannya:
| Aspek | Server Python FastAPI | Server Rust |
|---|---|---|
| Performa | Lebih lambat | Cepat dan konsisten |
| Memori | Lebih besar | Lebih kecil |
| Keamanan | Rentan CVE | Tidak terdampak |
| Rekomendasi | Legacy | Production |
Untuk seluruh episode produksi di series ini, kita akan selalu memakai server Rust. Klien Python dan JavaScript tetap sama — hanya server yang berbeda.
Saat kalian mengirim query, ChromaDB menjalankan alur yang terdiri dari tiga tahap:
query_text ──embed──> vektor ──HNSW search──> kandidat ──re-rank──> hasilAlur ini berjalan di belakang satu baris collection.query(...). Memahami tahapannya penting karena setiap tahap punya knob pengaturan tersendiri: embedding function di episode 6, filter sebelum index di episode 7, dan parameter HNSW di episode 9.
Info
Istilah yang sering membingungkan: embedded mode adalah cara menjalankan, bukan jenis database. Data bisa persisten di embedded mode. Yang membedakan hanyalah apakah ada server terpisah yang dilayani lewat jaringan.
Episode 2 memberi kalian peta arsitektur ChromaDB: Collection sebagai primitif utama dengan empat pilar (ids, embeddings, documents, metadatas), dua mode penjalanan (embedded dan client-server), perbedaan server Python FastAPI legacy dengan server Rust yang direkomendasikan, serta alur query embed → index → re-rank.
Inti yang harus dibawa pulang:
chroma run) adalah rekomendasi production, bukan server Python FastAPI.Di episode 3 selanjutnya kita akan mulai menulis kode sungguhan: setup, client, dan collection pertama — membandingkan berbagai jenis klien (Client, PersistentClient, EphemeralClient, HttpClient) dan membuat collection pertama dengan parameter yang tepat. Siapkan environment kalian dari episode 0.