Lompat ke konten
dokumentasi.id
Commit a3048a3
v1
Star929

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

5

Pipeline RAG dengan LangChain

01_qna.py menyusun satu pipeline retrieval-augmented generation utuh dalam satu berkas pendek: index dibangun sekali dari direktori news, lalu setiap pertanyaan dijawab lewat dua langkah terpisah, retriever.invoke untuk mengambil konteks dan llm.invoke untuk merangkai jawaban 01_qna.py:24-29. Fase generate yang ditulis manual ini menggantikan chain RetrievalQA yang sudah dihapus di LangChain 1.x CHANGES.md:30-58.

Fase indexing: dari berkas teks ke retriever

Empat impor di kepala berkas menentukan pustaka yang dipakai: DirectoryLoader dan TextLoader dari langchain_community.document_loaders, CharacterTextSplitter dari langchain_text_splitters, OpenAIEmbeddings beserta OpenAI dari langchain_openai, dan Chroma dari langchain_community.vectorstores 01_qna.py:1-9. Objek embeddings = OpenAIEmbeddings() dibuat sekali di level modul, lalu dipakai ulang oleh Chroma.from_documents 01_qna.py:20-22.

graph TD
  corpus["news/**/*.txt"] --> loader["DirectoryLoader<br/>glob=**/*.txt"]
  loader --> documents["documents"]
  documents --> splitter["CharacterTextSplitter<br/>chunk_size=2500"]
  splitter --> texts["texts"]
  texts --> embed["Chroma.from_documents"]
  embeddings["OpenAIEmbeddings"] --> embed
  embed --> store["docsearch"]
  store --> retriever["retriever"]
  style corpus fill:#8b5cf6,color:#fff
  style embed fill:#336791,color:#fff
  style store fill:#336791,color:#fff
  style embeddings fill:#f59e0b,color:#000
  style retriever fill:#2d7d46,color:#fff
%% fig: Fase indexing 01_qna.py
%% desc: Berkas teks di direktori news dimuat, dipotong, di-embed, dan disimpan ke Chroma sampai menghasilkan objek retriever.
Fig. 1: Fase indexing 01_qna.pyBerkas teks di direktori news dimuat, dipotong, di-embed, dan disimpan ke Chroma sampai menghasilkan objek retriever.

Loader menunjuk direktori news dengan pola **/*.txt, sehingga setiap berkas teks di bawahnya ikut termuat; versi TextLoader untuk satu berkas dibiarkan sebagai baris komentar 01_qna.py:11-14. Direktori itu berisi dua contoh teks, news/result.txt dan news/summary.txt, dan README menyarankan penggantian isinya dengan korpus sendiri README.md:80.

Pemotongan memakai CharacterTextSplitter dengan chunk_size=2500 dan chunk_overlap=0: setiap potongan berukuran maksimal 2500 karakter dan tidak ada tumpang tindih antar potongan 01_qna.py:16-17. Karena chunk_overlap bernilai nol, kalimat yang jatuh tepat di batas potongan kehilangan jembatan konteks; nilai ini titik setel pertama bila jawaban mulai terpotong.

TahapPanggilan di 01_qna.pyHasilRujukan
loadDirectoryLoader('news', glob="**/*.txt").load()documents01_qna.py:11-14
splitCharacterTextSplitter(chunk_size=2500, chunk_overlap=0)texts01_qna.py:16-17
embed dan indexChroma.from_documents(texts, embeddings)docsearch01_qna.py:20-22
ekspos retrievaldocsearch.as_retriever()retriever01_qna.py:20-22

Chroma.from_documents meng-embed seluruh potongan sekaligus, dan as_retriever() mengubah store itu menjadi objek yang punya method invoke 01_qna.py:20-22. Detail penyimpanan Chroma dan perbandingannya dengan Pinecone ada di Vector Store: Chroma Lokal dan Pinecone; mekanisme embedding-nya dibahas di Dasar LLM dan Embedding.

Siklus satu query

sequenceDiagram
  participant U as query
  participant R as retriever
  participant V as Chroma
  participant L as OpenAI
  U->>R: invoke q
  R->>V: similarity search
  V-->>R: docs
  R-->>U: docs
  U->>U: context join page_content
  U->>L: llm.invoke prompt dan context
  L-->>U: answer
  U->>U: print answer
