Lewati ke konten utama

Chatbot RAG DeepSeek R1 dengan Chroma, Ollama, dan Gradio

Pelajari cara membangun chatbot RAG lokal menggunakan DeepSeek-R1 dengan Ollama, LangChain, dan Chroma.
Diperbarui 28 Sep 2026  · 12 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Retrieval-augmented generation (RAG) muncul sebagai pendekatan ampuh untuk membangun aplikasi AI yang menghasilkan jawaban yang tepat, terverifikasi, dan relevan secara kontekstual dengan mengambil serta mensintesis pengetahuan dari sumber eksternal. 

Dalam tutorial ini, saya akan menjelaskan langkah demi langkah cara membangun chatbot berbasis RAG menggunakan DeepSeek-R1 dan sebuah buku tentang fondasi LLM sebagai basis pengetahuan. Di akhir tutorial, Anda akan dapat membuat aplikasi RAG lokal yang mampu menjawab pertanyaan dari buku tersebut dan berinteraksi dengan pengguna melalui antarmuka Gradio.

Mengapa Menggunakan DeepSeek-R1 dengan RAG?

DeepSeek-R1 sangat cocok untuk sistem berbasis RAG karena kinerjanya yang dioptimalkan, kemampuan pencarian vektor tingkat lanjut, dan fleksibilitas di berbagai lingkungan, dari setup lokal hingga deployment berskala. Berikut beberapa alasan mengapa ini efektif:

  1. Pengambilan berkinerja tinggi: DeepSeek-R1 menangani koleksi dokumen besar dengan latensi rendah.
  2. Peringkat relevansi yang terperinci: Memastikan pengambilan potongan teks yang akurat dengan menghitung kemiripan semantik.
  3. Keuntungan biaya dan privasi: Anda dapat menjalankan DeepSeek-R1 secara lokal untuk menghindari biaya API dan menjaga data sensitif tetap aman.
  4. Integrasi mudah: Mudah diintegrasikan dengan basis data vektor seperti Chroma.
  5. Kemampuan offline: Dengan DeepSeek-R1 Anda dapat membangun sistem retrieval yang tetap berfungsi tanpa akses internet setelah model diunduh.

Gambaran Umum: Membangun Chatbot RAG dengan DeepSeek-R1

Proyek demo kami berfokus pada pembuatan chatbot RAG menggunakan DeepSeek-R1 dan Gradio.

RAG Chatbot pipeline

Proses dimulai dengan memuat dan membagi PDF menjadi potongan teks, lalu menghasilkan embedding untuk potongan tersebut. Embedding ini disimpan di database Chroma untuk pengambilan yang efisien. Saat pengguna mengirimkan kueri, sistem mengambil potongan teks yang paling relevan dan menggunakan DeepSeek-R1 untuk menghasilkan jawaban berdasarkan konteks yang diambil.

Langkah 1: Prasyarat

Sebelum memulai, pastikan kita telah memasang alat dan pustaka berikut:

  • Python 3.8+
  • Langchain
  • Chromadb
  • Gradio

Jalankan perintah berikut untuk memasang dependensi yang diperlukan:

!pip install langchain chromadb gradio ollama pymypdf
!pip install -U langchain-community

Setelah dependensi di atas terpasang, jalankan perintah impor berikut:

import ollama
import re
import gradio as gr
from concurrent.futures import ThreadPoolExecutor
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.embeddings import OllamaEmbeddings
from chromadb.config import Settings
from chromadb import Client
from langchain.vectorstores import Chroma

Langkah 2: Muat PDF Menggunakan PyMuPDFLoader

Kita akan menggunakan PyMuPDFLoader dari LangChain untuk mengekstrak teks dari versi PDF buku Foundations of LLMs karya Tong Xiao dan Jingbo Zhu—ini adalah buku yang sarat matematika, sehingga chatbot kita seharusnya mampu menjelaskan matematika di balik LLM dengan baik. Anda dapat menemukan bukunya di arXiv. 

# Load the document using PyMuPDFLoader
loader = PyMuPDFLoader("/path/to/Foundations_of_llms.pdf")

documents = loader.load()

Setelah dokumen dimuat, kita dapat mulai membaginya menjadi potongan-potongan untuk diproses lebih lanjut.

Langkah 3: Bagi Dokumen Menjadi Potongan Lebih Kecil

Kita akan membagi teks yang diekstrak menjadi potongan kecil yang saling tumpang tindih agar pengambilan konteks lebih baik. Anda dapat mengubah ukuran chunk dan overlap sesuai kebutuhan sistem dalam fungsi RecursiveCharacterTextSpilitter().

# Split the document into smaller chunks
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)

chunks = text_splitter.split_documents(documents)

