Open In Colab GitHub Repository

Membangun RAG dengan Milvus dan EmbedAnything

EmbedAnything adalah pipeline penyisipan yang sangat cepat dan ringan yang dibangun di Rust yang mendukung teks, PDF, gambar, audio, dan banyak lagi.

Dalam tutorial ini, kami akan mendemonstrasikan cara membuat pipeline Retrieval-Augmented Generation (RAG) menggunakan EmbedAnything bersama dengan Milvus. Daripada menggabungkan secara ketat dengan basis data tertentu, EmbedAnything menggunakan sistem adaptor yang dapat dicolokkan - adaptor berfungsi sebagai pembungkus yang mendefinisikan bagaimana penyematan diformat, diindeks, dan disimpan dalam penyimpanan vektor target.

Dengan memasangkan EmbedAnything dengan adaptor Milvus, Anda dapat membuat embedding dari beragam jenis file dan menyimpannya secara efisien di Milvus hanya dalam beberapa baris kode.

⚠️ Catatan: Meskipun adaptor di EmbedAnything menangani penyisipan ke dalam Milvus, adaptor ini tidak mendukung pencarian di luar kotak. Untuk membangun pipeline RAG yang lengkap, Anda juga perlu menginstansiasi MilvusClient secara terpisah dan mengimplementasikan logika pencarian (misalnya, pencarian kemiripan vektor) sebagai bagian dari aplikasi Anda.

Persiapan

Ketergantungan dan Lingkungan

$ pip install -qU pymilvus milvus-lite openai embed_anything

Jika Anda menggunakan Google Colab, untuk mengaktifkan dependensi yang baru saja terinstal, Anda mungkin perlu memulai ulang runtime (klik menu "Runtime" di bagian atas layar, dan pilih "Restart session" dari menu tarik-turun).

Kloning Repositori dan Load Adapter

Selanjutnya, kita akan mengkloning repositori EmbedAnything dan menambahkan direktori examples/adapters ke jalur Python. Di sinilah kita menyimpan implementasi adaptor Milvus khusus, yang memungkinkan EmbedAnything berkomunikasi dengan Milvus untuk penyisipan vektor.

import sys

# Clone the EmbedAnything repository if not already cloned
![ -d "EmbedAnything" ] || git clone https://github.com/StarlightSearch/EmbedAnything.git

# Add the `examples/adapters` directory to the Python path
sys.path.append("EmbedAnything/examples/adapters")
print("✅ EmbedAnything cloned and adapter path added.")
✅ EmbedAnything cloned and adapter path added.

Kita akan menggunakan OpenAI sebagai LLM dalam pipeline RAG ini. Anda harus menyiapkan kunci api OPENAI_API_KEY sebagai variabel lingkungan.

import os
from openai import OpenAI

os.environ["OPENAI_API_KEY"] = "sk-***********"

openai_client = OpenAI()

Membangun RAG

Inisialisasi Milvus

Sebelum kita menyisipkan berkas, kita perlu menyiapkan dua komponen yang berinteraksi dengan Milvus:

  1. MilvusVectorAdapter - Ini adalah adaptor Milvus untuk EmbedAnything, dan hanya digunakan untuk konsumsi vektor (yaitu, menyisipkan penyematan dan membuat indeks). Saat ini tidak mendukung operasi pencarian.
  2. MilvusClient - Ini adalah klien resmi dari pymilvus, yang memungkinkan akses penuh ke kemampuan Milvus termasuk pencarian vektor, pemfilteran, dan manajemen koleksi.

Untuk menghindari kebingungan:

  • Anggap MilvusVectorAdapter sebagai alat "hanya-tulis" untuk menyimpan vektor.
  • Pikirkan MilvusClient sebagai mesin "baca-dan-pencarian" Anda untuk benar-benar melakukan pencarian dan mengambil dokumen untuk RAG.
import embed_anything
from embed_anything import (
    WhichModel,
    EmbeddingModel,
)
from milvus_db import MilvusVectorAdapter
from pymilvus import MilvusClient

# Official Milvus client for full operations
milvus_client = MilvusClient(uri="./milvus.db", token="")

# EmbedAnything adapter for pushing embeddings into Milvus
index_name = "embed_anything_milvus_collection"
milvus_adapter = MilvusVectorAdapter(
    uri="./milvus.db", token="", collection_name=index_name
)

# Delete existing collection if it exists
if milvus_client.has_collection(index_name):
    milvus_client.drop_collection(index_name)

# Create a new collection with dimension matching the embedding model later used
milvus_adapter.create_index(dimension=384)
Ok - Milvus DB connection established.
Collection 'embed_anything_milvus_collection' created with index.

