恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
从RAG到Agent:企业知识助手架构演进与实战指南
首页
资讯中心
/
从RAG到Agent:企业知识助手架构演进与实战指南
从RAG到Agent:企业知识助手架构演进与实战指南
发布时间:2026/10/8 4:36:14
1. 从检索到决策为什么知识助手必须走向 Agent先说个背景。去年我接手了一个企业内部知识助手的项目目标是让新员工在入职第一天就能自助查规章制度、查技术规范、查项目文档减少到处问人的时间。第一版做得很典型就是标准的 RAG 架构把文档切块、向量化、存向量库用户提问时做相似度检索把命中的文本片段塞给大模型让它组织答案。这个方案上线后效果一开始还可以大家觉得能自动回答一些问题已经很新鲜了。但用了两三周问题就暴露出来了。比如说有人问“新入职的研发同事多久能申请到测试环境权限”这个问题的答案分散在入职指引、权限管理办法、测试环境使用规范三个文档里单靠向量检索很难把三个片段同时命中有机地组合起来。又比如有人追问“那如果数据库账号也要一起申请呢”——多轮对话的上下文一旦变了问法系统就懵了。再比如员工问“我上周提交的工单到哪一步了”知识库里根本没有这个信息RAG 再怎么检索也答不上来。所以说RAG 本身没有任何问题它是知识问答的地基但它有一个天然边界只能回答知识库里面“有”的东西做的是检索加总结的活既不能自主决定去外部工具里拿数据也不能在一个多步骤的诉求里自己规划先做什么再做什么。要解决这些问题就必需从静态的“查文档”升级到动态的“干活”模型不仅要理解提问还要能拆解问题、选择工具、调用接口、看结果、再决定下一步——这就是从 RAG 走向 Agent 的核心动力。对企业知识助手来说Agent 的意义不是炫技而是把它从一个“问答玩具”变成一个“能完成任务的数字员工”。本文我会从整体设计、核心架构、代码实现、避坑经验四个层面完整拆解这个过程。2. 整体架构设计先解决“为什么”再谈“怎么做”2.1 企业知识助手到底在解决什么需求企业知识助手和通用聊天机器人最大的区别在于它面对的是业务问题不是闲聊。我把企业的真实诉求拆成了四类事实查询类员工找制度、找规范、找联系方式。这类问题答案基本确定本质是“知识定位”。多跳推理类答案是分散在多个文档里的需要先查A再查B再组合起来。这类问题考验检索和取舍。状态查询类问工单到哪步了、审批到哪个节点了、预算还剩多少。这类信息根本不在静态文档库而在业务系统里。操作执行类帮忙创建一个工单、发起一个审批、查询一条客户记录。这类问题已经从“问”变成了“做”。我在项目里把前两类归为 RAG 的主场后两类则是 Agent 的菜。第一版只做了前两类所以用户一开始觉得还行等到有人开始问“工单呢”“能帮我提个单嘛”就露馅了。这其实是一个需求分层的问题想做一个真正能用的企业知识助手一开始就得意识到答案不只在文档里还在系统里。一个关键的设计决策是不要一开始就搞一个敞开式的全能 Agent。全能的 Agent 意味着模型可以自由调用所有工具听起来很酷但企业内部这不是越灵活越好而是越可控越好。我的做法是“问答为主、工具为辅”Agent 核心里先有一个 RAG 检索器这个是基础能力再逐步挂上工单查询、权限申请、人员查找这类只有明确入参和出参的轻量工具有一个算一个不追求一步到位。2.2 RAG 的瓶颈和 Agent 的应对方案为什么一定要在 RAG 之上做 Agent把 RAG 的瓶颈拉出来对照看就清楚了。先说检索瓶颈。RAG 的召回质量高度依赖文本切块的方式。按固定长度切会把语义切成碎片按标题结构切又在长文档上控制不住每个块的体积。企业文档还喜欢用表格、流程图、附件这些都可能让向量召回失灵。我就遇到过一种情况某份制度的表格列被切到两个块里检索时每个块和问题的相似度都不高结果就是明明文档里有答案助手却说“抱歉未检索到相关信息”。再说编排瓶颈。经典 RAG 只有“检索一生成”两步就像一个只会查字典的学生你问他一道综合题他就翻一页字典抄一句话。而企业里大量问题是需要拆解的。这种“先做一步看结果再决定下一步”的能力就是 Agent 的规划特长。模型在每轮先“思考”这一步要执行什么动作——是检索、是调用工具、还是直接回答——相当于把一个人脑考虑问题的流程显式地跑了起来。最后是记忆瓶颈。RAG 每次问答都是无状态的上一轮用户说“那帮我申请一个”下一轮如果缺少上下文衔接助手就不知道“那”指代的是哪个权限。Agent 的架构里天然包含对话记忆模块短期记忆管理多轮上下文长期记忆沉淀用户的偏好和历史操作企业在落地时非常看重这一点。我在网上看到很多朋友搜 Agent 记忆相关的话题其实在企业场景里就是这两层短期内解决多轮指代问题长期内做到千人千面。用一句话总结 RAG 和 Agent 的边界RAG 是让模型“知道”Agent 是让模型“做到”。知道靠检索做到靠工具加循环。企业知识助手两者都需要架构上自然就形成了 RAG 是其中一种工具、而 Agent 是调度者的格局。2.3 RAG 知识库的分类与选型说到知识库很多团队上来就问该选哪个向量数据库。我倒是觉得先别急着选先把知识库里存什么捋清楚。网上关于“RAG 知识库和结构知识库区分”的讨论很多我把它们摊开讲。非结构化知识库放的是 Word、PDF、Markdown 这类自由文本用 embedding 模型向量化存入向量库。适合规章制度、技术规范、知识沉淀。这类知识库是 RAG 的默认形态优点是灵活缺点是召回准确性不稳定答案有时候模棱两可。结构化知识库放的是有明确 schema 的数据比如员工信息表、库存表、工单记录这些通常不放在向量库里而是放在 SQL 数据库或者表的字段里。对这类数据的访问不是向量检索而是写查询语句去取。企业里大量脏话其实都是结构化数据纯靠 RAG 是答不好的。混合知识库两个都上再配一个路由层。用户在提问时先判断意图查文档走向量检索查数据走 SQL 查询。Agent 天然适合做这个路由因为它能够根据用户输入决定调用哪个工具这就把两类知识库用一套交互统一起来了。至于一个常问的问题“RAG 知识库能存储图片吗”我的回答是能但通常不是直接存图片本身。向量库存的是语义向量不是文件。企业落地时有三种做法第一种是把图片转成文字描述再入库比如 OCR 提取图中文字第二种是用多模态 embedding 模型把图片编码成向量直接参与相似度检索第三种是只把图片作为文档附件存进对象存储向量库里面存图片的路径和说明文字。多数场景最务实的是第一种加第三种不太需要上多模态模型。3. 核心实现Agent 框架、工具调用与安全边界3.1 Agent 的核心运行循环讲完了设计看代码。下面这个简化版的 Agent 循环是最小可运行形态理解了它市面上任何 Agent 框架的底层思想都逃不开这一段。from typing import Callable, Dict, Any, List import json class SimpleAgent: def __init__(self, llm: Callable, tools: Dict[str, Callable], max_steps: int 5): self.llm llm self.tools tools self.max_steps max_steps def run(self, user_query: str, history: List[Dict[str, str]]) - str: messages history [{role: user, content: user_query}] for step in range(self.max_steps): response self.llm(messages, toolsself.tools) # 模型决定动作 action self.parse_action(response) if action[type] answer: return action[content] if action[type] tool_call: tool_result self.execute_tool(action[tool], action[args]) messages.append({ role: tool, name: action[tool], content: json.dumps(tool_result, ensure_asciiFalse) }) return 步骤太多已自动终止请换一种说法试试这个循环里有几个关键设计单独说明一下。第一是 max_steps这是安全底线。没有它Agent 可能在一个长任务里陷入循环调用浪费 token。经验值设为 5 到 8 之间简单问答 1 到 2 步就够了超过 5 步的问题多为用户意图太宽泛不如让它停下来反问用户。第二是 tools 的传参方式。现在主流 LLM 支持函数调用格式模型会输出类似 call_tool 的参数框架再去做映射。这时候参数校验特别重要代码里 execute_tool 内部必须做参数类型和枚举值校验。我见过不止一次模型把数字参数传成字符串、把日期传成“昨天”这种相对值导致接口报经典 400。第三是消息数组的维护。把工具返回结果以 role 为 tool 的消息继续丢回给模型模型才能基于真实结果进行下一轮思考。这不只是写法问题而是“感知-决策-行动”循环的消息协议。3.2 用工具组装业务能力下面的代码演示两个最典型的企业工具工单状态查询和信息检索。前者接结构化数据库后者接向量知识库。这样在代码层面就能直接体现“RAG 是 Agent 的一个工具”这一思想。# 工具1查工单状态接 MySQL 或内部业务接口 def query_ticket_status(ticket_no: str) - Dict[str, Any]: if not re.match(r^TKT\d{6}$, ticket_no): return {success: False, error: 单号格式不正确应为TKT加6位数字} # 真实项目中这里是查 MySQL 或者调用内部 HTTP API row db.execute( SELECT status, owner, update_time FROM ticket WHERE ticket_no?, (ticket_no,) ).fetchone() if not row: return {success: False, error: 工单不存在} return {success: True, status: row[0], owner: row[1], update_time: row[2]} # 工具2检索知识库文档RAG 的核心功能 def search_knowledge_base(query: str, top_k: int 3) - List[Dict[str, Any]]: embedding embed_model.encode(query) hits vector_store.search(embedding, top_ktop_k) return [ {title: h.title, content: h.chunk_text, score: h.score} for h in hits ]再看一段和这个 Agent 的对话示例能直观感受从 RAG 到 Agent 的跃迁。用户问“我名下有个工单 TKT202611现在到哪一步了”Agent 的思考过程是这个问题不是知识库查询用户需要的是实时业务系统数据需要调用 query_ticket_status 工具工具返回“已流转到直属主管审批当前负责人张三”生成最终答复“你的工单 TKT202611 当前处于主管审批环节负责人张三更新时间今天上午 10:24。如果 3 天内未处理可以在 OA 内发起催办。”用户继续问“公司对工单处理时限的规定是什么”Agent 的思考过程是这个问题属于制度知识从向量知识库检索即可调用 search_knowledge_base 工具命中《工单管理办法》的相关段落生成答复并附上制度出处。用户最后问“那如果张三一直不批我可以直接升级吗”这轮 Agent 需要联合两个工具先检索管理制度发现升级规则是需要工单超过三个工作日未审批再结合之前查到的工单状态未超时给出结论——“现在还不满足升级条件建议先与审批人沟通”。这个回答如果只有 RAG 做不出来因为系统不知道张三的审批到底进行了多久如果只有工具调用模型不知道升级的制度条件。两者结合才是完整企业知识助手的样子。3.3 记忆、Skill 与框架选型不少朋友在热搜里反复对比 LangChain、Dify、CrewAI 这堆框架问到底哪个好。我把最近在不同项目里折腾这些框架的经验梳理一下不一定适用于所有团队但应该能帮你在选择时更清楚取舍。先说记忆。无论用什么框架都要搞清楚它说的“记忆”是会话级还是用户级。很多框架自带的 memory 只是把最近 N 轮对话拼到提示词里这是短期记忆。但企业场景里更需要的是长期记忆比如某个员工第一次说自己所在部门是“平台研发中心”那么下次提问时 Agent 能自动带上这个上下文不用重复解释。框架上没有现成能力的话建议用一个简单的 key-value 存储用户维度的记忆做进 prompt 的系统提示词里比硬套框架效果好。再说 Skill。这个概念今年很火本质是把“工具提示词参数说明”打包成一个可复用的技能单元。我用下来觉得真正有价值的地方在“面向场景的组合复用”比如“工单操作”这个 Skill 里面包含查状态、催办、创建子任务三个工具Agent 一旦识别到用户是来处理工单的就自动挂载这个 Skill而不是让它面对几十个工具大海捞针。这样既压缩了决策空间又提高了准确率。框架选型方面给一个比较朴素的判断标准LangChain 类偏底层灵活度最高但学习和调试成本也最高适合团队里有较强模型功底的人而且在多工具复杂链路中它给开发者更多的控制权。Dify 类偏应用可视化编排和测试工具友好适合快速做 Demo 和给业务人员做 prompt 调优。但是在需要深度定制和复杂状态管理的场景它反而会成为一种约束。如果你看到团队里大量复制现有节点模板说明项目已经长大Dify 可能就不是最优解。CrewAI 类偏角色协作适合做多 Agent 的任务拆解不过说实话企业内部多数知识助手的任务复杂度还远没到需要多 Agent 协调的程度单 Agent 加工具就足够了。多 Agent 的通讯成本、调试成本都要高一个量级用不好会出现 Agent 之间互相甩锅。站在个人经验上说我的建议是不要一开始就绑定大而全的框架先自己写好一个简单的循环比如我上面这份代码把知识库工具和业务工具各接一个进去端到端跑通。再让业务同学试用一两个星期收集问题等到你明確知道缺什么再去用框架补什么不然很容易出现被框架拖着的被动局面。3.4 安全边界与权限管控企业里的 Agent 和拿着玩的那种个人助手安全级别完全不是一个概念。Agent 一旦接上工具它就从“语言模型”变成了“执行者”安全问题怎么强调都不过分。我把需要注意的点分成三层第一层是权限最小化。给 Agent 的每一个工具都要单独授权不要图省事给一个万能数据库账号。比如工单查询工具只能查本人相关工单系统提示词之外还要在工具内部做硬校验。因为提示词是可注入的模型可能会被诱导“忽略之前的指令”但工具里的代码永远不会被诱导——当用户输入试图越权时工具直接拒绝。第二层是写操作确认。涉及创建、修改、删除这类的工具必须设置 human-in-the-loop 环节。具体做法是 Agent 先把操作意图输出给用户确认用户明确回复“确认”才真正执行。不要完全信任 AI 在一条链上自作主张跑完所有写操作。第三层是输入输出过滤。用户输入里可能包含恶意指令模型输出里可能包含隐藏提示。企业内部建议至少做一次敏感信息扫描对身份证、手机号、银行卡做脱敏处理再入库。关于网上很多人担心的“Agent 安全”问题我实际的体会是单点防护不如全局管控。模型层的 system prompt 可以做第一道防线工具层的参数校验和权限校验做第二道流程层的“高风险操作必须人工兜底”做第三道。这三道都立住了Agent 就没有想象中那么可怕。4. 实操中的坑问题排查与避坑实录4.1 高频问题与对应解法这个部分我想直接放一个速查表把我在几家公司项目里真实踩过的坑罗列出来。每个问题都是实际发生过解法也是验证过的。问题现象根因解决方案多轮对话中用户在第三轮问“那审批流程呢”结果一塌糊涂模型没有记住前两轮的“办证”主题上下文被截断或拼接错序对消息列表做截断时要保留首轮系统指令和用户目标描述可引入消息摘要压缩过长的历史工具调用时把数字参数传成文本函数描述里类型约束不严模型自由发挥在工具 JSON Schema 中强制类型并附正则示例更稳妥的是在代码层做二次断言并返回友好错误检索结果里混入大量无关段落但相似度分数还很高embedding 模型对短实体型 query 区分度不足增加一个重排序层比如用 cross-encoder 对 Top20 重排截断前半部分用户问“上周的权限申请”但知识库里查“上周”语义为空知识库没有做时间词归一化引入文档更新时间和会话时间作为过滤条件涉及“最近”“上月”先做时间归一化解析Agent 连续调用工具三次以上用户等得不耐烦步骤多、推理慢、工具响应慢对工具响应做缓存同类参数直接走缓存给用户实时的“正在查询工单系统”过程提示体验差别极大4.2 一个精准定位检索偏差的实战案例展开讲一个我耗时最久的排障经历。现象是所有“怎么申请测试环境”相关问题回答总是漏掉关键步骤比如漏了“必须由直属主管先在 OA 上提交资源申请”这一步。起初我以为是文档内容不完整把制度文件翻了个底朝天发现内容其实都在。后来逐步排查发现两个问题叠加。第一个问题是切块方式把包含申请流程的表格单独切成了一个块表格文本在向量化时丢了行列表结构的语义模型看到的是一堆散开的单元格字符串。第二个问题是召回的 Top3 里有两段来自同一个长规程内容高度相似把表格结果挤到了第四位。修复方案是三层同步调整。第一层把表格类内容转成自然语言描述后入库而不是直接向量化原始表格第二层在检索阶段做 MMR 最大边际相关去重避免 TopN 被相似段落占满第三层加了重排。最终这个话题的答案准确率从不到六成提升到九成以上效果非常明显。4.3 成本控制与性能优化心得Agent 比 RAG 贵这是事实。RAG 一次问答通常一次模型调用Agent 可能要三五次。我总结了一些经验来平衡成本和效果。方法是给问题做个路由分类用一个小模型判断意图让简单问题走普通 RAG 甚至直接命中高置信度文档让复杂问题才付高昂的 Agent 推理成本。这个路由看似多花了一次调用实际上省掉的是 Agent 反复无效检索和不停思考的 token 费从账面上看完全是划算的。另一个心得是为同一类高频问题做“确定性问题即答合集”。知识库里有大量类似“会议室 Wi-Fi 密码是什么”“打印机型号”这样的确定性问答根本不需要向量检索命中精确规则直接返回。一个简单的关键词到答案映射表或别名表就能覆盖很多高频问题。知识助手百分之八十的问答可能都是这类简单问题这种直接答的方式对用户体验提升很大。5. 从单 Agent 到多 Agent 的扩展方向项目跑通以后团队自然会思考一个问题是不是该上多 Agent 了我的建议是在确认以下条件之前不要动这个念头已经存在至少三个差异明显的专业角色各自维护着自己独立的工具集和知识库用户的任务经常需要跨越这些专业角色协作完成比如“帮我查一下这个项目的延期风险和预算超支情况”既涉及项目管理工具又涉及财务系统单个 Agent 的提示词已经变得难以维护经常为了顾全某个子领域而影响主线任务。满足这三点之后再考虑多 Agent否则就是自寻烦恼。多 Agent 架构会引入新的问题Agent 之间的同步通信、任务依赖编排、失败重试传播等。我见过有人为了演示效果硬上三四个 Agent 的架构最终效果不升反降的问题常出在“一个 Agent 的判断结果偏差后面全都跟着错”。真要上多 Agent 的话我比较推荐“主编排 子专家”的星型架构而不是 Agent 互相聊天的网状架构。星型架构有一个中心调度 Agent 负责接收用户请求、拆分任务、分发给专家 Agent 并汇总结果。这样的好处是可控性和可观测性都强每个子 Agent 的问题可以单独排查不至于乱成一锅粥。网状架构下 Agent 之间的对话链路难以跟踪排障成本太高企业场景慎用。另外一个正向演进路径是逐步把 Agent 能力和企业流程体系打通。比如把知识助手接入 IM 机器人工单系统让它在钉钉或者企业微信里可以直接被对话召唤把查询到的信息一键转成工单。这已经超出了纯技术的范围但确实是企业知识助手最终落地的常见形态。6. 收个尾我自己的一些实际操作体会如果再让我从零做一遍这个项目我会把优先级定成这样先保证 RAG 的检索质量再接入一个查询类工具最后才上需要写操作的工具。每一步都跑稳了再走下一步不要一上来就整一个大而全的 Agent那多半会翻车。个人实际体会最深的一点是Prompt 工程在 Agent 项目里的作用被大大低估了。很多人花大量精力调模型、调工具却忽略了一件事Agent 的“思考”过程本质上是模型在自我打分你必须在提示词里告诉它什么时候该动用工具什么时候不该动。我的做法是在 system prompt 里写明工具使用的判定条件和输出格式模型的行为稳定性明显提升。还有一个小建议重视日志和可观测性。Agent 项目比传统接口多了一个“推理轨迹”排查问题的时候如果看不到模型每一步在想什么调用了什么拿到什么结果就只能靠瞎猜。我后来强制要求所有 Agent 调用都输出一份 JSON 日志包含每一步的动作、入参、出参、耗时调试效率直接翻倍。从 RAG 到 Agent不是一次替换而是一次能力边界的扩展。先把检索的地基打好再把工具的手脚接上让模型在需要的时候自己决定用哪条路。这个演进路径是当前企业落地 AI 应用最踏实、回报也最直接的一条路。