L
Artificial Intelligence & LLM • Literally Web ID

Membangun Sistem Retrieval-Augmented Generation (RAG) Performa Tinggi dengan Vector Database dan LLM Lokal

⏱️ 18 menit baca • 📅 19 Oct 2026 • 👁️ 5 views
Membangun Sistem Retrieval-Augmented Generation (RAG) Performa Tinggi dengan Vector Database dan LLM Lokal

Membangun Sistem Retrieval-Augmented Generation (RAG) Performa Tinggi dengan Vector Database dan LLM Lokal

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap enterprise modern, kebutuhan untuk mengintegrasikan Large Language Models (LLM) dengan data privat dan rahasia perusahaan menjadi krusial. Namun, mengirimkan data sensitif ke penyedia LLM komersial pihak ketiga (seperti OpenAI atau Anthropic) melanggar regulasi kepatuhan data yang ketat seperti GDPR, HIPAA, dan standar ISO/IEC 27001. Solusinya adalah membangun arsitektur Retrieval-Augmented Generation (RAG) secara mandiri (on-premise/self-hosted) menggunakan LLM lokal (seperti Llama 3 atau Mistral melalui Ollama/vLLM) yang dikombinasikan dengan database vektor berkinerja tinggi (seperti Qdrant atau Milvus).

Secara historis, tantangan terbesar dalam sistem RAG enterprise terletak pada latensi inferensi yang tinggi, akurasi pencarian semantik yang rendah akibat strategi chunking dokumen yang naif, serta bottleneck I/O pada infrastruktur backend web. Sebelum adopsi arsitektur RAG modern, perusahaan sering kali mengandalkan pencarian teks berbasis kata kunci (Full-Text Search seperti Elasticsearch) yang gagal menangkap konteks semantik atau hubungan makna antar dokumen internal. Setelah mengimplementasikan sistem RAG berbasis Vector Database dengan pipeline caching Redis dan reverse proxy Nginx yang dioptimalkan, latensi end-to-end dapat ditekan di bawah 800 milidetik, dengan tingkat relevansi informasi meningkat secara drastis.

2. Konsep Inti & Deep Dive Arsitektur

Arsitektur RAG lokal memadukan pencarian berbasis vektor (Vector Search) dengan generasi teks berbasis model bahasa lokal. Alur data dimulai dari ingestion dokumen, chunking, vektorisasi menggunakan model embedding, penyimpanan di vector database, hingga proses query real-time oleh klien web.

+-------------------------------------------------------------------------------------------------+
|                                    ARSITEKTUR SISTEM RAG LOKAL                                  |
+-------------------------------------------------------------------------------------------------+

 [ Client Browser / Web App ]
              |
              v (HTTPS / REST API / WebSocket)
 [ Nginx Reverse Proxy / Load Balancer ]
              |
              +-------------------------+
              |                         |
              v                         v
    [ Backend API (Go / Node) ]   [ Redis Cache (Semantic Query & Response) ]
              |
              +-------------------------+
              |
              +-----------------------------------------+
              |                                         |
              v (Vector Search)                         v (Inference API)
    [ Qdrant Vector Database ]             [ Ollama / vLLM Engine (Local LLM) ]
    (Dense Embeddings & Metadata)          (Llama 3 / Mistral 7B)

Alur eksekusi saat pengguna mengajukan pertanyaan:

  1. Kueri Masuk: Kueri dikirim dari frontend melalui API Gateway (Nginx) ke backend aplikasi.
  2. Pencarian Cache: Backend memeriksa Redis untuk melihat apakah kueri serupa pernah dijawab sebelumnya.
  3. Vector Retrieval: Jika cache miss, kueri diubah menjadi vektor embedding melalui model embedding lokal, lalu dikirim ke Qdrant untuk mencari $k$ dokumen terdekat menggunakan metrik Cosine Similarity.
  4. Context Assembly: Dokumen yang ditemukan digabungkan dengan prompt template sistem.
  5. Generation: Prompt akhir dikirim ke LLM lokal (Ollama/vLLM) untuk menghasilkan respons yang akurat berdasarkan data privat.

3. Perbandingan Komparatif / Analisis Pendekatan

Parameter Komparasi Pendekatan Tradisional (Keyword Search + LLM Cloud) Pendekatan Modern (Vector DB RAG + LLM Lokal) Dampak Infrastruktur & Operasional
Privasi & Keamanan Rendah (Data dikirim ke API pihak ketiga) Tinggi (100% On-Premise / Air-Gapped) Memenuhi standar kepatuhan industri keuangan & medis.
Latensi Rata-Rata 1.5 - 3.0 detik (Bergantung jaringan internet) 400 - 900 milidetik (Lokal network latency) Meningkatkan User Experience secara signifikan.
Biaya Operasional Berbayar per token (Pay-as-you-go, membengkak di skala besar) Fixed Cost (Investasi GPU server di awal) Lebih ekonomis untuk beban kerja tinggi jangka panjang.
Akurasi Kontekstual Sering mengalami halusinasi pada data spesifik perusahaan Tinggi berkat penyertaan dokumen referensi privat Mengurangi kesalahan informasi operasional.

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum memulai instalasi, pastikan infrastruktur server memenuhi spesifikasi minimum berikut:

  • OS: Ubuntu Server 22.04 LTS / Debian 12
  • CPU: Minimal 8 Cores
  • RAM: Minimal 32 GB (DDR4/DDR5)
  • GPU: NVIDIA GPU (Contoh: RTX 3090 / 4090 atau A10G dengan VRAM minimal 24GB)
  • Storage: 500GB NVMe SSD
  • Software: Docker Engine, Docker Compose, NVIDIA Container Toolkit, Nginx, Redis

