2026最新RAG面试题集:45问覆盖全链路

一、RAG基础概念与架构

Q1: 请解释RAG的工作原理,与微调(Fine-tuning)相比主要解决了什么问题?有哪些优势?

核心答案:

RAG(Retrieval-Augmented Generation)的核心思想是在大模型生成回答之前,先从外部知识库中检索相关信息,将检索结果作为上下文注入Prompt,引导模型基于事实生成回答。其工作流程分为两大阶段:

  • 索引阶段:文档 → 数据清洗 → 文本切分 → Embedding向量化 → 存入向量数据库
  • 查询阶段:用户Query → Query Embedding → 向量检索Top-K → 重排序 → 拼接Prompt → LLM生成回答

与微调的核心区别:

维度 RAG 微调(Fine-tuning)
知识更新 更新知识库即可,无需重训练 需重新训练模型
成本 算力成本降低70%,标注量减少80% 需大量标注数据+GPU算力
幻觉控制 锚定外部事实,幻觉率降低50-70% 模型仍可能编造训练数据外的内容
时效性 实时更新知识库即可 知识冻结在训练时间点
可解释性 可附带引用来源 难以追溯知识来源
适用场景 知识频繁更新、需要溯源 改变模型行为/风格/格式

面试加分点:主动提及"RAG和微调不是互斥的,实际生产中常组合使用------先用微调调整模型的输出风格和格式遵循能力,再用RAG注入领域知识"。

⚠️ 常见踩坑:不能说"RAG完全替代微调"。对于需要改变模型推理方式(如代码生成、数学推理)的场景,微调仍然是必要的。

深入追问与应对:

  • 追问:RAG的局限性是什么? → 1)检索质量是天花板,检索不准则生成必错;2)额外延迟(检索+重排增加200-500ms);3)上下文窗口限制能注入的文档数量;4)对需要深层推理的任务帮助有限。
  • 追问:什么场景下优先微调? → 改变模型行为模式(如让模型输出特定格式JSON)、领域术语理解(医疗/法律)、低资源语言适配。

生产实战要点:

python 复制代码
# 生产级RAG标准Pipeline(LangChain实现)
from langchain.chains import RetrievalQA
from langchain.vectorstores import Milvus
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.llms import OpenAI

# 1. 初始化Embedding模型
embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-large-zh-v1.5",
    encode_kwargs={"normalize_embeddings": True}  # 归一化,用余弦相似度
)

# 2. 连接向量数据库
vectorstore = Milvus(
    embedding_function=embeddings,
    collection_name="knowledge_base",
    connection_args={"host": "localhost", "port": "19530"}
)

# 3. 构建RAG链
qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(model="gpt-4", temperature=0),
    chain_type="stuff",  # stuff/map_reduce/refine
    retriever=vectorstore.as_retriever(
        search_kwargs={"k": 5, "score_threshold": 0.75}
    ),
    return_source_documents=True  # 返回引用来源
)

Q2: 请描述RAG架构的演进路线:Naive RAG → Advanced RAG → Modular RAG,各阶段的核心改进是什么?

核心答案:

Naive RAG(基础RAG):最简单的"检索-生成"流程,直接用用户Query做向量检索,Top-K结果拼入Prompt给LLM。问题:检索质量不稳定、上下文割裂、幻觉率高。

Advanced RAG(增强RAG):在Naive RAG基础上,在检索前、检索后分别增加优化环节:

  • 检索前:Query改写、HyDE、多查询扩展
  • 检索后:Rerank重排序、上下文压缩、元数据过滤
  • 检索中:混合检索(向量+关键词)、多路召回

Modular RAG(模块化RAG):将RAG的各环节拆解为独立模块,可自由组合和替换:

  • 检索模块:可替换为不同检索策略
  • 重排模块:可插拔不同Reranker
  • 生成模块:可切换不同LLM
  • 路由模块:根据问题类型走不同Pipeline

面试加分点:主动画出架构对比图,强调"Modular RAG的核心价值是解耦,不同业务场景可以组装不同的Pipeline,比如简单问题走轻量链路、复杂问题走完整链路"。

⚠️ 常见踩坑:不要把Advanced RAG简单理解为"加个Rerank",真正的Advanced RAG是全链路优化,检索前/中/后都有改进。

深入追问与应对:

  • 追问:Modular RAG如何实现路由? → 前置一个轻量级分类器(或用LLM做意图识别),将Query分为事实型/对比型/统计型等,不同类型走不同的检索+生成Pipeline。
  • 追问:生产中该选哪种? → MVP阶段用Naive RAG快速验证,效果不达标时先优化数据质量,再升级到Advanced RAG。Modular RAG适合多业务线共享基础设施的平台级系统。

生产实战要点:

python 复制代码
# Modular RAG路由实现示例
class RAGRouter:
    def __init__(self):
        self.classifier = self._load_intent_classifier()
        self.pipelines = {
            "simple": SimpleRAGPipeline(),      # 简单问答:向量检索 + 直接生成
            "hybrid": HybridRAGPipeline(),      # 复杂查询:混合检索 + Rerank
            "agentic": AgenticRAGPipeline(),    # 多跳推理:Agent驱动多轮检索
        }
    
    def route(self, query: str) -> str:
        intent = self.classifier.predict(query)
        if intent == "factual_simple":
            return "simple"
        elif intent == "comparison" or intent == "multi_hop":
            return "agentic"
        else:
            return "hybrid"

Q3: RAG端到端工作流程中,哪个环节对最终效果影响最大?为什么?

核心答案:

数据质量和文档处理环节是决定RAG效果的天花板。业界共识:RAG效果70%取决于数据质量,30%取决于模型和算法。

具体来说,各环节的影响权重排序:

  1. 文档解析与切分(~40%):解析出错(表格丢失、格式混乱)或切分不当(语义断裂、信息丢失),后续所有环节都无法弥补
  2. 检索质量(~30%):召回率和准确率直接决定LLM能否获取到正确信息
  3. 重排序与上下文组装(~15%):即使召回了正确文档,排序不当或噪声过多也会影响生成
  4. Prompt设计与LLM生成(~15%):好的Prompt能提升输出质量,但无法弥补检索层的缺失

面试加分点:引用Data-Centric AI的理念------"与其花时间调模型参数,不如花时间清洗数据"。主动提及在优化RAG时,第一步应该是做Bad Case分析,定位问题出在哪个环节。

⚠️ 常见踩坑:很多团队一上来就换更贵的LLM或加Reranker,但根本原因是文档切分不合理,属于"用战术勤奋掩盖战略懒惰"。

深入追问与应对:

  • 追问:如何量化各环节的影响? → 使用消融实验(Ablation Study),分别固定其他环节,单独优化一个环节,观察端到端指标变化。也可以用RAGAS框架分别评估Context Precision/Recall和Faithfulness,定位薄弱环节。

生产实战要点:

复制代码
RAG效果优化优先级(生产级SOP):
Step 1: 数据治理 → 清洗、去重、格式规范化(影响最大,优先做)
Step 2: 切分策略优化 → 语义切分、Parent-Child索引(次大影响)
Step 3: 混合检索 + Rerank → BM25+向量+重排序(第三优先级)
Step 4: Prompt工程 → 引用约束、拒答机制(锦上添花)
Step 5: 高级技术 → HyDE、Agentic RAG等(针对性优化)

Q4: RAG系统与搜索引擎(Search Engine)的核心区别是什么?它们分别适用于什么场景?

核心答案:

维度 搜索引擎 RAG系统
目标 返回相关文档列表 生成精准答案
输出 文档链接+摘要 自然语言回答+引用来源
推理能力 无,基于关键词/语义匹配 有,LLM可做综合推理
上下文理解 无,每次查询独立 有,支持多轮对话
准确性要求 允许部分不相关结果 要求答案事实准确
典型技术 倒排索引+PageRank 向量检索+LLM生成

适用场景:

  • 搜索引擎:信息发现型需求("找一下关于XX的资料")、浏览探索
  • RAG:知识问答型需求("XX的具体参数是什么")、决策支持、合规查询

面试加分点:提及"实际生产中RAG和搜索引擎常常组合使用------RAG的检索层本身就是一个搜索引擎,而搜索引擎的结果也可以作为RAG的外部知识源(CRAG中的Web Search降级策略)"。

⚠️ 常见踩坑:不要把RAG和搜索对立起来。RAG的检索层本质上是搜索引擎的升级版,搜索是RAG的子集。

深入追问与应对:

  • 追问:什么场景下搜索引擎就够了,不需要RAG? → 当用户只需要"找到文档"而非"获得答案"时(如文档管理系统),或当领域知识不需要推理只需要精确匹配时(如代码搜索)。

二、文档处理与知识库构建

Q5: RAG中常见的文档解析策略有哪些?如何处理PDF、扫描件、表格等复杂格式?

核心答案:

文档类型 解析工具 核心挑战 解决方案
PDF(文本型) PyMuPDF/pdfplumber 页眉页脚、多栏布局 版面分析+区域过滤
PDF(扫描件) OCR(PaddleOCR/Tesseract) 识别精度、版面还原 高精度OCR+版面恢复
Word python-docx 表格/图片嵌套 结构化提取+表格独立处理
HTML BeautifulSoup 广告/导航噪声 CSS选择器+正文提取
表格 Camelot/Tabula 跨页表格、合并单元格 单表独立切分+结构化描述
混合排版 Unstructured/MinerU 图文混排、公式 多模态解析+元素分类

扫描件处理流程:

  1. 图像预处理(去噪、倾斜校正)
  2. 版面分析(区分文本区/表格区/图片区)
  3. OCR识别(PaddleOCR中文场景准确率>95%)
  4. 阅读顺序恢复
  5. 结构化输出(Markdown/JSON)

