Open In Colab GitHub Repository

Retrieval-Augmented Generation (RAG) dengan Milvus dan Haystack

Panduan ini menunjukkan cara membangun sistem Retrieval-Augmented Generation (RAG) menggunakan Haystack dan Milvus.

Sistem RAG menggabungkan sistem pencarian dengan model generatif untuk menghasilkan teks baru berdasarkan prompt yang diberikan. Sistem ini pertama-tama mengambil dokumen yang relevan dari korpus menggunakan Milvus, kemudian menggunakan model generatif untuk menghasilkan teks baru berdasarkan dokumen yang telah diambil.

Haystack adalah kerangka kerja Python sumber terbuka dari deepset untuk membangun aplikasi khusus dengan model bahasa besar (LLM). Milvus adalah basis data vektor sumber terbuka tercanggih di dunia, yang dibangun untuk mendukung pencarian kesamaan embedding dan aplikasi AI.

Persyaratan

Tutorial ini memerlukan Python 3.10 atau yang lebih baru. Instal integrasi Haystack untuk Milvus bersama dengan paket PyMilvus dan Milvus Lite terbaru:

pip install --upgrade --quiet "milvus-haystack>=0.1.0" "pymilvus>=3.0.2" "milvus-lite>=3.2.2" "nltk>=3.9.1" markdown-it-py mdit_plain

Jika Anda menggunakan Google Colab, untuk mengaktifkan dependensi yang baru saja diinstal, Anda mungkin perlu me-restart runtime (klik menu “Runtime” di bagian atas layar, lalu pilih “Restart session” dari menu dropdown).

Kami akan menggunakan model dari OpenAI. Anda harus menyiapkan kunci API OPENAI_API_KEY sebagai variabel lingkungan.

import os

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

Siapkan data

Kami menggunakan konten daring tentang Leonardo Da Vinci sebagai penyimpanan pengetahuan pribadi untuk pipa RAG kami, yang merupakan sumber data yang baik untuk pipa RAG sederhana.

Unduh dan simpan sebagai berkas teks lokal.

import os
import urllib.request

url = "https://www.gutenberg.org/cache/epub/7785/pg7785.txt"
file_path = "./davinci.txt"

if not os.path.exists(file_path):
    urllib.request.urlretrieve(url, file_path)

Buat pipa pengindeksan

Buat pipa pengindeksan yang mengubah teks menjadi dokumen, memecahnya menjadi kalimat, dan menyematkannya. Dokumen-dokumen tersebut kemudian ditulis ke penyimpanan dokumen Milvus.

from haystack import Pipeline
from haystack.components.converters import MarkdownToDocument
from haystack.components.embedders import OpenAIDocumentEmbedder, OpenAITextEmbedder
from haystack.components.preprocessors import DocumentSplitter
from haystack.components.writers import DocumentWriter
from haystack.utils import Secret

from milvus_haystack import MilvusDocumentStore, MilvusEmbeddingRetriever

document_store = MilvusDocumentStore(
    collection_name="haystack_rag_demo",
    connection_args={"uri": "./milvus.db"},
    # connection_args={"uri": "http://localhost:19530"},
    # connection_args={"uri": os.environ["MILVUS_URI"], "token": Secret.from_env_var("MILVUS_TOKEN")},
    drop_old=True,
)

Untuk `connection_args`:

  • Menetapkan ` uri ` sebagai berkas lokal, misalnya `./milvus.db`, adalah metode yang paling praktis, karena secara otomatis memanfaatkan Milvus Lite untuk menyimpan semua data dalam berkas tersebut.
  • Jika Anda memiliki data dalam skala besar, Anda dapat menyiapkan server Milvus yang lebih berperforma di Docker atau Kubernetes. Dalam pengaturan ini, silakan gunakan URI server, misalnyahttp://localhost:19530, sebagai uri Anda.
  • Jika Anda ingin menggunakan Zilliz Cloud, layanan cloud yang dikelola sepenuhnya untuk Milvus, atur MILVUS_URI dan MILVUS_TOKEN ke Public Endpoint dan API key yang ditampilkan di konsol Zilliz Cloud.
