Database vektor adalah abstraksi yang keliru
(timescale.com)- Pesan yang menghantui tim engineering yang ingin membangun aplikasi AI: "embedding tidak tersinkron ulang"
- Implementasi pencarian vektor yang sederhana berkembang menjadi orkestrasi kompleks untuk pemantauan, sinkronisasi, dan troubleshooting
- Setelah berbicara dengan tim engineering yang membangun sistem AI dengan database vektor, ditemukan abstraksi database vektor yang keliru dan cacat pada cara penggunaannya saat ini
"Kasus umum saat membangun sistem RAG"
- Menggunakan Pinecone sebagai database vektor untuk menyimpan dan mengambil embedding
- Karena data teks tidak cocok dengan baik di metadata Pinecone, blob dan data aplikasi ditangani dengan DynamoDB
- OpenSearch dibutuhkan untuk pencarian leksikal
- Kini menghubungkan dan menyinkronkan 3 sistem menjadi mimpi buruk
Saat menghapus dokumen sumber, Anda harus melakukan hal berikut:
- Menjalankan boto3 untuk menghapus record dari DynamoDB
- Memperbarui Pinecone untuk memastikan embedding telah dihapus
- Memerlukan permintaan POST untuk memperbarui indeks pencarian leksikal
- Ini harus dilakukan untuk setiap pembaruan, penambahan, atau penghapusan dokumen sumber
- Manajemen konfigurasi bukan hanya berantakan, tetapi juga berisiko
- Bahkan ada tim yang membayar $2.000 per bulan untuk indeks yang seharusnya sudah dihapus 4 bulan lalu
- Ada risiko mengembalikan data yang salah atau usang kepada pengguna
Database vektor dibangun di atas abstraksi yang keliru
- Database vektor memperlakukan embedding sebagai data mandiri, bukan data turunan
- Dengan memperlakukan embedding sebagai data mandiri, kompleksitas yang tidak perlu pun tercipta
Cara yang lebih baik: abstraksi "Vectorizer"
- Diusulkan abstraksi "vectorizer" yang memperlakukan embedding seperti indeks database
- Pendekatan ini secara otomatis menyinkronkan embedding dengan data sumber sehingga menghilangkan biaya pemeliharaan
- Vectorizer yang setara dengan perintah
CREATE INDEXadalah sebagai berikut:
SELECT ai.create_vectorizer(
'public.blogs'::regclass,
embedding => ai.embedding_openai('text-embedding-3-small', 1536),
chunking => ai.chunking_recursive_character_text_splitter('content')
);
- Perintah ini membuat embedding untuk semua entri di tabel blog dan terus memperbarui embedding saat data di tabel berubah
Masalah pada database vektor (dan tipe data vektor)
- Database vektor dikembangkan untuk menangani embedding vektor dalam jumlah besar untuk data teks, gambar, dan multimodal
- Database serbaguna seperti PostgreSQL, MySQL, MongoDB, dan Oracle juga menambahkan dukungan pencarian vektor
- Namun, abstraksi pada sistem mandiri atau fitur pencarian vektor yang ditambahkan ke database yang ada memiliki cacat fatal
- Begitu embedding dimasukkan ke dalam database, keterkaitan antara data tak terstruktur yang di-embed dan embedding vektornya sendiri terputus
- Tanpa keterkaitan ini, embedding keliru diperlakukan sebagai atom data mandiri yang harus dikelola developer, bukan data turunan
- Jika embedding dipahami ulang sebagai data turunan, absurditas abstraksi database vektor saat ini—di mana embedding tidak terhubung dengan data sumber—menjadi jelas
Tim pengembang harus mengelola hal-hal berikut:
-
Pipeline ETL (extract-load-transform) yang kompleks
-
Database vektor untuk embedding, database lain untuk metadata dan data aplikasi, serta indeks pencarian leksikal
-
Layanan sinkronisasi data
-
Sistem queue untuk pembaruan dan sinkronisasi
-
Alat pemantauan untuk menangkap data drift dan menangani rate limit layanan embedding, dan sebagainya
-
Sistem notifikasi saat pencarian mengembalikan hasil yang usang
-
Pemeriksaan validasi untuk semua sistem
-
Untuk upgrade ke model embedding baru atau mencoba metode chunking lain, Anda harus menulis kode kustom dan mengoordinasikan perubahan di berbagai layanan data dan database
-
Pekerjaan ini membebankan tim pengembang tanggung jawab untuk memastikan embedding dibuat tepat waktu seiring perubahan data sumber
-
Jika tidak, embedding berisiko sering menjadi usang dan memberi pengguna pengalaman aplikasi yang lebih buruk
Cara yang lebih baik: biarkan database menangani kompleksitasnya
- Dengan memahami embedding sebagai data turunan, tanggung jawab untuk membuat dan memperbarui embedding saat data dasar berubah dapat diserahkan kepada sistem manajemen database
- Perubahan ini membebaskan developer dari beban menjaga embedding tetap sinkron dengan data sumber secara manual
- Pembedaan ini mungkin tidak penting untuk aplikasi sederhana yang hanya melakukan impor data satu kali untuk RAG
- Namun, pada sebagian besar aplikasi nyata, data terus berubah
- Bayangkan platform e-commerce yang menggunakan pencarian semantik berbasis embedding, atau aplikasi RAG asisten produk yang harus selalu mengikuti informasi produk terbaru.
- Melacak perubahan ini secara manual dan membuat ulang embedding bukan hanya padat karya dan rawan kesalahan, tetapi juga mengalihkan fokus developer dari tujuan bisnis inti
- Mengapa membuang waktu pengembangan jika sistem database dapat menanganinya secara otomatis?
Vectorizer: embedding vektor sebagai indeks
- Abstraksi yang lebih efektif adalah mengonseptualisasikan embedding vektor sebagai indeks khusus untuk data yang di-embed, bukan sebagai tabel atau tipe data yang berdiri sendiri
- Embedding vektor bukan indeks dalam arti tradisional
- Sebaliknya, embedding vektor berfungsi sebagai mekanisme pengindeksan untuk mengambil bagian data yang paling relevan berdasarkan embedding
- Abstraksi baru yang mirip indeks ini dapat disebut "vectorizer"
Manfaat utama abstraksi vectorizer:
Sinkronisasi otomatis
- Salah satu manfaat utama pengindeksan dalam database adalah menjaga data dasar dan indeks tetap sinkron secara otomatis
- Saat data dalam kolom berubah, indeks ikut diperbarui
- Dengan memperlakukan embedding vektor sebagai salah satu bentuk pengindeksan, kita bisa memanfaatkan sinkronisasi otomatis yang sama
- Sistem memastikan embedding vektor selalu diperbarui dengan data terbaru, menghilangkan kebutuhan pembaruan manual dan mengurangi risiko kesalahan
Hubungan data-embedding yang diperkuat
- Saat vektor disimpan secara mandiri, hubungan dengan data aslinya mudah hilang
- Apakah vektor ini dihasilkan dari pembaruan data terbaru? Atau vektor lama dari model embedding sebelumnya?
- Pertanyaan seperti ini penting, dan kebingungan di sini dapat menimbulkan kesalahan serius
- Dengan menghubungkan embedding vektor langsung ke data sebagai indeks, hubungan itu menjadi jelas dan terjaga secara otomatis
Manajemen data yang disederhanakan
- Developer sering menghadapi kesulitan saat harus mengelola sinkronisasi data secara manual
- Misalnya, jika lupa menghapus data dari model embedding lama ketika data dasarnya dihapus, inkonsistensi bisa terjadi
- Abstraksi vectorizer menjadikan pengelolaan hubungan ini sebagai tanggung jawab sistem, mengurangi beban kognitif developer dan meminimalkan kemungkinan kesalahan
Vectorizer adalah evolusi alami dari janji inti DBMS
- Konsep vectorizer adalah evolusi alami dari kapabilitas sistem manajemen database modern (DBMS)
- DBMS masa kini sudah sangat mahir mengelola transformasi dan sinkronisasi data melalui struktur deklaratif seperti indeks, trigger, dan materialized view
- Abstraksi vectorizer sangat cocok dengan paradigma ini karena menyediakan alat baru untuk menangani tugas pengelolaan embedding vektor yang kian penting
- Dengan memasukkan kemampuan ini langsung ke dalam DBMS, kita semakin dekat untuk mewujudkan janji utama sistem database
- Mengelola data dengan cara yang mengabstraksikan kompleksitas agar pengguna dapat fokus pada hal yang paling mereka kuasai: membangun aplikasi, menganalisis data, dan mendorong inovasi
Implementasi vectorizer untuk PostgreSQL: pgai Vectorizer
- Didorong oleh janji untuk meringankan beban developer, tim AI engineering Timescale telah mengimplementasikan vectorizer untuk PostgreSQL
- Namanya pgai Vectorizer dan saat ini tersedia dalam Early Access
- Ini adalah bagian dari proyek PGAI yang bertujuan membuat PostgreSQL lebih cocok untuk sistem AI dan mempermudah pengembangan AI bagi developer yang sudah familier dengan PostgreSQL
- Untuk melihat bagaimana pgai Vectorizer secara otomatis membuat dan memperbarui embedding vektor untuk data di PostgreSQL, silakan lihat video demo
Cara kerja pgai Vectorizer
- Vectorizer didefinisikan dan dibuat di SQL
- Query berikut membuat vectorizer dan menentukan tabel yang menjadi targetnya, kolom yang akan divektorkan, model embedding yang akan digunakan, serta pemformatan tambahan untuk informasi lain yang akan dimasukkan ke dalam data sumber yang di-embed
-- Membuat vectorizer yang secara otomatis meng-embed data di tabel blogs
SELECT ai.create_vectorizer(
'public.blogs'::regclass
-- Menggunakan model OpenAI text-embedding-3-small
, embedding=>ai.embedding_openai('text-embedding-3-small', 1536, api_key_name=>'OPENAI_API_KEY')
-- Membuat indeks StreamingDiskANN secara otomatis saat tabel memiliki 100k baris
, indexing => ai.indexing_diskann(min_rows => 100000, storage_layout => 'memory_optimized'),
-- Menerapkan chunking rekursif pada kolom content
, chunking=>ai.chunking_recursive_character_text_splitter('content')
-- Menambahkan metadata dari kolom lain ke embedding untuk pencarian yang lebih baik
, formatting=>ai.formatting_python_template('Blog title: $title url: $url blog chunk: $chunk')
);
-- Vectorizer memperbarui embedding saat tabel sumber berubah
-- Tidak diperlukan tindakan lain dari pengguna
- Selain itu, fungsi chunking dasar juga ditentukan karena teks panjang perlu dipecah menjadi beberapa chunk kecil agar sesuai dengan batas token model embedding
Melacak perubahan pada data sumber
- Secara internal, pgai Vectorizer memeriksa modifikasi pada tabel sumber (insert, update, delete) dan membuat serta memperbarui embedding vektor secara asinkron
- pgai Vectorizer dibangun untuk dua jenis deployment: self-hosted dan fully managed di Timescale Cloud
- Pada implementasi cloud-hosted pgai Vectorizer, pembuatan embedding memanfaatkan fungsi cloud di platform Timescale Cloud
- Pada versi open source pgai Vectorizer, worker eksternal dijalankan untuk menghasilkan embedding
- pgai Vectorizer menyimpan informasi konfigurasi dan katalog bersama data pembukuan internal penting di dalam database
Di mana embedding sebenarnya dibuat?
- Proses embedding yang sebenarnya terjadi di proses eksternal di luar database
- Ini mengurangi beban pada server database dan berarti vectorizer tidak memengaruhi kemampuan database untuk menangani query aplikasi
- Ini juga memudahkan penskalaan pekerjaan embedding secara independen dari pekerjaan database lainnya
- Proses ini mula-mula membaca database untuk memeriksa apakah ada pekerjaan yang harus dilakukan
- Jika ada, proses membaca data dari database, melakukan chunking dan formatting, memanggil penyedia model embedding seperti OpenAI untuk membuat embedding, lalu menulis hasilnya kembali ke database
Menyesuaikan proses
- pgai Vectorizer bersifat fleksibel: Anda dapat menentukan aturan chunking dan formatting yang digunakan untuk membuat embedding
- Secara khusus, Anda dapat mengatur kolom pada tabel sumber yang akan divektorkan serta aturan chunking dan formatting agar data sumber sesuai dengan batas token embedding dan data yang relevan ikut disertakan dalam setiap embedding
- Pada rilis Early Access pgai Vectorizer, pengguna dapat menyesuaikan pilihan model embedding OpenAI, strategi chunking untuk membagi teks menjadi chunk yang lebih kecil, opsi formatting untuk menyuntikkan konteks tambahan ke setiap chunk, pembuatan indeks otomatis, dan konfigurasi indexing kustom untuk tuning performa
- Ke depannya, direncanakan agar pengguna dapat mengirimkan kode Python mereka sendiri untuk menyesuaikan chunking, embedding, dan formatting sepenuhnya sehingga sistem ini menjadi lebih fleksibel lagi
Sebagai contoh, berikut adalah vectorizer yang dikonfigurasi untuk membagi file sumber HTML secara rekursif dan membuat embedding OpenAI dari data sumber. Chunking dan formatting dapat dikonfigurasi sesuai data aplikasi seperti kode, dokumentasi, Markdown, dan lainnya
-- Konfigurasi vectorizer lanjutan
SELECT ai.create_vectorizer(
'public.blogs'::regclass,
destination => 'blogs_embedding_recursive',
embedding => ai.embedding_openai('text-embedding-3-small', 1536),
-- Menerapkan chunking rekursif dengan pengaturan tertentu untuk konten HTML
chunking => ai.chunking_recursive_character_text_splitter(
'content',
chunk_size => 800,
chunk_overlap => 400,
-- Pemisah yang sadar HTML, diurutkan dari prioritas tertinggi ke terendah
separator => array[
E'
', -- Pisah di bagian dokumen utama
E'
', -- Pisah di batas div
E'
',
E'
', -- Pisah di paragraf
E'
', -- Pisah di baris baru
E'
', -- Pisah di item daftar
E'. ', -- Pengganti batas kalimat
' ' -- Jalan terakhir: pisah di spasi
]
),
formatting => ai.formatting_python_template('title: $title url: $url $chunk')
);
Pendapat GN⁺
- pgai Vectorizer tampak seperti alat yang kuat dan inovatif yang dapat sangat menyederhanakan pengelolaan embedding. Abstraksi vectorizer mengurangi beban developer untuk mengelola embedding secara manual dan memastikan embedding tetap sinkron dengan data sumber.
- Ini tampaknya sangat berguna terutama saat menerapkan perubahan seperti upgrade model embedding atau perubahan strategi chunking. Pada database vektor konvensional, perubahan semacam itu dapat memicu proses rumit yang membutuhkan penulisan dan koordinasi kode kustom di banyak sistem, tetapi dengan pgai Vectorizer Anda hanya perlu memperbarui konfigurasi vectorizer.
- Selain itu, mengelola embedding di database serbaguna seperti PostgreSQL dapat menghindari masalah karena harus mengorkestrasi banyak sistem khusus. Ini dapat sangat menyederhanakan pengembangan aplikasi.
- Satu hal yang perlu dipertimbangkan adalah bahwa embedding sebenarnya dibuat di proses Python eksternal. Ini adalah pilihan desain yang baik agar tidak memengaruhi performa database, tetapi juga berarti proses pembuatan embedding perlu dipantau dan dikelola secara terpisah.
- Pada akhirnya, pgai Vectorizer merepresentasikan kemajuan signifikan dalam cara pengelolaan embedding untuk aplikasi AI. Seiring semakin banyak tim mengadopsinya dan memberikan umpan balik, alat yang kuat ini kemungkinan akan berkembang lebih jauh. Mengintegrasikan pengelolaan embedding ke alat yang familier seperti Postgres akan memungkinkan lebih banyak developer memanfaatkan kapabilitas AI canggih.
1 komentar
Opini Hacker News
Overhead sinkronisasi data dinilai terlalu dibesar-besarkan, dan sebagian besar workflow berbasis embedding tidak banyak mengalami pembaruan atau penghapusan. Bahkan pada himpunan data kecil pun masalah konsistensi sulit dikenali. Namun, tetap keren karena tidak perlu khawatir soal sinkronisasi data
Sebagai karyawan Elastic, disebutkan bahwa Elasticsearch baru-baru ini menambahkan tipe data
semantic_text. Ini secara otomatis membagi teks menjadi chunk, menghitung embedding, lalu menyimpannya. Query juga disederhanakan sehingga I/O berkurang dan kode klien menjadi lebih sederhanaMemperkenalkan tool PostgreSQL yang membayangkan ulang vector embedding sebagai indeks database. Saat ini baru mendukung OpenAI, tetapi ada rencana segera menambahkan dukungan untuk model lokal dan OSS. Menantikan masukan dan respons
Mengajukan pertanyaan tentang penggunaan FAISS sebagai satu-satunya database. Ini seperti sqlite untuk vector embedding, dan dapat menyimpan metadata serta vektor bersama-sama untuk mempertahankan relasinya
Bersikap positif terhadap penggunaan vector di Postgres, sambil mengajukan pertanyaan tentang urutan filtering saat pencarian vector dan logika disertakan dalam query SQL. Menyukai DX pg_vector, tetapi filtering setelah pencarian vector bisa menurunkan kecepatan
Menyebut bahwa menyimpan embedding mentah di vector database mirip dengan menyimpan n-gram mentah dari teks di database. Menyimpan dokumen terasa lebih masuk akal
Menyebut sedang menggunakan sqlite-vec dan FTS5 di SQLite, dan itu sangat berguna
Membangun ORM PostgreSQL di Node.js agar bisa menulis kode yang mencakup field vector. Ini memungkinkan query terhadap data maupun konten embedding, serta mendefinisikan cara field pada model disimpan sebagai embedding
Menyebut bahwa Materialized Views itu bagus
Menyebut bahwa aplikasi AI yang memakai chunk berbasis karakter belum benar-benar melampaui tahap PoC