0Pricing
AI Engineering Academy · Pelajaran

Arsitektur RAG: Pengindeksan dan Pengambilan

Petakan dua fase RAG: fase pengindeksan luring yang membagi, menyematkan, dan menyimpan dokumen, serta fase pengambilan daring yang menemukan konteks relevan untuk setiap kueri.

Arsitektur RAG: Pengindeksan dan Pengambilan adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.

RAG Memiliki Dua Fase yang Berbeda

Sistem RAG beroperasi dalam dua fase yang pada dasarnya berbeda dan berjalan pada waktu yang berbeda. Fase pengindeksan luring memproses dokumen Anda satu kali (atau ketika dokumen berubah) dan menyiapkan indeks yang dapat dicari. Fase pengambilan daring berjalan secara waktu nyata untuk setiap kueri pengguna. Memahami pemisahan ini sangat penting untuk merancang sistem yang cepat saat kueri diproses dan mudah dipelihara dari waktu ke waktu.

Fase Pengindeksan: Langkah Satu—Muat

Pengindeksan dimulai dengan pemuatan dokumen: membaca file mentah dari sistem sumber Anda. Dokumen dapat berupa PDF, file Word, halaman HTML, file Markdown, baris basis data, atau sumber teks apa pun. Setiap dokumen dimuat ke memori sebagai teks biasa, dengan struktur yang dipertahankan sebisa mungkin. Pustaka seperti pypdf, python-docx, dan unstructured menangani sebagian besar pekerjaan penguraian khusus format.

from pypdf import PdfReader

def load_pdf(path):
    reader = PdfReader(path)
    pages = []
    for i, page in enumerate(reader.pages):
        text = page.extract_text()
        pages.append({'text': text, 'page': i + 1, 'source': path})
    return pages

docs = load_pdf('company_policy.pdf')
print(f'Loaded {len(docs)} pages')

Fase Pengindeksan: Langkah Dua—Potong

LLM memiliki jendela konteks yang terbatas dan mengambil seluruh dokumen merupakan pemborosan. Teks yang telah dimuat dibagi menjadi potongan yang lebih kecil, masing-masing sekitar 200–1000 token. Pemotongan yang baik mempertahankan koherensi semantik: sebuah potongan seharusnya menyampaikan satu gagasan lengkap. Strategi yang umum menggunakan jendela yang saling tumpang tindih agar kalimat di dekat batas potongan muncul dalam dua potongan, sehingga mencegah hilangnya informasi pada titik pemisahan.

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # characters per chunk
    chunk_overlap=50,    # overlap between chunks
    separators=['\n\n', '\n', '. ', ' ']
)

for page in docs:
    chunks = splitter.split_text(page['text'])
    for chunk in chunks:
        # Each chunk carries metadata from its source page
        print(f'Chunk ({len(chunk)} chars): {chunk[:80]}...')

Fase Pengindeksan: Langkah Tiga—Ubah Menjadi Representasi Vektor

Setiap potongan teks diubah menjadi representasi vektor padat yang menangkap makna semantiknya secara numerik. Anda memanggil model representasi vektor—seperti OpenAI text-embedding-3-small—untuk setiap potongan dan menerima larik float berdimensi tinggi. Potongan dengan makna serupa menghasilkan vektor yang berdekatan dalam ruang berdimensi tinggi ini, dan hal inilah yang memungkinkan pencarian kemiripan semantik.

from openai import OpenAI

client = OpenAI()

def embed_chunks(chunks):
    texts = [c['text'] for c in chunks]
    response = client.embeddings.create(
        model='text-embedding-3-small',
        input=texts
    )
    for i, chunk in enumerate(chunks):
        chunk['embedding'] = response.data[i].embedding
    return chunks

# Batch up to 2048 texts per API call
embedded = embed_chunks(all_chunks)

Fase Pengindeksan: Langkah Empat—Simpan

