Skip to content

目标:把 RAG 的“检索→融合→重排→生成”标准流程讲清楚,并能跑起来。

🎯 文章目标

  • 认识标准流程与关键设计点
  • 提供最小可运行示例(Python + Node.js)
  • 给出评估维度与常见取舍

📚 背景/前置

  • 检索:BM25/向量检索/融合检索
  • 融合:RRF/加权融合;重排:交叉编码器/LLM 评分
  • 生成:引用与约束输出;支持“无依据拒答”

🔧 核心内容

1) 标准流程

  • 切分→嵌入→索引→召回→融合/重排→生成→评估→反馈
  • 关键点:切分策略、嵌入模型选择、Top-K、重排器、提示约束

2) Python 最小示例(Chroma + SentenceTransformer)

python
# pip install chromadb sentence-transformers openai
import chromadb
from sentence_transformers import SentenceTransformer
from openai import OpenAI

m = SentenceTransformer('all-MiniLM-L6-v2')
col = chromadb.Client().get_or_create_collection('kb')
col.add(ids=['1','2'], documents=['RAG 包含检索与重写','重排可用交叉编码器提升相关性'])

q = 'RAG 的关键步骤?'
# 向量检索(toy)
ctx = '\n'.join(col.query(query_texts=[q], n_results=2)['documents'][0])
cli = OpenAI()
msg = [
  {"role":"system","content":"只基于上下文回答,引用出处,若无依据请说不知道"},
  {"role":"user","content":f"上下文:\n{ctx}\n\n问题:{q}"}
]
print(cli.chat.completions.create(model='gpt-4o-mini', messages=msg).choices[0].message.content)

3) Node.js 重排示意(LLM 评分)

javascript
const passages = ['片段A','片段B','片段C']
async function rerank(q, items){
  const scored = await Promise.all(items.map(async it => {
    const s = await scoreWithLLM(q, it) // 0~1
    return { it, s }
  }))
  return scored.sort((a,b)=>b.s-a.s).map(x=>x.it)
}

4) 评估与观测

  • 维度:正确率/引用一致性、Top-K 命中率、延迟与成本
  • 方法:离线集 + 在线 A/B;记录失败样本与最慢 5%

📊 对比/取舍(速查)

  • 先把召回做稳,再谈生成“写得好”
  • 重排提升质量,但增加成本与延迟
  • 融合检索对异构语料更稳,但实现更复杂

🧪 踩坑与经验

  • 片段切分:过短丢语义,过长拖慢与引噪
  • 嵌入版本漂移:更新需回归评测
  • 引用不显式:输出不可信,需“引用+拒答规则”

📎 参考与延伸

  • RRF/融合检索,交叉编码器与 LLM 重排
  • 切分/窗口策略,RAG 评估方法

💭 总结

  • 把“检索/融合/重排/生成/评估”串起来,并用观测与闭环持续优化