Sekarang kita memiliki potongan teks yang siap diubah menjadi embedding.

Langkah 4: Hasilkan Embedding Menggunakan DeepSeek-R1

Kita akan menggunakan Ollama Embeddings berbasis DeepSeek-R1 untuk menghasilkan embedding dokumen. Bergantung pada ukuran dokumen, pembuatan embedding bisa memakan waktu, sehingga lebih baik diparalelkan agar lebih cepat.

Catatan: model="deepseek-r1" secara bawaan menggunakan model 7B parameter. Anda dapat mengubahnya sesuai kebutuhan ke 8B, 14B, 32B, 70B, atau 671B. Ganti X pada nama model berikut dengan ukuran model: model="deepseek-r1:X"

# Initialize Ollama embeddings using DeepSeek-R1
embedding_function = OllamaEmbeddings(model="deepseek-r1")
# Parallelize embedding generation
def generate_embedding(chunk):
    return embedding_function.embed_query(chunk.page_content)
with ThreadPoolExecutor() as executor:
    embeddings = list(executor.map(generate_embedding, chunks))

Fungsi di atas menginisialisasi DeepSeek-R1 melalui Ollama untuk menghasilkan embedding semantik berdimensi tinggi, yang nantinya digunakan untuk retrieval dokumen berbasis kemiripan.

Fungsi generate_embedding() mengambil teks potongan dokumen dan menghasilkan embedding-nya. Terakhir, ThreadPoolExecutor() menerapkan generate_embedding() ke setiap potongan secara bersamaan, mengumpulkan embedding ke dalam daftar agar pemrosesan lebih cepat dibandingkan eksekusi berurutan.

Langkah 5: Simpan Embedding di Chroma Vector Store

Kita akan menyimpan embedding dan potongan teks terkait di basis data vektor berkinerja tinggi, Chroma.

# Initialize Chroma client and create/reset the collection
client = Client(Settings())
client.delete_collection(name="foundations_of_llms")  # Delete existing collection (if any)
collection = client.create_collection(name="foundations_of_llms")
# Add documents and embeddings to Chroma
for idx, chunk in enumerate(chunks):
    collection.add(
        documents=[chunk.page_content], 
        metadatas=[{'id': idx}], 
        embeddings=[embeddings[idx]], 
        ids=[str(idx)]  # Ensure IDs are strings
    )

Kita mulai dengan mengikuti langkah-langkah berikut untuk menyimpan embedding:

1. Inisialisasi klien Chroma dan reset koleksi:

  • Client(Settings()) menginisialisasi klien Chroma untuk mengelola vector store. 
  • Hapus koleksi yang sudah ada yang serupa dengan nama koleksi Anda menggunakan client.delete_collection() untuk menghindari error. Terakhir, gunakan client.create_collection() untuk membuat koleksi baru guna menyimpan potongan dokumen dan embedding-nya.

2. Iterasi melalui potongan dokumen:

  • Lakukan iterasi pada setiap potongan dokumen dan embedding terkait menggunakan ID string uniknya.

3. Tambahkan potongan dan embedding ke Chroma:

  • Untuk setiap potongan, collection.add() menyimpan:
    • Konten dokumen (chunk.page_content)
    • Metadata ({'id': idx}) untuk mereferensikan potongan
    • Vektor embedding terkait untuk retrieval
    • String ID unik untuk mengidentifikasi entri

Pengaturan ini memastikan setiap potongan dokumen terindeks dengan benar untuk retrieval berbasis vektor yang efisien.

Langkah 6: Inisialisasi Retriever

Kita akan menginisialisasi Chroma retriever, memastikan ia menggunakan embedding DeepSeek-R1 yang sama untuk kueri.

# Initialize retriever using Ollama embeddings for queries
retriever = Chroma(collection_name="foundations_of_llms", client=client, embedding_function=embedding_function).as_retriever()

Chroma retriever terhubung ke koleksi "foundations_of_llms" dan menggunakan embedding DeepSeek-R1 melalui Ollama untuk me-embed kueri pengguna. Ia mengambil potongan dokumen yang paling relevan berdasarkan kemiripan vektor untuk respons yang sadar konteks.

Langkah 7: Definisikan pipeline RAG

Selanjutnya, kita akan mengambil potongan teks yang paling relevan dan memformatnya agar DeepSeek-R1 dapat menghasilkan jawaban.

def retrieve_context(question):
    # Retrieve relevant documents
    results = retriever.invoke(question)
    # Combine the retrieved content
    context = "\n\n".join([doc.page_content for doc in results])
    return context

Fungsi retrieve_context me-embed kueri pengguna menggunakan DeepSeek-R1 dan mengambil potongan dokumen paling relevan melalui Chroma retriever. Lalu menggabungkan konten potongan yang diambil menjadi satu string konteks untuk diproses lebih lanjut.