面试加分点:提及"阿里/腾讯在OCR解析准确率上国内领先,腾讯云的AI文档解析准确率提升30%(居全国第一)"。主动推荐开源工具MinerU(原Magic-PDF),对中文PDF解析效果很好。

⚠️ 常见踩坑:1)直接用PyPDF2解析中文PDF乱码是常见问题;2)表格不能简单转成文本,字段和数值的对应关系会丢失;3)扫描件不做版面分析直接OCR,阅读顺序会错乱。

生产实战要点:

python 复制代码
# 生产级文档解析Pipeline
from unstructured.partition.auto import partition
from unstructured.documents.elements import Table, Image

def parse_document(file_path: str) -> list[dict]:
    """统一文档解析入口"""
    elements = partition(filename=file_path)
    chunks = []
    for element in elements:
        chunk = {
            "content": str(element),
            "type": type(element).__name__,
            "metadata": {
                "page_number": element.metadata.page_number,
                "source": file_path,
            }
        }
        # 表格特殊处理:生成结构化描述
        if isinstance(element, Table):
            chunk["content"] = f"表格内容:\n{element.to_text()}\n结构化描述:{describe_table(element)}"
            chunk["metadata"]["is_table"] = True
        chunks.append(chunk)
    return chunks

def describe_table(table) -> str:
    """用LLM生成表格的自然语言描述,增强语义检索效果"""
    # 将表格转为Markdown格式,让LLM生成描述
    table_md = table.to_markdown()
    prompt = f"请用简洁的自然语言描述以下表格的核心内容:\n{table_md}"
    return llm.generate(prompt)

Q6: 文本切分策略有哪些?如何选择合适的chunk size和overlap?这背后有什么权衡?

核心答案:

四种主流切分策略:

策略 原理 优点 缺点 适用场景
固定长度切分 按字符/Token数切割 简单、速度快 语义断裂 日志、短文本
递归切分 按分隔符层级递归切割 较好的语义完整性 不理解文档结构 通用场景(最常用)
语义切分 用Embedding相似度判断切分点 语义完整性最好 速度慢、成本高 高质量知识库
Markdown结构切分 按标题层级切割 保留文档结构 仅适用于结构化文档 Markdown/技术文档

Chunk Size权衡:

chunk_size 优势 劣势 推荐场景
100-200 tokens 检索精准度高 上下文丢失严重 事实型问答(精确匹配)
300-500 tokens 平衡精准与上下文 通用性最好 通用RAG知识库(推荐默认值)
600-800 tokens 上下文完整 检索噪声多、精准度下降 长文档摘要/分析
1000+ tokens 保留完整段落 检索非常不准 不推荐作为默认

Overlap设置:黄金比例10%-20%,语义密度高的文本(医疗/法律)可提升至25%-30%。

面试加分点:提及"Parent-Child索引(Small-to-Big)策略"------用小chunk(200 tokens)做精准检索,命中后返回大chunk(1000 tokens)给LLM,兼顾检索精准和上下文完整。同时提及NVIDIA的实验结论:页级切分(Page-level)在多样性数据集上平均准确率最高(0.648),且方差最小。

⚠️ 常见踩坑:1)chunk_overlap永远不要设为0,否则跨块信息必丢失;2)固定长度切分是最常见的"偷懒"做法,生产环境应优先用递归切分或语义切分;3)表格必须整表作为一个chunk,不能切割。

深入追问与应对:

  • 追问:如何确定最优chunk_size? → 没有银弹,需要根据业务数据做实验。推荐方法:1)用不同chunk_size构建索引;2)在同一测试集上对比Recall@K和Answer Correctness;3)选择效果最佳的参数。LlamaIndex的ChunkSizeExperiment可以自动化这个过程。

生产实战要点:

python 复制代码
# 递归切分(生产推荐)
from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n", "\n", "。", "!", "?", ".", "!", "?", " ", ""],
    chunk_size=500,         # 字符数
    chunk_overlap=100,      # 20%重叠
    length_function=len,
    is_separator_regex=False,
)

# Markdown结构切分(技术文档推荐)
from langchain.text_splitter import MarkdownHeaderTextSplitter

headers_to_split_on = [
    ("#", "h1"),
    ("##", "h2"),
    ("###", "h3"),
]
md_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)

Q7: 元数据设计对RAG检索效果有什么影响?如何设计合理的元数据标注规范?

核心答案:

元数据是RAG检索的"第二维度",能在向量语义检索基础上提供精确的结构化过滤,大幅提升检索精准度。

核心元数据字段设计:

python 复制代码
# 生产级元数据Schema
metadata_schema = {
    # 来源信息
    "doc_id": "string",           # 文档唯一ID
    "source_title": "string",     # 文档标题
    "source_url": "string",       # 原文链接(用于引用溯源)
    
    # 结构信息
    "page_number": "int",         # 页码
    "section_path": "string",     # 章节路径(如"第3章 > 3.2节")
    "chunk_index": "int",         # 文档内chunk序号
    "parent_chunk_id": "string",  # 父chunk ID(Parent-Child索引)
    
    # 内容属性
    "doc_type": "string",         # 文档类型(pdf/word/html/table)
    "content_type": "string",     # 内容类型(text/table/image/code)
    
    # 时间信息
    "publish_date": "datetime",   # 发布日期
    "update_date": "datetime",    # 更新日期
    
    # 权限信息
    "department": "string",       # 所属部门
    "access_level": "string",     # 访问级别(public/internal/confidential)
    
    # 版本信息
    "version": "string",          # 文档版本号
    "is_latest": "bool",          # 是否最新版本
}

元数据在检索中的应用:

  • 时间过滤:查询"2024年Q3营收"时,过滤publish_date >= 2024-07-01
  • 权限过滤:不同用户只能看到access_level允许的文档
  • 版本过滤:优先检索is_latest=True的文档
  • 部门过滤:只检索用户所属department的文档

面试加分点:提及"Milvus 2.5+支持标量字段索引,元数据过滤可在向量检索前执行,大幅减少扫描量,查询效率提升3倍"。

⚠️ 常见踩坑:1)不标注时间戳导致检索到过期文档------金融场景曾因此出错;2)不标注版本号导致新旧版本混排;3)元数据字段过多会影响写入性能和存储成本。


Q8: 知识库质量如何评估与治理?如何保证知识库的持续高质量?

核心答案:

知识库质量评估维度:

  1. 完整性:知识覆盖度,是否有缺失的关键信息
  2. 准确性:内容是否正确,是否存在错误/过时信息
  3. 一致性:相同信息在不同文档中是否矛盾
  4. 时效性:信息是否是最新的
  5. 可检索性:切分是否合理,元数据是否完整

知识库治理SOP:

  1. 入湖检测:新文档入库前自动检测格式/质量/重复
  2. 定期巡检 :每周扫描过期文档(基于update_date),标记需要更新的内容
  3. 版本管理:文档更新时自动归档旧版本,检索默认走最新版
  4. 去重策略:基于内容hash做精确去重,基于Embedding相似度做模糊去重
  5. Bad Case反哺:收集检索失败的Case,分析是知识缺失还是检索问题

面试加分点:提及"知识库治理应该是持续运营而非一次性建设",并建议建立"知识库健康度看板",监控文档覆盖率、过期率、重复率等指标。

⚠️ 常见踩坑:1)知识库"只进不出",过期文档越来越多,检索噪声大;2)多人维护知识库缺乏规范,同一知识有多份不同表述的文档。


三、Embedding与向量化

Q9: 在中文场景下,如何选择合适的Embedding模型?评估一个Embedding模型好坏有哪些指标?

核心答案:

中文主流Embedding模型对比:

模型 维度 最大长度 特点 适用场景
BAAI/bge-large-zh-v1.5 1024 512 C-MTEB榜首,中文通用最佳 通用RAG首选
BAAI/bge-m3 1024 8192 多语言+长文本+多功能 多语言/长文档场景
m3e-large 1024 512 中文社区广泛使用 轻量级中文场景
text-embedding-3-large(OpenAI) 3072 8191 效果好但需API 云端API方案
GTE-Qwen2-1.5B 1536 32768 超长上下文 超长文档检索

Embedding模型评估指标:

  1. MTEB排行榜(Massive Text Embedding Benchmark):综合评估检索、分类、聚类等任务
  2. C-MTEB:中文专属Embedding评测基准
  3. 检索召回率(Recall@K):在业务数据集上的实际召回效果
  4. 跨语言能力:中英混合查询的支持度
  5. 推理速度:单条编码耗时(影响检索延迟)

面试加分点:1)强调"模型选型必须在业务数据上实测,排行榜仅供参考";2)提及"Embedding模型的上下文长度很重要,如果chunk超过模型最大长度,会被截断导致语义丢失"。

⚠️ 常见踩坑 :1)用英文Embedding模型处理中文,效果大幅下降;2)忽略normalize_embeddings参数,导致余弦相似度计算不准确;3)Embedding模型和Reranker模型的训练语料分布不一致。

生产实战要点:

python 复制代码
# Embedding模型选型测试框架
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

def evaluate_embedding_model(model_name, test_pairs):
    """
    在业务数据上评估Embedding模型
    test_pairs: [(query, relevant_doc, irrelevant_docs), ...]
    """
    model = SentenceTransformer(model_name)
    
    recall_at_5 = []
    for query, relevant, irrelevant_list in test_pairs:
        query_emb = model.encode([query], normalize_embeddings=True)
        all_docs = [relevant] + irrelevant_list
        doc_embs = model.encode(all_docs, normalize_embeddings=True)
        
        sims = cosine_similarity(query_emb, doc_embs)[0]
        top5_indices = sims.argsort()[-5:][::-1]
        hit = 1 if 0 in top5_indices else 0  # relevant在index 0
        recall_at_5.append(hit)
    
    return sum(recall_at_5) / len(recall_at_5)

