知识库与索引工程
Q:GraphRAG 在处理 Agent 复杂关联查询时的优势在哪里?
来源:淘天 AI Agent 一面 【蚂蚁AI应用开发二面同题:GraphRAG 理解与应用】【字节二面追问:多跳推理/复杂逻辑查询场景下 RAG 架构优化】
新手答:”用知识图谱检索,比向量搜索更准。”
高手答:
先说清一个常见误解:GraphRAG ≠ 知识图谱检索。传统知识图谱检索是在预构建的三元组上做 SPARQL 查询,而 GraphRAG 是微软提出的一套完整架构——从文档自动构建知识图谱 + 社区摘要 + 本地/全局双搜索。
传统 RAG 的瓶颈:
传统 RAG 的检索单元是”文本块”(chunk),本质是扁平的。当用户的问题涉及多跳推理(A 和 B 的关系 → B 和 C 的关系 → 推导 A 和 C 的关系)或跨文档关联(信息分散在多个文档中)时,靠向量相似度只能找到局部相关的片段,无法把分散的信息串联起来。
传统 RAG 的困境:
用户问:”项目 A 的技术负责人和项目 B 的技术负责人之间有什么合作关系?”
文档1 提到:张三是项目 A 的技术负责人
文档2 提到:李四是项目 B 的技术负责人
文档3 提到:张三和李四共同发表了论文 X
→ 向量检索可能只召回文档1和文档2,漏掉关键的文档3
→ 即使三个都召回了,模型也需要自己做推理串联GraphRAG 的架构与流程:
GraphRAG 的三大核心优势:
1. 多跳推理能力
知识图谱天然支持关系链遍历。上面那个例子,在图中就是:项目A → 技术负责人 → 张三 → 合作论文 → 李四 → 技术负责人 → 项目B。沿着关系边走两三跳就能拿到完整的关联信息,不需要模型自己推理。
2. 全局理解能力
这是 GraphRAG 最大的创新——社区摘要。通过社区检测算法把图中紧密关联的实体聚成社区,再用 LLM 为每个社区生成主题摘要。当用户问”这个领域的整体趋势是什么”这类全局性问题时,传统 RAG 只能拼凑零散的片段,GraphRAG 可以直接基于社区摘要回答。
3. 结构化实体消歧
同一个实体在不同文档中可能有不同的名称(”OpenAI”、”openai”、”Open AI”),图构建过程中会做实体合并和消歧,保证检索的一致性。
不同查询类型下的对比:
| 查询类型 | 传统 RAG | GraphRAG |
|---|---|---|
| 单跳事实题(”X 是什么”) | 效果好,向量检索足够 | 效果好,但构建成本更高 |
| 多跳关系题(”A 和 C 什么关系”) | 容易漏召回,依赖模型推理 | 图遍历直接获取关系链 |
| 全局摘要题(”整体趋势是什么”) | 只能拼凑片段,质量差 | 社区摘要直接回答,质量显著更好 |
| 对比分析题(”X 和 Y 的异同”) | 需要分别检索再交叉,效果不稳定 | 两个实体的关联属性在图中直接可比 |
| 时序关系题(”先发生什么后发生什么”) | 缺乏时序建模 | 可在关系边上标注时间属性 |
什么时候该用 GraphRAG:
适合 GraphRAG 的场景:
[适用] 文档集中有大量实体间的关系信息
[适用] 用户经常问多跳推理或全局摘要类问题
[适用] 实体消歧是痛点(同一实体多种写法)
[适用] 需要可解释的推理路径
不适合 GraphRAG 的场景:
[不适用] 文档量小(<100篇),图太稀疏没有意义
[不适用] 查询以单跳事实题为主,传统 RAG 就够了
[不适用] 对实时性要求极高——图构建和社区摘要是离线批处理,延迟高
[不适用] 预算有限——图构建需要大量 LLM 调用(实体抽取 + 社区摘要)成本方面,GraphRAG 的图构建阶段需要对每个文档段落调用 LLM 提取实体和关系,再对每个社区调用 LLM 生成摘要。对于 10 万篇文档的知识库,图构建的 LLM 调用成本可能是传统 RAG embedding 计算的 10-50 倍。但构建完成后,查询阶段的成本差异不大。
差距在哪:新手把 GraphRAG 等同于”知识图谱检索”——这忽略了 GraphRAG 最核心的创新:社区摘要和本地/全局双搜索架构。高手的回答从传统 RAG 的瓶颈讲起,解释了 GraphRAG 的完整管线(实体抽取 → 图构建 → 社区检测 → 摘要生成 → 双路搜索),并用对比表格说清了不同查询类型下的效果差异和适用边界。面试官考的不是”你知不知道 GraphRAG”,而是”你能不能说清楚它比传统 RAG 好在哪、什么时候该用、什么时候不该用”。
追问:GraphRAG 召回海量关联信息后,生成阶段如何用 Self-Reflection 或 CoT 策略过滤检索噪声?
来源:蚂蚁 AI应用开发 二面
GraphRAG 的 Community Summary + 三元组召回会返回大量关联信息,其中不少是”图上相关但问题无关”的噪声。生成阶段的过滤策略:
CoT 策略(生成前过滤):在生成 Prompt 中要求模型先做一步”证据筛选”——逐条判断每个召回片段与当前问题的相关性,只保留高相关的片段再生成回答。这相当于在生成阶段内置了一个轻量 Rerank。
Self-Reflection 策略(生成后校验):先基于全部召回信息生成初版回答,然后用反思 Prompt 检查:”回答中是否引用了与问题无关的信息?是否遗漏了关键关联?” 发现问题后定向修正。
两者结合:CoT 做前置过滤降低噪声,Self-Reflection 做后置校验捕获遗漏。前者减少”答非所问”,后者减少”漏答关键点”。
追问:GraphRAG 的三元组是用 LLM 抽取的吗?怎么保证不幻觉?
来源:腾讯 AI 应用开发二面
是的,三元组(实体-关系-实体)通常由 LLM 抽取,但不能无条件信任 LLM 的抽取结果。
抽取流程:
文档段落 → LLM 提取实体 + 关系 → 结构化三元组 → 合并去重 → 入图幻觉控制的四层防线:
- Prompt 约束:在抽取 Prompt 中明确要求”只提取文本中明确提到的实体和关系,不推断”。给出具体的输出格式和 Few-shot 示例,减少模型自由发挥的空间
- Schema 约束:预定义允许的实体类型和关系类型(如医学领域只允许”疾病-症状-药物-基因”四类实体)。LLM 抽出的实体必须属于预定义类型,否则丢弃
- 多轮验证:同一段文本让 LLM 抽取两次,只保留两次结果一致的三元组(投票机制)。或者用一个 Critic 模型检查抽取结果是否有文本依据
- 溯源校验:每个三元组保留源文本引用。后续使用时可以回查原文验证
实体抽取错误的排查方法:
- 随机抽样检查:从抽取结果中随机抽 100 条三元组,人工校验准确率
- 高频实体审查:按实体出现频次排序,高频实体更值得校验(一个错误的高频实体会污染大量关系)
- 孤立节点检查:只有一条边的实体往往是噪声
追问:Community Summary 的设计思路是什么?
来源:腾讯 AI 应用开发二面
Community Summary 是 GraphRAG 最核心的创新——把知识图谱从”查询时遍历”变成”预计算摘要”。
设计思路:
- 社区检测:用 Leiden 算法对知识图谱做社区划分,把紧密关联的实体聚成社区(类似”话题簇”)
- 层次化摘要:对每个社区调用 LLM 生成一段自然语言摘要,描述”这个社区里的实体之间有什么关系、核心主题是什么”
- 多层级:社区可以递归聚合——小社区合成大社区,大社区有更宏观的摘要。查询时根据问题的抽象程度选择合适的层级
为什么这样设计:传统知识图谱回答全局性问题(”这个领域的整体趋势是什么”)需要遍历大量节点,成本高且容易遗漏。Community Summary 把全局知识预压缩成摘要,查询时直接检索摘要即可——用离线计算换在线效率。
追问:GraphRAG 的叶子节点在智能客服中如何触发?
来源:币安 AI大模型实习一面
GraphRAG 的图结构是分层的:根节点(全局摘要)→ 社区节点(主题簇摘要)→ 实体节点 → 叶子节点(原始文档 chunk / 三元组细节)。不同粒度的问题触达不同层级。
触发机制——Global Search vs Local Search:
| 用户问题类型 | 搜索模式 | 是否触达叶子节点 | 示例 |
|---|---|---|---|
| 全局性/概览性 | Global Search | 否,社区摘要足够 | “你们有什么售后服务” |
| 具体实体细节 | Local Search | 是,需要原始文档细节 | “iPhone 15 能不能 7 天无理由退” |
| 需要外部数据 | Local + API 调用 | 是,且需调用外部系统 | “我的订单 123456 什么时候到” |
叶子节点的触发流程:
工程实现要点:用意图分类器判断问题粒度——粗粒度走 Global(快但粗),细粒度走 Local 到叶子节点(慢但准)。两者可以级联:先 Global 判断主题范围确认实体所属社区,再 Local 深入到叶子节点获取具体细节。
智能客服中的典型场景:用户问”我买的 XX 产品能退吗” → 实体识别提取产品名 → 图中定位到该产品节点 → 沿”退货政策”关系边遍历到叶子节点(具体退货条件、时间限制、操作步骤)→ 聚合上下文生成精确回答。
Q:分块策略怎么设计?不同策略的优缺点?
来源:高德 AI 应用开发实习一面
新手答:“按 500 字切一段。”
高手答:
分块(Chunking)是 RAG 中影响效果最大的单一设计决策——切得不好,后面的检索和生成再怎么优化都救不回来。
五种主流分块策略对比:
| 策略 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 固定长度分块 | 按 token 数切分 | 实现简单、大小可控 | 可能切断语义 | 结构不清晰的纯文本 |
| 语义分块 | 按段落/章节/标题切分 | 保持语义完整 | 块大小不均匀 | 有清晰结构的文档 |
| 递归分块 | 先尝试大单元分割,不满足再细分 | 平衡语义和大小 | 实现复杂 | 通用场景首选 |
| Sliding Window | 固定大小 + 重叠区域 | 防止边界信息丢失 | 存储冗余 | 精度要求高的场景 |
| Agentic Chunking | 用 LLM 判断分块边界 | 最智能 | 成本高、速度慢 | 高价值文档 |
关键参数设计:
Chunk Size(块大小):256 ~ 1024 tokens
太小(< 200 tokens)→ 语义不完整,一个 chunk 可能只有半句话
太大(> 1500 tokens)→ 噪声多,embedding 被多个主题稀释,召回精度低
Overlap(重叠区域):chunk size 的 10 ~ 20%
作用:防止切断句子或段落,保证边界处的信息在相邻 chunk 中都有
Metadata(元信息):每个 chunk 保留——
source:来源文档标识
page:所在页码
section_title:所属章节标题
parent_doc_id:父文档 ID(用于父子索引)父子索引策略——同时解决检索精度和上下文完整性:
用小 chunk 做检索(精度高),返回大 chunk 给 LLM(上下文完整)——两全其美。
递归分块的实现逻辑:
分割优先级:
1. 先按 "\n\n"(段落)分割
2. 段落仍然太大 → 按 "\n"(换行)分割
3. 还是太大 → 按 "。"(句号)分割
4. 再不行 → 按空格或字符数强制切分
每一级都尽可能保持语义完整,只有上一级切不够小时才降到下一级。实践建议:从递归分块(LangChain 的 RecursiveCharacterTextSplitter)作为 baseline 开始,然后根据文档类型和评估结果调整。不同类型的文档用不同策略——技术文档用语义分块(按标题切),日志文件用固定长度分块,合同文档用 Agentic Chunking。
差距在哪:新手用固定长度一刀切,不考虑语义。高手对比了五种策略的优劣势,理解 chunk size 和语义完整性的 tradeoff,用父子索引同时满足检索精度和上下文质量,并且知道分块策略必须根据文档类型和评估结果来调整——不存在”万能的分块方案”。面试官考的是你对 RAG 管线中最关键的预处理环节有没有深入的工程理解。
追问:chunk 切分的边界修正怎么做?比如表格被切成了两半怎么处理?
来源:腾讯 AI 应用开发二面
边界修正是分块策略中最容易被忽视的工程细节。切错边界比不切更糟——一个被拦腰截断的表格,检索到任何一半都无法提供完整信息。
主流边界修正策略:
- 结构感知切分:先用文档解析器识别出结构元素(标题、段落、表格、代码块、列表),以完整结构元素为最小切分单位,绝不从结构内部切断
- Overlap(重叠窗口):相邻 chunk 之间保留 10-20% 的重叠区域。即使切断了,下一个 chunk 的开头会包含上一个的结尾,信息不会完全丢失
- 表格特殊处理:表格作为独立 chunk,不参与常规切分。如果表格超长,按行切分但每个子 chunk 都保留表头(表头是理解表格的关键)
表格被切成两半的检测和修复:
检测:解析文档时标记所有表格的起止位置 → 切分后检查是否有 chunk 边界
落在表格内部 → 有则标记为”边界异常”
修复:把跨越表格的两个 chunk 合并,或者把表格提取为独立 chunk实际工程中,最稳的做法是先提取后切分:先用文档解析器把表格、图片、代码块等结构化元素单独提取出来,剩余的纯文本再做常规分块。这样结构化元素天然不会被切断。
追问:领域文档(法律/医疗)的语义单元跨 chunk 被切散,怎么办?
来源:字节 AI 一面(法律 RAG 项目深挖)
法律文档中,“第三条第二款”和“第三条之二”是完全不同的法律概念——前者是第三条下的第二个分款,后者是独立的第三条之二。如果切片把这类语义单元切散,模型会混淆引用关系,直接导致回答错误。
领域感知切片的四层方案:
| 层级 | 做什么 | 具体实现 |
|---|---|---|
| 结构解析 | 用领域规则识别语义边界 | 法律:条/款/项层级正则;医疗:诊断-处方-医嘱分段 |
| 边界保护 | 语义单元不可被切断 | 将“第X条”到“第X+1条”之间的内容视为原子块 |
| 层级 metadata | 每个 chunk 携带完整的上下文链 | \{law: "民法典", chapter: "第三编", article: "第三条", clause: "第二款"\} |
| 交叉引用 | 法条互相引用时双向关联 | “依据第五条”→ 在 chunk metadata 中标记依赖关系 |
核心原则:通用切片策略(按 token 数、按段落)是 baseline,领域文档必须叠加领域感知的边界规则。切片粒度不是工程参数,是业务决策——需要和领域专家一起定义“什么是不可切断的最小语义单元”。
Q:知识库整体怎么设计?
来源:高德 AI 应用开发实习一面 【字节二面同题:RAG 完整流程从文档切块到生成】
新手答:“把文档存到向量数据库。”
高手答:
知识库不是“把文档扔进向量数据库”——它是一个完整的系统,涵盖文档处理、存储索引、检索召回、质量保障和运维五个层面。
整体架构:
五层设计:
1. 文档处理层——把非结构化文档变成可检索的结构化数据:
- 格式解析:PDF / Word / HTML → 纯文本。不同格式的解析难度差异很大——PDF 的表格和多栏排版是重灾区
- 清洗去噪:去掉页眉页脚、广告、导航栏等无关内容
- 元数据提取:来源、创建日期、类别、作者——这些元信息在检索时用于过滤和排序
2. 索引层——三种索引各司其职:
- 向量索引(FAISS / Milvus):语义检索,处理同义改写和模糊表述
- 倒排索引(Elasticsearch):关键词检索,处理精确术语和专有名词
- 元数据索引(过滤字段):结构化筛选,处理时间范围、文档类别等约束
为什么需要三种?因为不同类型的查询需要不同的索引——“退货政策”需要语义检索,“ERR_OOM_KILL”需要关键词检索,“最近一周的变更记录”需要元数据过滤。
3. 检索层——查询理解 + 多路召回 + 精排:
- 查询改写(多维度扩展用户意图)
- 多路召回(向量 + BM25 + 元数据过滤并行)
- Rerank 精排(Cross-Encoder 细粒度打分)
- 上下文组装(Top-K 截断、信息去冗余)
4. 质量保障层——知识库不是建完就不管了:
- 文档去重:内容指纹检测近重复文档
- 新鲜度追踪:过期文档标记或降权
- 冲突检测:同一主题的矛盾信息标记提醒
- 覆盖分析:哪些主题的文档充足,哪些有缺口
5. 运维层——保证知识库持续可用:
- 增量更新管线:新文档自动入库,变更文档自动重新索引
- 版本管理:文档变更可追溯
- 访问控制:不同用户看到不同范围的文档
- 监控:检索命中率、用户反馈、知识库健康度
关键设计决策:
| 决策点 | 选项 | 权衡 |
|---|---|---|
| Chunk 大小 | 256 / 512 / 1024 tokens | 粒度越小检索越精确,但上下文越不完整 |
| 单索引 vs 多索引 | 只用向量 vs 向量 + BM25 + 元数据 | 多索引召回率高,但系统复杂度增加 |
| 实时更新 vs 批量更新 | 文档变更立即入库 vs 每天定时批量处理 | 实时性 vs 系统稳定性和计算成本 |
差距在哪:新手认为知识库就是向量数据库。高手设计了五层系统——文档处理、索引、检索、质量保障、运维——覆盖了从数据入库到持续运维的完整生命周期。面试官考的是你对知识库的认知是“一个组件”还是“一套系统”。
Q:向量数据库怎么选型?不同规模下该用什么方案?
来源:阿里国际 AI 应用研发二面 【淘天Agent开发追问:为什么选 pgvector 而不是其他向量数据库】
新手答:“用 Milvus 就行。”
高手答:
向量数据库的选型不是“挑一个最有名的”,而是按数据规模分层选择,再根据业务需求做筛选。
按数据规模分层推荐:
小规模(< 10 万条向量):pgvector / SQLite-VSS
直接在现有关系型数据库上加向量扩展。运维成本几乎为零,不需要额外部署服务。对于早期项目和 PoC 阶段完全够用。
中等规模(10 万 - 1000 万条向量):Milvus Lite / Qdrant / Weaviate
需要专用的向量数据库。这个量级对索引类型(HNSW / IVF)、过滤能力、持久化都有要求。这三个都支持元数据过滤,且社区活跃、文档完善。
大规模(1000 万条以上):Milvus 集群 / Pinecone / Zilliz Cloud
需要分布式架构和水平扩展能力。Milvus 集群支持多副本和分片;Pinecone 和 Zilliz Cloud 是全托管服务,运维成本低但按量计费。
选型维度对比:
| 选型维度 | 关键问题 | 影响选择 |
|---|---|---|
| 数据规模 | 当前多少条?预期增长到多少? | 决定单机 vs 分布式 |
| 过滤需求 | 是否需要 metadata 过滤(按时间、类别筛选)? | 排除不支持过滤的纯 ANN 方案 |
| 延迟要求 | P99 延迟要求多少 ms? | 影响索引类型和部署架构 |
| 运维复杂度 | 团队有没有专人运维? | 决定自建 vs 托管服务 |
| 成本 | 预算约束是什么? | 开源自建 vs 商业托管 |
| 混合检索 | 是否需要向量 + 关键词混合搜索? | 部分方案原生支持(Qdrant、Weaviate),部分需要外接 ES |
关键考量:大多数真实 Agent 场景都需要元数据过滤——比如“只检索最近 30 天的文档”“只查某个品类下的内容”。这个需求会直接淘汰一些纯 ANN 方案(如裸用 FAISS),因为它们不支持带条件的向量检索。
生产建议:先简单后迁移。项目初期用 pgvector 快速验证效果,等数据量或性能真正成为瓶颈时再迁移到专用向量数据库。过早引入分布式向量数据库是典型的过度工程——你花两周部署 Milvus 集群,结果数据才 5 万条,pgvector 10ms 就能搞定。
差距在哪:新手只给一个品牌名。高手按数据规模分层推荐,且给出了选型维度和“先简单后迁移”的工程建议。面试官考的是你对向量检索基础设施的全面认知。
Q:Embedding 模型怎么选?选型时考虑哪些因素?
来源:高德 AI 应用开发实习一面
新手答:“用 OpenAI 的就行。”
高手答:
Embedding 模型选型不是“哪个最有名用哪个”,而是要从六个维度系统评估:
| 维度 | 考虑因素 | 说明 |
|---|---|---|
| 语言支持 | 中文/英文/多语言 | 中文场景优先选中文优化模型 |
| 向量维度 | 768/1024/1536 | 维度越高精度越好但存储和检索成本越大 |
| 检索精度 | MTEB/C-MTEB 排名 | 用公开基准评估基础能力 |
| 推理速度 | tokens/sec | 影响索引构建和在线检索延迟 |
| 部署成本 | 模型大小、GPU 需求 | 小模型可 CPU 部署 |
| 最大长度 | 512/8192 tokens | 影响 chunk 大小设计 |
主流模型对比:
| 模型 | 来源 | 特点 |
|---|---|---|
| BGE 系列 | BAAI(智源) | 中文效果好,开源,多尺寸可选 |
| M3E | Moka | 中文优化,轻量 |
| text-embedding-3 | OpenAI | 效果好但需 API 调用,成本高 |
| jina-embeddings-v3 | Jina AI | 多语言,支持长文本 |
| GTE | Alibaba | 中英文均衡 |
实际选型决策流程:
- 先确定语言需求:中文场景优先选中文优化模型,不要盲目选英文模型
- 跑 domain-specific evaluation:不只看 MTEB/C-MTEB 排名,必须在自己的数据上评估。公开 benchmark 上排名第一的模型,在你的业务数据上可能排第五
- 对比部署成本:API 调用模型(如 OpenAI)按量计费,自部署模型有 GPU 成本。数据量大时自部署更划算
- 考虑是否需要微调:领域术语多的场景(医疗、法律、金融),通用模型的 embedding 质量会明显下降,这时选开源模型做微调是更好的路径
关键认知:公开 benchmark 排名不等于你的场景效果。必须在自己的数据上做 A/B 评测——构建几百条 (query, relevant_doc) 的评估集,跑 Recall@K 和 MRR,用数据说话。
差距在哪:新手直接选最有名的模型。高手从六个维度系统评估,坚持在业务数据上做 domain-specific evaluation,而不是盲目跟 benchmark 排名。面试官考的是你选型时有没有工程化的方法论,以及对“通用模型 vs 领域适配”这个 tradeoff 的理解。
Q:为什么 Claude Code 不用 RAG 检索代码,而是直接用 grep?
来源:字节 Agent 开发实习一面
新手答:“可能是还没来得及实现 RAG。”
高手答:
这道题非常好,它直接挑战了“RAG 万能论”的假设。答案是:对于代码检索场景,grep 在多个维度上优于 RAG,这是一个深思熟虑的架构选择,而不是技术局限。
grep 胜过 RAG 的五个原因:
| 维度 | grep | RAG |
|---|---|---|
| 精确性 | grep "functionName" 精确匹配,100% 准确率 | 向量检索返回“语义相似”的结果,可能漏掉目标函数 |
| 实时性 | 直接操作当前文件系统,永远是最新的 | 需要索引,代码一改索引就可能过时(开发时代码频繁变动) |
| 成本 | 纯 CPU 计算,免费,耗时 <100ms | 需要 Embedding 计算、向量数据库,索引需随代码变更重建 |
| 可解释性 | 结果确定且可追溯——匹配到哪个文件第几行一清二楚 | 结果取决于 Embedding 质量,无法解释“为什么返回这个结果” |
| 代码结构利用 | 代码高度结构化(函数、类、import 有固定模式),grep + 正则能精准利用这种结构 | Embedding 会丢失代码的结构信息,把代码当成普通文本处理 |
什么时候 RAG 比 grep 更好:
grep 不是万能的,以下场景 RAG 占优:
自然语言查询:"认证逻辑在哪里?"
→ grep 无法处理,因为代码中没有"认证逻辑"这个字符串
→ RAG 的语义检索能找到 auth_middleware.py、login_handler.py
概念级搜索:"找到类似的实现"
→ grep 只能匹配精确字符串
→ 向量检索能找到语义相似的代码片段
跨模块依赖分析:"哪些模块依赖了这个服务?"
→ grep 能做简单的 import 搜索,但知识图谱 / RAG 能发现间接依赖Claude Code 的实际策略——渐进式披露(Progressive Disclosure):
核心原则是从最廉价、最精确的工具开始,按需逐步升级到更昂贵的工具。grep 和 find 是第一层(零成本、高精度),读文件是第二层(中等成本),只有在前两层无法满足需求时才考虑更重的检索手段。
这道题的 meta 启示:
最佳检索方法取决于查询类型。不要默认使用 RAG——有时候更简单的工具反而更好。这个原则不仅适用于代码检索,也适用于所有 Agent 的工具选择:先用廉价精确的工具,只在必要时才升级到昂贵复杂的工具。这就是渐进式披露在工具选择层面的体现。
差距在哪:新手假设 RAG 是万能的,认为不用 RAG 是技术缺陷。高手理解 grep 在精确性、实时性、成本、可解释性和代码结构利用五个维度上的优势,并且看到了 Claude Code 的渐进式披露策略是一个深思熟虑的架构选择——从廉价精确工具开始,按需升级。面试官考的是你能不能跳出“RAG 万能论”的思维定式,根据场景选择最合适的检索方案。
Q:升级 Embedding 模型后,怎么保证索引和检索向量的逻辑一致性?
来源:阿里国际 AI 应用研发二面
新手答:“重新跑一遍索引就行了。”
高手答:
核心问题:旧文档用 Model_v1 编码入库,新查询用 Model_v2 编码检索——两个模型的向量空间不对齐,导致检索质量断崖式下降。即使两个模型都很强,它们学到的向量空间是不同的,v1 空间里的“近邻”在 v2 空间里可能完全不是近邻。
“全量重建索引”是正确的方向,但对于百万级文档,全量重建需要数小时甚至数天,在此期间系统要么不可用,要么用旧模型继续服务(效果变差)。所以真正的挑战不是“能不能重建”,而是“怎么平滑过渡”。
三种升级策略:
策略一:双索引并行
在旧索引继续服务的同时,后台用新模型构建新索引。
新索引构建完成后,做一次原子切换——流量瞬间从旧索引切到新索引。优点:切换瞬间完成,用户无感知。缺点:过渡期需要双倍存储成本,且切换前无法验证新索引的线上效果。
策略二:渐进式迁移
给每个文档向量打上 embedding_model_version 标签。
过渡期内,查询同时用 v1 和 v2 两个模型编码,分别检索对应版本的分区,合并结果。
后台逐步将旧文档用新模型重新编码,完成后删除旧分区。优点:平滑过渡,任何时刻系统都可用。缺点:过渡期查询要编码两次、搜索两次,延迟翻倍。
策略三:版本化索引 + 灰度切换
新索引构建完成后,不立即全量切换,而是先导流 5-10% 到新索引。
对比新旧索引的线上指标(召回率、相关性、用户点击率)。
指标达标 → 逐步扩大流量比例直到全量切换。
指标异常 → 立即回滚到旧索引。优点:风险最低,有数据验证。缺点:验证周期长,需要流量分配基础设施。
完整的双索引过渡流程:
工程保障措施:
- 始终存储原始文本:向量可以重算,原始文本不能丢。每个 chunk 必须保留原始文本,这样任何时候都能用新模型重新编码
- 版本标记每个向量:
embedding_model_version字段必须持久化到向量记录中,方便区分哪些文档已迁移、哪些还没有 - 自动化质量回归测试:维护一组
(query, expected_relevant_docs)的黄金测试集,每次模型升级后自动跑 Recall@K 和 MRR,低于阈值则阻断上线
差距在哪:新手只想到“重建”——这是正确的第一步但忽略了过渡期的可用性。高手给出了双索引并行、渐进式迁移、灰度切换三种策略,且强调了版本标记和自动化质量回归测试。面试官考的是你对向量检索系统升级的工程化思维——不是“能不能升级”,而是“怎么平滑升级”。