检索算法与微调
Q:Embedding 和 ReRank 模型具体怎么做的微调?
来源:腾讯 AI 应用开发 【腾讯AI应用开发一面追问:重排序完整实现流程】
新手答:“用自己的数据训练一下。”
高手答:
Embedding 模型微调:
目标是让模型在业务领域里,把语义相近的 query 和文档映射到向量空间中的相近位置。
训练数据格式:(query, positive_doc, negative_doc) 三元组。hard negative 越难越好——随机采样的 negative 太简单,模型学不到有区分度的表示。用 BM25 或当前模型 top-K 中的非相关文档做 hard negative。
常用 loss:
- MultipleNegativesRankingLoss(sentence-transformers 最常用):batch 内其他 query 的 positive 自动作为 negative,不需显式构造
- InfoNCE / Contrastive Loss:拉近 positive pair,推远 negative pair
- Triplet Loss:
max(0, d(q, pos) - d(q, neg) + margin)
框架:sentence-transformers 最成熟,支持 BGE、E5、GTE 等预训练模型的微调。
ReRank 模型微调:
ReRank 是 Cross-Encoder——输入是 (query, doc) 拼接后一起过模型,输出相关性分数。比 Embedding 双塔精度高,但计算量大,只用于精排。
训练数据:(query, doc, label),label 是相关性分数或 0/1 标签。Loss 用 BCE 或 MSE。
微调关键细节:
- Hard Negative Mining:negative 质量决定微调效果
- 评估指标:用 Recall@K、MRR、NDCG 在验证集上评估,不是看 loss 降了就行
- 防止过拟合:微调轮数不宜过多(1-3 epoch),否则通用检索能力退化
差距在哪:新手只说了“用数据训”。高手覆盖了完整链路——数据构造(三元组 + hard negative)、loss 选择、框架、评估、防过拟合。面试官考的是你有没有真正微调过检索模型。
Q:RAG 系统检索到的文档很多但回答质量差,怎么排查?
来源:携程 Agent 开发实习一面
新手答:“可能是模型不够好,换个更强的模型。”
高手答:
“检索多但回答差”说明问题大概率不在模型,而在检索质量和上下文组装。排查按链路从前到后逐段定位:
1. 检索相关性差(召回了但不准):
- 症状:返回的文档和用户问题表面相关但实际不对口
- 排查:抽样看 top-K 文档和 query 的匹配度,计算 Recall@K / Precision@K
- 常见原因 + 解法:
- Embedding 模型领域适配差 → 用业务数据微调 Embedding
- Chunk 切分不合理(太大导致噪声多,太小导致上下文断裂)→ 调整 chunk size 和 overlap
- 缺少多路召回 → 加 BM25 关键词路补充精确匹配
2. 排序失效(相关文档排在后面):
- 症状:相关文档确实被召回了,但排在第 8、9 位,top-3 都是噪声
- 排查:对比有无 ReRank 时的排序效果
- 解法:加 Cross-Encoder ReRank 模型做精排;或微调 ReRank 模型
3. 上下文组装问题(给模型的信息太杂):
- 症状:top-K 文档质量还行,但模型回答仍然差
- 排查:直接看拼给模型的 context,是不是信息太多、互相矛盾、或关键信息被淹没
- 解法:减少 top-K(从 10 降到 3-5);对召回文档做摘要提取再喂给模型;加冲突检测
4. Prompt 模板问题:
- 症状:换了更好的检索结果,回答质量还是没提升
- 排查:检查 Prompt 是否清晰指示模型“基于以下资料回答,如果资料不足请说明”
- 解法:优化 Prompt 模板,加引用约束
差距在哪:新手第一反应是“换模型”——这是最贵且通常无效的做法。高手按 RAG 链路逐段排查(检索 → 排序 → 组装 → Prompt),每段都有具体的症状、排查方法和解法。面试官考的是你排查问题时的系统性思维。
Q:什么是嵌入(Embedding)?为什么 RAG 系统需要将文本转为向量?
来源:携程 Agent 开发实习一面
新手答:“把文本变成数字,方便计算。”
高手答:
嵌入(Embedding)是把文本映射到一个高维向量空间中的过程——每段文本变成一个固定长度的数字数组(如 768 维或 1536 维),这个数组就叫这段文本的“向量表示”。
关键特性:语义相近的文本,在向量空间中的位置也相近。
"北京今天天气很好" → [0.12, -0.45, 0.78, ...] ─┐
"今日北京晴朗" → [0.11, -0.43, 0.76, ...] ─┘ 向量接近
"明天股市走势如何" → [-0.67, 0.23, -0.11, ...] ← 向量远离为什么 RAG 需要向量化:
传统检索靠关键词匹配——用户搜“怎么退货”,系统只能找到包含“退货”两个字的文档。但用户可能问的是“买错了怎么办”“商品不满意能换吗”——意思一样,但没有一个共同关键词。
向量化解决的是语义匹配问题——“怎么退货”和“商品不满意能换吗”的 Embedding 向量很接近,即使没有共同关键词也能检索到。
Embedding 模型的选型考量:
- 通用模型:OpenAI text-embedding-3、BGE、E5、GTE——开箱即用,适合大部分场景
- 领域微调:如果业务术语多(医疗、法律、金融),通用模型可能把业务术语和日常用语混淆,需要用业务数据做微调
- 维度和性能的权衡:维度越高表达力越强,但存储和计算成本也越高。768 维是常见平衡点
差距在哪:新手的”变成数字”没有解释为什么要这么做。高手从语义匹配的角度解释了向量化的动机——解决关键词匹配的语义鸿沟问题,且覆盖了模型选型的实际考量。面试官考的是你理不理解 Embedding 在 RAG 管线中的核心作用。
追问:Embedding 的本质是什么?向量的每个维度代表什么含义?
来源:小红书 AI应用开发
Embedding 的本质是将离散符号映射到连续向量空间,使语义关系可以用几何距离衡量。但很多人会追问:向量的每个维度到底是什么意思?
每个维度不是一个可解释的特征——这是 Embedding 和传统特征工程的根本区别:
| 对比 | 传统特征向量 | Embedding 向量 |
|---|---|---|
| 每个维度 | 有明确含义(年龄、价格、频率) | 无单一可解释含义 |
| 表示方式 | 人工设计的特征 | 模型自动学到的潜在特征 |
| 信息分布 | 每维独立编码一种信息 | 一种语义分布在多个维度上 |
| 术语 | 特征工程 | 分布式表示(Distributed Representation) |
什么是分布式表示:一个语义概念(如”食物”)不是由某一个维度单独表达,而是由多个维度的组合模式来表达。反过来,一个维度也参与了多个语义概念的编码。这就是为什么单看某一维的数值没有意义,但整体向量之间的距离能反映语义相似性。
维度数量的工程权衡:
低维(256-384):存储小、速度快,但语义区分度有限,适合简单场景
中维(768): 最常见的平衡点,大多数场景够用
高维(1024-3072):区分度更高,能捕获更细粒度的语义差异,但存储和计算成本线性增长面试加分点:如果面试官继续追问”能不能让每个维度可解释”,可以提到 Sparse Embedding(如 SPLADE)——它在词表维度上做稀疏编码,每个维度对应一个 token,可解释性强但维度极高(30000+)。这也是为什么实际系统常用 Dense + Sparse 混合检索——Dense 捕获语义,Sparse 保留精确匹配能力。
Q:双路召回的 TopK,K 是如何确定的?有没有试过一个多召回点、一个少召回点?
来源:腾讯 AI 应用开发
新手答:“K 就取 10 或 20。”
高手答:
K 值要根据召回路的特性和下游精排的承载能力来定。
BM25 关键词召回:K = 10~20(精确匹配路,召回量不需要太大)
Embedding 向量召回:K = 20~50(语义路,覆盖面要大一些)
ReRank 精排后最终 TopK:K = 3~5(给模型的上下文不宜太多)K 值调优方法:Grid Search 在评估集上搜索最优组合——固定一路 K,遍历另一路(5、10、20、30、50),合并去重后精排,用 Recall@K 和最终生成质量评判。
一多一少的策略:实际中确实会对不同路设不同 K:
- 向量路 K 大、BM25 路 K 小:向量覆盖面广但精度稍低,多召回交给 ReRank 筛;BM25 精确率高,少量就够
- 反过来也有场景:精确查询(订单号、型号)时 BM25 路 K 调大
关键权衡:K 越大覆盖率越高但噪声也多(ReRank 负担重、延迟增加);K 越小精度高但可能漏掉相关文档。生产环境通常还有延迟约束(“总检索时间不超过 200ms”),K 值要在 Recall 和延迟之间找平衡。
差距在哪:新手随便定一个 K。高手有系统的调优方法论——Grid Search + 不同路不同 K + 延迟约束。面试官考的是你调 RAG 参数时有没有数据驱动的方法。
Q:如何用通俗易懂的方式向非技术人员解释 RAG?有没有好的类比?
来源:携程 Agent 开发实习一面
新手答:“就是让模型先搜索再回答。”
高手答:
给非技术同事解释 RAG,我会这么说:
一句话版本:RAG 就是让 AI 在回答问题之前,先去翻资料,而不是纯靠记忆回答。
图书馆类比(最直观):
核心价值(三点):
- 知识实时性:模型训练数据有截止日期,但外部知识库可以随时更新——今天新上线的产品文档,明天就能被检索到
- 可追溯性:回答附带引用来源,用户可以点击查看原文,建立信任
- 降低幻觉:有资料做依据,模型不容易“编”答案
主要应用场景:企业知识库问答(内部文档/FAQ)、客服系统(产品手册检索)、法律/医疗等需要精确引用的领域、代码文档助手。
差距在哪:新手的解释太技术化,非技术人员听不懂。高手用图书馆类比把 RAG 的三个角色(用户 → 检索员 → 专家)讲清楚了,再用三点核心价值说明“为什么需要”。面试官考的不只是你懂不懂 RAG,还考你能不能把复杂概念讲给不同背景的人听——这是工程师的沟通能力。
Q:如何快速上手一个没接触过的技术(如向量数据库)?
来源:携程 Agent 开发实习一面
新手答:“看官方文档,跑个 Demo。”
高手答:
快速上手一个新技术,我的方法论是**“倒金字塔学习法”——从应用场景倒推,不从底层原理开始**:
第一步:搞清楚“它解决什么问题”(30 分钟)
不是先看原理,而是先理解:传统方案的痛点是什么?向量数据库比传统数据库多解决了什么?答案是——传统数据库只能精确匹配,而向量数据库能做语义相似度检索。这一步决定了你后面学的所有东西有没有方向感。
第二步:跑通一个最小可用的 Demo(2-3 小时)
选一个主流方案(如 Milvus / Qdrant / Chroma),跑通“文本 → Embedding → 入库 → 查询 → 返回结果”的最短路径。不要一开始就研究分布式部署、索引类型选择这些细节。
# 最小 Demo:Chroma
import chromadb
client = chromadb.Client()
collection = client.create_collection("demo")
collection.add(documents=["北京今天晴天", "上海明天下雨"], ids=["1", "2"])
results = collection.query(query_texts=["天气怎么样"], n_results=1)第三步:对标项目需求,补齐关键知识点(1-2 天)
Demo 跑通后,对照项目需求列一个清单:需要什么索引类型(HNSW / IVF)?数据量级多大?需不需要过滤?需不需要持久化?然后按需深入,不铺开学。
第四步:踩坑 → 查 Issue → 形成经验(持续)
真正的理解来自踩坑。遇到问题先查 GitHub Issue 和社区讨论,很多坑别人已经踩过了。
差距在哪:新手的“看文档跑 Demo”没有方法论,容易在原理细节里迷失方向。高手的倒金字塔方法有明确的四步节奏——先理解价值、再跑通最短路径、再按需深入、最后靠实践沉淀。面试官考的是你的学习效率和自驱能力。
Q:什么是余弦相似度?在 RAG 系统中用来做什么?
来源:携程 Agent 开发实习一面
新手答:“衡量两个向量的相似程度。”
高手答:
余弦相似度衡量的是两个向量方向的接近程度,不关心长度,只关心角度:
cos(A, B) = (A · B) / (|A| × |B|)
值域:[-1, 1]
1 = 方向完全一致(语义最相似)
0 = 正交(语义无关)
-1 = 方向完全相反(语义相反)为什么用余弦而不是欧氏距离:
Embedding 模型输出的向量,不同文本的向量长度(模)可能差异很大。如果用欧氏距离,一段长文本和一段短文本即使语义相同,距离也可能很远(因为向量模不同)。余弦相似度归一化了长度,只比较方向——语义相同的文本,无论长短,余弦相似度都接近 1。
在 RAG 系统中的用途:
- 检索阶段:用户 query 向量和文档库中所有文档向量计算余弦相似度,取 top-K 作为候选
- 去重阶段:两个 chunk 的余弦相似度 > 0.95,判定为近重复,去掉一个
- 阈值过滤:相似度低于阈值(如 0.6)的文档直接丢弃,不进入精排——避免把完全不相关的文档喂给模型
补充:实际向量数据库(Milvus / Qdrant)在 ANN 检索时用的是近似最近邻算法(HNSW / IVF),不是暴力遍历所有向量。精确的余弦计算只在小规模候选集上做。
差距在哪:新手只背了定义。高手从公式、为什么选余弦而非欧氏、在 RAG 中的三个具体用途(检索/去重/过滤)做了完整解释,且补充了工程实现细节。面试官考的是你理解了这个指标的设计动机,而不只是会算。
Q:RAG 中如何提高文档召回率?
来源:蚂蚁集团智能体与大模型应用一面
新手答:“换更好的 Embedding 模型。”
高手答:
召回率低意味着正确文档没有进入候选集——模型连看到正确答案的机会都没有。提升召回率要从离线和在线两端同时入手:
离线端——提升文档的“可被检索性”:
- Chunk 策略优化:
- 块太大 → 一个 chunk 混了多个主题,语义被平均化,精准匹配变弱
- 块太小 → 上下文断裂,语义不完整
- 最佳实践:语义分块(按段落/标题/逻辑边界切割)+ overlap(相邻 chunk 重叠 10-20%)
- 文档增强:给每个 chunk 附加元信息——标题、所属章节、关键词标签、生成摘要。检索时不只匹配 chunk 正文,还匹配元信息
- Embedding 模型适配:通用模型在专业领域(医疗/法律/代码)的表现可能大幅下降。用业务数据微调 Embedding 模型,Recall 通常能提升 10-20%
在线端——提升查询的“被理解度”:
- 查询改写:用大模型对用户 query 做多维度改写(同义替换、意图展开、实体补全),从不同角度匹配文档
- 混合召回:不只用向量检索,同时用 BM25 关键词检索 + 标签检索,多路结果合并。向量路抓语义,关键词路抓精确匹配,互补覆盖
- HyDE(Hypothetical Document Embeddings):让模型先生成一个“假设性答案”,用这个答案的 embedding 去检索——因为答案和文档的语义更接近,比直接用 query 检索效果好
效果最大的三板斧:根据实践经验,混合召回 > chunk 优化 > Embedding 微调。很多团队一上来就微调模型,其实先加一路 BM25 召回就能显著提升 Recall。
差距在哪:新手只想到换模型。高手从离线端(chunk/文档增强/Embedding 微调)和在线端(查询改写/混合召回/HyDE)六个方向给出了完整方案,且点出了优先级排序。面试官考的不是你知不知道某个技术,而是你能不能系统性地优化一条 RAG 管线。
Q:RAG 为什么需要向量检索?和传统关键词检索有什么本质区别?
来源:蚂蚁集团智能体与大模型应用一面
新手答:“向量检索更准。”
高手答:
不是“更准”——是解决了不同的问题。传统检索和向量检索的核心差异在于匹配方式:
| 维度 | 传统关键词检索(BM25) | 向量检索(Embedding) |
|---|---|---|
| 匹配方式 | 词级精确匹配 | 语义级相似度匹配 |
| 核心算法 | TF-IDF / BM25 | ANN(近似最近邻) |
| 能处理同义词 | ❌ “退货”搜不到“退款” | ✅ 语义相近就能匹配 |
| 能处理精确术语 | ✅ 搜“order_id=123”直接命中 | ❌ 向量化后精确性丢失 |
| 计算成本 | 低(倒排索引,O(1)级) | 高(向量距离计算 + ANN 索引) |
| 索引存储 | 小(倒排表) | 大(每条文档一个高维向量) |
| 对新词/专业术语 | 好(只要文档里有就能匹配) | 差(模型没见过的词 embedding 质量低) |
RAG 为什么需要向量检索:
用户提问的方式和文档的表述方式几乎不可能完全一样。用户问“服务器老是挂”,文档里写的是“服务可用性异常”——没有一个共同关键词,但语义完全匹配。传统检索在这种场景下召回率为零,向量检索能轻松解决。
但向量检索不能完全替代关键词检索:
查具体的错误码(ERR_CONNECTION_REFUSED)、精确的文件路径、特定的 API 名称——这些场景关键词检索比向量检索更快更准。向量化反而会把精确信息“模糊化”。
生产环境的最佳实践是混合检索:
向量检索(语义匹配)─┐
├→ 合并去重 → ReRank 精排 → Top-K
关键词检索(精确匹配)─┘两路互补:向量路保证语义覆盖,关键词路保证精确命中。合并后用 ReRank 统一排序。
差距在哪:新手用“更准”一词概括——其实向量检索在精确匹配上反而不如关键词检索。高手明确了两者的优劣势互补关系,且指出生产环境用混合检索。面试官考的是你对检索系统的工程认知——不是“哪个更好”,而是“什么场景用什么”。
Q:如果用全量生产文档做关联性检索,用户每个问题要交互多少轮?有没有更高效的方案?
来源:蚂蚁集团智能体与大模型应用二面
新手答:“文档多了就慢一点,多检索几次。”
高手答:
全量文档场景的核心挑战是文档量级和查询效率的矛盾——几万甚至几十万份文档,用户一个问题不可能遍历所有文档找关联。
传统 RAG 的局限:
标准 RAG 是 query → embedding → top-K 召回。但当文档量大且内容跨领域时,单次召回很难覆盖所有相关信息。用户可能需要多轮追问才能拿到完整答案——每轮交互本质上是在“逐步缩小检索范围”。
更高效的方案:
1. 文档预处理——建立关联索引:
不等用户查询时才找关联,离线阶段就把文档间的关联性预计算好:
- 文档聚类:按主题对文档自动分组,查询时先定位到相关组,缩小搜索范围
- 知识图谱:从文档中抽取实体和关系,建立文档间的语义关联图。查询时沿着图谱做多跳检索,找到间接关联的文档
- 摘要索引:每份文档生成摘要,先用摘要做粗筛,再用原文做精排——两级检索比全量检索快很多
2. Multi-hop RAG——一次查询找到链式关联:
Multi-hop RAG 让 Agent 自动做多轮检索,每一跳基于上一跳的结果生成新的子查询,沿关联链逐步深入。用户只问一次,Agent 内部自动完成多轮检索。
3. GraphRAG——结构化关联检索:
微软提出的 GraphRAG 方案:先从全量文档构建知识图谱和社区摘要,查询时在图上检索而非在文档上检索。优势是能找到文档间的隐式关联——两份文档没有共同关键词,但通过实体关系链接在一起。
差距在哪:新手认为全量文档只能“多搜几次”。高手给出了三种更高效的方案——预计算关联索引、Multi-hop RAG 自动多跳检索、GraphRAG 结构化关联。面试官考的是你对 RAG 架构演进方向的认知——从单次检索到多跳检索到图检索,是检索系统面对大规模文档的自然演化路径。