08. SelfQueryRetriever
Self-querying
SelfQueryRetriever
adalah alat pencarian dengan kemampuan untuk menghasilkan dan menyelesaikan pertanyaan dengan sendirinya. Alat ini mengambil pertanyaan bahasa alami yang diberikan oleh pengguna dan membuat pertanyaan terstruktur menggunakan rantai LLM yang membangun pertanyaan, lalu menerapkan pertanyaan terstruktur ini ke penyimpanan data vektor yang mendasarinya (VectorStore) untuk melakukan pencarian.
Proses ini memungkinkan SelfQueryRetriever
untuk melakukan lebih dari sekadar membandingkan kueri input pengguna secara semantik dengan konten dokumen yang disimpan; SelfQueryRetriever dapat mengekstrak filter pada metadata dokumen dari kueri pengguna dan menjalankan filter ini untuk menemukan dokumen yang relevan. Hal ini memungkinkannya memberikan hasil yang lebih akurat dan relevan untuk kueri pengguna.
Catatan
Daftar pengambil kueri mandiri yang didukung oleh LangChain https://python.langchain.com/docs/integrations/retrievers/self_query
Memulai
Kita akan menggunakan penyimpanan vektor Chroma
untuk demonstrasi kita. Untuk tutorial ini, kami telah membuat satu set kecil dokumen demo dengan ringkasan film.
Catatan: Anda perlu menginstal paket lark
untuk menggunakan SelfQueryRetriever
.
Buatlah penyimpanan vektor yang memungkinkan pencarian kemiripan berdasarkan deskripsi film dan metadata.
Gunakan kelas Document
untuk membuat dokumen, daftar objek dokumen yang berisi deskripsi singkat tentang film dan metadatanya. Buat penyematan dokumen menggunakan OpenAIEmbeddings
. Gunakan metode Chroma.from_documents
untuk membuat penyimpanan vektor Chroma, vectorstore
, dari docs
dan OpenAIEmbeddings
.
Membuat SelfQueryRetriever
Sekarang Anda dapat menginstansiasi retriever. Untuk melakukannya, kita perlu menyediakan terlebih dahulu bidang metadata yang didukung oleh dokumen dan deskripsi singkat tentang konten dokumen.
Gunakan kelas AttributeInfo
untuk mendefinisikan informasi tentang bidang metadata film
Genre (
genre
): Jenis string, menunjukkan genre film dan dapat mengambil ['fiksi ilmiah', 'komedi', 'drama', 'thriller', 'romansa', 'aksi', 'animasi'] dan memiliki salah satu nilai berikuttahun (
year
): Tipe integer, menunjukkan tahun rilis film.stradara (
director
): Tipe string, menunjukkan nama sutradara film.rating (
rating
): Tipe bilangan real, menunjukkan peringkat film dalam rentang 1-10.
Tetapkan deskripsi ringkasan singkat tentang film ke variabel document_content_description.
Gunakan metode SelfQueryRetriever.from_llm()
untuk membuat objek retriever.
llm
: model bahasavectorstore
: Penyimpanan vektordocument_content_description
: Deskripsi konten dokumenmetadata_field_info
: Informasi bidang metadata
Pengujian
Sekarang kita dapat mencoba retriever
yang telah kita buat!
Panggil metode invoke
objek retriever
untuk melakukan pencarian yang difilter.
Kami mengoper “Saya ingin menonton film dengan rating lebih tinggi dari 8,5” sebagai permintaan pencarian kami, menentukan bahwa kami ingin mencari film dengan rating 8,5 atau lebih tinggi.
Dalam kueri ini, Anda dapat melihat bahwa kami telah menggunakan filter komposit
untuk menentukan kriteria pencarian kami.
Filter komposit: peringkat di atas 8,5, fiksi ilmiah
Kueri ini juga menggunakan filter gabungan untuk menyaring hasil pencarian.
Filter gabungan: 1990 hingga 2005, pilih film tentang gedung pertunjukan, pilih film animasi
Catatan: Solusi untuk error ini ada di-akhir bagian ini
Memfilter berdasarkan faktor K
k
adalah jumlah dokumen yang akan diambil.
Anda juga dapat menggunakan SelfQueryRetriever
untuk menentukan k
. Hal ini dapat dilakukan dengan mengoper enable_limit = True
ke konstruktor.
Buat objek retriever menggunakan kelas SelfQueryRetriever
.
document_content_description
: Deskripsi konten dokumenmetadata_field_info
: Informasi bidang metadataenable_limit
: Apakah akan membatasi hasil pencarian
(Metode 1) Dalam kasus berikut, search_kwargs = {“k”: 2}
untuk secara eksplisit menentukan bahwa 2 hasil pencarian harus dikembalikan.
Namun, Anda dapat menggunakan angka seperti dua
, tiga
, dst. dalam kueri Anda untuk membatasi hasil pencarian tanpa secara eksplisit menentukan search_kwargs
dalam kode Anda.
Mari kita modifikasi sedikit kueri untuk mengembalikan hanya satu.
Mengkonfigurasi chain menggunakan LCEL
Untuk melihat apa yang terjadi di balik layar dan memiliki lebih banyak kontrol khusus, kita dapat mengkonfigurasi ulang retriever dari awal.
Pertama, kita perlu membuat query-construction chain.
Chain ini akan mengambil kueri pengguna dan membuat objek StructuredQuery yang menangkap filter yang Anda tentukan.
Membuat pembuat kueri terstruktur (query_constructor)
Gunakan fungsi get_query_constructor_prompt
untuk mendapatkan prompt konstruktor kueri.
Fungsi ini menerima
document_content_description
danmetadata_field_info
sebagai argumen.
Gunakan metode StructuredQueryOutputParser.from_components()
untuk menginisialisasi pemilah keluaran kueri terstruktur.
Buatlah
query_constructor
dengan menghubungkan prompt generator(prompt
), model bahasa (LLM
), danoutput parser
dalam sebuah pipeline.Pipeline ini akan membuat query berdasarkan prompt, memprosesnya melalui model bahasa, dan kemudian mengubahnya menjadi format terstruktur menggunakan output parser.
Mari gunakan metode prompt.format()
untuk mengoper string “pertanyaan tiruan”
ke parameter kueri dan mencetak hasilnya untuk melihat apa yang dikatakan oleh prompt.
Tujuan Anda adalah menyusun kueri pengguna agar sesuai dengan skema permintaan yang disediakan di bawah ini.
<< Skema Permintaan Terstruktur >> Saat merespons, gunakan cuplikan kode penurunan harga dengan objek JSON yang diformat dalam skema berikut ini:
String query harus hanya berisi teks yang diharapkan sesuai dengan isi dokumen. Kondisi apa pun dalam filter tidak boleh disebutkan dalam kueri.
Pernyataan kondisi logis terdiri dari satu atau lebih pernyataan perbandingan dan operasi logis.
Sebuah pernyataan perbandingan mengambil bentuk: comp(attr, val)
:
comp
(eq | ne | gt | gte | lt | lte | contain | like | in | nin): pembandingattr
(string): nama atribut yang akan digunakan sebagai pembandingval
(string): adalah nilai perbandingan
Pernyataan operasi logika berbentuk op(pernyataan1, pernyataan2, ...)
:
op
(dan | atau | tidak): operator logikapernyataan1
,pernyataan2
, ... (pernyataan perbandingan atau pernyataan operasi logika): satu atau lebih pernyataan untuk menerapkan operasi
Perlu dipastikan:
Pastikan Anda hanya menggunakan pembanding dan operator logika yang tercantum di atas dan tidak menggunakan yang lainnya.
Pastikan bahwa filter hanya mengacu pada atribut yang ada di sumber data.
Pastikan bahwa filter hanya menggunakan nama atribut dengan nama fungsinya jika ada fungsi yang diterapkan pada atribut tersebut.
Pastikan filter hanya menggunakan format
YYYY-MM-DD
ketika menangani nilai tipe data tanggal.Pastikan bahwa filter memperhitungkan deskripsi atribut dan hanya membuat perbandingan yang layak berdasarkan jenis data yang disimpan.
Pastikan bahwa filter hanya digunakan sesuai kebutuhan. Jika tidak ada filter yang harus diterapkan, kembalikan “NO_FILTER” untuk nilai filter.
Contoh 1:
Data:
User query:
Structured Request:
Contoh 2:
Data:
User query:
Structured Request:
Contoh 3:
Data:
User query:
Structured question:
Panggil metode query_constructor.invoke()
untuk melakukan pemrosesan untuk kueri yang diberikan.
Elemen kunci dari pengambil kueri mandiri adalah konstruktor kueri. Untuk membuat sistem pencarian yang hebat, Anda harus memastikan konstruktor kueri berfungsi dengan baik.
Hal ini memerlukan penyesuaian pada petunjuk, contoh di dalam petunjuk, deskripsi properti, dll.
[Catatan].
Untuk contoh yang menunjukkan proses penyempurnaan konstruktor kueri untuk data inventaris hotel, lihat https://github.com/langchain-ai/langchain/blob/master/cookbook/self_query_hotel_search.ipynb.
Mengubah structured query menggunakan Structured Query Translator
Elemen penting berikutnya adalah penerjemah kueri terstruktur, yang bertanggung jawab untuk mengonversi objek StructuredQuery
umum menjadi filter metadata yang sesuai dengan sintaks penyimpanan vektor yang Anda gunakan.
Kami mengimplementasikan pencari yang menggunakan SelfQueryRetriever
untuk menghasilkan jawaban atas pertanyaan.
Gunakan
query_constructor
untuk membuat pertanyaan.Gunakan
vectorstore
untuk mengakses penyimpanan vektor.Gunakan
ChromaTranslator
untuk menerjemahkan kueri terstruktur agar sesuai dengan penyimpanan vektor Chroma.
Hasilkan jawaban untuk pertanyaan yang diberikan menggunakan metode retriever.invoke().
Anda dapat menggunakan generator kueri terstruktur + konverter kueri ini untuk memfilter dan mengambil data tanpa kesalahan.
Last updated