Penyiapan Lab

Menyiapkan Postgres dengan pgvector, Qdrant dalam container, dan endpoint model embedding untuk latihan sepanjang jalur.

Daftar isi

Lab pada jalur ini membutuhkan tiga komponen yang berjalan di komputer lokal, yaitu Postgres dengan ekstensi pgvector, Qdrant dalam container, dan satu endpoint model embedding. Topik ini membahas penyiapan ketiganya beserta cara memverifikasi bahwa setiap komponen sudah siap digunakan. Contoh kode yang murni Python dan NumPy pada jalur ini tetap dapat dijalankan tanpa lab, sedangkan latihan yang menyentuh basis data membutuhkan layanan yang disiapkan di sini.

Komponen lab#

Dua komponen pertama berjalan sebagai container, yaitu proses yang dijalankan Docker secara terisolasi bersama berkas sistemnya sendiri, sehingga versi dan pustaka yang dibutuhkan tidak menumpuk di sistem operasi utama. Postgres 16 dengan ekstensi pgvector menjadi tempat latihan berbasis SQL, sedangkan Qdrant menjadi mesin vektor khusus untuk latihan penyimpanan dan filter. Komponen ketiga berupa endpoint model embedding yang mengubah teks menjadi vektor, dan komponen ini boleh berupa layanan API atau model lokal.

Versi yang dijadikan acuan jalur ini adalah pgvector 0.8.x dan Qdrant 1.x. Perintah pada latihan ditulis untuk Docker Engine, dan psql digunakan sebagai klien SQL untuk Postgres. Pustaka Python seperti NumPy dipasang terpisah sesuai kebutuhan tiap latihan. Lab yang dibangun dengan container juga mudah dibongkar, karena menghapusnya tidak menyisakan jejak di sistem operasi utama.

Postgres dengan pgvector#

Container dibuat dari image, yaitu templat perangkat lunak yang sudah terpasang beserta pustakanya. Image resmi pgvector sudah memuat ekstensi di dalam Postgres 16, sehingga tidak ada pemasangan manual. Perintah berikut menjalankan container bernama pgvector-lab dengan port 5432, yaitu port standar Postgres:

bash
# tidak-dijalankan
# menjalankan Postgres 16 dengan ekstensi pgvector di dalam container
docker run -d --name pgvector-lab \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  pgvector/pgvector:pg16

Variabel POSTGRES_PASSWORD menetapkan sandi pengguna postgres untuk lab lokal, dan nilai apa pun yang mudah diingat dapat dipilih karena penyiapan ini bukan untuk produksi. Setelah container berjalan, ekstensi vector diaktifkan pada basis data yang akan digunakan. Ekstensi Postgres bersifat per basis data, sehingga perintah aktivasi perlu diulang apabila lab nantinya menggunakan basis data lain.

sql
-- tidak-dijalankan
-- mengaktifkan ekstensi vector pada basis data lab
CREATE EXTENSION IF NOT EXISTS vector;
-- memeriksa nomor versi ekstensi yang terpasang
SELECT extversion FROM pg_extension WHERE extname = 'vector';

Kedua pernyataan dijalankan melalui klien psql di dalam container:

bash
# tidak-dijalankan
# mengaktifkan ekstensi vector melalui psql di dalam container
docker exec -it pgvector-lab psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"
# memeriksa nomor versi ekstensi yang terpasang
docker exec -it pgvector-lab psql -U postgres -c "SELECT extversion FROM pg_extension WHERE extname = 'vector';"

Query kedua mengembalikan satu baris berisi nomor versi ekstensi, dan nomor tersebut pada penyiapan ini diawali 0.8. Apabila ekstensi belum diaktifkan, pernyataan yang membuat kolom bertipe vector akan gagal dengan pesan error bahwa tipe tersebut tidak dikenal. Pemeriksaan versi menjadi kebiasaan yang baik sebelum mengikuti latihan berbasis SQL.

Qdrant dalam container#

Qdrant dijalankan dengan perintah yang serupa, kali ini dengan dua port dan satu volume bernama. Port 6333 melayani REST API sekaligus antarmuka web bawaan, sedangkan port 6334 melayani gRPC yang digunakan klien resminya. Volume bernama qdrant_data menyimpan isi koleksi di luar siklus hidup container, dan versi Qdrant pada lab dapat dikunci sesuai kebutuhan latihan tanpa memengaruhi sistem lain.

bash
# tidak-dijalankan
# menjalankan Qdrant dengan volume bernama agar data bertahan antar penghapusan container
docker run -d --name qdrant-lab \
  -p 6333:6333 \
  -p 6334:6334 \
  -v qdrant_data:/qdrant/storage \
  qdrant/qdrant

Keberhasilan penyiapan diverifikasi dengan memanggil REST API dari komputer yang sama:

bash
# tidak-dijalankan
# memeriksa bahwa Qdrant sudah merespons melalui REST API
curl -s http://localhost:6333/collections