# 推荐:在业务数据上对比3-5个模型
models = ["BAAI/bge-large-zh-v1.5", "BAAI/bge-m3", "m3e-large"]
for m in models:
    score = evaluate_embedding_model(m, test_data)
    print(f"{m}: Recall@5 = {score:.3f}")

Q10: 向量维度和上下文长度对RAG效果有什么影响?如何权衡?

核心答案:

向量维度影响:

  • 维度越高(768→1024→1536→3072),语义表达能力越强,但存储和检索成本线性增加
  • 实测:768维到1024维效果提升明显(约5-8%),1024到3072提升边际递减(约2-3%)
  • 生产建议:1024维是性价比甜蜜点,3072维仅在极端精度要求场景使用

上下文长度影响:

  • 如果chunk的token数超过模型最大长度,会被截断,丢失信息
  • 传统模型512 tokens → 长chunk需要截断 → 语义丢失
  • 新一代模型(bge-m3: 8192, GTE-Qwen2: 32768)支持长文本
  • 但更长的输入不总是更好:过长输入会"稀释"关键信息的向量表示

权衡策略:

  • 通用场景:1024维 + 512上下文(bge-large-zh)
  • 长文档场景:1024维 + 8192上下文(bge-m3)
  • 极致精度:1536维 + 8192上下文(GTE-Qwen2),但检索延迟增加30%

面试加分点:提及"向量维度和存储成本直接相关------1亿条1024维向量约需400GB存储,3072维则需1.2TB,这直接影响Milvus的内存规划和成本"。


Q11: 什么时候需要对Embedding模型做领域微调?如何做?

核心答案:

需要微调的信号:

  1. 通用模型在领域术语上语义理解差(如"逆回购"被理解为"反向购买")
  2. 业务测试集上Recall@K比通用基准低10%以上
  3. 存在大量领域专有名词/缩写/黑话

微调方法:

  • 有监督微调:构造(query, positive_doc, negative_docs)三元组,用对比学习(Contrastive Learning)训练
  • 困难负例挖掘:用BM25或ANN召回的"假阳性"文档作为困难负例,比随机负例效果好很多
  • 合成数据增强:用LLM生成领域query-doc对,扩充训练数据

微调框架:

python 复制代码
# 使用sentence-transformers微调
from sentence_transformers import SentenceTransformer, InputExample, losses
from torch.utils.data import DataLoader

model = SentenceTransformer("BAAI/bge-large-zh-v1.5")

# 构造训练数据:(query, positive, negative)
train_examples = [
    InputExample(texts=["什么是逆回购", "国债逆回购是...", "回购是..."], label=1),
    # ... 更多领域样本
]

train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=32)
train_loss = losses.MultipleNegativesRankingLoss(model)

model.fit(
    train_objectives=[(train_dataloader, train_loss)],
    epochs=3,
    warmup_steps=100,
    output_path="./models/bge-finance-finetuned"
)

面试加分点:强调"微调数据质量>>数据数量",500条高质量领域三元组可能比5000条低质量数据效果更好。同时建议"先试Reranker微调,因为Reranker微调的ROI通常高于Embedding微调"。

⚠️ 常见踩坑:1)微调数据量不足(<200条)会导致灾难性遗忘;2)不做困难负例挖掘,只用随机负例,模型区分能力弱。


Q12: 多模态Embedding如何实现?文本+图像+表格如何统一向量化?

核心答案:

多模态Embedding方案:

  1. CLIP系列:文本+图像共享向量空间,支持跨模态检索

    • 流程:图像通过ViT编码,文本通过Text Encoder编码,映射到同一向量空间
    • 中文推荐:Chinese-CLIP、BGE-VL
  2. ColPali:直接用视觉模型处理文档图像,无需OCR

    • 优势:保留文档的视觉布局信息(表格、公式、图表)
    • 适合:扫描件/复杂排版文档
  3. 表格Embedding

    • 方案A:TableBERT/TAPAS专用表格模型
    • 方案B:将表格转为Markdown/自然语言描述,用文本Embedding
    • 生产推荐:方案B更实用,成本更低

多模态统一向量空间实现:

python 复制代码
# 文本+图像统一检索方案
from transformers import CLIPModel, CLIPProcessor

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

# 图像向量化
image_emb = model.get_image_features(pixel_values=image_inputs)

# 文本向量化
text_emb = model.get_text_features(input_ids=text_inputs)

# 跨模态检索:用文本query检索图片
similarity = cosine_similarity(text_emb, image_emb)

生产实战关键点:

  • 图片不直接存原图向量,而是存VLM生成的文本描述+图像向量(双保险)
  • 表格同时生成文本化描述向量 + 结构化向量
  • 检索时做模态路由:问题含"图/表/曲线"→优先检索图片/表格块

面试加分点:提及"ColPali是2024-2025年的热门方向,直接用视觉特征做文档检索,跳过OCR环节,在复杂版面文档上效果远超传统方案"。


Q13: 向量归一化的作用是什么?余弦相似度、欧氏距离、点积如何选择?

核心答案:

向量归一化:将向量除以其L2范数,使其长度为1。归一化后:

  • 余弦相似度 = 点积(计算更高效)
  • 向量方向完全代表语义,长度信息被忽略

三种距离度量选择:

度量方式 公式 特点 适用场景
余弦相似度 cos(a,b) = a·b/( a ·
欧氏距离 L2 = √Σ(a-b)² 同时考虑方向和长度 图像检索/特征匹配
点积 IP = a·b 归一化后等价余弦,未归一化时受向量长度影响 归一化向量/推荐系统

生产建议:

  • RAG场景统一使用 余弦相似度 + 归一化向量
  • Embedding时设置normalize_embeddings=True
  • Milvus中设置metric_type="COSINE"

⚠️ 常见踩坑:1)未归一化的向量用点积做相似度,结果会受到文档长度影响(长文档向量范数大,排名靠前);2)不同度量方式不能混用,索引和查询必须一致。


四、向量数据库选型与优化

Q14: 主流向量数据库(Milvus/Chroma/Pinecone/Weaviate/Qdrant)如何选型?各自的优劣势是什么?

核心答案:

数据库 类型 开源 中文支持 混合检索 分布式 适用场景
Milvus 专用向量库 企业生产首选
Chroma 轻量向量库 ⚠️ 本地开发/Demo
Pinecone 云服务 基础 免运维快速上线
Weaviate 混合向量库 ⚠️ 知识图谱场景
Qdrant 专用向量库 ⚠️ 高精度Rust实现

选型决策树:

  • 本地开发/Demo/毕设 → Chroma(零部署,5分钟上手)
  • 初创团队/无运维/快速上线 → Pinecone(免运维,但长期成本高)
  • 企业生产/私有化/大数据量/高并发 → Milvus(唯一支撑工业级RAG的开源方案)
  • 需要知识图谱 + 向量检索 → Weaviate

面试加分点:1)提及"腾讯云联合Elastic构建十亿级向量RAG应用,服务器从400+台缩减至30台,成本降低90%";2)提及"Milvus 2.6版本内存占用降低72%、检索速度提升4倍"。

⚠️ 常见踩坑:1)用Chroma上生产------不支持混合检索、无分布式、性能差;2)Pinecone长期成本高,数据量大了月费可达数万美元;3)选型只看功能不看运维成本。


Q15: Milvus中HNSW、IVF、PQ索引如何选择?参数如何调优?

核心答案:

索引类型 原理 召回率 速度 内存 适用场景
HNSW 多层导航小世界图 高(95%+) 10万-1亿级RAG首选
IVF_FLAT 聚类分桶+桶内检索 低配机器/海量冷数据
IVF_PQ 向量量化压缩 极低 亿级归档/容忍精度损失
FLAT 暴力全量比对 100% 极慢 仅测试/<1000条
DiskANN SSD磁盘索引 极低 超大数据量/内存不足

HNSW参数调优:

python 复制代码
# Milvus HNSW索引参数
index_params = {
    "index_type": "HNSW",
    "metric_type": "COSINE",
    "params": {
        "M": 16,              # 每层最大连接数,越大召回越高但内存越大(推荐12-64)
        "efConstruction": 200  # 构建时搜索深度,越大索引质量越高但构建越慢(推荐100-500)
    }
}

# 查询时参数
search_params = {
    "metric_type": "COSINE",
    "params": {
        "ef": 64   # 搜索深度,越大召回越高但越慢(推荐Top-K的2-4倍)
    }
}

参数调优口诀:

  • M=16是通用甜蜜点,M=32-64适合极致精度
  • efConstruction=200是质量与速度的平衡点
  • 查询时ef至少设为Top-K的2倍

面试加分点:提及"一键选型:本地开发/RAG/10万~百万数据 → HNSW+COSINE;机器内存小 → IVF_FLAT+COSINE;亿级海量归档 → IVF_PQ;关键词+语义混合 → HNSW(密集)+SPARSE_INVERTED_INDEX(稀疏)"。

⚠️ 常见踩坑:1)生产环境用FLAT索引------数据量一上去直接卡死;2)忘记建索引就load------Milvus会报错;3)ef设得太小导致召回率骤降。


Q16: 如何实现混合检索(向量+关键词)?RRF融合算法的原理是什么?

核心答案:

混合检索的必要性:

  • 向量检索:擅长语义匹配("报销流程"↔"费用申请步骤"),但精确匹配弱("SKU-12345")
  • 关键词检索(BM25):擅长精确匹配,但同义理解弱
  • 混合检索 = 向量语义覆盖 + 关键词精确匹配,召回率提升30%+

Milvus 2.5+ 混合检索实现:

python 复制代码
from pymilvus import AnnSearchRequest, RRFRanker

# 1. 稠密向量检索请求
dense_req = AnnSearchRequest(
    data=[query_embedding],
    anns_field="dense_vector",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=20
)

