从RAG到Agent:企业知识助手如何从检索文档变为调用工具

📅 发布时间:2026/10/8 16:30:32
从RAG到Agent:企业知识助手如何从检索文档变为调用工具
我至今还记得第一次给业务部门演示企业知识助手时的尴尬。他们问了一个很简单的问题“上个月销售部的费用超标了吗”我用 RAG 搭的问答机器人检索了半天找到的全是费用报销制度全文翻到最后也没说出个所以然。不是 RAG 的原理有问题而是我一开始就把方向定错了——企业知识助手要的从来不只是“搜得到资料”而是“搞得定事情”。这篇文章是系列第三部分里比较关键的一篇我打算把从 RAG 到 Agent 的完整演进过程摊开来讲。如果你是已经跑通过基础 RAG demo、正准备往 Agent 方向走的开发者这篇内容应该能帮你省掉我当初踩坑的几周时间。我会从企业知识助手的真实需求讲起拆解初版 RAG 落地时遇到的瓶颈再讲怎么把检索组件升级成会调用工具的规划器最后聊知识库设计、框架选型、记忆与安全这些生产环境绕不开的现实问题。1. 企业知识助手的真实需求纯 RAG 撑不住的那些场景1.1 从“帮我找资料”到“把事办了”需求的三级跳做企业知识助手之前我犯过一个典型的工程师思维错误以为把文档切块、灌进向量库、接上大模型就万事大吉了。业务同事试用后给出的反馈非常直接——“你这个东西像个搜索引擎不像个助手”。后来我才意识到企业内部的知识问答需求其实是分层的每一层的技术复杂度完全不同。我把需求粗略分成三级。第一级是单文档问答比如“报销发票的有效期是多久”直接在制度手册里找答案附带原文引用即可。第二级是跨文档综合比如“对比 A 项目和 B 项目的合同违约金条款有什么差异”需要同时检索多个文档、抽取对照字段、再做推理总结。第三级就复杂了是带动作的任务闭环比如“帮我查一下供应商发票的付款状态如果逾期了提醒财务跟进”。RAG 在处理第一级需求时效果很好第二级勉强能用到第三级就直接露馅了——因为它只能检索和生成没有办法调用任何外部系统。这也正是“RAG 瓶颈”这个热搜词背后大家普遍遇到的问题。1.2 三条典型业务问答的拆解为了把问题说得更具体我用一个表格把三类典型问题拆开对比看看 RAG 和 Agent 分别是怎么应对的问题类型实际例子RAG 的应对Agent 的应对事实检索型“2024 年销售激励政策中超额完成部分的提成比例是多少”能检索到相关段落但数值准确性依赖文档切块和召回质量检索之外可对关键数值做二次校验引用原文行号跨文档归并型“对比 A 项目和 B 项目的合同违约金条款差异”需要多次检索再合并容易遗漏对比维度能规划检索步骤先定位两份合同再抽取条款做结构化比较行动决策型“查一下这笔发票的付款状态逾期则通知财务”做不到因为只能读文档无法查系统、无法发起动作识别意图后调用发票查询工具和通知工具完成动作闭环从这个角度理解“RAG 到 Agent”的演进其实脉络非常清晰RAG 解决的是“让模型读到相关资料”Agent 解决的是“让模型知道该做什么、怎么做、做完之后还能调用什么工具”。1.3 企业助手的隐藏需求权限与归因除了功能分层企业知识助手还有两个 RAG demo 里没人提、但生产环境一定绕不开的隐藏需求权限隔离和结果归因。公司里一张合同的内容不应该让所有员工检索到一份涉密制度也不能因为“相似度命中”就被无关人员拉出来。权限隔离意味着检索层就必须按用户的身份做文档级过滤而不是等生成答案时才想起来。归因也很关键。业务人员看到 AI 给的结论第一反应一定是“你凭什么这么说”。所以答案里必须能追到来源部门、文档编号甚至具体段落。这块做得好的知识助手信任度会明显高一个档次。我在下面的章节里会反复提到这两个点因为它们会影响 Agent 的工具设计和执行链路而不只是检索策略。2. 初版 RAG 落地后踩过的五个具体坑2.1 分块策略企业文档天生不规整我初版 RAG 用的是最标准的流程PDF 解析 → 文本切块 → 向量化 → 存入向量库 → 相似度检索。结果上线第二天就翻车了。公司里的制度文档大量存在表格、页眉页脚、扫描件按固定字符数硬切之后经常出现“一个完整的表格被拦腰斩断”“条款和它的解释说明被分到两个块里”这类问题检索的时候当然就答非所问。后来我调整成分块策略先按 Markdown 标题层级做语义分段Header-based splitting每个标题下的内容作为天然段落表格部分单独提取转成结构化数据再入库不参与普通文本切块。参数上我踩过的经验是chunk_size设在 400 到 600 字符、overlap设在 50 到 100 字符起步但具体数值一定要根据文档类型调制度文档和小结纪要的分布规律差异很大。2.2 相似度检索解决不了属性型问题第二个坑让我印象特别深。有位同事问“哪个部门负责算薪系统的运维”向量检索返回的全是包含“运维”“系统”这些词的技术手册段落绕来绕去就是没有直接答出“信息技术二部数据运维组”这个结果。原因在于这类问题本质上是属性型问题答案存在组织架构表的某个字段里而不在某段自然语言描述中。向量相似度擅长的是“语义相近内容召回”碰到“某个实体的某个属性是什么”这种结构化查询它既不够精确也不够高效。这也是为什么后来我坚持在方案里引入结构化查询通道把人员、系统、合同台账这类数据放进数据库或知识图谱让 Agent 判断什么时候走向量检索、什么时候走 SQL。详细的做法放在第 4 章这里先记住一个结论不要把 RAG 当万能检索器。2.3 多轮对话中的上下文污染用户连续问“2024 年的销售激励政策是什么”“那超额完成部分呢”第二句里的“那”指的是前文的销售激励政策。纯 RAG 的做法是把第二句原样拿去检索结果搜出一堆和“超额完成”无关的内容。这就是典型的多轮对话上下文污染问题。我当时的处理办法是增加一个 Query Rewriting查询改写步骤每轮提问进来先让大模型结合历史对话把当前问题改写成一句独立、完整的问题再拿去检索。早期我直接用大模型做改写后来为了省成本用过更轻量的方案——把小模型或者规则模板放在前面命中关键指代词才升级到大模型改写。这个细节在 Agent 化改造里同样重要因为 Agent 的每一步工具调用前都需要一个“纯净的查询输入”。2.4 没有工具出口答案只能停在“建议”层面这是我认为 RAG 和 Agent 之间最本质的差距。初版系统做得再完善它能做的也只是“根据文档回答问题”而业务方真正要的是“查一下预算执行情况”“看一下这个客户还有多少未回款”这类需要实时连接业务系统的诉求。文档问答和数据查询、流程动作是三层不同的事。文档问答可以靠 RAG 解决数据查询必须有 SQL 或 API 通道流程动作必须能拉起某个系统里的操作。当需求里开始出现“查一下”“通知”“提交”这类动词时RAG 的架构就必须往 Agent 方向改了——你需要让模型学会调用工具而不是只会翻文档。2.5 安全与权限知识可以开放但决策不能最后这个坑是我被业务负责人直接点名批评后才彻底重视起来的。有次测试时一个普通员工竟然通过知识助手检索出了一份只发给部门经理的内部调整方案。问题出在初版 RAG 没有做权限过滤向量库里所有文档对所有查询可见。后来我把文档按权限粒度打上标签在检索前先过滤掉当前用户无权访问的文档才把这个问题解决。这个坑也提醒了我Agent 化之后权限问题会更复杂因为模型理论上能调用更多工具、触达更多数据。权限校验不能只在检索层做还要在工具调用层做。核心原则很简单知识可以按角色开放涉及决策和操作的动作必须在授权范围内执行。3. Agent 化改造把“检索组件”升级为“会调用工具的规划器”3.1 架构对比从两段式检索到规划-执行循环RAG 的标准链路是query → retrieve → generate一条直线干净利落。Agent 的架构完全不是这个形状它是循环的query → 意图识别 → 选择工具可能多步→ 执行工具 → 观察结果 → 再决策 → 最终回答。如果用生活化的类比普通 RAG 像是图书馆里按索书号帮你找书的管理员你把书名告诉他他去找找到了就给你。Agent 更像一个能自己判断去哪查、查完还能帮你办事的秘书你说“帮我整理一下这次项目花的钱有没有超预算”她会先想该翻财务系统还是合同文档查完了可能还要打个电话确认口头信息最后给你出一份总结。这个“自己想下一步做什么”的能力就是 Agent 相对 RAG 的核心增量。3.2 核心组件拆解意图识别、工具路由、执行循环与归因把 Agent 拆开看主要有四个组件第一是意图识别。Agent 不能把每个问题都往文档检索里塞。我通常先用大模型或规则路由判断意图类型事实问答、数据查询、流程动作、闲聊。这里建议用轻量模型因为分类任务不需要最强模型。第二是工具注册表Tool Registry。每个工具都要给大模型一份“说明书”包括工具名称、功能描述、输入参数 schema。这里有个反直觉的细节工具描述是写给模型看的不是写给用户看的。你必须写清“什么时候用”“什么时候不用”“参数怎么填”。第三是执行循环。最经典的模式是 ReAct即 Reason Act 的交替循环。模型先思考当前问题需要什么工具调用工具拿到结果后把观察结果作为新输入再继续思考下一步直到它判断信息足够才生成最终答案。第四是归因输出。Agent 的答案必须能列出“这个结论来自哪次工具调用、哪份文档或哪个数据库查询结果”。我在系统里给每次工具调用都留了 trace id前端展示时把来源折叠在答案下方。下面是一段我用 LangChain 实现的最小可跑示例把工具注册和 Agent 初始化的流程展示出来from langchain_openai import ChatOpenAI from langchain.agents import initialize_agent, AgentType from langchain.tools import Tool llm ChatOpenAI(modelgpt-4o, temperature0) def search_company_docs(query: str) - str: 从企业制度文档知识库检索与 query 相关的段落返回文本片段列表。 # 内部实现向量库相似度检索这里省略 return 相关制度片段... def query_contract_status(contract_no: str) - str: 根据合同编号查询合同系统的当前状态待签署/履行中/已归档。 # 内部实现调用合同系统 API这里省略 return 合同状态履行中 tools [ Tool(nameSearchCompanyDocs, funcsearch_company_docs, description当问题涉及公司制度、政策、流程说明时使用。不适用于查询具体业务数据。), Tool(nameQueryContractStatus, funcquery_contract_status, description当用户想了解某份合同当前的签署或执行状态时使用参数为合同编号。), ] agent initialize_agent( toolstools, llmllm, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, )跑起来之后你会发现Agent 实际执行时可能经历“思考 → 调用 SearchCompanyDocs → 观察 → 再思考 → 调用 QueryContractStatus → 观察 → 生成回答”这样多个来回。新手最容易犯的错误就是把 Agent 当成一次大模型 API 调用没意识到它内部是多轮循环。后面我看 LangSmith 的追踪记录很多问题其实消耗了 6 到 10 次模型调用。3.3 工具描述写不好模型就乱调Agent 开发第一坑就是工具描述质量。你做出来的工具必须让模型知道“什么场景该选我”。我吃过一个具体的亏某个知识库工具的描述写的是“检索知识库”结果模型在用户问“今天天气怎么样”时也跑去调它因为描述里没有任何限定条件。后来我把这个工具的描述改写成“当用户的问题涉及公司制度文档、产品说明书、项目总结等企业内部非结构化文档时使用。如果问题需要查询实时业务数据请改用 QueryBusinessData 工具。本工具无法回答事实性数据问题。”改完之后误调用率明显降下来了。这个经验在 Agent 生产化里非常值钱值得多花时间打磨。3.4 从 ReAct 到 LangGraph受控的 Agent 编排如果只是做个 demoLangChain 的initialize_agent就够用了。但到了生产环境我发现 ReAct 的自由循环不受控模型可能反复调用同一个工具绕圈子。后来我迁移到了 LangGraph 来做受控状态机编排把“意图识别 → 路由 → 工具调用 → 归因”作为显式的图节点每个节点之间定义清晰的条件边。这样每条 Agent 链路都变得可观测、可打断而不是一个黑盒循环。这里给一个参考思路把 Agent 链路拆成意图识别节点 → 工具路由节点 → 工具执行节点 → 答案合成节点其中工具路由节点根据工具注册表的描述选择目标工具并在执行后把结果返回给路由节点判断是否需要继续。LangGraph 的好处是你可以精确控制最大迭代轮数例如限制最多 5 轮工具调用超出就强制结束并返回已获得的信息避免模型钻牛角尖。4. 知识库设计的分界线向量检索、结构化查询与知识图谱怎么选4.1 三类知识三种存法很多人有个误区认为知识库就是向量库。但企业里真正需要打交道的知识其实分三种形态存储和检索方式完全不同知识形态典型内容适合的存储方案适合的检索方式典型问题示例非结构化文本制度文件、会议纪要、技术手册向量库语义相似度检索、BM25“请假制度里对年假的要求是什么”强结构化数据合同台账、人员花名册、财务明细关系型数据库SQL 查询、Text-to-SQL“合同 A1023 的违约金比例是多少”实体关系型知识组织架构、系统依赖、业务流程上下游知识图谱图查询Cypher/Gremlin“XX 系统的负责人是谁他还负责哪些系统”我在做知识助手时第一版把所有资料全塞进向量库导致属性型问题大量答错。后来把合同台账、人员表单独抽出来放进数据库再让 Agent 的路由节点判断走哪条检索通道准确率才真正上来。4.2 属性型问题的正确解法Text-to-SQL 与图查询“合同 A1023 的违约金比例是多少”这类问题本质上是在查表的某个字段。与其让向量检索在文档里碰运气不如让大模型先把问题转成 SQL再去执行查询。这里有个风险要特别注意Text-to-SQL 让模型直接操作数据库存在安全边界问题生产环境一定要做 SQL 白名单校验只允许 SELECT 查询并且强制带 WHERE 条件防止全表扫描。知识图谱则解决“关系查询”。比如你的组织架构里员工、部门、系统、流程都是实体它们之间的关系是“负责”“属于”“依赖”。这类问题 SQL 表达起来很别扭用图查询就自然多了。我在实践里发现不需要一开始就把所有知识都建模成图谱先挑查询频率高、关系稳定的几个领域做性价比最高。这也回应了热词里 ontology RAG 的讨论——本体Ontology的价值在于给知识实体和关系提供一套稳定的约束框架而不是所有文本都要塞进图谱。4.3 混合检索与重排让召回质量再上一个台阶向量检索不是万能的同义词、精确关键词、专有名词的召回表现各不相同。我在知识助手里用了混合检索BM25 负责精确词匹配向量负责语义匹配然后用 RRFReciprocal Rank Fusion把两个结果合并排序。实测下来组合召回的效果比单一向量检索提升明显。召回之后再上一步 Rerank重排。用专门的 rerank 模型把 Top 50 候选重新排序让最相关的片段排到最前面再喂给大模型生成答案。这一步对“长文档里藏答案”的场景特别有效。整个链路从“检索”到“生成”之间多了一个精排层成本增加不大但答案准确率的体感差别非常大。4.4 多模态问题图片、表格、图表能不能进知识库热词里有人问“RAG 知识库能存储图片吗”。能存但直接整图检索效果很差。我的建议是分类型处理表格类内容先做表格解析转成结构化行再入数据库或向量库检索时返回的是结构化数据图表类内容用视觉模型先做 caption图像描述把描述文本纳入向量索引如果用户需要看图再在回答时附带图片原图链接。一句话总结多模态不是不能做而是不能拿整张图去做语义检索先转成文本/结构化数据再进链路才是企业场景里更稳妥的落地方式。5. 框架选型实录LangChain、Dify、CrewAI 的取舍5.1 三个框架的定位差异最近在社区里看到一个高频问题Agent 框架选 LangChain、Dify 还是 CrewAI我先说结论再讲原因——这三个东西根本不在同一个维度上。框架定位适合的团队主要短板LangChain / LangGraph代码优先的 Agent 编排库自由度最高有专职工程师、需要深度定制的团队学习曲线陡抽象层次多Dify低代码/可视化工作流平台业务团队想快速出原型深度定制能力受限复杂逻辑难表达CrewAI面向多 Agent 协作与角色分工研究原型、多智能体场景生产环境需要自补可观测性和权限管控如果你团队的定位是“快速验证一个小场景”Dify 几天就能拉起来如果你要做一个严肃的企业级知识助手LangChain/LangGraph 配合自己的工具层是更可控的路线CrewAI 更多是你在做“多个专业助手协同”这种形态时才值得考虑。选框架的顺序问题排第二第一优先级的其实是工具边界。5.2 企业落地我真正看重的四件事技术选型不能只看“哪个火”我筛框架时主要看四点。第一是可控性。模型调用工具的过程能不能被约束和打断。第二是可观测性。每一条 Agent 链路的调用日志、Token 消耗、工具执行结果是否方便追踪。我用 LangSmith 记录过整个链路每轮“思考-调用-观察”都有迹可循排障效率翻倍。第三是权限集成。框架能不能轻松对接现有的 SSO/AD 做身份识别并在工具层做权限校验。第四是成本监控。Agent 的调用次数比普通 RAG 多一个数量级必须有清晰的 Token 计量。这四条没有一条是“哪个框架写起来漂亮”但它们是生产环境真正决定成败的指标。5.3 我最终的选型组合我的选择是快速验证和内部演示时用 Dify生产级主链路用 LangGraph 自建只有涉及多 Agent 角色协作时才引入 CrewAI。工具层全部自己实现用统一的 HTTP API 封装跟框架解耦。这样即便以后换了框架工具层不受影响。另外说一个比较反常识的经验与其纠结框架选型不如先把“你的 Agent 到底要精确调用哪些工具”这个清单列出来。边界清晰了框架只是把流程串起来的胶水。清单不清晰换什么框架都会乱。6. Agent 的记忆、安全与成本治理生产环境的三个现实问题6.1 记忆设计从零记忆到分层记忆Agent 要能干活记忆是必须的。但记忆不能只是一个无限膨胀的对话窗口。我在生产系统里把记忆分了三层短期记忆是当前多轮对话的上下文窗口直接传给模型长期记忆是把历史对话的关键信息提取出来存成向量或结构化摘要在需要时检索召回业务记忆则是用户偏好、常用操作对象这类结构化字段存在数据库里。这里有一个所有做 Agent 的人都会遇到的问题Token 成本爆炸。我的做法是每轮新问题进来时先把历史对话压缩成摘要summary memory只保留实体的关键上下文然后用改写后的 query 去检索长期记忆把命中的记忆片段拼接给模型。这个流程让多轮对话既保住了上下文又不至于把几万字历史全喂给模型。6.2 安全边界能力授权而不是完全放权Agent 能调用的工具越多安全风险就越大。我的原则是能力必须授权而不是放权。具体来说有三个层次检索层按文档级 ACL 过滤保证模型只能看到当前用户有权看到的内容工具层对每个工具做身份鉴权比如调用“发起审批”这类动作前必须在工具内部校验操作者的角色动作层对高影响操作发邮件、提交审批、修改数据实行 human-in-the-loop模型只负责生成建议真正执行必须人工点击确认。我在这块也交过学费。早期某个工具没有按用户身份过滤返回值导致一个员工通过 Agent 查到了他无权查看的合同明细。修复的方式就是给工具加上基于当前用户身份的查询参数强制注入。安全这事在 demo 阶段没人提到了生产环境就是 1 和 0 的区别。6.3 成本治理规划器的每一次循环都在花钱Agent 的成本和普通 RAG 不在一个量级。一个普通 RAG 问题可能只消耗 1 到 2 次模型调用一个 Agent 问题动辄触发 5 到 10 次甚至更多。如果每次都让旗舰模型跑月底账单会很难看。我现在的策略是分级用模型意图识别和 query 改写用轻量小模型比如快速、便宜的那档路由决策和答案生成用旗舰模型工具参数抽取看复杂度选择中间档。另外一定要设最大迭代轮数上限模型绕圈子时会主动掐断宁可回答“信息不足”也不要死循环。高频重复问答可以加一层缓存把问题和答案直接命中省掉整条链路。个人经验是靠这些手段能把成本压到原来的五到六成同时体验基本无损。从 RAG 到 Agent 的演进说到底不是把检索组件换掉而是把知识检索能力扩展成完整的工作执行能力。技术架构和选型都可以慢慢迭代但业务场景的拆解一定要走在前面。最后再分享一个小建议别想着“一步到位造一个万能助手”。先从两三个最有价值的工具开始让模型把这几个工具用熟练、用准确再逐步扩大工具集。一个能稳定完成三件事的 Agent远好过一个什么都想干、什么都不稳的方案。