Adapun argumen dari MilvusVectorAdapter dan MilvusClient:

  • Menetapkan uri sebagai file lokal, misalnya./milvus.db, adalah metode yang paling mudah, karena secara otomatis menggunakan Milvus Lite untuk menyimpan semua data dalam file ini.
  • Jika Anda memiliki data dalam skala besar, misalnya lebih dari satu juta vektor, Anda dapat menyiapkan server Milvus yang lebih berkinerja tinggi di Docker atau Kubernetes. Dalam pengaturan ini, gunakan alamat dan port server sebagai uri Anda, misalnyahttp://localhost:19530. Jika Anda mengaktifkan fitur autentikasi pada Milvus, gunakan ":" sebagai token, jika tidak, jangan setel token.
  • Jika Anda ingin menggunakan Zilliz Cloud, layanan cloud yang dikelola sepenuhnya untuk Milvus, sesuaikan uri dan token, yang sesuai dengan Public Endpoint dan Api key di Zilliz Cloud.

Inisialisasi Model Penyematan dan Sematkan Dokumen PDF

Sekarang kita akan menginisialisasi model penyematan. Kita akan menggunakan all-MiniLM-L12-v2 model dari pustaka pengubah kalimat, yang merupakan model yang ringan namun kuat untuk menghasilkan penyematan teks. Model ini menghasilkan penyematan 384 dimensi, jadi ini selaras dengan dimensi koleksi Milvus kita yang diatur ke 384. Penyelarasan ini sangat penting dan memastikan kompatibilitas antara dimensi vektor yang disimpan di Milvus dan yang dihasilkan oleh model.

EmbedAnything mendukung lebih banyak model penyematan. Untuk lebih jelasnya, silakan lihat dokumentasi resminya.

# Initialize the embedding model
model = EmbeddingModel.from_pretrained_hf(
    WhichModel.Bert, model_id="sentence-transformers/all-MiniLM-L12-v2"
)

Sekarang, mari kita menyematkan file PDF. EmbedAnything memudahkan untuk memproses dokumen PDF (dan banyak lagi) dan menyimpan penyematannya secara langsung di Milvus.

# Embed a PDF file
data = embed_anything.embed_file(
    "./pdf_files/WhatisMilvus.pdf",
    embedder=model,
    adapter=milvus_adapter,
)
Converted 12 embeddings for insertion.
Successfully inserted 12 embeddings.

Mengambil dan Menghasilkan Tanggapan

Sekali lagi, MilvusVectorAdapter dari EmbedAnything saat ini merupakan abstraksi ringan untuk pemasukan vektor dan pengindeksan saja. Ini tidak mendukung permintaan pencarian atau pengambilan. Oleh karena itu, untuk mencari dokumen yang relevan untuk membangun pipeline RAG kita, kita harus secara langsung menggunakan instance MilvusClient (milvus_client) untuk melakukan kueri ke penyimpanan vektor Milvus kita.

Tentukan sebuah fungsi untuk mengambil dokumen yang relevan dari Milvus.

def retrieve_documents(question, top_k=3):
    query_vector = list(
        embed_anything.embed_query([question], embedder=model)[0].embedding
    )
    search_res = milvus_client.search(
        collection_name=index_name,
        data=[query_vector],
        limit=top_k,
        output_fields=["text"],
    )
    docs = [(res["entity"]["text"], res["distance"]) for res in search_res[0]]
    return docs

Mendefinisikan fungsi untuk menghasilkan respons menggunakan dokumen yang diambil dalam pipeline RAG.

def generate_rag_response(question):
    retrieved_docs = retrieve_documents(question)
    context = "\n".join([f"Text: {doc[0]}\n" for doc in retrieved_docs])
    system_prompt = (
        "You are an AI assistant. Provide answers based on the given context."
    )
    user_prompt = f"""
    Use the following pieces of information to answer the question. If the information is not in the context, say you don't know.
    
    Context:
    {context}
    
    Question: {question}
    """
    response = openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
    )
    return response.choices[0].message.content

Mari kita uji pipeline RAG dengan sebuah contoh pertanyaan.

question = "How does Milvus search for similar documents?"
answer = generate_rag_response(question)
print(f"Question: {question}")
print(f"Answer: {answer}")
Question: How does Milvus search for similar documents?
Answer: Milvus searches for similar documents primarily through Approximate Nearest Neighbor (ANN) search, which finds the top K vectors closest to a given query vector. It also supports various other types of searches, such as filtering search under specified conditions, range search within a specified radius, hybrid search based on multiple vector fields, and keyword search based on BM25. Additionally, it can perform reranking to adjust the order of search results based on additional criteria, refining the initial ANN search results.