# 2. 稀疏向量(BM25)检索请求
sparse_req = AnnSearchRequest(
    data=["用户查询文本"],  # 直接传文本,Milvus自动分词
    anns_field="sparse_bm25",
    param={"params": {"drop_ratio_search": 0.2}},
    limit=20
)

# 3. RRF融合
ranker = RRFRanker(k=60)  # k值影响排名平滑度,推荐60
results = collection.hybrid_search(
    reqs=[dense_req, sparse_req],
    ranker=ranker,
    limit=10,
    output_fields=["content", "source_title", "page_number"]
)

RRF(Reciprocal Rank Fusion)原理:

复制代码
RRF_score(d) = Σ 1/(k + rank_i(d))
  • k是平滑常数(默认60),防止排名1的文档权重过大
  • 每个检索器的排名都贡献分数,排名越靠前贡献越大
  • 不需要归一化不同检索器的原始分数(避免了分数尺度不一致的问题)

面试加分点 :1)提及"LangChain的EnsembleRetriever也能实现混合检索,但生产环境推荐Milvus原生混合检索,减少网络开销";2)解释RRF相比加权融合的优势:不需要调权重,对分数分布不敏感。


Q17: 大规模数据下向量数据库如何做分布式部署?多租户方案如何设计?

核心答案:

分布式部署方案(Milvus Cluster):

Milvus采用存算分离架构:

  • Proxy:无状态查询代理,可水平扩展
  • QueryNode:执行检索,可按Collection分片
  • DataNode:数据写入,按Segment管理
  • IndexNode:构建索引,按需启动
  • etcd:元数据存储
  • MinIO/S3:持久化存储
  • Pulsar/Kafka:WAL日志

多租户方案:

方案 原理 隔离性 性能 成本 适用场景
Partition Key 按租户ID自动分区 逻辑隔离 好(分区剪枝) 推荐首选
独立Collection 每租户一个Collection 强隔离 灵活 大租户
Partition 每租户一个Partition 逻辑隔离 中小租户
python 复制代码
# Milvus Partition Key多租户方案(推荐)
from pymilvus import CollectionSchema, FieldSchema, DataType

fields = [
    FieldSchema(name="tenant_id", dtype=DataType.VARCHAR, max_length=64, 
                is_partition_key=True),  # 自动按租户分区
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1024),
    FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=65535),
]
schema = CollectionSchema(fields=fields)
collection = Collection(name="rag_kb", schema=schema)

# 查询时自动分区剪枝,只搜索目标租户的数据
results = collection.search(
    data=[query_emb],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=5,
    expr='tenant_id == "tenant_001"',  # 租户过滤
)

面试加分点:提及"Partition Key同时实现多租户隔离和检索加速------Milvus在搜索时会自动剪枝不相关的分区,相当于先缩小搜索范围再检索,效率提升显著"。

⚠️ 常见踩坑:1)用独立Collection做租户隔离,租户多了Collection数爆炸,元数据管理崩溃;2)Partition有数量限制(默认4096),超多租户场景需用Partition Key。


五、检索策略与优化

Q18: 请详细解释查询改写(Query Rewriting)技术,有哪些具体方法?

核心答案:

查询改写的核心动机:用户查询太口语化/模糊/有指代,直接检索效果差。改写后更规范、更精确、更适合检索。

五种主要改写方法:

  1. 基础改写:将口语化查询改为规范表述

    • "它怎么用" → "XX产品的使用方法"
    • "那个流程又失败了" → "XX项目部署流程失败原因及排查步骤"
  2. 指代消解:结合对话历史,替换代词

    • 历史:"什么是Transformer?" → 当前:"它的注意力机制怎么算?" → 改写:"Transformer的Self-Attention计算方法"
  3. 查询扩展(Multi-Query):从多个角度生成变体查询

    • "RAG怎么优化" → ["提升RAG检索准确率的方法", "RAG系统常见优化策略", "如何改善检索增强生成效果"]
  4. 查询分解(Decomposition):复杂问题拆成子问题

    • "对比GPT-4和Claude在代码生成上的表现" → ["GPT-4代码生成能力评估", "Claude代码生成能力评估"]
  5. CoT递归拆分:让LLM用思维链逐步分解复杂查询

生产级改写实现:

python 复制代码
# 查询改写Prompt模板
REWRITE_PROMPT = """你是一个查询改写助手。将用户的对话式查询改写为适合向量数据库检索的独立查询。

规则:
1. 改写后的查询必须独立,不依赖对话上下文即可理解
2. 解析所有指代词("它"、"这个"等),替换为具体名词
3. 保留关键技术术语,不要过度简化
4. 改写结果应该是陈述性短语,不要用疑问句
5. 如果查询已足够明确,保持原样

对话历史:
{history}

当前查询:{query}
改写结果:"""

面试加分点:提供A/B测试数据------"客服多轮对话场景,指代消解成功率达89%,CoT拆分的多跳召回覆盖率达78%,两者叠加效果最佳(+22%满意度)"。

⚠️ 常见踩坑:1)改写过度------简单问题也被改复杂了,反而降低召回;2)改写丢失了原始查询的关键信息;3)改写增加延迟(约+100-200ms),需要在效果和延迟间权衡。


Q19: HyDE(假设文档嵌入)的原理是什么?适用于什么场景?有什么局限性?

核心答案:

HyDE原理:

  1. 用LLM根据用户Query生成一段"假想的回答文档"(内容可能不准)

  2. 用假想文档的Embedding去检索真实文档

  3. 为什么有效:假想文档和真实文档都是"文档体"表述,在向量空间中距离更近;而用户Query是"提问体",和文档的语义距离天然较远

    向量空间示意:
    Query向量 ●
    ↖ (距离远)
    真实文档A ● ● 真实文档B
    ↑ (距离近)
    假想文档 ● ← 用这个向量检索,和真实文档更接近

适用场景:

  • 用户查询太短/太模糊,直接检索召回差
  • 查询和文档表述差异大的场景
  • 学术/技术类问题(专业术语多)

局限性:

  • 生成假想文档增加延迟(+200-500ms)
  • 假想文档可能引入错误方向(LLM编造的内容可能导致检索跑偏)
  • 对时间敏感问题(股价/天气)不适用------假想文档可能"写死"过期数据
  • temperature必须≤0.3,否则LLM"放飞"会导致召回跑偏

面试加分点:提及"HyDE的变体Query2doc效果也很好,将Query和伪文档拼接后再做Embedding,而不是完全替换Query。实测Recall@5从0.68提升到0.80(+12%)"。

⚠️ 常见踩坑:1)假想文档>100 token会引入幻觉,80 token是甜蜜点;2)对事实性精确查询("2024年Q3营收")不适合用HyDE,应该用关键词检索。

生产实战要点:

python 复制代码
# HyDE轻量级实现
def hyde_retrieve(query: str, vectorstore, top_k: int = 5) -> list:
    """HyDE检索:先生成假想文档,再检索"""
    # Step 1: 生成假想文档
    prompt = f"""请针对以下问题,写一段专业的技术文档片段。
    要求:直接给出内容,不要包含"根据"、"以下是"等引导语。
    尽量覆盖相关技术术语和概念。长度控制在80字以内。
    问题:{query}"""
    
    pseudo_doc = llm.generate(prompt, max_tokens=80, temperature=0.3)
    
    # Step 2: 用假想文档做检索
    results = vectorstore.similarity_search(
        query=pseudo_doc,  # 用假想文档替代原始Query
        k=top_k
    )
    return results

Q20: Rerank模型的作用是什么?Cross-Encoder与Bi-Encoder有什么区别?如何选型?

核心答案:

为什么需要Rerank?

  • 向量检索(Bi-Encoder)是"粗排",速度快但精度有限
  • Rerank(Cross-Encoder)是"精排",速度慢但精度高
  • 典型流程:粗排Top-50/100 → Rerank精排Top-5/10 → 送入LLM

Cross-Encoder vs Bi-Encoder:

维度 Bi-Encoder Cross-Encoder
输入 query和doc分别编码 query和doc拼接后联合编码
速度 快(向量预计算) 慢(每对都要过模型)
精度 高(full attention交互)
适用阶段 初筛/粗排 精排/Rerank
典型模型 BGE/M3E BGE-Reranker/Cohere Rerank

Reranker选型:

模型 特点 延迟 适用场景
BGE-Reranker-v2-m3 开源、多语言 ~50ms/对 中文场景首选
Cohere Rerank API调用、效果好 ~100ms/对 快速集成/英文场景
ms-marco-MiniLM-L-6-v2 轻量、速度快 ~20ms/对 低延迟场景
bge-reranker-large 精度最高 ~80ms/对 精度优先

面试加分点:1)提及"Rerank是RAG系统中ROI最高的优化环节,通常能带来10-20%的准确率提升";2)"Rerank微调的ROI远高于Embedding微调------4k正例+8k困难负例微调Reranker,Recall提升9.7%"。

⚠️ 常见踩坑:1)Rerank的输入是(query, doc)对,不要把所有文档拼接在一起;2)Rerank增加延迟,需要控制候选数量(建议Top-20到Top-50);3)开源Reranker中文效果不如英文,建议优先试BGE-Reranker-v2-m3。

生产实战要点:

python 复制代码
# BGE-Reranker使用示例
from FlagEmbedding import FlagReranker

reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True)

# 对粗排结果重排序
scores = reranker.compute_score([
    [query, doc1_content],
    [query, doc2_content],
    # ...
])

# 按分数排序,取Top-N
ranked_results = sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)[:5]

Q21: 检索评估指标有哪些?Recall@K、MRR、NDCG、Hit Rate分别怎么理解?

核心答案:

指标 含义 公式 关注点
Recall@K 前K个结果中包含多少相关文档 相关文档∩Top-K / 总相关文档 召回全面性
Hit Rate 前K个结果中是否至少包含1个相关文档 1 if 命中 else 0 是否能找到
MRR 第一个相关文档的排名倒数的均值 1/rank_of_first_relevant 相关文档排得靠不靠前
NDCG 考虑位置权重的归一化增益 DCG/IDCG 排序质量(位置越靠前权重越高)

