RAG dengan hy4: menghubungkan model 4B ke basis pengetahuan dan pencarian vektor
RAG dengan hy4: menghubungkan model 4B ke basis pengetahuan dan pencarian vektor
Pertanyaan "apakah model 4B bisa menjalankan RAG" hanya punya jawaban jujur jika Anda memperjelas apa yang dikerjakan model 4B itu. Jawabannya: untuk tahapan ringan di sepanjang jalur, sangat cukup; untuk sintesis panjang, mudah tersandung. hy4 sangat cocok untuk peran pertama: model dense 4,22 miliar parameter, konteks native 256K, dan Q4_K_M hanya 2,6GB, sehingga berjalan di kebanyakan mesin. Artikel ini memberikan satu set lengkap: vector store lokal, embedding bge-m3, dan hy4 yang menulis ulang kueri serta menghasilkan jawaban, lengkap dengan lima kesalahan yang akan benar-benar Anda temui.
Ringkasan 30 detik
hy4 memiliki tiga peran bernilai tinggi dalam RAG: menulis ulang kueri (mengubah pertanyaan santai menjadi istilah pencarian), routing niat (memutuskan basis mana yang akan dibuka), dan menghasilkan jawaban pendek (jawaban di bawah 300 kata dari potongan yang diambil). Sintesis banyak dokumen dan penalaran multi-langkah serahkan pada model besar di cloud. Sisi vektor memakai embedding terbuka seperti bge-m3, karena katalog cloud EXAIV saat ini belum memiliki model embedding sama sekali.
Tentukan peran dulu: apa yang sebaiknya dan sebaiknya tidak dilakukan 4B
Jalur RAG memiliki setidaknya dua peran: sisi pengambilan yang "mencari materi" dan sisi generasi yang "mengatur jawaban". Keduanya menuntut hal yang sangat berbeda dari sebuah model:
| Tahap | Yang dibutuhkan dari model | Apakah hy4 cocok |
|---|---|---|
| Menulis ulang dan memperluas kueri | hanya perlu memahami pertanyaan dan menghasilkan kata kunci | sangat cocok |
| Klasifikasi niat dan routing | hanya perlu mengeluarkan satu label | sangat cocok, bahkan 0,5B pun bisa |
| Ringkasan dan ekstraksi | perlu mencakup poin utama dari sumber | cocok |
| Jawaban pendek yang berpijak | perlu setia dan tidak mengarang | cocok dengan prompt yang ketat |
| Sintesis panjang dari banyak dokumen | perlu penalaran jauh dan konsistensi | tidak cocok, pilih model besar |
| Penalaran multi-langkah | perlu langkah-langkah antara | tidak cocok |
Mengapa model kecil cocok di separuh awal jalur
Separuh awal menghasilkan teks pendek atau label, di mana kesalahan murah dan mudah diverifikasi; separuh akhir menghasilkan teks panjang, di mana kesalahan mahal dan sulit ditelusuri. Menaruh 4B di depan berarti penulisan ulang yang kurang ideal masih bisa ditopang oleh recall; menaruhnya di belakang berarti setiap kalimat karangan langsung menghadap pengguna.
Satu set lengkap yang bisa dijalankan
Langkah 1: menjalankan server inferensi lokal
./llama-server -m ./hunyuan4b/Q4_K_M.gguf \
--host 127.0.0.1 --port 8080 \
--ctx-size 32768 --jinja
Endpoint yang terbuka adalah API kompatibel OpenAI standar, dan semua kode di bawah menunjuk ke http://127.0.0.1:8080/v1.
Langkah 2: memotong dokumen
from pathlib import Path
import re
def load_docs(folder: str) -> list[str]:
chunks = []
for p in sorted(Path(folder).glob("**/*.md")):
text = p.read_text(encoding="utf-8")
sections = re.split(r"\n(?=#{1,3} )", text)
for sec in sections:
if len(sec) < 200:
continue
for i in range(0, len(sec), 1200):
piece = sec[i:i + 1200]
if len(piece.strip()) > 50:
chunks.append(sec.split("\n")[0] + "\n" + piece)
return chunks
chunks = load_docs("./docs")
print(len(chunks))
Prinsip pertama saat memotong: jangan sampai memutus satuan makna
Memotong berdasarkan jumlah karakter tetap akan membelah dua sebuah tabel atau deskripsi API, sehingga potongan yang diambil terbaca tidak utuh dan model hanya bisa menebak. Potong berdasarkan hierarki judul terlebih dahulu, baru berdasarkan panjang, dan pertahankan judul sebagai awalan untuk disambungkan kembali, karena judul adalah jangkar recall terbaik yang Anda miliki.
Langkah 3: menanamkan vektor (embedding lokal)
from sentence_transformers import SentenceTransformer
embed_model = SentenceTransformer("BAAI/bge-m3")
vectors = embed_model.encode(chunks, normalize_embeddings=True, batch_size=32)
bge-m3 adalah salah satu model embedding multibahasa terbuka yang paling banyak diunduh di komunitas, dan mendukung campuran Tiongkok-Inggris serta teks panjang.
Mengapa tidak memakai embedding di cloud
Pertama, katalog cloud EXAIV saat ini tidak memiliki model jenis embedding. Kedua, volume permintaan embedding besar tetapi nilai per permintaan kecil, sehingga membawanya ke cloud justru menjadi bagian biaya terbesar. Ketiga, model embedding hanya beberapa ratus MB hingga sedikit di atas 1GB, menjalankannya secara lokal hampir tidak menelan biaya operasional dan biasanya lebih cepat secara menyeluruh.
Langkah 4: mengingat kembali dan menyusun ulang
import numpy as np
query_vec = embed_model.encode([query], normalize_embeddings=True)[0]
scores = np.dot(vectors, query_vec)
top_idx = np.argsort(-scores)[:20]
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
pairs = [[query, chunks[i]] for i in top_idx]
rerank_scores = reranker.predict(pairs)
final_idx = [top_idx[i] for i in np.argsort(-rerank_scores)[:4]]
Penyusunan ulang adalah langkah dengan leverage tertinggi
Recall vektor adalah saringan kasar (murah, cepat, jangkauan luas), sedangkan penyusunan ulang dengan cross-encoder adalah saringan halus (lebih lambat, lebih mahal, tetapi urutannya jauh lebih akurat). Banyak sistem RAG tersandung justru di urutan recall, bukan di model generator. Mengubah top-20 menjadi top-4 yang bersih biasanya lebih efektif daripada menaikkan generator dari 4B ke 7B.
Langkah 5: menulis ulang kueri dan menghasilkan jawaban dengan hy4
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="local")
def rewrite(query: str) -> str:
r = client.chat.completions.create(
model="local-model",
messages=[
{"role": "system", "content": "Tulis ulang pertanyaan pengguna menjadi 3 frasa kata kunci untuk pencarian vektor, satu per baris, tanpa penjelasan."},
{"role": "user", "content": query},
],
temperature=0.1,
)
return r.choices[0].message.content
def answer(query: str, context_chunks: list[str]) -> str:
context = "\n\n---\n\n".join(context_chunks)
r = client.chat.completions.create(
model="local-model",
messages=[
{"role": "system", "content":
"Anda adalah asisten basis pengetahuan. Jawablah hanya dari materi yang diberikan. "
"Jika materi tidak memuatnya, nyatakan dengan jelas bahwa materi belum menyebutkannya, jangan berspekulasi. "
"Jawablah dalam 300 kata dan tandai sumber di akhir kalimat dengan [potongan N]."},
{"role": "user", "content": f"Materi:\n{context}\n\nPertanyaan: {query}"},
],
temperature=0.2,
)
return r.choices[0].message.content
rewritten = rewrite(query)
print(answer(query, [chunks[i] for i in final_idx]))
Kunci tiga ikatan dalam prompt
Jawab hanya dari materi, nyatakan ketika materi tidak memuatnya, dan sebutkan nomor potongan. Tiga baris ini menurunkan tingkat karangan model 4B secara signifikan. Model 4B tidak memutuskan sendiri apakah ia boleh mengarang, tetapi bisa diikat oleh instruksi.
Lima kesalahan yang akan Anda temui
Kesalahan satu: pemotongan memutus makna
Gejalanya adalah potongan yang diambil terbaca tidak utuh dan jawaban memuat setengah kalimat. Perbaikilah dengan memotong berdasarkan hierarki judul dan mempertahankan judul sebagai awalan, lalu memotong ulang berdasarkan batas kalimat.
Kesalahan dua: hanya recall tanpa penyusunan ulang
Gejalanya adalah dokumen yang benar berhasil diambil tetapi berada di posisi 12 dan terpotong oleh filter top-4. Perbaikilah dengan menambah jumlah recall dan menambahkan reranker, atau memakai beberapa versi penulisan ulang kueri lalu menggabungkan hasilnya.
Kesalahan tiga: prompt tanpa ikatan
Gejalanya adalah model melengkapi dengan pengetahuan latihannya dan tetap terlihat percaya diri meski materi tidak memuatnya. Perbaikilah dengan instruksi eksplisit "bilang saja bila belum ada di materi", menyebutkan nomor potongan, dan menurunkan temperature di bawah 0,2.
Kesalahan empat: menganggap recall sebagai tanya jawab
Gejalanya adalah pengguna bertanya bagaimana cara memakai sebuah fitur dan model menjawab dengan paragraf pengantar produk yang menjelaskan apa fitur itu. Perbaikilah dengan mengklasifikasikan pertanyaan lebih dulu (pencarian fakta, panduan langkah, penanganan masalah) dan memakai template prompt yang berbeda untuk setiap jenis.
Kesalahan lima: memenuhi konteksi berlebihan
Gejalanya adalah hy4 gagal menemukan kalimat kunci di tengah materi yang banyak dan mulai mengulang. hy4 memang mendukung konteks 256K secara native, tetapi bisa dimasukkan tidak berarti bisa dipakai dengan baik. Sebaiknya beri 4 hingga 8 potongan per panggilan, dan kompres lebih dulu bila lebih dari itu.
Kapan sebaiknya tidak memakai model 4B untuk generasi
| Situasi | Pilihan yang lebih baik |
|---|---|
| Perlu sintesis dari lebih dari 5 sumber | Model besar di cloud |
| Hasilnya laporan panjang atau makalah | Model besar di cloud |
| Recall buruk dan dokumen tidak pernah muncul | Perbaiki recall, jangan ganti generator |
| Tanya jawab bervolume tinggi dengan persyaratan latensi rendah | hy4 atau model ringan sejenis |
| Dokumen sumber panjang yang perlu ringkasan panjang | Model yang lebih kuat dalam konteks, atau ringkas bertingkat terlebih dahulu |
Catatan tambahan sebelum dipakai sungguhan
Tiga hal yang mudah dilupakan saat berpindah dari percobaan ke pemakaian harian:
- Simpan catatan pengukuran recall. Jalankan sekumpulan pertanyaan uji setiap kali Anda mengubah cara memotong dokumen atau menukar embedding, karena angka recall@k lah yang memberi tahu apa yang berhasil.
- Jaga potongan agar tetap bisa dilacak. Simpan judul dan jalur dokumen pada setiap potongan, sehingga jawaban yang salah bisa ditelusuri kembali ke sumbernya.
- Sediakan jalur cadangan. Untuk layanan internal, siapkan model ringan lain sebagai cadangan ketika hy4 sedang sibuk atau sedang dimuatkan ulang.
Dengan ketiganya, perjalanan dari percobaan ke pemakaian harian menjadi jauh lebih pendek.
FAQ
Apakah model 4B cukup untuk RAG?
Berapa lama konteks yang didukung hy4?
Model embedding mana yang sebaiknya dipakai?
Apakah perlu reranking?
Bagaimana cara mengurangi karangan model?
Bagaimana menghubungkan endpoint hy4 lokal ke aplikasi yang sudah ada?
Bacaan lanjutan
- Halaman model hy4 β spesifikasi, matriks quantization, dan perhitungan memori
- Catatan kanal hy4-preview β kanal konteks 1M
- Penerapan hy4 dengan GGUF β langkah lengkap agar server berjalan
- Menjalankan hy4 dengan Ollama β menghubungkan endpoint lokal ke alat pengembangan
- Open WebUI dengan Hunyuan lokal β antarmuka percakapan yang di-host sendiri
- Panduan rekayasa konteks β mengatur informasi dalam anggaran jendela
- Panduan pemilihan model embedding β bagaimana bge, gte, jina, dan e5 berbeda
- Panduan pemilihan model hy4 β ukuran dan pembagian dengan A13B
Sumber data
Angka unduhan dan spesifikasi mengikuti repositori resmi yang berlaku saat ini, disampel November 2026.