Respons yang benar berupa JSON berisi status ok dan daftar koleksi yang masih kosong. Antarmuka web bawaan juga dapat dibuka melalui port yang sama untuk melihat daftar koleksi secara visual. Setelah respons ini muncul, mesin vektor siap menerima koleksi pertama pada latihan berikutnya.

Endpoint model embedding#

Latihan sepanjang jalur ini membutuhkan vektor asli untuk disimpan dan dicari, sehingga satu endpoint model embedding perlu tersedia. Kontraknya sederhana, yaitu array teks masuk dan keluar array vektor dengan panjang tetap sesuai modelnya, satu vektor untuk satu teks. Model yang digunakan menentukan panjang vektornya, misalnya 1536 dimensi untuk text-embedding-3-small, 384 dimensi untuk all-MiniLM-L6-v2, dan 1024 dimensi untuk bge-m3 yang bersifat multibahasa.

Dua pilihan penyiapan sama-sama lazim. Layanan API embedding membutuhkan kunci akses yang disimpan di variabel lingkungan, bukan ditulis di dalam kode, sedangkan model lokal seperti all-MiniLM-L6-v2 berjalan dari pustaka sentence-transformers tanpa koneksi keluar. Apa pun pilihannya, satu aturan tidak boleh dilanggar, yaitu dimensi vektor dari model harus sama dengan dimensi yang dideklarasikan pada koleksi tujuan. Perubahan model berarti seluruh koleksi perlu dihitung ulang dengan model yang baru.

Bentuk payload, yakni isi data yang dikirim atau dikembalikan sebuah endpoint, dapat diperiksa secara lokal sebelum menyentuh lab. Skrip berikut memuat payload sampel yang bentuknya sama dengan respons endpoint embedding, lalu memeriksa dimensi dan norma vektornya. Ganti nilai embedding di dalam skrip dengan respons asli dari endpoint lab untuk memeriksa payload sebenarnya:

python cek_payload.py
# cek_payload.py — memeriksa bentuk payload respons endpoint embedding
import numpy as np

# payload sampel dengan bentuk yang sama seperti respons endpoint embedding;
# ganti nilai embedding dengan respons asli dari endpoint di lab
payload = {
    "model": "model-contoh",
    "embedding": [0.0425, -0.1130, 0.2067, 0.0512, -0.0181, 0.0944],
}

vektor = np.array(payload["embedding"], dtype=float)
norma = float(np.linalg.norm(vektor))
print(f"model          : {payload['model']}")
print(f"dimensi        : {vektor.shape[0]}")
print(f"norma L2       : {norma:.4f}")
print(f"ternormalisasi : {'ya' if abs(norma - 1.0) < 1e-3 else 'tidak'}")
text Keluaran
model          : model-contoh
dimensi        : 6
norma L2       : 0.2630
ternormalisasi : tidak

Nilai dimensi 6 hanya milik payload sampel, sedangkan model nyata menghasilkan angka 384, 1024, atau 1536 sesuai daftar di atas. Baris norma menunjukkan panjang vektornya, dan nilai itu tidak dituntut bernilai 1 untuk metrik kosinus karena kemiripan kosinus hanya membandingkan arah.

Kesalahan umum#

Lupa mengaktifkan ekstensi vector. Perintah yang membuat kolom bertipe vector gagal dengan pesan error bahwa tipe tersebut tidak dikenal. Penyebabnya, CREATE EXTENSION vector belum dijalankan pada basis data yang sedang digunakan. Ekstensi Postgres bersifat per basis data, sehingga aktivasi di satu basis data tidak berlaku otomatis ke basis data lain.

Menjalankan Qdrant tanpa volume. Container yang dijalankan ulang karena pembaruan atau restart mengembalikan kondisi kosong, dan seluruh koleksi hilang. Penyebabnya, isi Qdrant hanya tersimpan di lapisan container. Perbaikannya, lampirkan volume bernama seperti opsi -v pada perintah penyiapan, lalu jalankan container baru dengan volume yang sama.

Menulis kunci akses endpoint di dalam kode. Kunci yang tertanam di dalam skrip ikut terbawa saat berkas dibagikan atau disimpan di repository, dan kredensial tersebut dapat digunakan orang lain. Perbaikannya, simpan kunci di variabel lingkungan dan baca nilainya dari kode saat endpoint dipanggil.

Ringkasan#

  • Lab jalur ini terdiri atas Postgres 16 dengan pgvector 0.8.x, Qdrant 1.x dalam container, dan satu endpoint model embedding.
  • Ekstensi vector diaktifkan per basis data dengan CREATE EXTENSION sebelum tipe vector dapat digunakan.
  • Volume bernama menjaga isi koleksi Qdrant tetap hidup antar siklus container.
  • Dimensi model embedding harus sama dengan dimensi koleksi tujuan, dan perubahan model menuntut perhitungan ulang seluruh koleksi.

Referensi#