生产场景选择:

  • 关注"是否找到"→ Hit Rate(简单直观)
  • 关注"找全了吗"→ Recall@K(知识库场景核心指标)
  • 关注"排得对不对"→ NDCG(推荐系统场景)
  • 关注"第一个正确结果在哪里"→ MRR(搜索场景)

面试加分点:提及"RAG场景最核心的指标是Recall@5或Recall@10,因为LLM的生成质量高度依赖检索的全面性------如果正确文档没被召回,LLM不可能生成正确答案"。

⚠️ 常见踩坑:1)只看Precision不看Recall------召回不全比混入噪声更致命;2)评估指标和业务目标不一致------搜索场景看重排序(NDCG),RAG场景看重召回(Recall)。


Q22: 分页检索与深度分页问题如何解决?

核心答案:

问题:向量数据库的分页通常基于Top-K检索,当用户翻到第N页时,需要检索Top-(N×pageSize)个结果,页码越深,检索成本越高。

解决方案:

  1. Search After(推荐):基于上一页最后一条结果的排序值继续检索,避免重复计算
  2. 缓存策略:首次检索时缓存Top-100结果,翻页时从缓存读取
  3. 限制最大页数:只允许翻到前5-10页,超出则建议用户优化查询
  4. 预计算:高频查询的Top-50结果预计算并缓存

生产建议:RAG场景不同于搜索,用户通常只需要第一页的Top-5/Top-10结果,深度分页需求极少。如果确实需要,建议用Search After模式。


六、RAG生成与后处理

Q23: RAG场景下如何设计高效的Prompt?有哪些最佳实践?

核心答案:

RAG Prompt设计最佳实践:

python 复制代码
# 生产级RAG Prompt模板
RAG_PROMPT = """你是一个专业的知识助手。请严格基于以下参考资料回答用户问题。

## 参考资料
{context_with_citations}

## 回答要求
1. 只基于参考资料中的信息回答,不得编造或推测
2. 如果参考资料不足以回答问题,请明确说明"根据现有资料无法完全回答"
3. 在回答中标注引用来源,格式:[来源编号]
4. 如果参考资料之间存在矛盾,请指出并分别说明
5. 回答要简洁准确,不要重复参考资料的原话,要用自己的语言总结

## 用户问题
{query}

## 回答
"""

核心原则:

  1. 约束性指令:"只基于参考资料"、"不得编造"------减少幻觉
  2. 引用要求:"标注引用来源"------可溯源,提升可信度
  3. 拒答机制:"资料不足时明确说明"------避免模型编造
  4. 冲突处理:"指出矛盾"------处理检索结果不一致的情况
  5. 结构化输出:要求模型按"结论+依据+建议"三段式回答

上下文注入格式(带引用编号):

复制代码
[1] 来源:XX手册第3页 - 内容...
[2] 来源:YY规范第5章 - 内容...
[3] 来源:ZZ公告 - 内容...

面试加分点:1)提及"不同场景需要不同的Prompt模板------客服场景要求'三段式(结论+依据+建议)',运营场景要求'表格化输出'";2)提及"Lost in the Middle问题------LLM对中间位置的上下文关注度低,建议将最相关的文档放在Prompt的首尾位置"。

⚠️ 常见踩坑:1)Prompt中没有明确要求"只基于参考资料",模型会混入自己的知识;2)没有拒答机制,模型宁愿编造也不说"不知道";3)检索结果太多塞满上下文窗口,反而干扰生成。


Q24: 上下文窗口管理有哪些策略?如何处理长文档?

核心答案:

上下文窗口限制的影响:

  • GPT-4: 128K tokens,GPT-4o: 128K
  • Claude 3.5: 200K
  • 但实际有效利用远低于理论值------"Lost in the Middle"现象

上下文管理策略:

  1. 检索结果压缩

    • LLM Lingua:用小模型压缩上下文,保留关键信息
    • 提取式压缩:只保留和Query相关的句子
    • 实测:Token消耗可降低70-80%,效果损失<5%
  2. 动态Top-K调整

    • 简单问题:Top-3,复杂问题:Top-10
    • 根据检索分数分布动态决定------分数差距大说明区分度高,少取几个
  3. 分层次上下文注入

    • 核心证据(Rerank Top-3):完整注入
    • 补充证据(Top-4~10):只注入摘要
    • 背景信息(Top-11~20):只注入标题
  4. 长文档处理

    • Map-Reduce:先对每个chunk独立生成摘要,再合并
    • Refine:逐chunk迭代优化答案
    • Parent-Child:小chunk检索,大chunk注入

面试加分点:提及"长上下文模型(128K+)不意味着可以无脑塞入所有检索结果------过多的无关上下文反而降低回答质量。研究表明,最优上下文长度通常在2K-4K tokens左右"。


Q25: RAG中的幻觉检测与缓解策略有哪些?

核心答案:

RAG幻觉分类(2026工业界标准):

类型 定义 占比 解决方法
事实性幻觉 编造上下文中不存在的事实/数据 60% Prompt约束+引用增强
引用幻觉 错误标注引用来源 25% 引用校验+后处理过滤
上下文外幻觉 混入检索上下文之外的信息 15% 拒答机制+知识边界控制

幻觉检测方法:

  1. Faithfulness评估(RAGAS):将答案拆成陈述句,逐一验证是否可从上下文推断
  2. 引用校验:检查答案中的每个引用标注是否与原文一致
  3. 自一致性:多次生成取交集,不一致的部分可能是幻觉
  4. LLM-as-Judge:用另一个LLM判断答案是否忠实于上下文

幻觉缓解全链路方案:

复制代码
文档源治理 → 文档解析 → 文本切分 → 向量化 → 检索召回 → Reranker重排
→ 上下文组装 → 低temperature生成 → 引用要求 → 答案校验 → 低置信度则拒答

面试加分点:提及"未经优化的Naive RAG幻觉率35-50%,工业级优化后可控制在5%以下,金融/法律/医疗要求<1%"。

⚠️ 常见踩坑:1)只靠Prompt约束防幻觉是不够的------如果检索内容本身有问题,模型会基于错误内容稳定输出错误答案;2)低temperature只能降低随机幻觉,不能保证事实正确。


Q26: 引用溯源如何实现?如何保证答案的可信度?

核心答案:

引用溯源实现方案:

方案1:Chunk打标签(基础方案)

python 复制代码
# 入库时为每个chunk预埋引用标识
chunk_metadata = {
    "citation_id": f"[doc_{doc_id}_p{page_num}_c{chunk_idx}]",
    "source_title": doc.title,
    "source_url": doc.url,
    "page_number": page_num,
}

# Prompt中注入带编号的上下文
context = ""
for i, chunk in enumerate(retrieved_chunks):
    context += f"[{i+1}] 来源:{chunk.metadata['source_title']} 第{chunk.metadata['page_number']}页\n{chunk.content}\n\n"

方案2:后处理验证(进阶方案)

python 复制代码
# 生成答案后,验证每个句子的引用
def verify_citations(answer: str, chunks: list) -> dict:
    sentences = split_into_sentences(answer)
    verification = []
    for sent in sentences:
        # 用Embedding相似度匹配最相关的chunk
        sent_emb = embedding_model.encode(sent)
        chunk_embs = [embedding_model.encode(c.content) for c in chunks]
        similarities = cosine_similarity([sent_emb], chunk_embs)[0]
        best_match_idx = similarities.argmax()
        verification.append({
            "sentence": sent,
            "matched_source": chunks[best_match_idx].metadata["citation_id"],
            "confidence": similarities[best_match_idx]
        })
    return verification

方案3:LLM辅助校验:让LLM判断答案中的每个声明是否能从提供的上下文中推导出来。

面试加分点:提及"引用溯源不仅是技术问题,更是合规需求------金融、医疗、法律场景下,每个回答都必须可追溯来源"。


Q27: 流式输出(Streaming)在RAG中如何实现?

核心答案:

为什么需要流式输出? RAG的端到端延迟通常1-5秒,用户等待体验差。流式输出可以让用户看到"正在思考"的过程,体感延迟大幅降低。

实现方案:

python 复制代码
# 基于LangChain的流式RAG
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

# 1. LLM层流式输出
llm = ChatOpenAI(
    model="gpt-4",
    streaming=True,
    callbacks=[StreamingStdOutCallbackHandler()]
)

# 2. 完整流式Pipeline
async def stream_rag_response(query: str):
    # Step 1: 检索(同步,~100-300ms)
    docs = retriever.get_relevant_documents(query)
    yield {"type": "retrieval_done", "sources": [d.metadata for d in docs]}
    
    # Step 2: 流式生成
    context = format_context(docs)
    prompt = build_prompt(context, query)
    
    async for chunk in llm.astream(prompt):
        yield {"type": "token", "content": chunk.content}
    
    # Step 3: 引用信息
    yield {"type": "citations", "sources": extract_citations(docs)}

生产关键点:

  • 检索阶段无法流式(必须等完整结果),但可以在检索时显示"正在搜索知识库..."
  • SSE(Server-Sent Events)是主流传输协议
  • 前端需要支持逐字渲染和Markdown流式解析

七、生产级RAG系统架构

Q28: 如何设计高可用的RAG系统架构?

核心答案:

高可用架构核心原则:

  1. 存算分离:向量数据库、LLM服务、业务逻辑独立部署
  2. 多级冗余:LLM多模型fallback(GPT-4 → Claude → 本地模型)
  3. 熔断降级:LLM超时自动降级到缓存/预设回答
  4. 灰度发布:新版本先放5%流量验证,逐步放量

千万级RAG系统架构:

