hy4 本地 RAG 实战:4B 小模型怎么接知识库与向量检索
hy4 本地 RAG 实战:4B 小模型怎么接知识库与向量检索
「用 4B 模型做 RAG 行不行」这个问题,答案取决于你让 4B 模型干什么。答案是:做检索流水线里的轻量环节,完全够用;做长文综合答案,容易翻车。混元 hy4 的定位很适合前者——42.2 亿参数稠密模型、原生 256K 上下文、Q4_K_M 只要 2.6GB,能塞进大多数机器。本文给一套完整可跑的本地方案:本地向量库 + bge-m3 embedding + hy4 做改写与生成,外加五个真实会踩的坑。
30 秒版本
hy4 在 RAG 里的三个高价值岗位:查询改写(把口语问题变成检索词)、意图路由(决定走哪个知识库)、短答案生成(基于召回片段给出 300 字以内的答案)。长文综合、多跳推理交给云端大模型。向量侧用 bge-m3 这类开源 embedding(EXAIV 云端目录暂无 embedding 模型,本地跑更省心)。
先定分工:4B 该做什么,不该做什么
RAG 流水线里至少有两个角色:检索侧的「找到材料」和生成侧的「组织答案」。这两件事对模型的要求完全不同:
| 环节 | 对模型的要求 | hy4 适合吗 |
|---|---|---|
| 查询改写 / 扩展 | 只需理解问题、产出关键词 | 很适合 |
| 意图分类 / 路由 | 只需输出一个标签 | 很适合,甚至 0.5B 都够 |
| 摘要 / 抽取 | 需要覆盖原文要点 | 适合 |
| 基于片段答短问题 | 需要忠实、不编造 | 适合,配合严格提示词 |
| 多文档综合长答案 | 需要长程推理与一致性 | 不适合,换大模型 |
| 多跳推理 | 需要中间推理步骤 | 不适合 |
为什么小模型更适合流水线前半段
前半段的输出是短文本或标签,错误成本低、可验证;后半段的输出是长文本,错误成本高、难回溯。把 4B 放在前半段,即使偶尔改写得不理想,召回还有兜底;把 4B 放在后半段,答错的每一句都会直接面向用户。
一套完整可跑的本地方案
第 1 步:起本地推理服务
./llama-server -m ./hunyuan4b/Q4_K_M.gguf \
--host 127.0.0.1 --port 8080 \
--ctx-size 32768 --jinja
暴露出来的端点是标准 OpenAI 兼容接口,下游直接用 http://127.0.0.1:8080/v1。
第 2 步:文档切分
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))
切分的第一原则:不要切断语义单元
按固定字符数硬切会把一张表格或一个 API 说明切成两半,召回回来的片段读起来是残缺的,模型只能猜。优先按标题层级切,再按长度兜底,并把标题作为前缀拼回去——标题本身就是最好的检索锚点。
第 3 步:向量化(本地 embedding)
from sentence_transformers import SentenceTransformer
embed_model = SentenceTransformer("BAAI/bge-m3")
vectors = embed_model.encode(chunks, normalize_embeddings=True, batch_size=32)
bge-m3 是目前开源社区里下载量最大的多语言 embedding 模型之一(近 30 天下载量超过 2900 万次),支持中英文混合与长文本。
为什么不用云端 embedding
第一,EXAIV 云端目录目前没有 embedding 类模型;第二,embedding 请求量大而单条便宜,走了云端反而是成本大头;第三,embedding 模型只有几百 MB 到 1GB 多,本地跑几乎没有运维负担,反而更快。
第 4 步:召回 + 重排
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]]
重排是性价比最高的一步
向量召回是粗筛(便宜、快、召回广),交叉编码器重排是精排(慢一点、贵一点、但排序准得多)。很多 RAG 系统的答案质量瓶颈不在生成模型,而在召回排序。先花力气把 top-20 精排成 top-4,往往比把 4B 换成 7B 效果更明显。
第 5 步:用 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": "把用户问题改写成 3 个用于向量检索的关键词短语,用换行分隔,不要解释。"},
{"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":
"你是知识库助手。只依据给定材料回答问题。"
"材料中没有的信息,明确回答“材料未提及”,不要推测。"
"回答控制在 300 字以内,并在句末用 [片段N] 标注依据。"},
{"role": "user", "content": f"材料:\n{context}\n\n问题:{query}"},
],
temperature=0.2,
)
return r.choices[0].message.content
rewritten = rewrite(query)
print(answer(query, [chunks[i] for i in final_idx]))
提示词里写死三条约束
「只依据材料」「没有就说没有」「标注来源」。这三条能把 4B 模型的幻觉率压下来一大截。4B 模型不会自己判断该不该编造,但可以被指令约束。
五个会踩的坑
坑一:切分把语义切断了
表现是召回片段读起来残缺,答案里出现半句话。修法是按标题层级切分并保留标题前缀,超长段落再按句子边界二次切。
坑二:只召回不重排
表现是召回了正确文档,但排在第 12 位,被 top-4 截断丢掉。修法是加大召回数并加重排,或者把召回 query 改成多个改写版本分别检索后合并。
坑三:提示词没约束
表现是模型用训练知识补全,即使材料里没有也答得很自信。修法是加「材料未提及就不答」和「标注片段编号」,并把温度降到 0.2 以下。
坑四:把检索当问答
表现是用户问「这个功能怎么用」,模型拿一段产品介绍回答了功能是什么。修法是先把用户问题归类(事实查询、操作步骤、故障排查),不同类别用不同的提示词模板。
坑五:上下文塞太满
表现是 hy4 在长材料里找不到关键句,回答开始复读。hy4 原生支持 256K 上下文,但能塞进去不等于能用好。一次给 4 到 8 个片段最稳,超出就先压缩再送。
什么时候不该用 4B 生成
| 情况 | 更好的选择 |
|---|---|
| 需要跨 5 份以上材料做综合 | 云端大模型 |
| 输出是长报告、方案书 | 云端大模型 |
| 检索质量差、召回不到材料 | 先修检索,不是换生成模型 |
| 高并发问答、要求低延迟 | hy4 这类轻量模型反而合适 |
| 材料本身是长文档、需要长文摘要 | 换长上下文更强的模型,或先分层摘要 |
FAQ
4B 模型做 RAG 够用吗?
hy4 支持多长的上下文?
embedding 用哪个模型?
需要重排吗?
怎么减少模型编造?
hy4 的本地端点怎么接进现有应用?
相关阅读
- hy4 模型页 — 规格、量化矩阵与显存估算
- hy4-preview 通道说明 — 1M 上下文通道的定位
- hy4 GGUF 本地部署实操 — 把服务跑起来的完整步骤
- hy4 Ollama 接入 — 本地端点接进开发工具
- Open WebUI 接本地混元 — 自托管聊天界面
- 上下文工程指南 — 窗口即预算的信息组织方法
- 嵌入模型选型指南 — bge / gte / jina / e5 怎么选
- hy4 选型指南 — 各尺寸与 A13B 的分工
数据来源
下载量与参数规格以官方仓库实时信息为准,采样于 2026 年 11 月。