Langkah 8: Ajukan pertanyaan ke DeepSeek-R1 untuk jawaban kontekstual

Sekarang kita memiliki pertanyaan dan konteks yang diambil. Selanjutnya, kirimkan ke DeepSeek-R1 melalui Ollama untuk mendapatkan jawaban akhir.

def query_deepseek(question, context):
    # Format the input prompt
    formatted_prompt = f"Question: {question}\n\nContext: {context}"
    # Query DeepSeek-R1 using Ollama
    response = embedding_function.chat(
        model="deepseek-r1",
        messages=[{'role': 'user', 'content': formatted_prompt}]
    )
    # Clean and return the response
    response_content = response['message']['content']
    final_answer = re.sub(r'<think>.*?</think>', '', response_content, flags=re.DOTALL).strip()
    return final_answer

Untuk memperoleh jawaban akhir, kita mulai dengan menggabungkan pertanyaan pengguna dan konteks yang diambil ke dalam prompt terstruktur. Lalu kirimkan prompt ini ke model DeepSeek-R1 melalui Ollama untuk menerima respons. Agar keluaran akhir rapi, kita menghapus tag yang tidak perlu dan mengembalikan jawaban akhir.

Langkah 9: Bangun Antarmuka Gradio

Kita sudah memiliki pipeline RAG. Sekarang, kita akan menggunakan Gradio untuk membuat antarmuka interaktif agar pengguna dapat mengajukan pertanyaan terkait basis pengetahuannya (dalam kasus ini Foundations of LLMs).

def ask_question(question):
    # Retrieve context and generate an answer using RAG
    context = retrieve_context(question)
    answer = query_deepseek(question, context)
    return answer
# Set up the Gradio interface
interface = gr.Interface(
    fn=ask_question,
    inputs="text",
    outputs="text",
    title="RAG Chatbot: Foundations of LLMs",
    description="Ask any question about the Foundations of LLMs book. Powered by DeepSeek-R1."
)
interface.launch()

Fungsi ask_question() mengambil konteks yang relevan menggunakan Chroma retriever dan menghasilkan jawaban akhir melalui DeepSeek-R1. Antarmuka Gradio, yang dibuat dengan gr.Interface(), memungkinkan pengguna bertanya secara interaktif dan menerima jawaban yang akurat serta berbasis konteks.

Selamat! Anda kini memiliki chatbot yang berjalan secara lokal dan siap membahas apa pun terkait LLM.

Aplikasi RAG dengan DeekSeek-R1 dan Gradio

Optimasi

Demo di atas mencakup implementasi RAG yang sangat dasar, yang dapat dioptimalkan lebih lanjut untuk efisiensi. Berikut beberapa hal yang bisa dicoba:

  • Penyesuaian ukuran chunk: Atur parameter chunk_size dan chunk_overlap untuk menyeimbangkan kinerja dan kualitas retrieval.
  • Versi model yang lebih kecil: Jika DeepSeek-R1 terlalu berat sumber daya, Anda dapat menggunakan versi lain (deepseek-r1:7b atau deepseek-r1:8b atau deepseek-r1:14b) melalui Ollama.
  • Skalakan menggunakan Faiss: Untuk dokumen yang lebih besar, pertimbangkan mengintegrasikan Faiss untuk retrieval yang lebih cepat.
  • Pemrosesan batch: Jika pembuatan embedding lambat, lakukan batching pada potongan untuk meningkatkan efisiensi.

Kesimpulan

Dalam tutorial ini, kita membangun chatbot lokal berbasis RAG menggunakan DeepSeek-R1 dan Chroma untuk retrieval, yang memastikan jawaban akurat dan kaya konteks terhadap pertanyaan berdasarkan basis pengetahuan besar.

Untuk mempelajari lebih lanjut tentang DeepSeek, saya merekomendasikan blog berikut:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Saya adalah Google Developers Expert di ML (Gen AI), Kaggle 3x Expert, dan Women Techmakers Ambassador dengan pengalaman lebih dari 3 tahun di bidang teknologi. Saya ikut mendirikan startup health-tech pada 2020 dan sedang menempuh studi magister ilmu komputer di Georgia Tech dengan spesialisasi machine learning.

Topik
Kecerdasan Buatan
Large Language Models

Pelajari AI dengan kursus-kursus ini!

Kursus

Retrieval Augmented Generation (RAG) dengan LangChain

3 jam
21.3K
Pelajari metode mutakhir untuk mengintegrasikan data eksternal dengan LLM menggunakan Retrieval Augmented Generation (RAG) dengan LangChain.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

Lihat SelengkapnyaLihat Selengkapnya