RAG‑Fusion dengan Reciprocal Rank Fusion (RRF) — Paduan Singkat
RAG‑Fusion menambahkan langkah re‑ranking ke pendekatan multi‑query Retrieval‑Augmented Generation. Setelah menghasilkan beberapa query…
RAG‑Fusion dengan Reciprocal Rank Fusion (RRF) — Paduan Singkat

ilustrasi bagan
RAG‑Fusion menambahkan langkah re‑ranking ke pendekatan multi‑query Retrieval‑Augmented Generation. Setelah menghasilkan beberapa query (misalnya 4 query dari model LLM), setiap query mengekstrak dokumen yang relevan. Dokumen‑dokumen tersebut kemudian di‑urutkan kembali menggunakan algoritma RRF, yang menggabungkan peringkat relatif tiap dokumen di seluruh set query menjadi satu urutan akhir yang lebih representatif.
Mengapa RRF cocok?
- Menyatukan skala skor berbeda: Query yang menghasilkan skor tinggi pada satu model tidak mengabaikan skor pada model lain.
- Meningkatkan diversitas (keragaman): Dengan menilai posisi setiap dokumen di banyak rangkaian hasil, dokumen yang konsisten di peringkat atas akan tetap dipertahankan.
- Sederhana dan efisien: Implementasinya hanya memerlukan perhitungan invers rank + penjumlahan bobot.
Alur kerja yang dapat diimplementasikan
from langchain_ollama import OllamaEmbeddings
from langchain_postgres.vectorstores import PGVector
from langchain.prompts import ChatPromptTemplate
from langchain_openai.chat_models import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
from langchain_ollama import OllamaEmbeddings
from langchain_postgres.vectorstores import PGVector
import os
default_model_name = os.environ["OPENAI_MODEL"]
pg_connection = os.environ["PGVECTOR_CONNECTION_STRING"]
llm = ChatOpenAI(model=default_model_name,temperature=0)
# embed each chunk and insert it into the vector store
embeddings_model = OllamaEmbeddings(model="nomic-embed-text")
# Coba dengan nama default
try:
db = PGVector.from_existing_index(
embedding=embeddings_model,
collection_name="langchain", # Coba default
connection=pg_connection,
)
print("Berhasil konek dengan collection 'langchain'")
except Exception as e1:
print(f"Collection 'langchain' tidak ditemukan: {e1}")
# Coba dengan nama lain yang mungkin
try:
db = PGVector.from_existing_index(
embedding=embeddings_model,
collection_name="nomic-embed-text", # Nama model
connection=pg_connection,
)
print("Berhasil konek dengan collection 'nomic-embed-text'")
except Exception as e2:
print(f"Collection 'nomic-embed-text' tidak ditemukan: {e2}")
retriever = db.as_retriever(search_kwargs={"k": 2})
#---------------------- START DISINI -------------------------------------
prompt_rag_fusion = ChatPromptTemplate.from_template("""Anda adalah asisten
yang berguna untuk menghasilkan beberapa kata kunci pencarian berdasarkan
satu pertanyaan masukan. \n
Buatlah beberapa kata kunci pencarian yang berkaitan dengan: {question} \n
Hasil (4 kueri):""")
def parse_queries_output(message):
return message.content.split('\n')
query_gen = prompt_rag_fusion | llm | parse_queries_output
def reciprocal_rank_fusion(results: list[list], k=60):
"""Reciprocal Rank Fusion (RRF) diterapkan pada beberapa daftar dokumen
yang telah diperingkat, dengan parameter opsional k yang digunakan
dalam rumus RRF.
"""
# Inisialisasi dictionary untuk menyimpan skor gabungan setiap dokumen
# Dokumen akan diindeks berdasarkan isinya untuk memastikan keunikan
fused_scores = {}
documents = {}
# Iterasi melalui setiap daftar dokumen yang telah diperingkat
for docs in results:
# Iterasi melalui setiap dokumen dalam daftar,
# beserta peringkatnya (posisi dalam daftar)
for rank, doc in enumerate(docs):
# Gunakan isi dokumen sebagai kunci untuk memastikan keunikan
doc_str = doc.page_content
# Jika dokumen belum pernah ditemukan sebelumnya,
# - inisialisasi skor ke 0
# - simpan untuk digunakan nanti
if doc_str not in fused_scores:
fused_scores[doc_str] = 0
documents[doc_str] = doc
# Perbarui skor dokumen menggunakan rumus RRF:
# 1 / (rank + k)
fused_scores[doc_str] += 1 / (rank + k)
# Urutkan dokumen berdasarkan skor gabungan secara menurun
# untuk mendapatkan hasil peringkat ulang akhir
reranked_doc_strs = sorted(
fused_scores, key=lambda d : fused_scores[d], reverse=True
)
# Ambil dokumen yang sesuai untuk setiap doc_str
return [
documents[doc_str]
for doc_str in reranked_doc_strs
]
retrieval_chain = query_gen | retriever.batch | reciprocal_rank_fusion
# Pemakaian
docs=retrieval_chain.invoke({"question":"cabe hujau?"})
print(docs)
Langkah implementasi (Python contoh)
- Generate queries — gunakan prompt + LLM seperti yang sudah ditunjukkan.
- Retrieve docs — untuk setiap query, panggil retriever (mis. FAISS, Elasticsearch) dan dapatkan top‑k dokumen.
- RRF scoring — untuk setiap dokumen, hitung skor:
score(d)=∑_i=1N1k+ranki(d)score(d)=∑i=1Nk+rank_i(d)1
di mana
kbiasanya 60 atau 1000, danrank_i(d)adalah posisi dokumendpada hasil query ke‑i. - Sort & select — urutkan dokumen berdasarkan skor total dan ambil top‑M (mis. 4‑5) untuk disampaikan ke LLM.
- Generate answer — kirim dokumen ter‑reranking ke LLM untuk menghasilkan respons akhir.
Setelah skor gabungan (fused score) dihitung, fungsi tersebut melakukan pengurutan menurun (descending) berdasarkan skor tersebut. Urutan ini kemudian menjadi daftar peringkat ulang (re‑ranking) yang dikembalikan sebagai hasil akhir.
Parameter k – Fungsi mengambil argumen k yang mengontrol seberapa besar pengaruh setiap dokumen pada peringkat akhir (ranking) terhadap hasil gabungan. Nilai k yang lebih besar memperpanjang “jangkauan” pengaruh dokumen yang berada di peringkat rendah, sehingga mereka dapat menambah kontribusi pada skor akhir. Sebaliknya, nilai k yang kecil memperkuat pengaruh hanya pada dokumen yang berada di peringkat tinggi.
Pemilihan k: Jika koleksi dokumen sangat besar dan Anda ingin memberi kesempatan pada dokumen yang lebih dalam ke peringkat akhir, gunakan nilai k yang lebih tinggi (mis. 100‑1000). Jika Anda ingin fokus pada hasil paling relevan, pilih k yang lebih rendah (mis. 10‑50).
Tips praktis
- Parameter
k: Nilai yang lebih kecil memberi bobot lebih besar pada peringkat pertama; coba rentang 40‑100 untuk hasil yang lebih stabil. - Jumlah query: Menambah query (mis. 6‑8) dapat meningkatkan diversitas, tetapi juga menambah latensi.
- Cache hasil retrieval: Simpan hasil pencarian per query agar tidak dihitung ulang setiap kali di‑rerank.
- Evaluasi: Gunakan metric seperti MRR atau recall pada validation set untuk menyesuaikan jumlah query,
k, dantop‑M.
Dengan menambahkan langkah RRF, sistem RAG‑Fusion tidak hanya mengumpulkan informasi dari banyak perspektif, tetapi juga menyortir hasil tersebut secara yang lebih “holistik”, menghasilkan jawaban yang relevan dan terinformasi.
Sumur : Learning Langchain oleh by Mayo Oshin, Nuno Campos Ditingkatkan dengan: nvidia / Nemotron 3 Nano 30B A3B
메타데이터
- post_id
- 99868e491ff7
- slug
- rag-fusion-dengan-reciprocal-rank-fusion-rrf-paduan-singkat-99868e491ff7
- url
- https://medium.com/@pbseven/rag-fusion-dengan-reciprocal-rank-fusion-rrf-paduan-singkat-99868e491ff7
- canonical_url
- https://medium.com/@pbseven/rag-fusion-dengan-reciprocal-rank-fusion-rrf-paduan-singkat-99868e491ff7
- author_url
- https://medium.com/@pbseven
- status
- ok
- fetched_at
- 2026-07-14 01:45:45