Verifikasi instalasi NVIDIA Container Toolkit pada host:

nvidia-smi
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Konfigurasi Docker Compose untuk Seluruh Stack

Buat file docker-compose.yml untuk menjalankan Ollama, Qdrant, Redis, dan Backend API secara terpadu.

version: '3.8'

services:
  qdrant:
    image: qdrant/qdrant:v1.9.0
    container_name: qdrant_vector_db
    restart: always
    ports:
      - "6333:6333"
      - "6334:6334"
    volumes:
      - qdrant_storage:/qdrant/storage
    environment:
      - QDRANT__SERVICE__HTTP_PORT=6333

  ollama:
    image: ollama/ollama:latest
    container_name: ollama_local_llm
    restart: always
    ports:
      - "11434:11434"
    volumes:
      - ollama_storage:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

  redis:
    image: redis:7.2-alpine
    container_name: redis_cache
    restart: always
    ports:
      - "6379:6379"
    command: redis-server --save 60 1 --loglevel warning
    volumes:
      - redis_data:/data

volumes:
  qdrant_storage:
  ollama_storage:
  redis_data:

Jalankan stack menggunakan perintah:

docker compose up -d

Langkah 2: Setup Model LLM Lokal dan Embedding via Ollama

Masuk ke kontainer Ollama untuk mengunduh model bahasa dan model embedding:

docker exec -it ollama_local_llm ollama run llama3
# Setelah model terunduh, unduh juga model embedding
docker exec -it ollama_local_llm ollama pull nomic-embed-text

Langkah 3: Implementasi Backend Python (FastAPI) untuk Pipeline RAG

Buat file main.py yang menangani chunking, embedding, interaksi dengan Qdrant, dan pemanggilan Ollama.

import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
from qdrant_client import QdrantClient
from qdrant_client.http import models

app = FastAPI(title="Enterprise Local RAG API", version="1.0.0")

QDRANT_HOST = os.getenv("QDRANT_HOST", "localhost")
OLLAMA_HOST = os.getenv("OLLAMA_HOST", "http://localhost:11434")

client = QdrantClient(host=QDRANT_HOST, port=6333)

class QueryRequest(BaseModel):
    prompt: str
    collection_name: str = "enterprise_docs"

async def get_embedding(text: str):
    async with httpx.AsyncClient() as ac:
        response = await ac.post(
            f"{OLLAMA_HOST}/api/embeddings",
            json={"model": "nomic-embed-text", "prompt": text},
            timeout=30.0
        *}
        return response.json()["embedding"]

@app.post("/api/v1/rag")
async def query_rag(request: QueryRequest):
    try:
        # 1. Generate embedding dari kueri pengguna
        query_vector = await get_embedding(request.prompt)
        
        # 2. Cari dokumen relevan di Qdrant
        search_result = client.search(
            collection_name=request.collection_name,
            query_vector=query_vector,
            limit=3
        )
        
        context = "\n".join([hit.payload["text"] for hit in search_result])
        
        # 3. Susun prompt augmentasi
        augmented_prompt = f"Gunakan konteks berikut untuk menjawab pertanyaan dengan akurat:\n\nKonteks:\n{context}\n\nPertanyaan: {request.prompt}\nJawaban:"
        
        # 4. Kirim ke LLM lokal (Ollama)
        async with httpx.AsyncClient() as ac:
            llm_response = await ac.post(
                f"{OLLAMA_HOST}/api/generate",
                json={"model": "llama3", "prompt": augmented_prompt, "stream": False},
                timeout=60.0
            )
            answer = llm_response.json()["response"]
            
        return {"status": "success", "context_used": context, "answer": answer}
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

Langkah 4: Konfigurasi Nginx sebagai Reverse Proxy dan WAF Gateway

Buat file konfigurasi Nginx /etc/nginx/sites-available/rag-gateway:

upstream rag_backend {
    server 127.0.0.1:8000;
    keepalive 32;
}

server {
    listen 80;
    server_name rag.internal.enterprise.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name rag.internal.enterprise.com;

    ssl_certificate /etc/letsencrypt/live/rag.internal.enterprise.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/rag.internal.enterprise.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 50M;

    location / {
        proxy_pass http://rag_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        proxy_read_timeout 300s;
        proxy_connect_timeout 300s;
    }
}

