RAG 基础架构详解:检索-增强-生成的完整工作流

RAG 基础架构详解:检索-增强-生成的完整工作流
RAG 基础架构详解检索-增强-生成的完整工作流模型的知识是训练时定格的但世界在变。RAG 就是给模型装上一根网线——实时、可验证、可更新。前言为什么 Agent 需要 RAGAgent 的核心能力之一是获取信息。但模型内部的知识有几个硬伤知识截止模型不知道训练之后的任何事情幻觉模型会编造不确定的信息不精确模型的知识是模糊的不是精确的不可更新想更新知识得重新训练RAGRetrieval-Augmented Generation解决这些问题不是让模型记住知识而是让模型检索知识。模型我知道的知识 → 训练时定格的不可靠 RAG我检索的知识 → 实时获取的可验证一、RAG 的核心流程1.1 三段式架构用户输入 ↓ ① 检索Retrieve 从知识库中找到相关文档 ↓ ② 增强Augment 把检索到的文档加入上下文 ↓ ③ 生成Generate 模型基于上下文 用户输入生成回答 ↓ 输出1.2 最小可运行示例defrag_pipeline(query,docs,llm,retriever):# 1. 检索relevant_docsretriever.retrieve(query,k3)# 2. 增强context\n\n.join([f文档{i1}{doc}fori,docinenumerate(relevant_docs)])# 3. 生成promptf 基于以下信息回答问题{context}问题{query}请基于以上信息回答不要添加外部知识。 如果信息不足以回答问题请说信息不足。 returnllm.generate(prompt)1.3 Naive RAG vs 高级 RAG阶段Naive RAG高级 RAG检索前直接检索查询改写、HyDE、查询分解检索简单向量检索多路检索、混合检索检索后直接拼接重排序、过滤、去重生成单次生成多轮生成、验证、迭代二、Chunk分块策略2.1 为什么需要分块文档通常很长整本书、整篇论文不能直接当作检索单元。需要把文档切成小块。2.2 分块方法# 方法 1固定长度分块最简单deffixed_chunk(text,chunk_size512,overlap50):chunks[]start0whilestartlen(text):endstartchunk_size chunks.append(text[start:end])startend-overlapreturnchunks# 方法 2语义分块推荐defsemantic_chunk(text,model):在语义边界处切分段落、章节、句子# 先按段落切分paragraphstext.split(\n\n)chunks[]current_chunkforparainparagraphs:iflen(current_chunk)len(para)MAX_CHUNK_SIZE:chunks.append(current_chunk)current_chunkparaelse:current_chunk\n\nparaifcurrent_chunk:chunks.append(current_chunk)returnchunks# 方法 3递归分块LangChain 方法fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitterRecursiveCharacterTextSplitter(chunk_size512,chunk_overlap50,separators[\n\n,\n,。,, ,],)chunkssplitter.split_text(text)2.3 分块参数参数推荐值说明chunk_size256-1024太小信息不完整太大检索精度下降chunk_overlap10-20%避免边界处信息丢失separators按语义层级从粗到细避免在句子中间切分三、检索策略3.1 检索方法对比方法原理适合场景局限性向量检索语义相似度搜索语义匹配对精确匹配不敏感关键词检索BM25 词频匹配精确匹配对语义理解差混合检索两者结合通用需要调权重SQL 检索结构化查询有结构的数据需要精确查询条件3.2 向量检索defvector_retrieve(query,embeddings,vector_db,k5):# 1. 把查询转为向量query_embeddingembeddings.embed(query)# 2. 在向量数据库中搜索resultsvector_db.search(query_embedding,kk,metriccosine,# 或 dot_product, euclidean)returnresults3.3 混合检索defhybrid_retrieve(query,chunks,k5,alpha0.5): 混合检索向量检索 BM25 关键词检索 alpha: 向量检索的权重0-1 # 1. 向量检索vector_scoresvector_retrieve(query,chunks,k*2)# 2. BM25 关键词检索keyword_scoresbm25_retrieve(query,chunks,k*2)# 3. 融合分数combined_scores{}fordoc,scoreinvector_scores:combined_scores[doc]alpha*scorefordoc,scoreinkeyword_scores:combined_scores[doc]combined_scores.get(doc,0)(1-alpha)*score# 4. 排序取 top-krankedsorted(combined_scores.items(),keylambdax:x[1],reverseTrue)return[docfordoc,_inranked[:k]]四、增强Augment策略4.1 上下文注入把检索到的文档注入到 Prompt 中defaugment_prompt(query,retrieved_docs,templatedefault):iftemplatedefault:returnf 基于以下信息回答问题{format_docs(retrieved_docs)}问题{query}要求 - 只基于提供的信息回答 - 如果信息不足说信息不足 - 引用信息来源 eliftemplateagent:returnf 你是一个 AI Agent。以下是检索到的参考信息{format_docs(retrieved_docs)}用户问题{query}请根据参考信息回答用户的问题。 如果信息不足以回答请使用搜索工具获取更多信息。 returntemplate4.2 多轮增强对于复杂问题可能需要多轮检索defmulti_step_rag(query,llm,retriever,max_steps3):context[]current_queryqueryforstepinrange(max_steps):# 检索docsretriever.retrieve(current_query,k3)context.extend(docs)# 判断信息是否足够promptf 基于以下信息你能回答这个问题吗 信息{context}问题{query}如果足够回答请给出答案。 如果不够请说明还需要什么信息。 responsellm.generate(prompt)# 检查是否足够if信息不足notinresponse:returnresponse# 提取需要的信息作为下一轮检索的查询current_queryextract_missing_info(response)return经过多轮检索仍无法回答这个问题。五、RAG 的常见问题5.1 检索不到关键信息问题原因解决方案查询词不匹配用户用词和文档用词不同查询扩写、同义词替换分块不合理信息被切分到不同块中改进分块策略、增加 overlap检索数量不足top-3 不够增加检索数量、重排序索引不完整文档没有正确索引检查索引流程5.2 检索到的信息不相关问题番茄炒蛋怎么做 检索到番茄的种植技术 解决方案提高检索质量 - 使用更好的嵌入模型 - 增加重排序步骤 - 降低检索数量提高精度5.3 模型忽略检索结果问题模型基于自己的知识回答而不是检索到的信息 解决方案 - 在 Prompt 中明确强调只基于以下信息 - 使用信息不足作为默认输出 - 降低模型的 temperature减少创造性六、RAG 在 Agent 中的角色6.1 作为工具在 Agent 中RAG 通常作为工具被调用tooldefsearch_knowledge_base(query:str)-str: 搜索公司内部知识库 适合查询公司政策、产品信息、技术文档 docsretriever.retrieve(query,k3)returnformat_docs(docs)6.2 与 Agent Memory 的关系Agent Memory存储对话历史和用户偏好 RAG存储外部知识和文档信息 Memory 是这个人说过什么 RAG 是这个知识库有什么6.3 RAG 的局限性RAG 不是万能的。它解决的是获取信息的问题不是推理的问题。RAG 擅长需要精确信息的场景 RAG 不擅长需要推理、分析、综合的场景 一个 Agent 的正确用法 RAG 负责提供事实基础 模型负责推理和决策总结阶段核心组件关键决策检索索引、分块、嵌入模型分块策略、检索方法增强Prompt 模板、上下文注入注入方式、引用格式生成LLM温度控制、约束条件RAG 给 Agent 装上了知识库——模型不再需要记住所有知识只需要知道怎么检索。下一篇文章我们将深入嵌入模型与向量数据库——如何选择 Embedding 模型、向量库的选型对比以及如何优化检索质量。思考题你的 Agent 场景中哪些信息需要通过 RAG 获取哪些靠模型内部知识就够了分块大小对检索质量有什么影响你会在什么场景选择 256、512、1024 的分块大小RAG 作为 Agent 的工具和直接调用搜索 API 有什么区别什么时候用哪个上一篇[14] 从 Prompt 到 Context Engineering下一篇[16] 嵌入模型与向量数据库