ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RAG工程实践:从分块、向量化到生产排错的完整指南

RAG工程实践:从分块、向量化到生产排错的完整指南 AI、LLM、GenAI 是当前技术社区讨论热度最高的几个词但真正要把这些能力落到业务系统里RAG 是无法绕开的关键工程路径。RAG 的全称是 Retrieval-Augmented Generation也就是检索增强生成先从知识库中检索出与问题相关的资料片段再让大模型基于这些片段生成回答。它解决的是大模型训练数据截止后的知识盲区、私有数据隔离、以及回答幻觉三个实际问题。这篇内容定位在 AI 与 LLM 工程实战学习路径的第三阶段重点不是再讲一遍大模型 API 怎么调用而是围绕 RAG 做完整的工程化落地从最小链路搭起到分块、向量化、检索、生成的关键参数再到知识库指标、进阶架构和生产排错。适合已经会调用大模型接口、写过一个简单 Demo但准备把知识库问答做成可用系统的开发者。读完这篇文章你可以独立搭建一个 RAG 问答原型知道哪些参数会影响效果能够用指标而不是肉眼判断来评估知识库质量并且遇到“回答不对、引用不对、检索不到”的问题时知道按哪条链路去排查。1. 先理解RAG在LLM工程里的位置再决定要不要用RAG1.1 RAG解决的核心问题知识时效、私有数据和幻觉先给RAG一个通俗的定义。大模型本身像一个知识面很广、但训练数据截止之后就很难更新的专家。你问它常识问题它可以回答得很好你问它公司内部最近更新的项目文档它要么说不知道要么凭训练数据里的近似内容编一个答案。RAG 的思路就是把这个场景变成“开卷考试”先让检索器从知识库里找出相关资料再让大模型结合资料作答。从技术定义上看RAG 是一个由检索器Retriever和生成器Generator组成的框架。检索器负责从外部知识库中召回与用户问题相关的文档片段生成器负责把这些片段作为上下文输入给大模型最终生成回答。这套思路在 2020 年 Lewis 等人的论文《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》中得到了系统化表述之后成为知识密集型 NLP 任务的主流方案之一。RAG 能解决三类问题知识时效性。大模型训练数据有截止时间而业务文档、行业规范、技术方案可能每天都在变化。RAG 可以在查询阶段实时检索最新内容不需要重训模型。私有知识。公司内部文档、协议、专利、日志、业务规则不可能进入公开训练数据。RAG 可以在不修改模型权重的前提下把这些私有内容放进知识库让模型按需读取。幻觉。大模型在没有事实依据时容易编造内容。RAG 通过把回答范围限制在检索出的上下文里大幅降低无依据生成的概率。这里要强调一个容易误解的点RAG 不能保证 100% 消除幻觉它只是把幻觉的来源从“模型记忆”转移到了“检索上下文”。如果检索器召回的内容本身不正确、不完整或者被切碎导致语义丢失生成器依然会基于错误上下文给出错误答案。所以做 RAG 项目时不能只盯着生成端的模型能力检索质量往往是决定效果上限的地方。1.2 RAG 和微调、长上下文、Agent 怎么选RAG 不是唯一的知识注入方式。实际项目中经常有人问到底该用 RAG、微调、长上下文还是引入 Agent它们解决的问题有重叠但适用边界不一样。方案核心思路适合场景主要成本RAG检索外部知识后生成知识更新频繁、需要引用来源、私有数据隔离索引构建、检索链路、向量库运维微调用训练数据调整模型权重固定写作风格、领域术语、能力塑造GPU 训练资源、数据标注、版本管理长上下文把大量文档直接放入 Prompt一次性分析少量长文档、跨章节连续理解Token 费用、接口延迟、上下文窗口占用Agent让模型规划多步工具调用多轮查询、跨库汇总、需要调用多个 API编排复杂度、错误传播、调试成本从这些对比可以看出RAG 的核心优势是知识可更新、答案可溯源。当你需要回答“这个问题来自哪份文档的哪一段”时RAG 天然比微调和长上下文更合适。微调更适合改变模型的行为和风格而不是更新事实性知识。长上下文适合单次读取大文档但每次都把全部内容塞进 Prompt 会非常昂贵也不适合频繁更新的数据。Agent 和 RAG 不是对立关系而是组合关系。Agent 负责判断“这个问题需要几步、调用哪些工具”RAG 可以作为 Agent 的一个工具负责从知识库检索。后面讲 Agentic RAG 时会再展开。1.3 学习环境与生产环境的差异很多教程只演示了脚本级别的 RAG读者照做之后觉得“跑通了”但把它放在生产环境立刻就会出现问题。差异主要体现在几个方面维度学习环境生产环境数据量级几份文档、几百个分块几十万甚至上百万分块向量库Chroma、FAISS 本地存储Milvus、pgvector、Elasticsearch 等独立服务请求模式单线程手工调用高并发、超时、限流数据更新手动重新建库增量更新、数据版本管理权限控制无或极简按用户、部门、文档级别隔离日志监控无全链路日志、检索耗时、指标监控异常处理报错就重跑降级、重试、告警学习阶段最重要的是把链路跑通理解每个环节的作用生产阶段则要考虑知识库替换、权限隔离、检索延迟和成本。文章后面会单独讲生产落地问题。2. 搭建最小可运行的RAG链路这一部分从零开始搭建一个 RAG 最小系统。技术栈选择 Python 生态的 LangChain 作为编排工具Chroma 作为本地向量库HuggingFace 的本地 Embedding 模型做向量化LLM 使用任意兼容 OpenAI Chat 接口的服务或本地部署模型。下面示例用于说明完整流程实际项目要结合自己的包名、路径和模型版本调整。2.1 环境准备与依赖版本建议使用 Python 3.9 以上版本。安装依赖时不需要一次性装完所有 LangChain 相关包只需要当前链路需要的部分python --version pip install langchain langchain-community langchain-huggingface chromadb sentence-transformers pypdf各依赖的作用langchain提供文本分割、Chain 编排、Prompt 模板等核心能力。langchain-community提供非核心的文档加载器、向量库封装等集成组件。langchain-huggingface提供HuggingFaceEmbeddings用于加载本地 Embedding 模型。chromadb轻量级本地向量数据库适合学习和小规模原型。sentence-transformersEmbedding 模型的推理依赖。pypdf用于解析 PDF 文件。注意LangChain 在 0.1、0.2、0.3 等多个版本中 API 变化较大很多类从langchain.xxx迁移到了langchain_community.xxx。如果你使用的是旧版教程代码导入报错时优先检查包名是否已经迁移。2.2 文档加载与解析全流程RAG 第一步是把原始文档变成可以被后续处理的 Document 对象。不要把整个 PDF 直接扔给模型因为 PDF、Word 等格式本质上是排版文件里面包含页眉、页脚、表格、图片等复杂结构不解析就直接切分会产生大量噪声。先看一个加载 PDF 的示例from langchain_community.document_loaders import PyPDFLoader loader PyPDFLoader(docs/project_manual.pdf) pages loader.load() print(f加载页数: {len(pages)}) print(pages[0].page_content[:200]) print(pages[0].metadata)loader.load()返回的是一个Document列表每个Document包含page_content和metadata。metadata中通常会包含页码、来源路径等信息这些信息在后续做来源引用时非常有用。如果是批量加载文本类文件可以使用DirectoryLoaderfrom langchain_community.document_loaders import DirectoryLoader, TextLoader loader DirectoryLoader( docs/, glob**/*.txt, loader_clsTextLoader, loader_kwargs{encoding: utf-8}, ) documents loader.load() print(f加载文档数: {len(documents)})加载完成后还需要做一轮文本清洗。PDF 解析经常出现页眉页脚重复、多余换行、多余空格等情况import re def clean_text(text: str) - str: # 合并连续三个以上换行 text re.sub(r\n{3,}, \n\n, text) # 合并连续空格和制表符 text re.sub(r[ \t], , text) return text.strip() for doc in documents: doc.page_content clean_text(doc.page_content)这里的检查点很简单加载完成后打印总字符数和文档条数快速判断内容是否完整、是否出现大量乱码或空页。一个常见问题是扫描版 PDF它本质上是一张张图片pypdf解析出来可能只有空白内容此时需要 OCR 技术配合处理这属于另一条技术线。2.3 文本分块策略与参数大模型的上下文窗口有限Embedding 模型通常也只适合处理一段几百字以内的文本所以必须把长文档切分成多个文本块。分块质量直接影响后续检索质量。推荐使用 LangChain 的RecursiveCharacterTextSplitter它会按优先级逐级尝试分隔符尽量保持语义完整from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, separators[\n\n, \n, 。, , , ., , ], ) chunks text_splitter.split_documents(documents) print(f分块数量: {len(chunks)}) print(chunks[0].page_content)参数含义chunk_size每个文本块的最大字符数。chunk_overlap相邻文本块之间重叠的字符数。separators切分时使用的分隔符优先级列表。为什么需要chunk_overlap因为如果一句话被恰好切到上一块末尾下一块没有开头语义就断掉了。重叠部分可以让前后块之间保留上下文衔接。分块大小对检索效果的影响可以用下表简单概括chunk_size优点缺点适合场景偏小200 左右检索粒度细定位准确上下文信息少容易语义不完整事实型问答、关键词检索适中500 左右平衡召回率和上下文中等长度需要结合 overlap大多数通用文档偏大1000 以上上下文完整适合总结向量平均化严重检索精度下降需要大段理解的技术报告这里提到的“向量平均化”是指当一段文本包含多个主题时Embedding 会把所有信息压缩成一个向量导致这段文本与任何单个问题的相似度都不高检索阶段反而召不回相关内容。所以分块并不是越大越好。2.4 向量化、存储与检索文本块准备好之后需要把它们转换成向量。向量化这一步由 Embedding 模型完成它的目标是把语义相近的文本映射到向量空间里相近的位置。中文场景可以优先选择支持中文的 Embedding 模型。下面使用BAAI/bge-m3它是一个支持中英双语的模型效果和本地部署成本都比较均衡from langchain_huggingface import HuggingFaceEmbeddings embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-m3, encode_kwargs{normalize_embeddings: True}, )首运行时会下载模型权重到本地缓存目录。如果网络环境受限可以提前在其他机器下载权重放到本地目录后再通过model_name指定本地路径。向量存储和检索使用 Chromafrom langchain_community.vectorstores import Chroma vectorstore Chroma.from_documents( documentschunks, embeddingembedding_model, persist_directory./chroma_db, )执行完成后./chroma_db目录下会保存向量索引。后续再次运行可以通过Chroma(persist_directory./chroma_db, embedding_functionembedding_model)重新加载而不需要重新分块和向量化。检索最小示例如下query 项目的部署环境有哪些要求 retrieved vectorstore.similarity_search(query, k4) for i, doc in enumerate(retrieved): print(f--- 第 {i 1} 个结果 ---) print(doc.page_content[:150])k4表示召回与问题最相似的 4 个文本块。这一步是 RAG 中最关键的动作后续生成质量完全取决于这 k 个文本块是否正确。2.5 生成回答并验证最后一步是把检索到的文本块和用户问题一起交给大模型。这里使用一个通用 Prompt 模板from langchain.prompts import PromptTemplate template 你是一个严谨的知识库问答助手。请只根据下面的上下文回答问题。 如果上下文中没有足够信息请直接回答“根据当前资料无法确定”不要编造。 回答时尽量简洁并注明信息来源。 上下文 {context} 问题{question} 回答 prompt PromptTemplate( input_variables[context, question], templatetemplate, )通过 LangChain 的RetrievalQA串联检索和生成from langchain.chains import RetrievalQA # 假设 llm 已经初始化具体初始化方式取决于你使用的模型服务 llm None # 替换为你的 LLM 实例 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, retrievervectorstore.as_retriever(search_kwargs{k: 4}), return_source_documentsTrue, chain_type_kwargs{prompt: prompt}, ) result qa_chain({query: 项目的部署环境有哪些要求}) print(result[result])需要把llm替换成真实可用的模型实例。常见的接入方式包括 OpenAI 兼容的 Chat 接口、Ollama 本地模型、vLLM 部署的服务等使用哪种取决于你的资源和场景。运行之后有两个校验点回答是否忠于检索上下文还是出现了上下文里没有的内容。返回的source_documents中是否真的包含能支撑回答的片段。这两点往往比“回答流不流畅”更重要。如果回答流畅但内容完全来自模型自身记忆那 RAG 的约束就没有起作用。3. 影响RAG效果的关键参数与调优很多 RAG 项目第一版跑通后效果不佳问题往往不是出在大模型上而是出在分块、向量化、检索策略和 Prompt 这几个环节。3.1 分块大小与重叠参数分块是 RAG 效果波动最大的环节之一。chunk_size和chunk_overlap需要根据文档类型调整对于条款类文档比如协议、规范一个条款通常就是一个语义完整单元可以按条款编号、章节标题切分比固定字符数切分更可靠。对于技术手册段落之间有较强上下文关联建议使用较大的chunk_overlap比如 80 到 100 字符。对于表格和代码块固定字符切分会破坏结构最好先把表格转成 Markdown 表格、代码块保持整体再做切分。判断分块是否合理的信号有三个检索召回的前 k 个块中是否总包含正确答案所在的片段。单个块内部是否只讲一个主题。关键术语是否在块内首次出现时就有合理解释。这里常犯的错误是直接照抄教程里的 500/50 参数。不同的 Embedding 模型对文本长度敏感度不同落地前应该用你自己的文档做一组小实验对比不同分块参数下的召回效果。3.2 Embedding 模型与向量库选型Embedding 模型决定“语义相似”怎么计算。中文场景常用的几类选择模型特点适用场景BAAI/bge-m3中英双语支持长文本效果稳定多数中文知识库m3e-base / m3e-large中文优化轻量中文问答、小规模项目text2vec-large-chinese中文匹配效果好中文短文本检索商业 Embedding API调用简单维护成本低对数据外发无限制的项目这里有一个容易被忽略的点检索阶段使用的 Embedding 模型必须和入库阶段一致。如果文档入库存量时用的是 A 模型查询时换成了 B 模型两个模型的向量空间不兼容检索结果会完全不可用。向量库选型同样重要向量库部署方式适合规模特点Chroma本地/嵌入式小规模原型零运维入门快FAISS本地/服务中等规模检索性能高无内置数据管理Milvus独立服务大规模生产分布式、过滤、权限控制完整pgvectorPostgreSQL 插件中等规模与业务库同库避免多系统Elasticsearch独立服务混合检索场景原生支持关键词和向量检索学习阶段用 Chroma 就够了生产环境则要考虑数据规模、并发、备份和权限这些不是本地嵌入式向量库能直接承担的。3.3 检索策略参数RAG 生成质量的上限由检索决定。下面几个参数是排查效果问题时的重点关注对象。k召回数量默认常见值是 3 到 5。k太小可能漏掉正确答案。k太大会引入噪声块稀释上下文。调参时先看一个直观现象正确答案通常排在第几位。如果正确答案稳定排在第一位k3通常够用如果正确答案经常排到第五位以后应该优先优化分块和 Embedding而不是继续增大k。相似度阈值retriever vectorstore.as_retriever( search_typesimilarity_score_threshold, search_kwargs{score_threshold: 0.5, k: 4}, )score_threshold表示只保留相似度超过阈值的文档。阈值调太高容易召回为空调太低噪声块大量涌入。不同 Embedding 模型产出的分数范围不一致不要直接套用别的项目的阈值先打印一批真实查询的相似度分数再决定阈值。混合检索向量检索擅长语义匹配但遇到精确 ID、编号、型号、全文包含的专有名词时关键词检索往往更可靠。生产项目常见做法是向量检索 BM25 关键词检索再把两类结果做合并和去重之后进入 Rerank 阶段。Rerank召回阶段为了召回率会保留较多候选文档Rerank 用一个专门的排序模型对这些候选重新打分把最相关的文档排到最前面。这在文档数量较大的知识库中提升明显。常用的方案有bge-reranker等模型使用时把它放在向量检索之后、生成之前。3.4 Prompt 模板设计Prompt 在 RAG 中承担的任务不是“让模型更有创意”而是“把模型约束在事实范围内”。一份合格的 RAG Prompt 通常包含四类指令角色和身份告诉模型它是知识库问答助手。任务描述要求基于上下文回答而不是凭记忆。约束条件不确定时明确说不知道不要编造。输出格式是否需要引用来源、是否使用列表、回答长度。上面第 2.5 节给出的模板已经覆盖了前三点。再补充一个带来源引用的示例template 你是知识库问答助手。请基于下面的上下文回答问题。 在回答末尾列出你参考的文档编号。 约束 1. 只使用上下文中的信息。 2. 如果上下文不足回答“根据当前资料无法确定”。 3. 不要输出上下文外的推测。 上下文 {context} 问题{question} 回答 【结论】 【参考文档】 实际项目可以在context中携带文档的 metadata例如来源project_manual.pdf 第 3 页模型就能在回答时引用具体来源。3.5 从“能跑”到“精准”的建设路径如果现有 RAG 表现不稳定按下面的顺序逐层调优先确认文档加载和清洗是否正确有没有乱码和空白页。再检查分块是否切碎关键句子。然后检查检索 TopK 里是否包含正确答案。接着检查 Rerank 是否把正确答案排到前面。最后检查 Prompt 是否把生成约束在上下文中。很多团队跳过前几步直接换大模型结果换了更强的模型回答依然错误。原因往往是检索层已经丢了正确答案生成端再强也没有用。4. RAG知识库指标怎么选、怎么理解、怎么用判断 RAG 效果不能只靠肉眼抽查几条回答。肉眼看不全面也无法在文档更新后做回归对比。要建立一套可重复的评测方式把检索质量和生成质量分开衡量。4.1 为什么要单独评测一个端到端的 RAG 系统由“检索”和“生成”两个阶段组成。如果最终回答错误可能是检索召回的内容不对也可能是检索正确但生成时没有正确利用上下文。如果不分开评测你就无法定位问题在哪一层。所以评测要拆成两个维度检索质量模型有没有把正确答案对应的文本块召回出来。生成质量模型有没有基于召回的文本块生成忠实回答。4.2 检索质量指标构建评测集时准备若干条问题并为每个问题标注“正确答案所在的文本块编号”。然后让检索器返回TopK结果计算以下指标Hit Rate命中率含义在数据集中TopK结果里至少包含一个正确答案的查询占比。用途判断检索是否基本可用。示例10 个问题中有 8 个在 Top5 里召回了正确答案Hit Rate5 0.8。MRRMean Reciprocal Rank平均倒数排名含义对每个查询取第一个正确答案的排名倒数再对所有查询取平均。用途判断正确答案排名是否尽量靠前。示例两个查询中正确答案分别排在第一位和第三位MRR (1/1 1/3) / 2 0.667。RecallK 和 PrecisionKRecallKTopK 召回的相关文档占全部相关文档的比例。PrecisionKTopK 中相关文档占 TopK 的比例。用途在“一个查询对应多个相关片段”的场景中使用。下面是一个模拟命中率计算的 Python 示例def hit_rate(retrieved_ids, ground_truth_ids): hit_count 0 for retrieved, truth in zip(retrieved_ids, ground_truth_ids): if set(retrieved) set(truth): hit_count 1 return hit_count / len(retrieved_ids) # 示例数据 retrieved_ids [ [12, 34, 56, 78], # 第一个查询召回的块ID [10, 20, 30, 40], # 第二个查询召回的块ID ] ground_truth_ids [ [56], # 第一个查询的正确答案块ID [99], # 第二个查询的正确答案块ID ] print(hit_rate(retrieved_ids, ground_truth_ids)) # 输出 0.5这段代码只是用 Python 原生列表模拟计算实际项目中把向量库返回的Document的metadata或id传入即可。4.3 生成质量指标生成质量的评估比检索更复杂因为它涉及语义判断。社区中比较常用的三类指标Faithfulness忠实度含义回答内容是否完全由上下文支持没有编造。判断方式逐个检查回答中的事实点是否都能在上下文中找到依据。典型场景回答中出现了“根据文档该系统支持 XX 功能”但上下文中根本没有提到 XX则忠实度低。Answer Relevance答案相关性含义回答是否针对用户问题而不是答非所问。判断方式删除上下文后单独看回答和问题的相关性。典型场景用户问“部署需要什么硬件”回答却介绍软件架构答案相关性低。Context Relevance上下文相关性含义检索出的上下文是否与问题相关。判断方式逐句检查上下文中的内容有多少比例和问题相关。典型场景问题问的是“配置项怎么改”召回结果却全是“产品简介”的内容上下文相关性低。这三类指标在 Ragas 等评测库中有对应的实现思路。Ragas 采用 LLM 辅助打分即把上下文、问题、回答组织成评测 Prompt让一个强模型输出打分。使用时要留意LLM 辅助评测本身也有偏差因此评测模型最好与生成模型不同避免自评偏差。4.4 评测集和落地方式一个完整的 RAG 评测流程包含构建评测集。从真实场景中收集 50 到 200 条问题越多越能反映真实分布。问题要覆盖简单事实查询、组合查询、边界查询。标注正确答案。为每条问题标注检索层面的正确块 ID 和生成层面的期望回答要点。运行评测。分别计算检索指标和生成指标。对比回归。修改分块参数、更换 Embedding 模型、调整 Prompt 后重新运行同一套评测集用指标对比效果变化。评测集分为“检索评测集”和“生成评测集”。检索评测集只包含问题和正确答案块 ID不需要完整参考答案生成评测集还需要参考答案或至少标注回答要点。这样拆开可以在调检索时不重复评估生成。指标怎么理解要结合场景如果业务对答案准确性要求极高优先保证 Faithfulness。如果业务关注用户能否快速找到信息优先优化 Hit Rate 和 MRR。如果回答经常跑题先检查 Answer Relevance。如果回答内容完整但引用的上下文不对先检查 Context Relevance。5. 进阶路线Agentic RAG、Graph RAG、OAG 与工具化平台基础 RAG 已经能解决不少问题但面对复杂查询、跨文档整合、高度结构化文档时需要演进到更高级的架构。5.1 Agentic RAG把检索变成可规划的步骤经典 RAG 是“一问一检”用户提交问题系统检索一次生成一次回答。Agentic RAG 则让大模型作为 Agent自己判断是否需要检索、检索几次、使用什么工具。典型场景包括用户问题同时涉及多个文档需要多次检索并整合。用户问题本身不清晰Agent 先反问澄清再检索。用户需要执行“先查条件再筛选数据”的复合流程。实现思路上Agent 通过 ReAct 循环工作接收用户问题决策是否调用检索工具观察检索结果再决定下一步动作最终生成回答。LangChain 的create_retriever_tool可以把检索器包装成一个 Agent 可调用的工具。Agentic RAG 的优势是灵活代价是复杂度上升模型可能做出错误决策、调用次数增加、延迟变高、错误可能被多步放大。生产环境中要给 Agent 设置最大迭代次数、单次检索返回数量上限并对超时和失败做兜底。5.2 Graph RAG 与 Ontology RAG让知识组织更精确Graph RAG 是在 RAG 链路中引入知识图谱技术。与向量库只存文本块不同Graph RAG 把实体、关系和属性存成图结构。查询时先通过实体匹配定位到图节点再沿关系扩展相关上下文最后把扩展结果交给生成器。它的典型优势在于处理“实体关系型”问题比如“某个协议中A 网元与 B 网元的接口流程是什么”“某个专利的权利要求依赖哪些从属权利要求”“某类故障会导致哪些下游模块受影响”这类问题如果只靠向量相似度检索往往只能召回包含关键词的片段无法沿着关系链路找到完整答案。Graph RAG 更适合。Ontology RAG 更进一步在图中定义清晰的类型、属性和约束关系。比如在 3GPP 协议文档中定义“网元”“接口”“流程”“参数”等类型以及它们之间的关联关系。检索时先判断问题涉及的实体类型再按本体约束检索能显著提高召回准确率。它的落地成本也比较高需要人工或半自动抽取实体关系构建和维护图谱对文档结构变化敏感。适合协议、专利、法规等高度结构化、长期稳定的文档领域。5.3 RAG 与 OAG 的差异社区讨论中还有一个概念是 OAG即 Online Augmented Generation在线增强生成。相对于经典 RAG 的“离线构建索引 在线检索生成”OAG 更强调在线检索与生成的实时联动典型做法是从搜索引擎、实时 API、实时数据库获取最新信息并即时组织回答。这两者的边界在工程中并不需要严格划分。离线知识库适合公司内部私有文档在线检索适合时效性要求高的公开信息。实际系统往往同时包含两条链路先查内部向量库查不到或需要最新资讯时再调用在线搜索引擎最后统一交给模型生成。设计时重点不是争论概念而是明确数据源、查询路由和结果合并策略。5.4 常用框架与平台选型工程落地时选择框架和平台会直接影响开发效率。常见的选择如下工具/框架定位适合场景LangChain开发框架深度定制 RAG 流程、需要细粒度控制LlamaIndex开发框架文档索引和知识库构建场景Dify可视化平台快速搭建应用、多人协作、包含工作流AnythingLLM本地知识库工具个人和小团队快速使用私有知识库Spring AIJava 生态框架已有 Java 技术栈的团队做 AI 集成选型原则很简单如果你的核心能力是业务逻辑和模型策略直接用 LangChain 或 LlamaIndex如果团队需要快速做应用演示Dify 这类平台能省去很多前端和运维工作如果是 Java 团队优先考虑 Spring AI避免引入异构技术栈。6. 生产落地常见问题、排查链路和最佳实践6.1 排查链路从用户输入到回答逐层定位RAG 问题的定位顺序应该是输入 - 文档加载 - 分块 - 向量化 - 检索 - 生成。每一层都可能引入错误排查时按层检查不要跳过。排查层核心问题检查方法用户输入问题本身是否清晰打印原始 query文档加载文档是否被正确解析检查页数、字符数、乱码分块内容是否被切碎打印样本块看语义是否完整向量化向量是否有效做相似度自检同一句话检索自己检索正确答案是否被召回打印 TopK 文档人工核对生成模型是否正确利用上下文对比上下文与回答的事实点6.2 常见坑和解决方案问题现象常见原因检查方式处理建议回答总是“不知道”阈值过高或检索结果为空打印检索结果和相似度分数降低score_threshold检查知识库是否包含答案回答流畅但与文档不符模型依赖自身记忆没有遵循上下文对比回答与检索内容强化 Prompt 中的约束引入来源引用检索结果全是相近内容分块过大导致向量平均化打印分块内容和检索 TopK减小 chunk_size按文档结构调整分块某类关键词永远检索不到向量检索对精确编号不敏感用关键词直接搜索原文档加入 BM25 关键词检索做混合检索换模型后检索效果变差入库和查询使用了不同 Embedding检查两个阶段模型名统一入库
返回列表