Potongan yang telah diubah menjadi representasi vektor disimpan dalam basis data vektor bersama metadatanya (file sumber, nomor halaman, judul bagian). Penyimpanan vektor membangun struktur indeks (biasanya HNSW) yang memungkinkan pencarian tetangga terdekat secara aproksimatif dengan cepat. Indeks ini disimpan ke disk agar tetap tersedia setelah sistem dimulai ulang. Pengindeksan biasanya dilakukan sekali saat penyiapan dan secara bertahap ketika dokumen baru ditambahkan.

import pinecone

pc = pinecone.Pinecone(api_key='YOUR_KEY')
index = pc.Index('rag-documents')

# Upsert vectors with metadata
vectors_to_upsert = [
    (
        chunk['id'],
        chunk['embedding'],
        {'text': chunk['text'], 'source': chunk['source'], 'page': chunk['page']}
    )
    for chunk in embedded_chunks
]

# Upsert in batches of 100
for i in range(0, len(vectors_to_upsert), 100):
    index.upsert(vectors=vectors_to_upsert[i:i+100])
print('Indexing complete')

Fase Pengambilan: Representasi Vektor Kueri

Ketika pengguna mengirimkan kueri, fase pengambilan daring dimulai. Langkah pertama adalah mengubah pertanyaan pengguna menjadi representasi vektor menggunakan model representasi vektor yang sama dengan yang digunakan selama pengindeksan. Hal ini sangat penting: jika Anda melakukan pengindeksan dengan text-embedding-3-small, Anda juga harus melakukan kueri dengan text-embedding-3-small. Representasi vektor kueri adalah vektor yang menyandikan makna semantik dari hal yang ditanyakan pengguna.

def embed_query(question):
    response = client.embeddings.create(
        model='text-embedding-3-small',  # MUST match indexing model
        input=[question]
    )
    return response.data[0].embedding

user_question = 'What is our parental leave policy?'
query_vector = embed_query(user_question)
print(f'Query embedded: {len(query_vector)}-dim vector')

Fase Pengambilan: Pencarian ANN

Representasi vektor kueri dikirim ke penyimpanan vektor, yang melakukan pencarian tetangga terdekat secara aproksimatif (ANN) untuk menemukan K potongan yang representasi vektornya paling mirip dengan vektor kueri. Pencarian ini sangat cepat (biasanya kurang dari 10 md) karena indeks HNSW mengorbankan sedikit daya ingat demi peningkatan kecepatan yang sangat besar dibandingkan pencarian menyeluruh. Anda mengambil K potongan teratas—biasanya K=5 hingga K=20.

results = index.query(
    vector=query_vector,
    top_k=5,
    include_metadata=True
)

print(f'Retrieved {len(results.matches)} chunks:')
for match in results.matches:
    print(f'  Score: {match.score:.3f} | Source: {match.metadata["source"]}')
    print(f'  Text: {match.metadata["text"][:100]}...')
    print()

Menghubungkan Kedua Fase

Pemahaman utamanya adalah bahwa pengindeksan dan pengambilan dirancang untuk bekerja bersama. Model representasi vektor harus identik pada kedua fase, karena ruang matematis tempat vektor berada bersifat spesifik terhadap model. Jika Anda mengganti model representasi vektor, Anda harus membuat ulang indeks semua dokumen. Penyimpanan vektor menjadi penghubungnya: penyimpanan ini menerima vektor selama pengindeksan dan mengembalikan vektor selama pengambilan, sehingga kedua fase terpisah dalam waktu tetapi tetap selaras dalam ruang vektor.

Penyaringan Metadata Selama Pengambilan

Pencarian vektor menemukan potongan yang mirip secara semantik, tetapi terkadang Anda juga perlu menyaring berdasarkan metadata. Contohnya: hanya mengambil potongan dari dokumen yang diunggah pada 2025, atau hanya dari folder departemen HR. Penyimpanan vektor mendukung penyaringan awal atau penyaringan akhir pada bidang metadata. Penyaringan awal (didukung oleh Pinecone dan Qdrant) menerapkan penyaring sebelum pencarian ANN, sehingga lebih cepat dan akurat daripada penyaringan akhir pada hasil K teratas.