indexing_pipeline = Pipeline()
indexing_pipeline.add_component("converter", MarkdownToDocument())
indexing_pipeline.add_component(
    "splitter", DocumentSplitter(split_by="sentence", split_length=2)
)
indexing_pipeline.add_component("embedder", OpenAIDocumentEmbedder())
indexing_pipeline.add_component("writer", DocumentWriter(document_store))
indexing_pipeline.connect("converter", "splitter")
indexing_pipeline.connect("splitter", "embedder")
indexing_pipeline.connect("embedder", "writer")
indexing_pipeline.run({"converter": {"sources": [file_path]}})

print("Number of documents:", document_store.count_documents())
Number of documents: 134

Buat pipa pengambilan

Buat pipa pengambilan yang mengambil dokumen dari penyimpanan dokumen Milvus menggunakan mesin pencari kesamaan vektor.

question = "Where is Leonardo's earliest dated work kept?"

retrieval_pipeline = Pipeline()
retrieval_pipeline.add_component("embedder", OpenAITextEmbedder())
retrieval_pipeline.add_component(
    "retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3)
)
retrieval_pipeline.connect("embedder.embedding", "retriever.query_embedding")

retrieval_results = retrieval_pipeline.run({"embedder": {"text": question}})

print(retrieval_results["retriever"]["documents"][0].content)
This
small picture, which has been considerably repainted, and is perhaps
by Andrea del Verrocchio, Leonardo's master, is the subject of Plate
II.

To January 1473 belongs Leonardo's earliest dated work, a pen-and-ink
drawing--"A Wide View over a Plain," now in the Uffizi. The
inscription together with the date in the top left-hand corner is
reversed, and proves a remarkable characteristic of Leonardo's
handwriting--viz., that he wrote from right to left; indeed, it has
been suggested that he did this in order to make it difficult for any
one else to read the words, which were frequently committed to paper
by the aid of peculiar abbreviations.

Leonardo continued to work in his master's studio till about 1477.

Buat pipa RAG

Buat pipa RAG yang menggabungkan MilvusEmbeddingRetriever dan OpenAIChatGenerator untuk menjawab pertanyaan menggunakan dokumen yang telah diambil.

from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage

prompt_template = [
    ChatMessage.from_user(
        """Answer the following query based on the provided context. If the context does
        not include an answer, reply with 'I don't know'.

        Query: {{query}}
        Documents:
        {% for doc in documents %}
            {{ doc.content }}
        {% endfor %}
        Answer:
        """
    )
]

rag_pipeline = Pipeline()
rag_pipeline.add_component("text_embedder", OpenAITextEmbedder())
rag_pipeline.add_component(
    "retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3)
)
rag_pipeline.add_component(
    "prompt_builder", ChatPromptBuilder(template=prompt_template)
)
rag_pipeline.add_component(
    "generator",
    OpenAIChatGenerator(
        api_key=Secret.from_env_var("OPENAI_API_KEY"),
    ),
)
rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder.prompt", "generator.messages")

results = rag_pipeline.run(
    {
        "text_embedder": {"text": question},
        "prompt_builder": {"query": question},
    }
)
print("RAG answer:", results["generator"]["replies"][0].text)
RAG answer: Leonardo's earliest dated work is kept in the Uffizi Gallery (the Uffizi).

Kesimpulan

Anda telah membangun pipa pengindeksan, pipa pencarian semantik, dan pipa RAG dengan Haystack dan Milvus. Untuk opsi integrasi lainnya, lihat berkas README milvus-haystack.

Diterjemahkan olehDeepL

Coba Milvus yang Dikelola secara Gratis

Zilliz Cloud bebas masalah, didukung oleh Milvus dan 10x lebih cepat.

Mulai
Umpan balik

Apakah halaman ini bermanfaat?