【AI面试临阵磨枪】RAG 完整流程:文档 → 切块 → Embedding → 检索 → 生成
一、面试题目面试官聚焦技术流程考察核心认知同学你好RAG作为大语言模型落地的核心技术之一其完整流程常被提及为“文档→切块→Embedding→检索→生成”请你详细拆解这个完整流程说明每个环节的核心作用、关键逻辑以及各环节之间的衔接关系展现你对RAG流程的整体掌控力。二、知识储备本面试题核心围绕RAGRetrieval-Augmented Generation检索增强生成的完整技术流程展开核心考察面试者对RAG各环节的理解、核心作用及底层逻辑以下是流程各环节的知识点汇总便于系统学习和记忆清晰掌握RAG的工作原理一RAG核心定位RAG的本质是“将检索能力与大语言模型的生成能力结合”解决LLM大语言模型“知识滞后、幻觉生成、无法引用具体文档”的核心痛点通过从外部文档中检索相关信息辅助LLM生成准确、有依据、可追溯的回答实现“模型知识外部文档知识”的协同输出。二完整流程拆解文档→切块→Embedding→检索→生成1. 文档DocumentRAG的知识来源核心定义指RAG系统中用于提供外部知识的原始数据是检索和生成的基础也是LLM补充知识的核心来源。常见类型结构化文档Excel、CSV、数据库表、非结构化文档PDF、Word、TXT、网页、对话记录、半结构化文档HTML、Markdown。核心要求文档需具备相关性与业务场景、用户需求匹配、准确性避免错误知识导致LLM生成幻觉、完整性覆盖核心知识点同时需进行预处理去重、去噪、格式统一确保后续环节的效率和效果。核心作用为整个RAG流程提供“可检索、可引用”的原始知识是解决LLM知识滞后的关键——LLM的训练数据有时间上限而文档可实时更新实现知识的动态补充。2. 切块Chunking文档的精细化处理核心定义将原始文档按照一定规则分割成若干个大小合适、语义完整的“文本块Chunk”避免因文档过长导致Embedding不准确、检索效率低、生成时上下文冗余的问题。核心痛点原始文档如长PDF、万字文档通常篇幅较长直接进行Embedding会导致语义信息混乱、向量表征不准确且检索时无法精准定位到相关片段生成的回答缺乏针对性。常见切块策略固定长度切块按固定字符数/token数分割如每512个token为一个Chunk简单易实现适合结构简单的文档。语义切块基于文档的语义结构如段落、标题、章节分割确保每个Chunk的语义完整如按句号、换行符分割或基于LLM判断语义边界适合结构化、逻辑性强的文档。重叠切块在切块时保留部分重叠内容如前一个Chunk的末尾50个token与后一个Chunk的开头50个token重叠避免因分割导致语义断裂提升检索的完整性。核心作用将长文档拆解为“语义完整、大小适中”的文本块为后续Embedding和检索提供基础提升向量表征的准确性和检索的精准度。3. Embedding嵌入文本到向量的转换核心定义通过Embedding模型如BERT、Sentence-BERT、M3E等将每个文本块Chunk转换为固定维度的“向量Vector”即将文本的语义信息映射到高维向量空间实现“语义可计算”。核心原理Embedding模型通过训练能够捕捉文本的语义特征如词语关联、句子含义、上下文逻辑将语义相似的文本映射到向量空间中距离较近的位置语义不同的文本映射到距离较远的位置为后续检索提供“语义匹配”的依据。关键要求Embedding模型需与业务场景匹配如中文场景选用中文优化的模型向量维度需平衡“表征能力”和“存储/计算效率”常用维度为768、1024同时需对向量进行归一化处理提升检索准确性。核心作用将文本的“语义信息”转化为“可计算的向量”打破文本无法直接进行相似性对比的局限为后续的语义检索提供核心支撑。4. 检索Retrieval精准匹配相关知识核心定义当用户输入查询Query后先将Query通过相同的Embedding模型转换为向量再在向量数据库如Milvus、Pinecone、Chroma中检索出与Query向量“语义相似度最高”的Top N个文本块Chunk作为辅助生成的“相关知识”。核心流程用户Query → Embedding转换为Query向量 → 向量数据库中计算Query向量与所有Chunk向量的相似度常用余弦相似度、欧氏距离 → 筛选出相似度最高的Top N个ChunkN通常为3-5可根据场景调整 → 输出检索结果。常见检索策略稠密检索Dense Retrieval基于向量的语义相似度检索精准度高是RAG的核心检索方式适合语义匹配场景。稀疏检索Sparse Retrieval基于关键词的检索如TF-IDF速度快适合关键词明确的场景常与稠密检索结合使用混合检索。混合检索结合稠密检索的精准度和稀疏检索的速度提升检索的效率和效果适合复杂场景。核心作用从海量文档块中快速、精准地筛选出与用户Query相关的知识为LLM生成回答提供“事实依据”避免LLM凭空生成内容幻觉。5. 生成Generation基于检索结果的精准输出核心定义将用户Query、检索到的相关文本块Chunk结合提示词Prompt输入到LLM中让LLM基于检索到的事实知识生成符合用户需求、准确、可追溯的回答同时引用检索到的文档片段作为依据。核心逻辑LLM不再仅依赖自身训练数据生成回答而是以“检索到的相关知识”为基础结合自身的语言组织能力将知识整合、提炼生成连贯、准确的回答同时可标注知识来源哪个文档、哪个Chunk提升回答的可信度。关键优化通过Prompt Engineering提示词工程引导LLM“仅基于检索到的知识生成回答”避免引入自身训练数据中的滞后或错误知识同时可加入“知识融合”逻辑将多个相关Chunk的知识整合避免回答碎片化。核心作用将检索到的“碎片化知识”转化为“用户可理解、符合需求的完整回答”实现“检索生成”的闭环既解决LLM的幻觉问题又弥补其知识滞后的缺陷。三各环节衔接逻辑文档是基础切块是预处理让文档可被高效处理Embedding是核心转换让文本可被语义检索检索是精准筛选找到与Query相关的知识生成是最终输出将知识转化为用户需要的回答各环节环环相扣缺一不可——没有文档就没有知识来源没有切块Embedding和检索效率会大幅下降没有Embedding无法实现语义检索没有检索LLM无法获得外部知识仍会产生幻觉没有生成检索到的碎片化知识无法转化为可用的回答。三、破局之道在面试中用这段话展现我对RAG完整流程的深层掌控力回答RAG“文档→切块→Embedding→检索→生成”的完整流程本质上是展示我对“LLM知识增强落地逻辑”和“检索与生成协同”的掌控程度。你可以告诉面试官文档决定了RAG的知识广度与准确性是整个流程的根基切块决定了知识处理的效率与语义完整性是流程的预处理关键Embedding决定了语义匹配的精准度是检索的核心支撑检索决定了生成的依据与针对性是解决LLM幻觉的核心环节而生成则决定了RAG的最终落地价值让检索到的碎片化知识转化为可用的服务。在生产环境下我更关注各环节的协同优化——比如通过语义切块提升Embedding质量通过混合检索提升检索精准度通过提示词工程引导LLM精准引用知识避免检索与生成脱节。没有完整闭环的RAG流程只是“检索工具生成工具”的简单拼接而各环节高效协同的RAG才是真正能解决LLM落地痛点、为业务提供精准、可信知识服务的核心方案。四、代码实现说明以下代码为RAG完整流程的简化实现聚焦各环节的核心逻辑选用Python和JavaScript两种版本基于成熟框架LangChain、Sentence-BERT、Chroma便于直观理解流程衔接实际生产中需根据业务场景优化切块策略、Embedding模型和检索参数。一Python版基于LangChainChroma完整流程实现from langchain.document_loaders import TextLoader # 文档加载 from langchain.text_splitter import RecursiveCharacterTextSplitter # 切块 from langchain.embeddings import SentenceTransformerEmbeddings # Embedding from langchain.vectorstores import Chroma # 向量数据库检索 from langchain.chat_models import ChatOpenAI # LLM生成 from langchain.chains import RetrievalQA # 检索-生成链条 # 1. 文档Document加载并预处理原始文档 # 模拟加载本地文本文档实际可替换为PDF、Word等文档加载器 loader TextLoader(test_document.txt, encodingutf-8) documents loader.load() # 加载文档返回文档列表 # 2. 切块Chunking语义切块确保语义完整 text_splitter RecursiveCharacterTextSplitter( chunk_size512, # 每个Chunk的token数可调整 chunk_overlap50, # 重叠token数避免语义断裂 length_functionlen # 长度计算方式 ) chunks text_splitter.split_documents(documents) # 分割文档为多个Chunk print(f文档切块完成共生成{len(chunks)}个文本块) # 3. Embedding嵌入文本块转换为向量 embedding_model SentenceTransformerEmbeddings(model_nameall-MiniLM-L6-v2) # 轻量高效的Embedding模型 # 4. 检索Retrieval将向量存入向量数据库实现语义检索 # 初始化Chroma向量数据库存入Chunk向量 vector_db Chroma.from_documents( documentschunks, embeddingembedding_model, persist_directory./chroma_db # 向量数据库持久化路径 ) vector_db.persist() # 持久化数据库避免每次重新生成 # 初始化检索器设置检索数量Top 3 retriever vector_db.as_retriever(search_kwargs{k: 3}) # 5. 生成Generation检索生成闭环 # 加载LLM模拟实际需配置OpenAI API Key llm ChatOpenAI(temperature0.7, model_namegpt-3.5-turbo) # 构建检索-生成链条将检索结果传入LLM生成回答 rag_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 将检索到的Chunk全部传入LLM retrieverretriever, return_source_documentsTrue # 返回检索到的原始Chunk可追溯来源 ) # 测试RAG完整流程 if __name__ __main__: user_query 请基于文档内容说明RAG中Embedding环节的核心作用 result rag_chain({query: user_query}) # 输出结果 print(f用户查询{user_query}) print(f\n生成回答{result[result]}) print(f\n检索到的相关文档块) for i, doc in enumerate(result[source_documents]): print(f文档块{i1}{doc.page_content[:100]}...)二JavaScript版简化实现突出流程衔接// 模拟RAG完整流程文档→切块→Embedding→检索→生成 // 实际生产中需使用成熟库如langchain-js、xenova/transformers // 1. 文档Document模拟原始文档 const rawDocument RAG检索增强生成是将检索能力与大语言模型生成能力结合的技术核心流程为文档→切块→Embedding→检索→生成。 文档是RAG的知识来源可分为结构化、非结构化和半结构化文档需进行去重去噪预处理。 切块是将长文档分割为语义完整的文本块常用语义切块和固定长度切块策略避免语义断裂。 Embedding是将文本块转换为向量通过Embedding模型捕捉语义特征实现语义可计算。 检索是根据用户Query的向量在向量数据库中匹配相似文本块为生成提供依据。 生成是将Query和检索结果传入LLM生成准确、可追溯的回答。; // 2. 切块Chunking语义切块按句号分割保留重叠 function chunkDocument(document, chunkSize 100, overlap 20) { const sentences document.split(。).filter(s s.trim()); const chunks []; let currentChunk ; for (const sentence of sentences) { const trimmedSentence sentence.trim() 。; // 若当前Chunk长度不足继续添加句子 if (currentChunk.length trimmedSentence.length chunkSize) { currentChunk trimmedSentence; } else { // 添加当前Chunk保留重叠部分 chunks.push(currentChunk); currentChunk currentChunk.slice(-overlap) trimmedSentence; } } if (currentChunk) chunks.push(currentChunk); return chunks; } // 3. Embedding嵌入模拟向量转换实际用Embedding模型 function embedding(chunks) { // 模拟为每个Chunk生成随机向量768维模拟真实Embedding维度 return chunks.map(chunk { return { chunk: chunk, vector: Array(768).fill().map(() Math.random() * 2 - 1) // 随机生成[-1,1]的向量 }; }); } // 4. 检索Retrieval模拟语义检索计算余弦相似度 function retrieval(query, embeddedChunks, topK 3) { // 模拟将Query转换为向量随机生成 const queryVector Array(768).fill().map(() Math.random() * 2 - 1); // 计算Query向量与每个Chunk向量的余弦相似度 const similarityScores embeddedChunks.map(item { const dotProduct queryVector.reduce((sum, val, i) sum val * item.vector[i], 0); const queryNorm Math.sqrt(queryVector.reduce((sum, val) sum val ** 2, 0)); const chunkNorm Math.sqrt(item.vector.reduce((sum, val) sum val ** 2, 0)); const similarity dotProduct / (queryNorm * chunkNorm); return { ...item, similarity }; }); // 按相似度排序取Top K return similarityScores.sort((a, b) b.similarity - a.similarity).slice(0, topK); } // 5. 生成Generation模拟LLM生成基于检索结果 function generation(query, retrievedChunks) { // 模拟整合检索结果生成回答 const retrievedContent retrievedChunks.map(item item.chunk).join(\n); return 基于检索到的知识回答您的问题${query}\n\n${retrievedContent}\n\n总结RAG中各环节环环相扣Embedding实现语义转换检索提供事实依据最终生成准确可追溯的回答。; } // 测试RAG完整流程 function runRAG() { // 1. 文档 const document rawDocument; console.log( 1. 文档加载完成 ); console.log(原始文档${document.slice(0, 100)}...\n); // 2. 切块 const chunks chunkDocument(document); console.log( 2. 文档切块完成 ); console.log(共生成${chunks.length}个文本块); chunks.forEach((chunk, i) console.log(块${i1}${chunk.slice(0, 50)}...)); console.log(); // 3. Embedding const embeddedChunks embedding(chunks); console.log( 3. Embedding完成 ); console.log(每个文本块已转换为768维向量共${embeddedChunks.length}个向量\n); // 4. 检索 const userQuery 请说明RAG中切块环节的作用; const retrievedChunks retrieval(userQuery, embeddedChunks); console.log( 4. 检索完成 ); console.log(用户查询${userQuery}); console.log(检索到${retrievedChunks.length}个相关文本块); retrievedChunks.forEach((item, i) console.log(块${i1}相似度${item.similarity.toFixed(4)}${item.chunk.slice(0, 50)}...)); console.log(); // 5. 生成 const result generation(userQuery, retrievedChunks); console.log( 5. 生成完成 ); console.log(生成回答${result}); } // 执行RAG流程 runRAG();