深入研究RAG: 在线阶段-查询问答

张开发
2026/5/3 21:07:49 15 分钟阅读
深入研究RAG: 在线阶段-查询问答
前言在前面的学习中我们研究了RAG在离线阶段进行的工作----文档解析、文本分片与向量化那么接下来就来研究一下在线阶段如何使用我们已经准备好的数据吧也就是我们的检索、重排序与生成实际上生产环境中还要考虑非常多的优化问题但是今天只讲一些流程对于项目、深度和优化我后面一定会讲也是我4月的主攻方向一、用户提问(User Query) 查询预处理虽然流程图上只是一个简单的输入框但在工程上这里往往是优化的第一步。核心概念原始输入用户自然语言输入例如“年假怎么算”。查询重写 (Query Rewriting)用户的问题往往是不完整的、有歧义的或者包含口语化表达。详细流程接收用户输入。拼写纠错如果是英文或特定术语先纠错。多轮对话上下文融合如果用户接着问“那如果是试用期呢”系统需要结合上一轮对话将其重写为“试用期年假怎么算”。意图识别判断用户是想闲聊、查数据还是写代码从而决定走 RAG 流程还是直接回复。工程化考量延迟控制重写通常需要一个小型的 LLM 调用会增加几百毫秒的延迟。如果系统对速度要求极高可以跳过此步。HyDE (Hypothetical Document Embeddings)这是一种高级技巧。让 LLM 先根据问题“瞎编”一个完美的答案文档然后用这个“假文档”去向量库检索。因为假文档的向量分布往往比问题本身更接近真实文档能显著提高检索命中率。二. 问题向量 (Query Embedding)核心概念将处理后的文本问题转化为高维向量Vector。关键原则必须使用与离线阶段完全相同的 Embedding 模型。如果离线用了text-embedding-3-small在线也必须用它否则向量空间不一致检索结果为空或错误。详细流程调用 Embedding 模型 API 或本地模型。输出一个固定长度的浮点数数组例如[0.02, -0.5, 0.9...]。工程化考量缓存机制 (Caching)对于高频问题如“公司wifi密码”直接缓存其向量结果避免重复调用模型节省成本和时间。批量处理如果有并发请求尽量合并 Embedding 请求以提高吞吐量。三、相似检索 (Retrieval)这是 RAG 的“心脏”负责从向量数据库中捞数据。核心概念向量相似度计算通常使用余弦相似度 (Cosine Similarity) 或 欧氏距离 (Euclidean Distance)。ANN (Approximate Nearest Neighbors)近似最近邻搜索。因为精确搜索太慢工程上通常用 HNSW 或 IVF 等索引算法来加速。TopK设定返回多少条最相关的文档片段Chunk。详细流程拿着“问题向量”去向量数据库如 Milvus, Pinecone, Elasticsearch, Chroma中比对。计算问题向量与库中所有向量的距离。返回距离最近相似度最高的 TopK 个文档片段及其元数据Metadata。工程化考量 (重中之重)混合检索 (Hybrid Search)单纯靠向量检索有时候不准比如搜特定的产品型号 X-200向量可能抓不住精确匹配。最佳实践是向量检索 (Dense Retrieval) 关键词检索 (Sparse Retrieval / BM25)。最后通过加权算法如 RRF合并结果。元数据过滤 (Metadata Filtering)在检索前加过滤条件。例如用户问“2023年的财报”可以在检索时直接过滤time2023的文档避免检索到 2022 年的干扰项。TopK 的选择通常设为 5-10。太少可能漏掉关键信息太多会引入噪音且超出 LLM 上下文窗口。检索出来就直接用吗 肯定不是我们还要优化进一步提高准确性那么就需要把检索出来的top-k进行一个重排序了。四、重排序 (Rerank)这是提升 RAG 准确率性价比最高的一步。核心概念Bi-Encoder vs Cross-Encoder前面的 Embedding 是 Bi-Encoder双塔模型速度快但精度一般它分别计算问题和文档的向量。Rerank 模型通常是 Cross-Encoder交叉编码器它将“问题”和“文档”拼接在一起输入模型进行深度的语义交互匹配精度极高但速度慢。详细流程接收上一步检索回来的 TopK例如 20 条粗排结果。使用 Rerank 模型如 BGE-Reranker, Cohere Rerank对这 20 条逐一打分。根据分数重新排序截取分数最高的 TopN例如 5 条作为最终上下文。工程化考量延迟权衡Rerank 模型通常比 Embedding 模型慢。不要对全库做 Rerank只对检索回来的少量候选集做。模型选择开源模型推荐BGE-Reranker-v2-m3或bge-reranker-large闭源推荐Cohere Rerank效果极好但收费。五、提示词组装 (Prompt Construction)这一步是将检索到的“食材”文档和“菜谱”指令打包给厨师LLM。核心概念Context (上下文)检索到的文档片段。System Prompt (系统提示词)规定 LLM 的角色、回答风格、限制如“不知道就说不知道不要编造”。User Query (用户问题)原始问题。详细流程去重检索回来的文档可能有重复内容需要去重。拼接按照特定模板组装。最终的提示词类似于你是一个助手。请根据以下参考信息回答问题。 如果参考信息里没有答案请直接说“资料中未提及”。 参考信息 1. [文档片段1内容] 2. [文档片段2内容] ... 用户问题{query}上下文压缩 (Context Compression)如果检索回来的内容太长超过了 LLM 的窗口限制可以使用 LLM 或提取算法只保留与问题最相关的句子。️ 工程化考量Token 限制必须计算组装后的 Prompt 总 Token 数确保不超过模型上限如 8k, 32k, 128k。如果超长需要截断或压缩。防注入攻击确保用户输入的问题不会覆盖掉 System Prompt 的指令Prompt Injection。六. LLM 生成 (LLM Generation)核心概念基于组装好的 Prompt 进行推理生成。详细流程调用大模型 API如 GPT-4, Claude, 或本地部署的 Llama 3。设置参数Temperature通常设为 0 或很低保证回答严谨、确定性强Top_P等。️ 工程化考量流式输出 (Streaming)为了用户体验不要等生成完再返回而是通过 SSE (Server-Sent Events) 一个字一个字地推送到前端让用户感觉响应很快。模型路由简单问题用小模型便宜、快复杂推理用大模型贵、慢。七、 答案输出 引用溯源 (Citation)这是流程图的最后一步也是建立用户信任的关键。核心概念引用溯源告诉用户答案是根据哪份文件的哪一段生成的。详细流程解析回答LLM 生成文本。映射来源在 Prompt 组装阶段我们给每个文档片段加了编号如[1],[2]。LLM 生成时如果能带上这些编号如“根据规定[1]...”后端就可以解析这些编号找到对应的原始文档 URL 和段落。前端渲染在答案旁边显示小脚标鼠标悬停显示原文点击跳转原文。️ 工程化考量强制引用在 System Prompt 中明确要求 LLM“回答必须在句尾标注来源编号如 [1]”。幻觉检测如果 LLM 生成了[5]但实际只给了它 3 篇文档说明产生了幻觉需要后端进行校验和清洗。八、流程总结从整理来说RAG实际上很单纯就是利用知识库用特殊的方法向量化、ANN等进行存储与检索再对Prompt进行增强来提高我们的LLM的回答效果。那么实际开发的流程可以总结成以下图片但是实际企业级开发的流程更加的精密和严谨接下来我会一一道来。

更多文章