Appearance
课 1 · 混合检索
本课目标
理解为什么纯向量检索在 API 名、专有名词、错误码这类问题上容易失手,并用“关键词 + 语义”组合把结果拉回正轨。课后你会拿到一个默认走混合检索的可运行 Demo。
模块 3 已经让知识库“能回答”。但真到前端项目里,你很快会遇到一个问题:
- 用户搜
useEffect - 结果却给你一段“副作用管理”的泛泛说明
- 语义相关,但不是你最想要的那条
这不是向量检索错了,而是它只擅长“语义像不像”,不擅长“这个词是不是被明确写出来了”。
为什么纯向量检索不够稳
把问题分成两类就容易理解了:
| 问题类型 | 纯向量检索表现 |
|---|---|
| 同义表达、概念解释 | 通常不错 |
| API 名、函数名、配置项、错误码 | 容易被“语义相近但不够精确”的内容挤掉 |
所以模块 4 的主线不是再堆更多名词,而是先解决一个具体问题:
让精确术语别被语义相似结果盖过去。
混合检索的直觉
做法很简单:
- 先跑一遍关键词检索,照顾术语命中
- 再跑一遍向量检索,照顾语义相似
- 把两路结果融合排序,取前几条给模型
你会看到两个常见术语:
BM25:经典关键词检索打分方法RRF:把两路排名融合到一起的常见做法
这节课只要求你知道它们各自“负责什么”,不要求记公式。
最小可运行流程
下面这个流程就是这节课的核心:
混合检索:两路召回,一次融合
用户查询
关键词检索BM25:照顾术语、API 名、错误码
向量检索Semantic Search:照顾同义表达
↓
RRF 融合排序
↓
取 TopK 文档送给模型
ts
async function hybridSearch(query: string, topK = 3) {
const keywordResults = bm25.search(query, 5)
const semanticResults = await vectorSearch(query, 5)
const fused = reciprocalRankFusion([keywordResults, semanticResults])
return fused.slice(0, topK)
}
async function answerWithHybrid(query: string) {
const docs = await hybridSearch(query, 3)
const context = docs.map((doc) => doc.content).join('\n\n---\n\n')
return generateText({
model,
system: `基于以下文档回答问题,没有相关内容时明确说明。
<documents>
${context}
</documents>`,
prompt: query,
})
}对前端工程师来说,最重要的不是把检索系统讲全,而是记住这条主线:
默认问答先用混合检索把上下文拿准。
在主线项目里怎么落
本模块能力会在基础项目 basic/project/ 中收束,当前课内 Demo 见下方运行方式。
这一版的默认问答链路已经改成:
- 默认自由提问和
/ask:走混合检索 /compare:用来直观看三种检索方式差异/rerank:保留为进阶命令,不再作为默认门槛
也就是说,主线必修只有一件事:
先把混合检索和来源意识吃透。
扩展阅读
下面这些内容本课会提到,但不放在主线里硬吃:
Rerank作用是对候选结果再做一次精排。适合你已经把主线跑顺后,再追求更高精度。HyDE作用是先改写查询,再去检索。适合短问题、表述模糊的问题,但会增加一次模型调用。
记住它们的定位就够了:增强项,不是模块 4 的默认门槛。
本课产物
- ✅ 明白纯向量检索为什么会在术语问题上失手
- ✅ 一个默认走混合检索的 RAG Demo
- ✅ 一套“关键词 + 语义一起用”的直觉框架
- ✅ 对
Rerank、HyDE的正确定位
试试看
bash
cd daqi-ai-agent
pnpm exec tsx basic/examples/04-rag-advanced/01-hybrid-search/index.ts- 用
/compare useEffect看 BM25、向量检索、混合检索的差异 - 用
/hybrid getServerSideProps看专有名词命中是否更稳 - 再用
/rerank看进阶精排会不会继续改善排序
面试追问
Q:为什么混合检索通常比纯向量检索更稳?
因为它同时覆盖了两类信号:关键词命中和语义相似。对前端项目里常见的 API 名、配置项、错误码,关键词信号很重要;对同义表达和概念问题,语义信号又很重要。两者结合,比单一路线更稳。
Q:RRF 一定要背公式吗?
不用。工程上先理解它的作用就够了:它不纠结不同检索器的分数怎么对齐,而是直接看各自的排名,再把排名靠前的结果融合起来。这对教学和实际落地都更友好。