标准回答
整体分两个阶段
RAG 的本质是「先检索、再生成」,工程上拆成离线索引阶段和在线查询阶段,两者通过同一个向量库连接。索引可批量预处理,查询要求低延迟。
索引阶段:把知识灌进向量库
按顺序串四个组件:① DocumentLoader 从 PDF、Markdown、网页、数据库等来源加载原始文档;② TextSplitter(如 RecursiveCharacterTextSplitter)按语义边界切块并设 chunk_size 与 overlap,避免切碎语义;③ Embeddings 把每个文本块编码成向量;④ VectorStore(FAISS、Chroma、Milvus、pgvector 等)持久化「向量 + 原文 + 元数据」,建好索引供检索。
查询阶段:检索增强生成
用户提问后:① Retriever 从向量库做相似度召回 Top-K 相关块;② 可选加 Rerank(交叉编码器精排)或上下文压缩,过滤噪声、提升相关性;③ 把召回内容与问题填进 Prompt 模板,明确要求「仅依据给定上下文作答,缺信息就说不知道」;④ 交给 LLM 生成,再经 OutputParser 整理输出。
用 LCEL 串联
LangChain 表达式语言(LCEL)用管道符把组件拼成链,例如 chain = {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | parser,天然支持流式、异步与并行,便于替换任意环节。
生产化两件事
一是来源引用:在 Prompt 中要求标注引用,并把检索块的 metadata(标题、URL、页码)回传给前端,方便用户溯源、降低幻觉风险;二是多轮记忆:接入 Memory 或基于历史的 Retriever,先把追问改写成独立问题再检索,支撑连续对话。
常见误区
⚠️ 常见踩坑
只堆组件却忽视切块质量——chunk 太大引入噪声、太小切碎语义,overlap 设置不当导致召回失败;查询时用的 Embeddings 模型与建库时不一致导致向量空间错配;不加「仅依据上下文作答」约束和来源引用,模型照样幻觉且无法溯源。
追问
追问 1:召回质量差、答案不相关,从哪些环节排查?
追问 2:文档频繁更新,如何维护向量库的增量同步?
给每个文档块带稳定的来源 ID 和内容哈希作为 metadata。更新时对比哈希:内容未变跳过,变了则按文档 ID 删除旧块再写入新块(upsert),删除的文档同步清理对应向量。LangChain 的 indexing API(RecordManager)可自动做去重与增量同步,避免重复 embedding 浪费成本,也防止脏数据残留导致召回过期内容。
🔗 相似问题
同一考点的不同问法,面试官可能换着问,一起刷更稳
没找到想看的面试题?把你想看的告诉我们 →
延伸学习
按主题分类的相关资源,便于系统复习