6. Bedah Kode & Penjelasan Detail Baris Kunci

  • keepalive 32; (Nginx): Memelihara koneksi TCP tetap terbuka ke backend FastAPI, memangkas overhead pembuatan handshake koneksi berulang untuk request concurrent tinggi.
  • nomic-embed-text: Model embedding pilihan karena menghasilkan representasi vektor berdimensi 768 yang sangat padat dan dioptimalkan khusus untuk pencarian teks semantik lokal.
  • client_max_body_size 50M; (Nginx): Memastikan dokumen enterprise berukuran besar (PDF, DOCX) dapat diunggah melalui gateway tanpa memicu error HTTP 413 Payload Too Large.
  • query_vector = await get_embedding(request.prompt): Proses konversi kalimat menjadi representasi numerik multidimensi agar dapat dihitung tingkat kedekatannya (cosine distance) secara matematis di dalam Qdrant.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Pada implementasi sistem RAG di sektor perbankan dengan beban 500 concurrent requests per detik, bottleneck utama biasanya terjadi pada penggunaan VRAM GPU saat LLM melakukan token generation secara bersamaan (batched inference).

Strategi mitigasi di tingkat infrastruktur:

  1. Model Quantization: Menggunakan model Llama 3 versi ter-kuantisasi AWQ atau GGUF (4-bit atau 8-bit precision) untuk memangkas penggunaan VRAM hingga 70% tanpa penurunan akurasi yang signifikan.
  2. Horizontal Scaling Ollama / vLLM: Menjalankan beberapa instance vLLM di balik Nginx load balancer dengan algoritma least_conn untuk mendistribusikan beban inferensi ke beberapa node GPU.
  3. Semantic Caching dengan Redis: Menyimpan hasil kueri yang sering diajukan bersama embedding-nya. Jika kueri baru memiliki kemiripan kosinus > 0.95 dengan kueri di Redis, sistem langsung mengembalikan respons cache tanpa memanggil Qdrant dan LLM.

8. Common Pitfalls, Anti-Patterns & Solusi

[!WARNING] Anti-Pattern: Menggunakan ukuran chunk dokumen yang terlalu besar (misal > 2000 token) atau terlalu kecil (< 100 token).

  • Akibat: Chunk terlalu besar mengaburkan detail informasi spesifik; chunk terlalu kecil menghilangkan konteks kalimat pendukung.
  • Solusi: Gunakan teknik Recursive Character Text Splitting dengan ukuran chunk optimal antara 400 hingga 500 token serta overlap 50 token.

[!IMPORTANT] Pitfall Keamanan: Membuka port Qdrant (6333) dan Ollama (11434) secara publik ke internet tanpa autentikasi.

  • Solusi: Batasi akses hanya melalui localhost atau jaringan internal Docker bridge, serta terapkan API Key verification di layer API Gateway Nginx.

9. Benchmark, Metrik Kinerja & Tuning Performa

Pengujian beban (load testing) dilakukan menggunakan tool k6 untuk mengukur latensi dan throughput sistem RAG.

Skrip pengujian load-test.js:

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 50 },
    { duration: '1m', target: 100 },
    { duration: '30s', target: 0 },
  ],
};

export default function () {
  const url = 'https://rag.internal.enterprise.com/api/v1/rag';
  const payload = JSON.stringify({
    prompt: 'Bagaimana prosedur klaim asuransi kesehatan perusahaan?',
    collection_name: 'enterprise_docs'
  });

  const params = {
    headers: { 'Content-Type': 'application/json' },
  };

  const res = http.post(url, payload, params);
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 800ms': (r) => r.timings.duration < 800,
  });
  sleep(1);
}

Interpretasi hasil tuning parameter:

  • Jika p95 latensi melebihi 1000ms, tingkatkan jumlah worker FastAPI menggunakan Uvicorn dengan parameter --workers 4. Optimalkan indeks Qdrant dengan mengonfigurasi parameter HNSW (m=16, ef_construction=100) untuk mempercepat pencarian vektor skala besar.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum merilis sistem RAG ke lingkungan produksi, pastikan checklist berikut terpenuhi:

  • Seluruh endpoint API dilindungi HTTPS dengan SSL/TLS valid.
  • Pengaturan firewall (UFW/iptables) menutup akses langsung ke port Qdrant dan Ollama dari luar.
  • Rotasi log dan monitoring resource (CPU, RAM, VRAM GPU) aktif menggunakan Prometheus dan Grafana.
  • Kebijakan backup otomatis untuk volume data Qdrant dan Redis telah dijadwalkan via cron job.
  • Model LLM telah diuji terhadap skenario injeksi prompt (prompt injection) dan kebocoran data privat.

Dengan mengikuti arsitektur dan panduan implementasi ini, organisasi Anda dapat membangun sistem RAG lokal yang memiliki performa tinggi, latensi rendah, serta keamanan data privat tingkat enterprise yang mumpuni.

🏷️ Tags: #Nginx #Backend Architecture #Llm #Vector Database #Artificial Intelligence