复制代码
用户请求 → CDN → LB(多活) → API网关
                              ├── Query预处理服务(可水平扩展)
                              ├── 检索服务 → Milvus Cluster(主从复制)
                              ├── Rerank服务(GPU实例)
                              ├── LLM服务(多副本 + 多模型fallback)
                              └── 缓存层(Redis + 语义缓存)

关键指标:

  • 可用性:99.9% = 每天最多8.6秒不可用
  • 延迟目标:P99 < 2秒
  • QPS:1000万/天 ≈ 116 QPS(峰值可达10倍)

面试加分点:提及"LLM层的容错设计是关键------模型API可能超时/限流/返回异常,必须有重试机制(指数退避)+熔断器+降级策略"。


Q29: 语义缓存的原理是什么?如何设计RAG系统的缓存策略?

核心答案:

语义缓存 vs 精确缓存:

缓存类型 匹配方式 命中率 准确性 延迟
精确缓存 Query完全匹配 100% <5ms
语义缓存 Query语义相似度>阈值 依赖阈值 <100ms

语义缓存原理:

  1. 用户Query → Embedding → 在缓存向量库中搜索
  2. 如果找到相似度>阈值(0.85-0.95)的缓存项 → 直接返回缓存答案
  3. 否则 → 走正常RAG流程,结果写入缓存

阈值选择:

  • 高精度场景(金融/医疗):0.90-0.95
  • 高召回场景(通用客服):0.85-0.90

多级缓存架构:

python 复制代码
class MultiLevelCache:
    def __init__(self):
        self.local_cache = {}       # L1: 本地内存,<1ms
        self.redis_cache = Redis()  # L2: Redis精确缓存,~5ms  
        self.semantic_cache = SemanticCache(  # L3: 语义缓存,~50ms
            threshold=0.90,
            vectorstore=Milvus(collection="cache")
        )
    
    async def get(self, query: str):
        # L1: 精确匹配本地缓存
        if query in self.local_cache:
            return self.local_cache[query]
        
        # L2: 精确匹配Redis
        cached = await self.redis_cache.get(hash(query))
        if cached:
            return cached
        
        # L3: 语义匹配
        results = await self.semantic_cache.search(query, top_k=1)
        if results and results[0].score >= 0.90:
            return results[0].answer
        
        return None  # 缓存未命中,走RAG流程

面试加分点:1)提及"Redis官方实现语义缓存后成本降低68.8%,响应速度快65倍";2)"语义缓存的阈值需要根据业务做A/B测试,阈值太高命中率低,太低会返回不相关答案"。

⚠️ 常见踩坑:1)语义缓存返回了"看起来相似但实际不同"的答案;2)缓存没有TTL导致过期信息被返回;3)缓存和知识库更新不同步。


Q30: RAG系统的监控与可观测性如何设计?

核心答案:

三层监控体系:

  1. 基础设施监控(Prometheus + Grafana)

    • CPU/GPU/内存/磁盘使用率
    • 向量数据库QPS/延迟/连接数
    • LLM API调用次数/延迟/错误率
  2. 应用链路追踪(LangSmith/LangFuse/Jaeger)

    • 每个请求的全链路Trace
    • 各阶段耗时:Query预处理 → 检索 → Rerank → 生成
    • 检索到的chunks及相似度分数
    • Token消耗和成本追踪
  3. RAG质量监控(核心差异化)

    • 检索质量:Recall@K、Context Precision趋势
    • 生成质量:Faithfulness、Answer Relevance
    • 幻觉率:定期采样人工标注 + LLM-as-Judge自动评估
    • 用户反馈:点赞/踩比例

关键告警规则:

yaml 复制代码
alerts:
  - name: rag_latency_high
    condition: rag_latency_p99 > 3000ms
    action: 通知oncall
  
  - name: retrieval_quality_drop
    condition: avg(context_precision_1h) < 0.7
    action: 触发Bad Case分析
  
  - name: hallucination_rate_high
    condition: daily_hallucination_rate > 10%
    action: 暂停自动发布 + 人工审核
  
  - name: cache_hit_rate_low
    condition: cache_hit_rate_1h < 30%
    action: 检查缓存配置

面试加分点:提及"RAG可观测性最重要的是关联ID(Correlation ID)------每个用户请求携带唯一ID,贯穿检索/重排/生成全链路,出现问题时可以完整复现执行路径"。


Q31: 数据更新与增量索引如何实现?

核心答案:

增量更新核心机制:

  1. 变更检测:基于文档内容hash检测新增/修改/删除
  2. 增量写入:只处理变化的文档,不重建整个索引
  3. 版本管理 :旧版本标记为is_latest=False,新版本写入
  4. 原子性保证:删除旧chunks和写入新chunks在同一事务中完成
python 复制代码
# 增量更新Pipeline
class IncrementalIndexer:
    def __init__(self, vectorstore, metadata_store):
        self.vectorstore = vectorstore
        self.metadata_store = metadata_store  # 记录文档hash和索引状态
    
    async def update_documents(self, documents: list[Document]):
        for doc in documents:
            content_hash = hash(doc.content)
            stored_hash = await self.metadata_store.get_hash(doc.id)
            
            if stored_hash == content_hash:
                continue  # 未变化,跳过
            
            if stored_hash is not None:
                # 文档已修改:先删旧chunks
                await self.vectorstore.delete(expr=f'doc_id == "{doc.id}"')
            
            # 解析、切分、向量化、写入
            chunks = self.split_and_embed(doc)
            await self.vectorstore.add_documents(chunks)
            
            # 更新hash记录
            await self.metadata_store.set_hash(doc.id, content_hash)

垃圾回收:自动清理源文档已删除的孤立chunks,防止知识库逐渐退化。

⚠️ 常见踩坑:1)更新期间可能出现短暂的"部分文档缺失"窗口;2)大规模更新时向量库写入压力骤增,需要限流;3)忘记清理旧版本chunks,导致检索到过期信息。


Q32: RAG系统如何做成本优化?

核心答案:

成本构成分析:

  • LLM API调用:占总成本50-70%(最大头)
  • 向量数据库:20-30%
  • Embedding计算:5-10%
  • Reranker:5-10%

优化策略:

  1. 语义缓存:相似Query复用答案,减少LLM调用,成本降低60%+
  2. 模型路由:简单问题用GPT-3.5(0.5/1M tokens),复杂问题用GPT-4(30/1M tokens),平均成本降低80%
  3. 上下文压缩:压缩检索结果再送入LLM,Token消耗降低70%
  4. 本地模型替代:高频简单场景用本地Qwen2-7B替代GPT-4
  5. Embedding缓存:相同文档不重复计算Embedding
  6. 向量量化:IVF_PQ压缩向量,内存降低75%

面试加分点:提供具体数据------"某客户通过模型路由+语义缓存,月度LLM API成本从2万美元降至3000美元,同时保持95%的回答质量"。


八、RAG系统评估与优化闭环

Q33: RAGAS评估框架包含哪些核心指标?如何理解和使用?

核心答案:

RAGAS核心指标体系:

指标 评估对象 需要参考答案 计算方式
Context Precision 检索结果排序质量 相关文档是否排在前面
Context Recall 检索结果覆盖度 参考答案中的陈述是否可从上下文推断
Faithfulness 生成答案忠实度 答案中的陈述是否可从上下文推断
Answer Relevance 答案与问题相关性 答案是否能反向推导出原问题
Answer Correctness 答案正确性 答案与参考答案的一致性

分数解读:

  • 0.9-1.0:优秀
  • 0.7-0.9:良好
  • 0.5-0.7:一般,需优化
  • <0.5:较差,严重问题

使用方式:

python 复制代码
from ragas import evaluate
from ragas.metrics import (
    context_precision, context_recall,
    faithfulness, answer_relevance,
    answer_correctness
)
from datasets import Dataset

# 准备评估数据
eval_data = {
    "question": [...],
    "answer": [...],           # RAG系统生成的答案
    "contexts": [...],         # 检索到的上下文
    "ground_truth": [...]      # 人工标注的参考答案(部分指标需要)
}
dataset = Dataset.from_dict(eval_data)

# 运行评估
results = evaluate(
    dataset=dataset,
    metrics=[
        context_precision, context_recall,
        faithfulness, answer_relevance,
        answer_correctness
    ],
    llm=ChatOpenAI(model="gpt-4"),  # Judge LLM
    embeddings=HuggingFaceEmbeddings(model_name="BAAI/bge-large-zh-v1.5")
)
print(results)

面试加分点:1)提及"RAGAS的核心创新是无参考评估------大部分指标不需要人工标注的参考答案,利用LLM-as-Judge降低评估成本";2)"Context Precision和Context Recall之间存在权衡------增加检索数量提高Recall但降低Precision"。

⚠️ 常见踩坑:1)RAGAS内置提示词是英文的,中文场景需要定制;2)评估结果受Judge LLM质量影响------建议用GPT-4做Judge;3)少量样本评估结果不稳定,建议至少100条测试集。


Q34: 如何建立自动化的RAG评估Pipeline?

核心答案:

自动化评估Pipeline架构:

复制代码
[知识库文档] → LLM自动生成测试集 → [测试集]
                                           ↓
[用户真实Query] → RAG系统 → [生成结果] → RAGAS评估 → [评估报告]
                    ↑                                    ↓
              [检索日志] → Bad Case分析 → 优化建议 → [迭代优化]

测试集生成策略:

  1. 进化生成(RAGAS自带):从文档中自动生成(question, context, answer)三元组
  2. 真实Query采样:从生产日志中采样真实用户Query
  3. 人工标注补充:对关键场景人工编写Golden Set

自动化评估脚本:

