ARTICLE DETAIL

资讯详情

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

agent-native架构实战:重构企业工单系统的完整复盘

agent-native架构实战:重构企业工单系统的完整复盘 上季度我们团队接了个企业内部IT工单自动处理的需求刚开始完全按老思路做——画状态机、堆规则、搭接口再让大模型在几个节点上帮忙做分类。结果不出两周状态机的分支膨胀到看不懂每个疑难工单都要手工加规则迭代一次要个半天。后来我提议整个重构参考行业内讨论度很高的 agent-native 思路把所有业务能力都变成Agent可以调用的工具由Agent主导决策和执行。这篇文章就是这次重构的完整复盘。先说清楚 agent-native 是什么为什么传统做法撑不住然后把五个核心组件拆开讲透放一份可以直接参考的实现过程最后把我在生产环境里踩过的坑和排查思路整理给你。如果你正在做AI应用开发、想把LLM真正落到业务流程里这篇值得读完再动手。1. 从流程优先到决策优先agent-native 到底在讲什么1.1 传统AI集成模式的反例传统开发里我见过太多把LLM当成高级翻译或者分类小工具的架构。拿工单分类来说常规做法是定义几十个工单类型用Prompt让模型做意图识别识别完再走一套完整的规则链路——关键词匹配、部门路由、SLA计算、消息通知。这套思路在需求简单时很爽可规则超过一定数量后就会出问题。规则引擎本身是个容易膨胀的东西新增一个业务规则就要动一次决策树改一个分支再跑一遍回归测试。我们当时工单类型到八十多个的时候平均每次迭代光改分类逻辑就要半天而且规则之间还可能出现互斥比如A类工单如果是VIP用户就优先新老规则叠在一起谁也说不清谁更优先。类似的矛盾不止出现在分类场景。凡是决策路径依赖大量上下文的业务用规则写都会面临一个共同困境你永远在追逐需求而需求本身长满了尾巴。用户表述稍微换一种说法规则就匹配不上一个之前没见过的组合情况就要再补一条规则。系统表面上是逻辑驱动的实际上是拆东墙补西墙。1.2 agent-native 的核心定义agent-native 现在还没有特别严格的标准定义但业内共识比较接近在系统设计之初就把Agent作为核心执行者和决策者把业务流程、领域API、数据结构、外部系统全部当作Agent的工具和环境而不是反过来把AI塞进传统的流程框架里。打个比方。传统系统像一家长着流水线的工厂每个工位只干一个动作产品规格一换就要重新调产线agent-native 更像一个管事很全的店长遇到问题他会自己判断是缺货、退货还是咨询自己决定是叫仓库查库存还是找财务核账单必要的时候他还会去新配一把钥匙也就是注册一个新工具。所有业务能力以工具注册的方式挂在Agent身上决策路径由Agent根据当前情况生成而不是预先写死。从工程形态上看agent-native 和 cloud-native 承袭的是同一种思维方式。cloud-native 把基础设施当成可编排的资源池而 agent-native 把业务能力当成Agent可调度的一组工具把业务逻辑从代码里搬到决策过程里。这意味着传统软件最核心的部分——那些写死在代码里的 if-else 分支、状态转移、业务编排——变成了Agent在运行时的推理产物。1.3 什么时候该用 agent-native也不是说所有系统都应该 agent-native。我总结了几条判断标准团队在立项评估时可以对着看第一任务边界明确但完成路径不定。比如帮用户申请一台云服务器目标很清楚但从申请到开通要经过选规格、查配额、走审批、配置网络等多个步骤路径因人而异用流程编排写会非常臃肿让Agent自己调工具反而是最自然的方式。第二需要多个工具组合使用才能完成一个目标。查资产、核对权限、调用变更、发通知这一整条链路如果用传统编排也不是不行但每个环节的决策又依赖上一环节的上下文硬编码会导致耦合度极高。第三长尾需求多到规则无法枚举。客服问答、运维排障建议、数据分析报告生成都属于这一类用户的问题千奇百怪规则永远追不上。反过来如果是强监管场景、每条路径都必须精确可控、需要完整审计每一步且不能接受模型自由发挥硬上 agent-native 等于给自己挖坑。银行核心交易、医疗处方环节就不适合让Agent临场发挥。一句话决策空间越开放agent-native 越有优势决策空间越封闭老一套越稳。2. agent-native 架构的五个核心组件一个成熟的 agent-native 应用远远不是一个LLM加一堆工具函数那么简单。我一般会把架构拆成五层Agent核心、工具层、记忆层、编排层、评估体系。每一层都有独立的设计问题哪一层偷懒后面都要在生产环境里加倍还回来。2.1 Agent核心让决策中枢不飘Agent核心是对模型能力、推理框架和系统提示词的封装。模型层面我们主要用的是支持函数调用的模型GPT-4o系列、Claude系列以及国产的Qwen-Max、DeepSeek都有实践。底层模型决定了Agent的天花板但真正把模型能力变成可用系统的是推理框架。目前主流决策模式有三种。ReAct是最常见的让模型在思考、行动、观察之间循环每一步先想我还需要知道什么再调工具再看结果再想下一步。它适合动态变化的任务缺点是Token消耗大、循环多。Plan-and-Execute是让Agent先把完整计划列出来再执行适合目标明确但步骤多的任务比如生成一份季度报表。Reflexion是执行完整体任务后做自我反思把反思结果写回记忆下次做得更好。我在生产环境里用得最多的是ReAct变体在LangGraph里做有向图控制既保留ReAct的灵活性又能给循环加限制。有个参数必须盯紧Temperature。工具调用场景下我一般调到0.1以内甚至直接设0因为工具参数是模型生成的随机性太高会导致参数漂移——同一个请求有时候通过校验有时候就被系统拒绝。系统提示词也特别关键。好的Agent系统提示词不能只写你是一个助手要写清楚四件事角色和权限边界哪些操作永远不做每个工具什么时候用、什么时候不用遇到歧义时是继续追问还是使用默认策略输出格式和结束条件是什么。我们甚至会把可选的下一步行动直接枚举在提示词里让模型在决策时少走弯路。实测下来这比反复调Prompt效果好得多。2.2 工具层能力边界和安全闸门工具层是Agent和外部世界的接口也就是所有外部能力的注册表。每个工具的本质是一份函数Schema描述方法、参数和返回结构。这一层设计得好不好直接决定Agent能用起来还是用废掉。我踩过最多次的坑就是工具描述写得模糊。模型是靠描述来理解什么时候调用工具的如果你的工具描述写的是查询用户信息模型大概率会在一些不该调用它的地方调用它。更合理的描述应该像这样根据工单中的用户名查询内部通讯录里的用户基本信息返回部门、职级、邮箱仅当工单中明确包含用户名或工号时才调用。描述里要写清楚触发条件、输入参数格式、边界和返回结构。把工具描述当作给一个聪明但不知轻重的实习生看的说明书你大概就能写对了。工具层目前有两类主流方案。一类是模型平台自带的Function Calling原生支持、简单直接适合工具数量不多、范围固定的场景。另一类是MCP协议相当于把工具标准化成一组可动态发现的接口生态正在快速起来。MCP的好处是工具服务化Agent进程可以通过远程调用发现并使用工具不用每次把工具代码打包进Agent应用里。如果团队要做多Agent共享能力MCP值得优先考虑。安全边界必须在工具层做死。Agent调用工具就是让AI碰真实系统权限必须最小化。我们的做法是双重校验Agent传给函数的参数先过一遍Schema校验再在函数内做一次业务校验。凡是涉及写操作的工具比如重置密码、创建账号全部加二次确认机制由Agent生成确认请求人工或流程审批后再真正执行。别嫌麻烦这一条能救你。2.3 记忆层让Agent成为有经验的老手没有记忆的Agent很难处理长任务因为它在每次请求里都是第一次遇到这个问题。我们把记忆拆成两层来设计。短期记忆就是对话上下文窗口。在长任务场景里上下文会越来越大模型性能反而下降Token成本也会飙升。我给上下文设置一个阈值超过阈值就触发摘要压缩最新的几条消息保留原文旧内容压缩成一两百字的摘要。这个机制上线后长工单的回答质量明显稳定了。长期记忆用的是向量库加结构化存储。向量库存的是语义记忆比如这个用户上周问过软件安装问题最终解决方案是走自助安装平台。Agent解决完一个问题会把问题、决策过程、结果整理成一条经验写回向量库。下次遇到相似问题通过查询历史经验把它加进提示词Agent可以直接复用过去的路径不需要从零推理。这个机制是整体效果提升最明显的一块。但记忆写入一定要控制噪音。刚开始我们图省事把所有对话都写进记忆库结果库里的脏数据越来越多检索出来的全是不相关记录。后来改成只写入已解决工单的决策摘要再由后处理程序做关键词抽取和去重。千万别让记忆库变成垃圾桶否则就是垃圾进、垃圾出。2.4 编排层单Agent还是多Agent很多业务场景一个Agent做不完需要多个Agent协作。我见过的模式有三种。主从式是有一个主Agent负责任务拆解和结果汇总多个子Agent分别执行。适合任务类型差异大的场景比如客服工单里一个Agent做分类一个查知识库一个对接工单系统。对等式是多个Agent互相协作没有明显中心节点适合复杂协商任务。管道式是前一个Agent的输出作为后一个Agent的输入适合有明确先后顺序的流程。我们真正跑通的是主从式。主Agent只负责任务理解和人员调度不参与具体执行子Agent各管一块领域。这样每个Agent可以针对自己的领域写精细的系统提示词各司其职互不干扰。通信协议也很简单主Agent把任务和约束条件通过结构化消息传给子Agent子Agent执行完把结果和状态回传。这里有句实话能用单Agent就别上多Agent。多Agent看起来高级但通信成本、上下文传递、错误传播都会成倍增加。多Agent不是装饰品只有在任务确实需要分工时才有价值。2.5 评估体系没有反馈闭环就是盲人摸象Agent系统最大的问题是不确定性。同一个Prompt模型可能给出完全不同的行动路径所以不能用传统软件那套输入输出比对的方法来测试。我们搭了一套离线和在线结合的评估体系。离线评估集大约一千多条真实历史任务每条都标注了期望的工具调用序列和最终结果。每次改Prompt、换模型都用这套任务集跑一遍重点看三个指标任务完成率、工具调用准确率、循环次数。任务完成率看最终结果是否满足需求工具调用准确率看是否在正确的时机调了正确的工具循环次数反映决策效率循环过多说明提示词或工具描述有歧义。在线监控则看延迟、Token消耗、人工介入率、失败率。我们会记录Agent的思考摘要、工具调用日志和最终答案出现问题随时复盘。没有这套体系你根本没法回答这次升级到底变好了还是变差了。3. 落地实操把企业内部工单系统改造成 Agent-Native说完了概念和组件还是得来点能直接抄作业的东西。这一节我用内部IT服务台的工单处理场景完整走一遍从需求拆解到技术选型再到关键实现的过程。3.1 业务场景与需求拆解场景背景企业内部IT服务台员工提交工单类型包括账号权限、软件安装、网络故障、硬件申请、基础咨询。原来的系统是规则引擎加人工分派每天几百条工单客服团队根本忙不过来。我们拆解后的目标流程是六步员工提交工单系统自动分类并判断紧急程度针对分类检索知识库给出自助解决方案方案能解决就回复员工并自动关闭工单解决不了就自动分配给对应工程师并带上完整上下文每次任务的决策结果和最终解决内容写入长期记忆。关键点在第三步和第四步之间。流程不是死板固定的有的工单需要查资产系统有的工单需要查权限系统有的工单需要先追问员工几个问题。Agent必须根据工单内容自主决定调哪些工具、先后怎么调这个动态决策过程就是 agent-native 和传统流程引擎最大的区别。3.2 技术选型框架对比与取舍工具链我们当时对比了LangGraph、AutoGen、CrewAI和自研。LangGraph控制能力强支持有向图、循环、条件边适合ReAct模式的精确控制这也是我们最终的选型。AutoGen更适合多Agent对话场景但控制粒度不够细。CrewAI上手快可复杂流程控制弱一些。自研当然最自由但成本太高一个成熟的Agent编排框架需要处理状态持久化、检查点、并发控制这些杂活自研周期跟不上业务节奏。用了LangGraph之后模型是可以随时替换的只要兼容OpenAI接口就行。我们的实际配置是用Qwen-Max做分类和意图分析因为便宜且中文效果好用GPT-4o做复杂决策和最终方案生成。两个模型在架构上都是同一套Agent流程只是不同节点接不同的模型便宜。当然选型不是绝对的团队如果对TypeScript更熟LangGraph有JS版本或者干脆写一个简单的大循环也可以。流程控制的核心说白了就三样状态存储、工具注册、条件跳转。3.3 关键实现状态、工具与主流程下面是用Python写的简化示意基于LangGraph。先定义状态状态就是Agent在执行过程中要维护的全部上下文。class AgentState(TypedDict): ticket_content: str # 原始工单 user_name: str # 用户 category: str # 分类结果 knowledge_result: str # 知识库检索结果 actions: list # 已执行的动作 messages: list # 上下文消息 resolved: bool # 是否已解决接着定义工具。工具是Agent可以调用的原子能力每个函数都要写清楚描述、参数和返回。def classify_ticket(content: str) - str: 判断工单分类返回 账号权限/软件安装/网络故障/硬件申请/其他 ... def query_asset(user_name: str) - str: 查询用户资产信息返回设备类型和型号 ... def search_kb(category: str, content: str) - str: 在知识库检索返回最相关的解决方案 ... def reset_account_permission(user_name: str) - str: 重置账号权限写操作需要二次确认 ... tools [classify_ticket, query_asset, search_kb, reset_account_permission]然后构建图。一个基础的两节点图就能跑通ReAct模式agent节点负责思考和生成工具调用tools节点负责实际执行工具并把结果写回上下文。from langgraph.graph import StateGraph, END def agent_node(state: AgentState): # 把当前状态组装成提示词调用LLM并传入工具列表 response llm.invoke(build_prompt(state), toolstools) return {messages: [response]} def tools_node(state: AgentState): # 执行LLM返回结果中的 tool_calls executed_actions [] for tool_call in latest_message(state).tool_calls: result execute_tool(tool_call) state[messages].append(ToolMessage(result)) executed_actions.append(tool_call.name) return {actions: state[actions] executed_actions} def should_continue(state: AgentState) - str: # 模型返回里没有 tool_calls说明任务结束 if not latest_message(state).tool_calls: return end # 超过迭代上限强制结束 if len(state[actions]) 5: return end return continue graph StateGraph(AgentState) graph.add_node(agent, agent_node) graph.add_node(tools, tools_node) graph.set_entry_point(agent) graph.add_edge(tools, agent) graph.add_conditional_edges(agent, should_continue, { continue: tools, end: END })实际线上系统比这个示意复杂一些。我们在agent节点前加了一个人机确认节点凡是写操作工具比如重置账号权限先跳转到确认节点生成确认请求人工点确认后再真正执行。实现方式是用条件边判断工具类型完全可控不需要改主循环。还有一个小细节工具返回结果里一定要带上可读性摘要不要只丢一个JSON结构给模型。比如资产查询返回的原始JSON模型阅读效率很低我们可以把它转成用户张三有1台MacBook Pro序列号XXX购买日期2023-05-12这样一段文字。这个改动显著提升了模型对工具结果的理解和后续决策质量。3.4 参数配置与成本控制方案几个关键参数的经验值直接列成表格方便参考参数推荐值设计意图temperature0.1以内工具参数生成要稳定随机性越低越好max_iterations5防止Agent无限循环context_max_tokens8000超过即触发摘要压缩单次LLM超时30秒避免长尾请求拖垮整体时延工具失败重试2次网络抖动等瞬时错误可以容忍成本控制方面我们最有效的一招是分级路由。先用便宜的小模型做分类和意图识别只有确实需要复杂推理时才调用旗舰级模型。这一条实际执行下来八成工单在小模型这一层就处理完了旗舰模型调用次数大幅减少整体成本节省了差不多六成。另一个招是缓存工具返回结果。知识库检索、资产查询这类非实时数据缓存五分钟就够了同一工单多轮对话中重复检索的概率很高缓存能省下大量重复调用。4. 落地半年之后常见问题与排查实录生产环境跑了半年多遇到的问题和解决的思路我认为比架构本身更有参考价值。这一节直接以问题清单的形式来整理方便你对照排查。4.1 高频问题速查表问题典型现象排查思路模型幻觉编造工具参数、虚构解决方案工具输出做严格Schema校验关键数据要求模型引用来源写操作二次确认工具调用不准确该调搜索引擎时不调不该调时频繁调重写工具描述写清触发条件和反例检查系统提示词里对场景的约束Agent死循环同一组动作反复执行设置max_iterations增加轨迹去重连续三轮相同动作直接转人工上下文膨胀回答质量越来越差、Token猛增做摘要压缩定期清理会话把长历史转存为长期记忆记忆污染检索出的经验不相关甚至错误写入前加质量过滤只记录已解决任务的决策摘要定期清理低分片段成本失控Token消耗异常高分级路由缓存工具结果限制循环次数对超大上下文触发压缩安全违规Agent调用了不该调的权限双重校验写操作强制人工确认工具权限按角色最小化4.2 三个反复踩、再也不想踩的坑第一个大坑工具描述太简略。上线第一周Agent频繁在查询资产这个工具上调错参数后台日志里全是参数校验失败。排查下来因为描述里只写了查询用户资产模型自己发明了字段名。后来我把每个工具的描述统一改成四段式触发条件、参数格式、返回结构、反例。参数错误率立刻降了一个数量级。第二个大坑循环检测太宽松。有次Agent在判断分类、搜索知识库、再次判断分类之间反复横跳因为没有设置迭代上限硬生生跑了二十多轮才发现。这不是简单的技术失误更是产品问题——如果Agent一直在原地打转用户看到的就是一个卡死的机器人。后来我们不仅加了max_iterations还增加了动作轨迹去重逻辑连续三轮执行完全相同的工具序列就强制终止并转人工。第三个大坑非确定性导致回归测试基本失效。传统软件测试是输入一组、比对一个但Agent每次输出可能完全不同。一开始离线评估集的判定标准是和标准答案完全一致结果每次跑都是一片红。后来我们把判定标准改成最终结果是否达到预期 工具调用序列是否在允许集合内测试才真正可用。这个思路转变对团队比较重要——Agent的正确性不是一个点而是一个区间。4.3 沉淀下来的几条实战心得工具打磨永远优先于模型升级。把工具的Schema、描述、返回结构这些基础设计做到位系统的稳定性提升比换一个更强的模型来得快得多性价比也高得多。我的排序通常是先调工具再调提示词最后才是换模型。Prompt不值得玄学化把决策路径写清楚才是关键。与其反复琢磨提示词的措辞不如把Agent的思考步骤、可选行动、结束条件都明明白白摆出来。模型不是要靠提示词激发而是要靠清晰的路径约束来避免走偏。从一个小业务闭环跑起来再横向扩展。不要一开始就想着做一个解决所有问题的全能Agent先让一条工单流程跑通积累两个月的经验数据再逐步加工具、加场景。每次只加一个变量出问题时你还能定位到原因一次性引入太多变量系统出问题你只会一脸迷茫。这基本就是我把一个传统工单系统改造成 agent-native 架构并在生产环境稳定运行大半年后的全部经验。如果你还在纠结要不要上Agent我的建议是找一个小而具体的场景严格按照这五个组件搭一版跑两个月看指标比读一百篇架构文章都管用。等第一个场景跑顺了第二个、第三个场景怎么设计你自然就有感觉了。
返回列表