
1. 先搞清楚RAG 智能体到底是在解决什么问题去年团队接到一个制度条例学习助手的活儿业务方给了一堆 PDF 和网页材料要求既能查答案又能按条款来源给依据还要能对员工提问给出个性化答复。最初我们用传统搜索做用户搜“休假天数”能出来几十条结果但要他自己判断哪一条适用体验很差。后来换成 RAG模型能把条款原文找到、归纳成一段话并说明出处整个体验立刻不一样。这里的关键在于RAGRetrieval-Augmented Generation不是把文档丢进模型而是让大模型在回答之前先从外部知识库里检索相关资料再把资料作为上下文生成有依据的回答。它的价值不在于“会用大模型”而是解决大模型最容易被人诟病的问题编造事实、知识陈旧、没有出处。但在实际项目里RAG 很少单独存在。你可能听过 Agentic RAG、多智能体、RAG as Service 这些词但它们并没有脱离 RAG 的核心逻辑。下面这部分我先带你重新梳理 RAG 智能体的技术坐标再看它和普通问答系统到底差在哪里。1.1 从“查文档”到“会查文档的智能体”纯 RAG 的流程很简单用户提问 → 向量检索 → 拼 Prompt → 生成回答。这个链路适合 FAQ 类和简单知识问答。一旦问题带有多轮上下文、需要查多个来源、需要调用外部系统比如查打卡记录、生成休假审批单单线程的 RAG 就不够用了。于是出现了 Agentic RAG智能体先判断这个问题要不要检索、检索哪个知识库、如果第一轮检索不够要不要换一种方式再查一次甚至把多个结果汇总后再做推理。多智能体方案更进一步把“提问理解”“检索”“生成”“检查”拆成不同的角色各自维护一套模型、工具和记忆再通过调度器协作。工程上我的建议是先不要为“智能体”的概念投入太多热情。先跑通朴素 RAG再在出现明显瓶颈时逐步引入重写、路由、重排和工具调用。所谓 Agentic RAG并不是一种新的神秘架构而是把传统 RAG 的关键环节全部“可编程化”让系统能根据上下文做决策。如果你还没搞清楚朴素的检索增强流程直接上多智能体大概率会把问题搞复杂。1.2 全栈开发到底“全”在哪里我见过不少项目把全栈开发理解成“前端写个聊天框 后端调大模型接口”。等到真上线问题全出在中间层文档表格解析错位、检索命中率只有 40%、回答引用了过期条款、并发一高就超时。这些都不是模型的问题而是数据、检索和工程化的问题。因此所谓 RAG 智能体全栈开发我拆成六层数据层获取文档、解析、清洗、分块、存储。检索层向量/关键词/图混合检索、重排、路由。生成层Prompt 模板、上下文组装、模型调用。智能体层工具注册、任务规划、多轮记忆、多智能体协作。服务层API 设计、并发控制、权限、日志、缓存。评测运维层离线指标、线上监控、效果回归。这套文档后面每一章基本就是按照这个分层展开的。技术框架可以换但这几层的事情躲不掉。你可以在 Dify 上拖出界面也可以用 LangChain4j 写 Java 服务更可以用 AgentScope 2.0 把检索能力服务化但无论用哪种方案最终都要回答清楚数据从哪来、怎么检索、怎么组装回答、怎么保证可维护性。2. 架构选型先别动手先决定输赢我把“选框架”放在很前面是因为很多项目做到一半推倒重来不是模型不好而是框架跟场景不匹配。技术选型这件事本质上不是在选“最流行的工具”而是在选“团队未来半年最容易维护的路径”。2.1 场景决定框架Dify、LangChain4j 还是 AgentScope先放一张我常用的选型对照表方便你按团队情况对号入座框架类型适合场景要付出的代价Dify低代码智能体平台快速搭建知识库问答、工作流编排复杂逻辑被平台封装二次开发有边界LangChain4j / Spring AI开发框架Java 技术栈的深度定制每个模块都自己拼前期成本高AgentScope 2.0多智能体框架多角色协作、RAG as Service 服务化需要学习分布式消息和智能体协议LlamaIndex数据框架文档处理、索引、复杂检索策略本身不解决智能体编排问题自研自由组合项目规模大到框架无法满足全链路都由团队维护选型时记住三句话团队熟悉什么用什么场景需要什么再决定要不要框架框架只是加速器不是护身符。Dify 适合业务人员和研发比例悬殊的团队。你可以把文档管理、AI 编排、模型接入都在界面里完成让业务人员自己调整知识库。AgentScope 2.0 我接触比较多的是它把 RAG 作为一项服务暴露出来让多个智能体可以共享同一个检索服务这样避免在每次对话时重复建索引资源利用会更干净。LangChain4j / Spring AI 适合已经有 Java 后端的团队。很多人一开始纠结“要不要上 LangChain”如果你的服务端是 Java我更推荐直接看 LangChain4j。它最近把 Easy RAG 这类组件做成了开箱即用对于不想自己拼装太多组件的场景非常友好。团队全是 Java 开发者时硬上一套 Python 的 LangChain反而会给运维带来更多麻烦。2.2 模型与知识库的本地化/服务化取舍模型这一层现在可选路径很多。在线大模型 API 效果稳定但数据要出域本地模型用 Ollama 跑量化模型数据不出内网但回答质量和推理速度都会打折扣。我的做法是“两端准备”开发阶段用 Ollama 拉一个 7B/14B 量级模型再配一个本地向量库先把流程跑通。生产阶段根据业务数据的敏感程度决定是否走在线模型若必须本地化优先用 vLLM 做推理加速或采购商用 GPU 服务。需要提醒的是本地 RAG 并不是“把模型下载下来就行”。文档解析、检索、Prompt 设计、评测这些环节和用云端 API 是一样的。你省下的只是调用成本该干的活一点都不会少。另一个常见误区是把知识库和模型部署绑在一起。纯概念上向量数据库和模型服务本来就是两个独立组件完全可以分开扩容。我甚至在 Dify 上搭过一套原型检索用线上向量库生成用本地模型效果也正常。所以选型时务必要问一句将来知识库变化大还是并发变化大答案不同部署结构也不同。3. 知识库构建效果天花板在数据侧检索效果不是模型决定的而是知识库决定的。我在不同项目里观察到一个规律数据清洗和分块做得好最后的命中率通常不会差反过来模型再强也救不回来。所以这一章是整套文档里最“脏”但也最值钱的部分。3.1 数据清洗细节知识库里的原始文档往往来自 PDF、Word、网页、Excel、扫描件。最常见的坑有几个PDF 文字层缺失直接提取出乱码。表格跨页解析后行列错位。条款编号和正文分属不同文本块检索时上下文被切断。同一制度有多个版本年份不同混在一起就是雷。处理这些问题的基本思路是先做一次全量体检。按文件类型统计可解析文本的行数和字符数挑出明显异常的样本单独处理。对于扫描件先 OCR但 OCR 结果通常有错字需要结合制度文本里的固定术语做二次校正。清洗后我建议给每个知识块打上元数据标签。比如“机构名称、制度名称、版本、章节、生效日期、原文链接”。这一步看起来多余但它直接影响重排和引用溯源。很多系统上线后回答“看似正确但找不到出处”就是因为元数据没有保留到生成层。3.2 分块、重叠与嵌入模型选择的经验值文本分块没有唯一标准但有几个经验值可以参考。首先中英文混排时chunk_size 设 512按 token 计或 500-800 字重叠 50-100 字是比较稳妥的起点。太长的块会稀释语义太短的块又会切断上下文。分割时尽量按 Markdown 标题、段落或句子边界切不要硬按字符数切。其次Embedding 模型要跟检索场景匹配。做中文制度问答我常用 BGE 系列或 M3 系列等中文效果比较好的模型。别只看榜单分数一定要拿自己的文档做召回测试。方法很简单准备 20 个“问题-正确段落”样本计算向量召回时正确段落出现在 Top-5 里的比例。用这个比例选择模型比看任何评测文章都可靠。对重叠有争议的部分我的看法是如果文档以条款为主重叠主要解决“问题上半句在上一段答案在下半段”的切碎问题如果文档是教程类的承上启下结构重叠应稍大一些。当然重叠越大存储和检索成本越高不要盲目拉到 200 字。3.3 混合检索与图增强检索只靠向量检索会出现两个问题专有名词和编号对不上同一件事换个说法就搜不到。我通常会做“向量检索 BM25 关键词检索”的混合召回再用 RRFReciprocal Rank Fusion把两边结果融合。这样既能把握语义又能兜底精确词匹配。对于实体关系密集的制度文档我会额外考虑 Ontology RAG 或 GraphRAG。简单说就是在原有文档块之外再把“条款与条款之间、岗位与权限之间、流程与表单之间”的关系建成图索引。回答“这个流程里有哪些审批节点”时普通向量检索只能找到碎片图索引能把完整链路拉出来。不过图增强不是万能的。它需要额外维护本体定义和实体抽取小项目可能投入产出比不高。我建议先混合检索等遇到实体关系类问题变多时再上 GraphRAG。别因为“GraphRAG 很火”就把它放进每个项目。4. 检索生成流程把每一步都变成可干预的知识库建好了接下来是 RAG 流程的编排。我把这部分定为“可干预”意思是流水线里的每个环节都能单独调试而不是黑盒一把梭。4.1 查询改写与意图路由用户提问往往是口语化、指代不明的。比如对话历史里用户先问“休假规则”再问“那出差呢”如果不把第二句补全成“出差的休假规则”检索结果会很差。所以第一件事是查询改写用大模型把多轮对话转换成独立、自包含的查询语句。另外许多知识库不是单一结构可能有制度问答区、FAQ 区、操作手册区。问题路由的作用是决定把问题送到哪个知识库甚至决定用检索还是直接生成。这一层可以用规则或轻量分类模型来做不一定每次都调用大模型。我的路线是优先用便宜的模型做路由只有当一个知识库的检索结果明显不相关时才允许智能体尝试另一个知识库。并且给这种“重试”设置最高次数避免死循环。这个设计在做 Agentic RAG 时特别重要。4.2 多路召回与重排召回阶段系统先把向量检索、BM25、图检索的结果合并成一个候选池然后交给重排模型打分。这里最核心的参数有两个召回数量和重排保留数量。我常用的方案是召回 Top-K20。重排后保留 Top-N5。重排模型维度与查询相关性和回答可引用性都要考虑。重排不一定非要用大模型。在响应时间敏感的线上服务里交叉编码器cross-encoder之类模型比大模型快得多。如果你用长上下文模型也可以省掉重排直接把 20 个结果全塞进去但成本和延迟都会上升。更好的做法是让重排结果只保留最相关片段再对片段做摘要式处理保证 Prompt 长度稳定。# 伪代码示意多路召回 RRF 融合 def rag_search(query, vector_topk20, bm25_topk20): vector_hits vector_store.search(query, topkvector_topk) bm25_hits bm25_search(query, topkbm25_topk) fused rrf_fusion([vector_hits, bm25_hits], k60) return fused[:20]这段伪代码里的 rrf_fusion 可替换成你选型框架里已有的实现思路是给每个文档在不同检索路上的排名取倒数分值再相加排序。你不需要自己实现 RRF 把分数调得很复杂用现成库就够了。4.3 上下文组装与引用溯源生成阶段的 Prompt 很关键。我的原则是信息透明把候选块按“文档名、章节、原文”的格式列出。强制引用要求回答中每个观点都要用[来源编号]标注。设置“不知道”边界如果检索结果与问题无关明确回答“知识库中没有找到”。防止“过度推理”不要强迫模型在缺乏信息时补充细节。打个比方RAG 像是给模型配了一位图书管理员而不是让它直接背百科全书。那位管理员找错书模型就只能胡说。所以 Prompt 里我会加上“只依据以下资料回答不得使用其他知识”这句话能显著减少幻觉。上下文组装环节还要考虑长度预算。候选块较长时先做摘要再组装成结构化段落而不是原封不动塞进去。核心逻辑是保留最贴近答案的细节丢弃冗余背景。5. 智能体层从回答问题到执行任务单纯做问答到第四章就可以收尾了。但如果业务方要求“查完制度之后还要生成请假单、推送审批提醒”就得进入智能体层。5.1 智能体工作流的最小骨架智能体和普通对话接口的最大差别是会主动调用工具。比如收到“请帮我根据考勤制度统计我这个月迟到次数”系统不能只回答制度而是要完成三步解析身份、查考勤系统、算次数并给出结论。这就是工具调用。我搭建最简智能体时会至少包含这些模块大模型核心决策工具注册表每个工具的名称、参数、返回格式规划器决定先调用哪个工具使用什么参数记忆记录前几轮的目标和结果终止条件任务完成或失败。工作流引擎适合把任务拆成固定 DAG如“先查制度 → 再查数据 → 组装报告”。多智能体则适合在任务分支多、需要不同角色讨论的场景里使用。以我自己的经验多数业务场景用固定工作流就够了真正需要多个智能体自由对话的反而少。行业里一直有“把智能体做成自由对话”的说法但你要想清楚两个模型互相对话很容易陷入循环。工程上更可靠的方式是用工作流把主干流程固定下来只在分支节点上让模型做选择和生成。这样既保留了智能体的灵活性也避免了不可控的发散。5.2 工具调用的“敏感变量”与权限控制这里必须讲一个容易被忽视的问题工具的输入参数是“敏感变量”。大模型可以按照用户指令生成参数比如生成 SQL 去查数据库、组装 HTTP 请求去调用后端。我见过一个项目把“用户ID”做成对话变量结果用户改参数就能查到别人数据。所以工具参数不能盲目信任模型输出。要做三件事参数校验所有参数按白名单校验非法值直接拒绝。权限映射从会话令牌中解析用户权限而不是让大模型自己决定能查什么。结果脱敏工具返回的数据先做脱敏或以摘要形式返回给模型避免模型把敏感信息当上下文输出。遇到“技能敏感变量”这类词我的理解就是智能体的技能越强变量越要受控。一个能调数据库的智能体和一个只能查文档的智能体风险完全不同权限设计也完全不同。5.3 多智能体协作与服务化如果项目确实需要多智能体我建议避免无序聊天而是给每个智能体明确职责。比如一个 RAG 智能体负责检索文档一个稽核智能体负责检查回答是否忠实于引用一个编排智能体负责汇总。每个智能体之间通过消息队列或共享状态传递结果而不是直接让模型之间互相对话。AgentScope 2.0 里把 RAG 作为服务提供是我比较认可的做法。原因是多智能体如果各自持有知识库索引会造成重复建设和数据不一致。把“知识检索能力”独立成一个服务所有智能体都通过同一个接口访问数据更新和权限控制都能集中管理。顺着这个思路你还会遇到“RAG as Service”这个说法。它本质上就是把离线索引管理、在线检索、重排等能力从具体业务里抽出来暴露成统一 API。好处是当你要接入新的智能体场景时不需要重新做知识库只需要调接口。坏处是服务层的稳定性要求变高了检索服务一旦挂掉所有智能体都会受影响。6. 评测体系没有验收标准就谈不上工程化很多 RAG 项目上线前不看评测上线后靠业务方“感觉不行”来反馈。这是最影响口碑的做法。我建议把评测当作 RAG 开发的一部分从第一天就建评测集。6.1 离线指标别只盯准确率RAG 系统的效果至少要分开看“检得准不准”和“生成得好不好”。下面是几个常用指标指标衡量对象含义RecallK / Hit Rate检索真实相关片段是否出现在 Top-K 结果中MRR检索第一个相关片段的排名有多靠前Faithfulness / 忠实度生成生成回答是否基于上下文有没有事实错误Answer Relevance生成回答是否切题、完整Citation Accuracy引用回答中引用的来源是否真的支持对应句子Hit Rate 很多文章会提但它只能说明“相关段落有没有被捞出来”不能保证生成效果。评测时至少要同时看检索指标和生成指标否则容易自欺欺人。6.2 评测集与 Evaluation 智能体评测集不宜太大但要覆盖常见问题、边界问题、否定问题和跨章节问题。每条样本至少包含三部分问题、标准答案或要点、关联的知识块 ID。然后可以做一个“Evaluation 智能体”让一个独立的智能体来评判回答质量。为了减少偏见我会在设计评估提示时要求它先摘录回答中的关键句再对照知识块判断是否一致如果发现回答内容没有来源直接判为不通过。请你作为评测员判断下面的回答是否忠实于给定资料。 资料片段... 模型回答... 要求回答中的每条事实都必须能在资料片段中找到依据。 输出PASS 或 FAIL并列出不符合依据的句子。把这样的评测流程自动化以后每次改 Prompt、换模型、调分块参数都能跑一遍回归集把效果变化量化出来。这是整个项目里最值得投入的部分。6.3 监控与回归线下评测不能覆盖所有线上情况所以线上要记录三类数据用户问题、检索结果、最终回答、引用来源用户是否点了“有帮助/无帮助”对话是否触发“无法回答”或长时间空转。这些数据按周聚合挑出高分和低分样本反哺评测集。我习惯每两周跑一次回归测试同时对比知识库变更前后的表现。很多“效果莫名其妙变差”的问题最后都能追溯到某次文档更新或模型切换。7. 部署落地从笔记本到生产环境的最后一公里理论和实验做完最终要让系统跑起来。这一章讲的是可落地、可运维的部署方式。7.1 零基础本地 RAG 的可复制方案如果你只想在本机跑通一个简易 RAG我推荐“Ollama 向量库 简易 Web UI”的组合。整体可以全部用 Docker 起version: 3.9 services: ollama: image: ollama/ollama:latest ports: [11434:11434] volumes: [./ollama:/root/.ollama] vector-db: image: chromadb/chroma:latest ports: [8000:8000] volumes: [./chroma:/data] web: image: nginx:alpine volumes: [./web:/usr/share/nginx/html:ro] ports: [8080:80]这套方案不涉及 GPU 也能跑适合开发调试和知识验证。如果要达到生产可用则要引入模型推理服务vLLM 之类、向量数据库集群、API 网关和应用日志系统。选项很多关键是先把本地方案跑通再按瓶颈逐层替换。7.2 生产环境服务化与可观测性生产环境里我建议把 RAG 能力封装成独立服务而不是塞在单体应用里。接口可以设计成POST /v1/query传入问题、会话 ID、用户权限返回回答和引用来源。内部再拆成检索服务、重排服务和生成服务便于独立扩容。可观测性要提前考虑。日志里必须有 trace_id从用户问题开始贯穿到各环节耗时。否则一次超时你很难判断是向量库慢了还是模型推理慢了。加一个简单的耗时记录每个环节都打点是最基本的工程素养。7.3 权限隔离与安全底线知识库内的文档往往不是所有人都能看。制度条例可能分部门、分级别。所以接口的权限过滤不能只在应用层做要在检索层就限制可检索范围。比如查询条件里携带角色 ID向量检索只扫到该角色允许访问的文档分区。同时工具调用权限要做到最小化。能返回摘要就不返回原表能只读就不要写权限。模型输出也要做敏感信息过滤防止工具返回到模型上下文后又原样吐给用户。安全设计不要等上线后再补这是我带过不少项目后的最大教训。8. 高频问题排查实录8.1 问题排查速查表问题常见原因排查方向检索结果为空文档解析失败、数据未入库先查文档是否成功切片并写入向量库命中率一直上不去分块不合适、嵌入模型效果差做评测集对比不同分块和嵌入模型回答乱编检索结果不相关、Prompt 约束不够增加“只依据资料”指令检查引用环节引用来源错乱元数据丢失、重排后上下文切碎在重排结果中保留文档 ID 和章节回答过长/超 token候选块太多太长增加重排截断或对候选块做摘要延迟高模型推理慢、没有缓存用更小量化模型增加语义缓存多轮对话检索不准没有查询改写加入多轮对话改写模块这张表解决 80% 的常见故障。剩下的是长期调优的事需要把评测循环跑起来。8.2 三个值得反复排查的隐性坑第一个坑是文档解析器版本问题。同一个 PDF 文件用不同解析库得到的内容差异很大。我遇到过解析后丢失了表格里的审批时限用户查“多久能批”时模型只能瞎猜。排查时一定要打开知识库里的原文片段逐条核对而不是只看总数。第二个坑是向量库索引和文档更新不同步。文档更新后旧切片没有删除导致新旧条款同时存在。做制度问答时检索结果经常会命中旧条款。解决办法是元数据里带上版本号并在入库时做“同版本覆盖”。第三个坑是大模型“过度配合”。用户问“制度里没有规定怎么办”模型可能自动补充行业惯例。这在业务系统里很危险。排查时注意 Prompt 中是否让模型把“不知道”当作正常输出。必要时增加一个稽核步骤让另一个智能体专门检查回答是否有超出文档范围的表述。8.3 调优节奏别用“随机调参”代替实验很多人调 RAG 效果今天试一下 chunk size明天试一下新模型但从不记录前后对比。这样很难定位到底是哪一步起了作用。我建议每一次调优只改一个变量并且跑同一份评测集。比如这次只把重叠从 50 改成 100下次只换 Embedding 模型然后再看 Hit Rate 和忠实度有没有变化。调优顺序也可以固定下来先解决“检索能不能找到”再解决“生成好不好”最后才优化“响应快不快”。很多团队一上来就换大模型结果检索的问题没解决生成质量自然上不去。9. 归档文档的维护建议这份文档叫“永久查阅版”但世界上不存在真正永久不变的文档。我的经验是给文档建一个更新日志每两个月回看一次把框架版本、模型版本、评测结论和踩坑记录都追加进去。知识库本身在变评测集在变框架在变归档版本也需要跟着变。9.1 版本矩阵与基线记录为了便于追溯我建议维护一张简单的版本矩阵表日期模型向量库分块策略Hit Rate主要变更2026-01-15Qwen2.5-14BChroma512/1000.72增加查询改写2026-02-01Qwen2.5-14BChroma512/1000.78引入混合检索记录时不要只写参数要把“为什么这么改”也写上。比如“因为多轮对话检索差所以增加了查询改写”。这些决策理由比一个单纯的数字更能给后来人启发。9.2 交接清单如果将来有同事接手你的系统请务必在归档里附上三样东西架构选型时的决策理由为什么选 Dify 而不是自研、评测集和评测脚本、线上关键指标基线。这些信息比一段漂亮的代码更能让后来人少走弯路。清单里还应该包含环境变量清单、部署命令、回滚方案、权限账号、成本预算和例行维护时间表。很多系统交接时只剩代码没有文档新同事光是搞清楚“哪个模型跑在哪台机器上”就要花一周。最后分享一个我在实际项目里坚持的做法每个 RAG 项目启动时先建一个“效果基线文档”把最初的检索命中率、回答忠实度、坏例样本都记录下来。后续每次改动都拿这个基线做对比。没有基线的 RAG 项目做再多的优化也只是在给感觉打补丁。到这儿这份归档的技术主线基本完整了。希望能给你的 RAG 智能体开发提供一份可以长期翻阅的参照。如果哪天你也在自己的项目里踩到新坑记得把它补进来这才是“永久查阅版”真正的价值。