python 复制代码
# 每日自动评估Job
class DailyRAGEvaluation:
    def __init__(self, rag_chain, eval_dataset):
        self.rag_chain = rag_chain
        self.eval_dataset = eval_dataset
    
    async def run(self):
        # 1. 运行RAG系统
        results = []
        for sample in self.eval_dataset:
            answer = await self.rag_chain.ainvoke(sample["question"])
            results.append({
                "question": sample["question"],
                "answer": answer["result"],
                "contexts": [d.page_content for d in answer["source_documents"]],
                "ground_truth": sample["ground_truth"]
            })
        
        # 2. RAGAS评估
        dataset = Dataset.from_list(results)
        scores = evaluate(dataset, metrics=[...])
        
        # 3. 对比基线,检测退化
        baseline = load_baseline()
        regression = detect_regression(scores, baseline)
        
        # 4. 生成报告
        if regression:
            alert_team(f"RAG质量退化: {regression}")
        
        # 5. 保存评估结果
        save_evaluation(scores)
        return scores

面试加分点:强调"评估应该是持续的过程而非一次性活动------每次系统变更后自动跑评估,像CI/CD一样做'质量门禁'"。


Q35: Bad Case分析与反馈闭环怎么做?

核心答案:

Bad Case分类框架:

问题类型 定位方法 典型原因 修复方向
检索不到 Recall@K=0 chunk切分不当/Embedding不匹配 优化切分/换Embedding
检索到了但不相关 Context Precision低 向量语义漂移/噪声多 加Rerank/优化Query
检索相关但生成错误 Faithfulness低 Prompt问题/LLM幻觉 优化Prompt/加引用约束
检索相关且生成相关但不够好 Answer Relevance低 上下文不完整/Top-K不够 增加检索量/Parent-Child

反馈闭环流程:

复制代码
用户反馈(踩/赞)→ 标记Bad Case → 自动分类(检索/生成问题)
→ 根因分析 → 定向优化 → A/B测试验证 → 上线

关键指标追踪:

  • Bad Case率趋势(周维度)
  • 各类问题占比(检索vs生成)
  • 修复率(已修复/总数)

面试加分点:提及"建立Bad Case的'诊断树'------先用RAGAS的Context Precision/Recall定位是检索问题,再用Faithfulness定位是生成问题,精准施策"。


Q36: RAG系统的持续优化策略有哪些?

核心答案:

持续优化的四个维度:

  1. 数据层优化(最基础)

    • 定期补充缺失知识
    • 清理过期/冗余文档
    • 优化切分策略(根据Bad Case调整chunk_size)
  2. 检索层优化(效果最明显)

    • 混合检索权重调优
    • Reranker模型微调(困难负例挖掘)
    • Query改写策略迭代
  3. 生成层优化(锦上添花)

    • Prompt模板A/B测试
    • 模型版本升级
    • 温度/top_p参数调优
  4. 架构层优化(长期演进)

    • 缓存策略优化(提升命中率)
    • 模型路由优化(降本增效)
    • 新技术引入(如Agentic RAG)

优化优先级排序:数据层 > 检索层 > 生成层 > 架构层


九、高级RAG技术

Q37: 什么是Agentic RAG?与传统RAG有什么本质区别?

核心答案:

Agentic RAG = 传统RAG + LLM Agent自主决策

核心升级:从"被动检索+生成"升级为"主动理解→规划→多轮检索→反思→生成"。

维度 传统RAG Agentic RAG
检索策略 固定流程,一次检索 Agent动态决策,多轮检索
问题理解 浅层关键词匹配 深层意图识别+槽位提取
复杂问题 无法处理多跳推理 可拆分子问题逐步推理
纠错能力 自我反思+纠错+重检索
交互方式 单轮问答 可反问澄清、主动补全
多源融合 通常单知识库 并行调用向量库/Web/DB/API

Agentic RAG主流实现路线:

  1. Self-RAG:模型自主判断何时检索、评估检索质量
  2. CRAG(Corrective RAG):检索质量差时自动纠错降级(如切换到Web Search)
  3. ReAct-RAG:推理→行动→观察循环
  4. Plan-RAG:先全局规划检索步骤,再按序执行
  5. Router-RAG:前置分类器,不同问题走不同Pipeline

面试加分点:1)提及"Agentic RAG不是银弹------它增加了延迟(多轮检索+LLM决策)和成本(多次LLM调用),适合复杂查询场景,简单问答不需要";2)"生产中推荐Router-RAG------按问题复杂度路由到不同Pipeline,平衡效果和成本"。

生产实战要点:

python 复制代码
# LangGraph实现Agentic RAG
from langgraph.graph import StateGraph, END

def should_retrieve(state):
    """判断是否需要检索"""
    if state["confidence"] > 0.8:
        return "generate"
    return "retrieve"

def check_relevance(state):
    """评估检索结果相关性"""
    if state["relevance_score"] > 0.7:
        return "generate"
    elif state["retry_count"] < 3:
        return "rewrite_query"  # 改写后重试
    else:
        return "web_search"     # 降级到Web搜索

# 构建Agentic RAG图
workflow = StateGraph(AgentState)
workflow.add_node("retrieve", retrieve_node)
workflow.add_node("generate", generate_node)
workflow.add_node("rewrite_query", rewrite_node)
workflow.add_node("web_search", web_search_node)

workflow.add_conditional_edges("retrieve", check_relevance)
workflow.add_edge("rewrite_query", "retrieve")
workflow.add_edge("web_search", "generate")

Q38: Graph RAG的原理是什么?什么场景下应该用知识图谱替代向量检索?

核心答案:

Graph RAG核心思想: 将文档转化为结构化知识图谱,通过图结构进行语义检索和多步推理。

Graph RAG工作流程:

  1. 实体抽取:从文档中抽取实体和关系(用LLM或NER模型)
  2. 图构建:构建知识图谱(Neo4j/NetworkX)
  3. 社区发现:用Leiden等算法发现实体社区
  4. 层次摘要:为每个社区生成摘要描述
  5. 图检索:基于图结构的路径检索+社区摘要检索
  6. 生成:将图检索结果作为上下文给LLM

Graph RAG vs 向量RAG:

维度 向量RAG Graph RAG
擅长 语义匹配、事实查询 关联推理、多跳查询
弱项 多跳推理、全局理解 构建成本高、维护复杂
知识表示 平面文本 结构化实体+关系
可解释性 高(路径可追溯)
适用场景 通用问答 风控/法务/供应链/知识关联查询

适用Graph RAG的场景:

  • 需要"从A到B"的关联推理(如供应链风险传导分析)
  • 实体间关系密集的场景(如法规条款间的引用关系)
  • 全局性查询("总结所有产品的共性特点")

面试加分点:1)提及"Graph RAG和向量RAG不是替代关系,而是互补------生产中常采用'向量检索+图检索'的混合方案";2)"微软的GraphRAG是2024-2025年的标志性工作,核心创新是社区发现+层次摘要,解决了全局查询问题"。

⚠️ 常见踩坑:1)知识图谱构建质量是Graph RAG的天花板------实体抽取错误会级联放大;2)图谱维护成本高,文档更新需要重新抽取实体和关系;3)简单事实查询用Graph RAG是大材小用,延迟更高。


Q39: Self-RAG和CRAG的原理是什么?如何选择?

核心答案:

Self-RAG(自我反思RAG):

  • 核心思想:让LLM自己决定"是否需要检索"和"检索结果是否够好"
  • 三个关键判断token:[Retrieve](是否检索)、[ISREL](检索结果是否相关)、[ISSUP](生成是否忠实)
  • 流程:LLM生成时自动插入反思token,如果[ISREL]=No则重新检索

CRAG(Corrective RAG/纠错RAG):

  • 核心思想:检索结果质量差时,自动纠错降级
  • 三级决策:
    • 检索结果正确 → 正常生成
    • 检索结果部分相关 → 补充Web搜索
    • 检索结果完全不相关 → 完全依赖Web搜索或拒答
  • 用轻量级评分器评估检索质量
维度 Self-RAG CRAG
决策者 生成LLM本身 独立的评估器
纠错方式 重新检索 降级到Web搜索
额外开销 需要微调模型加入反思token 不需要微调,可用任何LLM
适用场景 需要精细控制的场景 生产环境更易落地

面试加分点:提及"生产环境推荐CRAG------不需要微调模型,实现简单,效果稳定。Self-RAG需要微调模型学习反思token,落地门槛更高"。


Q40: 多模态RAG的实现方案有哪些?如何处理图片和表格?

核心答案:

多模态RAG三种实现路线:

路线1:文本化方案(最成熟)

  • 图片:用VLM(如Qwen-VL)生成文本描述 → 文本Embedding → 文本检索
  • 表格:转为Markdown/自然语言描述 → 文本Embedding → 文本检索
  • 优势:无需多模态检索基础设施
  • 劣势:视觉信息(布局、颜色、趋势)丢失

路线2:多模态Embedding方案

  • 使用CLIP/BGE-VL将文本和图像映射到同一向量空间
  • 支持文本查图片、图片查图片
  • 优势:跨模态检索能力强
  • 劣势:多模态模型精度低于纯文本模型

路线3:ColPali视觉检索方案(最新)

  • 直接用视觉模型处理文档图像,生成视觉token
  • 无需OCR,保留文档视觉布局
  • 优势:跳过OCR环节,复杂版面效果好
  • 劣势:模型较大,推理成本高

生产推荐: 路线1(文本化)最成熟稳定,适合大部分场景;路线3(ColPali)适合扫描件/复杂版面。

三级检索架构(多模态RAG推荐):

  1. 粗排:混合检索(向量+BM25)+ 模态路由
  2. 重排:跨模态Reranker(BGE-Reranker-M3)
  3. 压缩:上下文压缩后注入LLM

Q41: 长上下文RAG vs 传统RAG,128K上下文的模型还需要RAG吗?

核心答案:

长上下文模型(128K+)带来的变化:

  • 可以一次性注入更多文档,减少检索的必要性
  • 但"能塞入"≠"能有效利用"------Lost in the Middle问题依然存在