%% fig: Siklus satu pertanyaan di 01_qna.py
%% desc: retriever mengambil dokumen relevan dari Chroma, dokumen digabung menjadi context, lalu llm.invoke menghasilkan answer.
Fig. 2: Siklus satu pertanyaan di 01_qna.pyretriever mengambil dokumen relevan dari Chroma, dokumen digabung menjadi context, lalu llm.invoke menghasilkan answer.

query(q) mencetak pertanyaan, memanggil retriever.invoke(q), menyambung doc.page_content setiap dokumen dengan pemisah dua baris baru, lalu menempelkan konteks itu ke dalam template prompt tetap 01_qna.py:24-29. Template berbunyi Use the following context to answer the question. diikuti Context:, Question:, dan Answer:, sehingga model menerima konteks dan pertanyaan dalam satu string. Fungsi itu dipanggil empat kali dengan pertanyaan tentang dampak legislasi emisi, rencana energi terbarukan Tiongkok, larangan ekspor batu bara Indonesia, dan para eksportir batu bara ke Tiongkok 01_qna.py:31-34.

Karena tidak ada chain yang menyusun prompt, seluruh tanggung jawab perakitan konteks berada di fungsi ini: jumlah dokumen yang disisipkan mengikuti default as_retriever(), dan page_content digabung tanpa penanda sumber.

Pola agent sebagai pembanding

Dua skrip lain memilih jalur berbeda: model tidak diberi konteks teks, tetapi alat yang boleh dipanggil berulang sampai jawaban terkumpul. 03_db.py membungkus SQLite lewat SQLDatabase.from_uri lalu membuat create_sql_agent dengan agent_type="openai-tools" dan verbose=True; komentar di dalamnya mencatat bahwa SQLDatabaseChain sudah deprecated di LangChain 1.x 03_db.py:1-15. Pada 04_csv.py, peran itu dipegang CSVLoader untuk membaca academy/academy.csv dan create_csv_agent dengan agent_type="openai-tools" 04_csv.py:8-16.

BerkasSumber dataObjek kunciCara mendapat konteksRujukan
01_qna.pynews/**/*.txtretriever dari Chromaretriever.invoke(q) lalu konteks disisipkan ke prompt01_qna.py:20-22
03_db.pysqlite:///academy/academy.dbSQLDatabase dan create_sql_agentagent menyusun lalu menjalankan query SQL03_db.py:8-10
04_csv.pyacademy/academy.csvCSVLoader dan create_csv_agentagent mengeksekusi kode pandas atas CSV04_csv.py:8-16

Kedua skrip agent memakai ChatOpenAI dengan temperature=0 dan model="gpt-3.5-turbo" karena openai-tools membutuhkan dukungan tool-calling 03_db.py:1-15. Siklus agent SQL dan CSV, termasuk pertanyaan contohnya, dibahas di Text-to-SQL dan Analitik Data.

Jebakan yang perlu dijaga

⚠️ Dataset academy tidak ikut di repository. 03_db.py memakai sqlite:///academy/academy.db dan 04_csv.py memakai academy/academy.csv, keduanya disertai komentar bahwa dataset aslinya tidak tersedia untuk publik 03_db.py:8-10, 04_csv.py:8-16. Tanpa berkas tersebut, kedua skrip gagal sebelum satu request pun mencapai model. Baris dburi = os.getenv("DATABASE_URL") juga dinonaktifkan dan os tidak diimpor di kepala berkas, jadi mengaktifkannya kembali butuh import os 03_db.py:1-15.

⚠️ 04_csv.py mengaktifkan allow_dangerous_code=True saat membuat create_csv_agent. Opsi ini membolehkan agent mengeksekusi kode pandas yang disusunnya sendiri, sehingga hanya aman untuk data yang dipercaya 04_csv.py:8-16.

⚠️ 01_qna.py bergantung pada Chroma, sedangkan ChromaDB memakai pydantic.v1 yang gagal diimpor di Python 3.14. Catatan kompatibilitas mewajibkan Python 3.12, atau versi apa pun di bawah 3.14 CHANGES.md:62-66. Langkah penyiapan lingkungan dan API key ada di Persiapan Lingkungan dan Konfigurasi API Key.