# Retrieve only from HR department documents
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={'department': {'$eq': 'HR'}},
    include_metadata=True
)

# Or filter by date range
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={
        'upload_year': {'$gte': 2024},
        'doc_type': {'$eq': 'policy'}
    },
    include_metadata=True
)

Pengindeksan Bertahap untuk Pembaruan

Dalam penggunaan produksi, korpus dokumen Anda berubah seiring waktu. Arsitektur pengindeksan yang efektif mendukung pembaruan bertahap: ketika dokumen diedit, hapus vektor yang ada berdasarkan ID-nya dan upsert vektor yang baru. Ketika dokumen dihapus, hapus vektornya. Tetapkan ID deterministik untuk setiap potongan berdasarkan jalur dokumen sumber dan posisi potongan agar Anda selalu dapat menemukan dan memperbarui vektor yang tepat tanpa mengindeks ulang semuanya.

import hashlib

def make_chunk_id(source_path, chunk_index):
    # Deterministic, stable ID for each chunk
    key = f'{source_path}::chunk_{chunk_index}'
    return hashlib.md5(key.encode()).hexdigest()

def update_document(source_path, index):
    # Delete old vectors for this document
    index.delete(filter={'source': source_path})
    # Re-index the updated document
    new_chunks = load_and_chunk(source_path)
    new_embedded = embed_chunks(new_chunks)
    index.upsert(vectors=new_embedded)
    print(f'Updated {source_path}: {len(new_chunks)} chunks')

Keseluruhan Pipeline RAG secara Singkat

Arsitektur RAG lengkap terlihat seperti ini: Luring: Dokumen → Pemuat → Pemotong → Model Representasi Vektor → Penyimpanan Vektor. Daring: Kueri Pengguna → Model Representasi Vektor → Penyimpanan Vektor (pencarian ANN) → Potongan K Teratas → Penyusunan Perintah → LLM → Jawaban. Pipeline luring berjalan satu kali setiap kali dokumen diperbarui. Pipeline daring berjalan dalam hitungan milidetik untuk setiap kueri pengguna, dengan LLM hanya melihat konteks yang relevan, bukan seluruh korpus dokumen.

Pemeriksaan Singkat

Uji pemahaman Anda tentang konsep Rekayasa AI dari pelajaran ini.

Rangkuman Pelajaran

Dalam pelajaran ini Anda mempelajari: fase pengindeksan luring yang terdiri dari langkah memuat, memotong, mengubah menjadi representasi vektor, dan menyimpan yang berjalan satu kali untuk setiap dokumen, fase pengambilan daring yang mengubah kueri menjadi representasi vektor, melakukan pencarian ANN, dan mengembalikan potongan K teratas dalam hitungan milidetik, serta strategi pengindeksan bertahap untuk menjaga penyimpanan vektor tetap terbaru saat dokumen berubah. Selanjutnya kita akan mempelajari cara menyusun perintah teraugmentasi yang efektif dan memanfaatkan konteks yang diambil dengan baik.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Arsitektur RAG: Pengindeksan dan Pengambilan” gratis?

Ya — teks lengkap “Arsitektur RAG: Pengindeksan dan Pengambilan” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Arsitektur RAG: Pengindeksan dan Pengambilan”?

Petakan dua fase RAG: fase pengindeksan luring yang membagi, menyematkan, dan menyimpan dokumen, serta fase pengambilan daring yang menemukan konteks relevan untuk setiap kueri. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?

Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Arsitektur RAG: Pengindeksan dan Pengambilan” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Masalah yang Diselesaikan RAG
  2. Arsitektur RAG: Pengindeksan dan Pengambilan
  3. Menyusun Perintah yang Diperkaya
  4. RAG vs Penyempurnaan: Kapan Menggunakan Masing-Masing
← Kembali ke AI Engineering Academy