长上下文模型 vs RAG的对比:

维度 长上下文(无RAG) RAG
知识量 受128K限制 知识库无限
更新成本 需重新输入 更新知识库即可
延迟 输入越长推理越慢 检索+短上下文更快
准确率 长上下文中间信息被忽略 精准检索+短上下文更可靠
成本 128K输入Token费用高 只输入相关片段,成本更低

结论:长上下文不取代RAG,而是互补:

  • 短文档(<50K):可直接塞入长上下文模型
  • 中等文档(50K-500K):RAG + 长上下文模型做精排
  • 大规模知识库(>500K):必须用RAG

面试加分点:提及"最佳实践是'充足上下文RAG'------用RAG检索出最小且连贯的证据集合,确保LLM无需猜测即可推导出答案,追求的不是'更多文档'而是'精准的信息边界'"。


十、真实生产问题与排障

Q42: 召回率低的排查思路是什么?

核心答案:

系统化排查SOP:

复制代码
Step 1: 确认是检索问题还是生成问题
├── 检查RAGAS的Context Recall指标
│   ├── Context Recall低 → 检索问题,继续Step 2
│   └── Context Recall高但Answer差 → 生成问题,检查Prompt/LLM
│
Step 2: 定位检索链路的瓶颈环节
├── 检查Query质量
│   ├── 用户Query是否太模糊/口语化 → Query改写
│   └── Query是否有指代/省略 → 指代消解
│
├── 检查切分质量
│   ├── 关键信息是否被切到不同chunk → 优化chunk_size/用语义切分
│   └── 表格/公式是否被破坏 → 单独处理
│
├── 检查Embedding质量
│   ├── 换模型后Recall是否提升 → 考虑微调或换模型
│   └── 同义词/领域术语是否理解 → 领域微调
│
└── 检查检索策略
    ├── 纯向量检索是否漏召回 → 加BM25混合检索
    └── Top-K是否够大 → 适当增加(5→10)

快速诊断命令:

python 复制代码
# 1. 检查Query和目标chunk的相似度
query_emb = embedding_model.encode(query)
target_emb = embedding_model.encode(target_chunk)
sim = cosine_similarity([query_emb], [target_emb])[0][0]
print(f"Query-目标chunk相似度: {sim:.3f}")  # <0.7说明Embedding有问题

# 2. 检查目标chunk是否在Top-K中
results = vectorstore.similarity_search_with_score(query, k=20)
target_in_topk = any(target_chunk_id == r.metadata["chunk_id"] for r in results)
print(f"目标chunk是否在Top-20: {target_in_topk}")

# 3. 检查BM25是否能召回
bm25_results = bm25_retriever.get_relevant_documents(query, k=20)
target_in_bm25 = any(target_chunk_id == r.metadata["chunk_id"] for r in bm25_results)
print(f"目标chunk是否在BM25 Top-20: {target_in_bm25}")

面试加分点:强调"召回率低不要急于加Reranker------Reranker只能排好已有结果,不能找回缺失的文档。先解决召回问题,再优化排序"。


Q43: 响应延迟高的优化方案有哪些?

核心答案:

延迟分解与优化:

阶段 典型延迟 优化方案 优化后延迟
Query预处理 100-200ms 缓存改写结果/用轻量模型 50ms
Embedding计算 50-100ms 批量编码/预计算/用小模型 20ms
向量检索 50-200ms HNSW调优/预过滤/分区剪枝 30ms
Rerank 100-300ms 减少候选数/用轻量模型 50ms
LLM生成 1000-3000ms 流式输出/用小模型/缓存 200-500ms
端到端 2-5s 综合优化 0.5-1s

核心优化策略:

  1. 并行化:Embedding计算和Query改写并行执行
  2. 语义缓存:相似Query直接返回缓存结果,<100ms
  3. 模型路由:简单问题用快速模型,复杂问题用精确模型
  4. 流式输出:检索完立即开始生成,用户体感延迟降低50%
  5. 预计算:高频Query的Embedding预计算缓存

面试加分点:提及"LLM生成通常占总延迟60-70%,是最大的瓶颈。优化LLM延迟的ROI最高------流式输出+模型路由可以降低50%以上的体感延迟"。


Q44: 多语言/跨语言检索如何实现?敏感信息过滤与安全如何保障?

核心答案:

多语言/跨语言检索方案:

  1. 多语言Embedding模型:bge-m3支持100+语言,同一向量空间
  2. Query翻译:将非英语Query翻译为英语后检索(知识库以英语为主时)
  3. 多语言知识库:同一文档存储多语言版本,用语言标签过滤

敏感信息过滤与安全:

  1. PII脱敏:入库前自动检测并脱敏个人身份信息(姓名/身份证/电话)
  2. 权限控制:基于元数据的多级权限过滤(部门/级别/项目)
  3. Prompt注入防御
    • 输入验证:检测并过滤可疑指令
    • 分隔符标记:明确区分系统指令和用户输入
    • 输出审查:检测生成的敏感内容
  4. 审计日志:记录所有查询和返回结果,支持事后审计
python 复制代码
# PII脱敏示例
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine

analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()

def sanitize_content(text: str) -> str:
    results = analyzer.analyze(text=text, language="zh")
    sanitized = anonymizer.anonymize(text=text, analyzer_results=results)
    return sanitized.text

⚠️ 常见踩坑:1)用户可以通过Prompt注入绕过安全过滤------必须做输入和输出双向防护;2)权限过滤必须在检索层执行,不能只依赖LLM判断。


Q45: 大规模并发下RAG系统如何保障稳定性?

核心答案:

稳定性保障体系:

  1. 限流与降级

    • 多级限流:用户级 → 租户级 → 系统级
    • LLM API限流:监控Rate Limit,自动排队/降级
    • 向量数据库连接池:控制最大连接数
  2. 熔断器模式

    python 复制代码
    # LLM调用熔断器
    from circuitbreaker import circuit
    
    @circuit(failure_threshold=5, recovery_timeout=60)
    async def call_llm(prompt):
        return await llm.agenerate(prompt)
    
    # 降级策略
    async def call_llm_with_fallback(prompt):
        try:
            return await call_llm(prompt)  # 主模型
        except CircuitBreakerError:
            return await call_local_model(prompt)  # 本地模型降级
  3. 重试机制

    • 指数退避重试(初始1s,最大30s,3次)
    • 只对可重试错误重试(超时/限流),不对业务错误重试
  4. 超时控制

    • 向量检索:3s超时
    • LLM调用:30s超时
    • 端到端:5s超时
    • 关键:必须设置全局超时,防止某个环节阻塞导致服务雪崩
  5. 压力测试与容量规划

    • 定期做压测,确定系统容量上限
    • 峰值流量预估:日均QPS × 10倍
    • 弹性伸缩:K8s HPA根据CPU/QPS自动扩缩

面试加分点:提及"某客户因未设LLM调用超时,单点故障引发全站5分钟不可用。生产环境必须设置每个外部调用的超时时间"。

⚠️ 常见踩坑:1)不设超时------最危险的生产问题;2)重试没有退避------雪崩效应;3)没有降级策略------一个组件挂了全站挂。


附录:面试冲刺速查表

RAG全链路优化Checklist

复制代码
□ 数据层:文档解析质量、切分策略、元数据完整性、知识库去重
□ Embedding层:模型选型、归一化、维度选择、领域微调
□ 检索层:混合检索、Top-K调优、元数据过滤
□ 重排层:Reranker选型、候选数量、阈值调优
□ 生成层:Prompt设计、引用约束、拒答机制、流式输出
□ 架构层:缓存策略、模型路由、限流降级、监控告警
□ 评估层:RAGAS自动化评估、Bad Case分析、持续优化

生产级RAG技术栈推荐

组件 推荐方案 备选
文档解析 Unstructured/MinerU Apache Tika
文本切分 RecursiveCharacterTextSplitter 语义切分
Embedding bge-large-zh-v1.5 bge-m3
向量数据库 Milvus Qdrant
混合检索 Milvus BM25 + Dense Elasticsearch
Reranker BGE-Reranker-v2-m3 Cohere Rerank
LLM GPT-4o / Qwen2-72B DeepSeek-V3
RAG框架 LangChain / LlamaIndex Haystack
评估框架 RAGAS DeepEval
监控 LangFuse + Prometheus LangSmith
缓存 Redis + 语义缓存 GPTCache

📝 本题集基于2024-2026年最新技术实践整理,涵盖RAG生产落地的10大方向45道核心面试题。建议面试前重点复习标注⭐的加分点和⚠️的踩坑提醒,用"问题定位→方案选择→量化效果"的框架组织回答,体现生产级思维。

相关推荐
AnthonyInCanada12 小时前
AssistantAgent 电商分析 Agent 系列 03:怎么把“为什么跌了”做成一条标准归因链
agent
小皮咖12 小时前
DeepSeek-Reasonix:缓存命中率高达 90% 的AI编程助手
人工智能
南汁bbj12 小时前
从Prompt到Agent:教育错题分析系统的流程编排设计实践
人工智能·prompt
前沿科技说i12 小时前
2026年AI大模型API中转系统生产级实测:主流服务商性能与成本综合排名全指南
大数据·人工智能
黑巧克力可减脂12 小时前
开源AI大模型统一网关CrossLink部署实战:LiteLLM轻量化替代方案
人工智能·开源
耶夫斯计12 小时前
AI修出写真照
人工智能·ai作画
薛定猫AI12 小时前
【深度解析】Hermes Agent + 多模型 API:构建可持续运行的自主 AI 工作流
人工智能
手写码匠12 小时前
手写 MoE(混合专家模型):从零实现大模型的稀疏激活架构
人工智能·深度学习·算法·aigc
MediaTea12 小时前
PyTorch:主要模块简介
人工智能·pytorch·python·深度学习·机器学习