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-291. Fase generate yang ditulis manual ini menggantikan chain RetrievalQA yang sudah dihapus di LangChain 1.x CHANGES.md:30-582.
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-93. Objek embeddings = OpenAIEmbeddings() dibuat sekali di level modul, lalu dipakai ulang oleh Chroma.from_documents 01_qna.py:20-224.
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.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-145. Direktori itu berisi dua contoh teks, news/result.txt dan news/summary.txt, dan README menyarankan penggantian isinya dengan korpus sendiri README.md:806.
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-177. Karena chunk_overlap bernilai nol, kalimat yang jatuh tepat di batas potongan kehilangan jembatan konteks; nilai ini titik setel pertama bila jawaban mulai terpotong.
| Tahap | Panggilan di 01_qna.py | Hasil | Rujukan |
|---|---|---|---|
| load | DirectoryLoader('news', glob="**/*.txt").load() | documents | 01_qna.py:11-145 |
| split | CharacterTextSplitter(chunk_size=2500, chunk_overlap=0) | texts | 01_qna.py:16-177 |
| embed dan index | Chroma.from_documents(texts, embeddings) | docsearch | 01_qna.py:20-224 |
| ekspos retrieval | docsearch.as_retriever() | retriever | 01_qna.py:20-224 |
Chroma.from_documents meng-embed seluruh potongan sekaligus, dan as_retriever() mengubah store itu menjadi objek yang punya method invoke 01_qna.py:20-224. 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.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-291. 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-348.
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-159. 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-1610.
| Berkas | Sumber data | Objek kunci | Cara mendapat konteks | Rujukan |
|---|---|---|---|---|
01_qna.py | news/**/*.txt | retriever dari Chroma | retriever.invoke(q) lalu konteks disisipkan ke prompt | 01_qna.py:20-224 |
03_db.py | sqlite:///academy/academy.db | SQLDatabase dan create_sql_agent | agent menyusun lalu menjalankan query SQL | 03_db.py:8-1011 |
04_csv.py | academy/academy.csv | CSVLoader dan create_csv_agent | agent mengeksekusi kode pandas atas CSV | 04_csv.py:8-1610 |
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-159. Siklus agent SQL dan CSV, termasuk pertanyaan contohnya, dibahas di Text-to-SQL dan Analitik Data.
Jebakan yang perlu dijaga
⚠️ Dataset
academytidak ikut di repository.03_db.pymemakaisqlite:///academy/academy.dbdan04_csv.pymemakaiacademy/academy.csv, keduanya disertai komentar bahwa dataset aslinya tidak tersedia untuk publik 03_db.py:8-1011, 04_csv.py:8-1610. Tanpa berkas tersebut, kedua skrip gagal sebelum saturequestpun mencapai model. Barisdburi = os.getenv("DATABASE_URL")juga dinonaktifkan danostidak diimpor di kepala berkas, jadi mengaktifkannya kembali butuhimport os03_db.py:1-159.
⚠️
04_csv.pymengaktifkanallow_dangerous_code=Truesaat membuatcreate_csv_agent. Opsi ini membolehkan agent mengeksekusi kode pandas yang disusunnya sendiri, sehingga hanya aman untuk data yang dipercaya 04_csv.py:8-1610.
⚠️
01_qna.pybergantung padaChroma, sedangkan ChromaDB memakaipydantic.v1yang gagal diimpor di Python 3.14. Catatan kompatibilitas mewajibkan Python 3.12, atau versi apa pun di bawah 3.14 CHANGES.md:62-6612. Langkah penyiapan lingkungan dan API key ada di Persiapan Lingkungan dan Konfigurasi API Key.