资讯详情

工单处理Agent频繁翻车?从大而全到小而稳的架构重构复盘

📅 2026/10/21 14:36:35 | 华诺云谱 👁 阅读
工单处理Agent频繁翻车?从大而全到小而稳的架构重构复盘
一个让我印象深刻的Agent项目最开始做的时候信心满满结果上线不到两周就被业务方投诉到差点下线。原因很简单它在真实工单上频繁误判、乱调用工具、还出现过把用户投诉工单直接标记为已解决的操作事故。后来我花了整整三周时间彻底重做才把局面挽回。这篇文章把这次失败和重做的完整过程做一次深度复盘从最初怎么设计、上线后出了哪些问题、到背后真实的系统性原因以及我重做时的架构调整、工具收敛、记忆管理和评测兜底方案。如果你正在做一个生产级Agent或者已经做了但效果不稳定这篇文章应该能帮你避开大部分坑。1. 第一版诞生一个大而全的工单处理Agent1.1 业务背景每天几百张工单人工撑不住了我接手的场景是某平台的客户支持系统改造。这个平台每天会生成几百张客户工单分为订单咨询、物流催查、退款进度、售后补偿、投诉升级等类型。原来的处理方式是几个客服专员纯手工处理先看工单内容再切到后台系统查订单、查物流、查退款单最后手工写回复、改状态、分派给相关组。流程本身不复杂但架不住量大尤其是促销季和物流异常的时候工单经常积压上千张。我当时的目标很明确做一个Agent来自动处理大部分常规工单。理想状态是客户在工单里说“我的订单还没到帮我查一下”Agent自己完成查单、判断物流状态、生成一段可发送的答复全文再顺手把工单状态改成“处理中”。这样人工只需要抽检不用逐条点开处理。这个设想听起来很自然也是当时市面上很多Agent演示视频里的典型场景。1.2 第一版设计一个Agent负责全流程技术选型上我用了当时某个已经支持Function Calling能力的大模型后端把业务系统封装成一堆工具函数暴露给模型。第一版的设计非常“直给”一个Agent包办所有事情没有内部角色区分。系统提示词核心内容你是一个资深的平台客服专家能熟练使用各类后台工具帮助客户解决问题。工具数量一共8个。包括查询订单信息、查询物流轨迹、查询退款单、查询优惠券、查询历史工单记录、修改工单备注、发送邮件、变更工单状态。上下文策略把整个工单对话历史原样塞进系统上下文不加摘要不做筛选。输出策略让模型直接生成给客户的最终回复文本和要执行的动作。当时为什么这么设计说白了就是图省事。我觉得一个能力足够强的模型给一堆工具和足够的信息它自己应该能搞定“读工单-查数据-做判断-写回复”这条链路。毕竟演示的时候效果确实不错我拿了平台上5个非常典型的工单去测试每个都能给出正确分类、正确调用工具、写出一段像模像样的回复。1.3 Demo很顺为什么还是上了线这里要特别说一句第一版之所以敢上线是因为我有一个致命的误判我能跑通Demo就以为它“可用”了。我当时验证的方式非常简单5个工单样本人工判断结果对不对觉得对了就部署。这5个工单覆盖面严重不足全部都是“订单号明确、客户诉求单一、后台数据正常”的教科书型样例。实际情况是什么真实工单里有缺订单号的、有电子邮箱和收货人张冠李戴的、有一个人在两个工单里反复催单的有情绪激动骂人的各种边角情况我完全没有覆盖。更不用说工具调用失败、参数格式错误这类技术层面的干扰。还有一个让我后悔到现在的问题我压根没想过“这个Agent如果做错了事怎么办”。Demo里工具调用全部成功所以我没有设计任何护栏。后来想想那会儿整个系统就是一条没有保险丝的高压线路跑得越顺炸得越突然。2. 失败现场两周内我是怎么被业务方找上门的2.1 引爆点一张投诉工单被自动标记为“已解决”上线第三天早上我收到了客服主管发来的消息语气很冲“你们的机器人把一张投诉工单标成已解决了客户正在后台大发脾气你们到底在搞什么。”我去查了日志过程让人血压飙升。那张工单的内容是客户投诉物流慢原话是“快递已经三天没动了我联系了派送员也没人理你们到底能不能送”。Agent的处理流程是先调用查询订单接口拿到了订单号和物流单号又调用查询物流接口返回的状态是“运输中”。然后它在没有跟客户做任何确认、也没有人工复核的情况下直接调用了变更工单状态为“已解决”同时生成一段模板回复“您的订单正在运输中请您耐心等待”通过邮件发出去了。关键问题在于这是一张投诉类工单平台规则里明确要求投诉单必须有客服主管人工审核后才能关闭。Agent不读规则、不走流程直接越权闭环了客户诉求客户发现自己连申诉入口都被关掉之后情绪彻底失控。业务方当天就打了报告要求停掉这个功能。2.2 更多故障工具乱调、信息混淆、上下文遗忘误标“已解决”是引爆点但绝不是唯一的故障。我接下几天把一周内的数据处理了一遍发现了大量莫名其妙的问题。最典型的是工具调用混乱。有一张工单问的是退款单号RF20241213的退款进度Agent拿这个单号直接去调了查询物流接口物流系统当然返回“单号不存在”它居然分析说“该订单可能未发货”。还有一张工单问优惠券为什么用不了Agent先去查了订单又去查了退款单折腾半天最后回复说“您的退款已到账”客户一脸茫然。我翻日志的时候发现有些工单里同一个查询工具被重复调用四五次返回结果一模一样完全没有任何新增信息。信息混淆也很可怕。有一位客户先咨询了A订单的发货问题后来又提了一句“顺便把地址改成新的”Agent在后半程把客户的旧地址当成新地址写进了回复草稿。另一个工单里客户明确写了“配件请寄到这个收货地址”Agent却在回复里再次询问客户要寄到哪里——因为早期对话内容已经被后面的超长对话挤出了模型注意力范围。2.3 两周真实数据62%的分类准确率事故发生之后我拉了两周的真实数据做人工复核结果非常难看。一共70张新增工单人工复核后分类准确率只有62%意味着将近四成的工单被分到了错误类别回复内容真正可以直接发送的只有一半左右剩下30%需要人工大改还有20%完全不能用直接删掉重写。更讽刺的是平均处理时长。原本期望Agent能把单张工单处理时间从人工的三四分钟压到1分钟以内结果实际上因为Agent经常给出错误结果每一个工单都需要人工打开复核、修正处理时间反而比纯人工还多了将近一倍。那段时间我的感受是这不是提效这是给大家添乱。2.4 看不见的成本信任崩塌我觉得损失最大的还不是准确率而是业务方对整个自动处理方案的信任。出事的那个星期之后客服主管明确要求凡是被Agent处理过的工单不管结果看着对不对都必须人工逐条再审一遍。这意味着所有工单要经历“Agent先跑一遍 人工再查一遍”的流程处理成本反而变成了原来的两倍多。直到后来重做之后业务方的配合度依然非常低。他们前几周看到Agent给出的回复草稿第一反应永远是“先怀疑再说”。这种由信任崩塌带来的隐性成本是我复盘时最痛心的一点也是我在后面几个Agent项目里再也不敢轻视的教训。3. 复盘失败不是偶然而是五个系统性问题3.1 职责不清一个Agent同时拥有查询权和变更权第一版最大的设计错误是让模型同时掌握“读取数据”和“改写数据”两类工具。查询订单、查询物流这类操作危害极小查错了也无所谓。但变更工单状态、发送邮件、修改备注这类写操作的危害是破坏性的一旦判错后果直接落在真实用户身上。我当时还把这种设计理解成“给模型充分的自主性”。现在回头看这个类比就是给一个实习生同时授权“查公司资料”和“直接修改线上系统配置”然后指望他每个场景都知道什么该做什么不该做。大模型在简单场景里确实可以判断但在上下文模糊、多轮对话、情绪化表达干扰的情况下它的判断力极不稳定。让这种不稳定的判断直接触发不可逆操作本质上就是在赌。3.2 工具失控8个工具没有校验没有护栏工具数量太多是第二个明显问题。8个工具意味着模型每次处理都要从8个候选中选一个而且这些工具之间还有功能重叠。比如查询退款单和查询订单工单里说“退了一笔钱”模型经常分不清该查哪个。当工单语义越模糊选错概率被放得越大。比工具数量更严重的是没有任何防御机制。工具接口拿到一个空order_id照样执行拿到一个明显不是公司内部单号的字符串照样查询甚至连调用次数都没有限制。我翻日志时发现有工单里Agent用同一个查询参数调了4次工具这完全是无意义浪费。这些问题放到生产环境里就是源源不断的脏数据。3.3 记忆失效全量历史拼接的致命伤第一版我把整个工单的对话历史无脑拼接进系统上下文以为信息越多越好。实际效果是长工单的token数量高达四五千模型表面能看到所有内容但注意力机制决定了它更关注最近几轮早期那些关键信息会被“冲淡”。比如客户在前两轮说过“收货地址是XX”隔了二十轮之后模型已经完全无视这条信息反复追问地址。更可怕的是如果Agent自己在某个中间轮次错误理解了客户意图这个错误理解会留在上下文里之后模型甚至会沿着错误方向继续推理。在当时的数据里我就看到一个工单Agent把物流问题错判成退款问题后后面几轮它还在努力编造“退款进度”的理由自圆其说。3.4 Prompt失控角色扮演替代不了执行规程现在很多Agent教程都爱把System Prompt写成“你是一个资深客服专家请耐心、友善、准确地为客户解决问题”。我当时也是这么写的后来发现问题恰恰出在这种“人设式”Prompt上。它只定义了语气和角色感完全没有定义流程边界。模型拿到这种Prompt自由度非常高它可以自由选择工具自由决定要不要闭环工单自由决定回复内容结构。结果就是同一个工单今天跑和明天跑处理思路可能完全不同。我的结论是Agent的System Prompt应该更像SOP手册而不是角色小传。它必须明确“先做什么、再做什么、什么情况下能做什么、什么情况绝对禁止做什么”。3.5 没有评测集和兜底线上就成了盲区第一版上线前没有建立固定评测集没有回归测试更没有兜底机制。我只用5个样例工单做了冒烟测试就把它推进了生产。后续每次想调整某些参数都没有办法量化判断“改完是变好了还是变坏了”完全靠肉眼抽样效率极低。最危险的还是没有兜底。我给模型的权限是它自己判断“这个问题已解决”然后直接调用状态变更接口关单。没有置信度阈值没有人工复核没有操作频率限制。这套设计把“判断”和“执行”全部交给一个不可完全信赖的系统任何一次概率性的判断错误都会变成真实的业务事故。这也是我不止一次在复盘里提醒自己“上线前不加兜底就是在给自己埋雷”的原因。4. 重做从“大而全”到“小而稳”的完整改造4.1 架构重构一个Agent拆成路由、处理、行动三个角色我重做时做的第一件事是放弃“一个Agent干所有事”的思路改成职责单一的三段式架构。路由AgentRouter只负责读工单产出结构化标签。包括工单类型、紧急程度、涉及的单号类型订单号/退款单号/物流单号、是否属于可自动处理范围。它不产生回复也不执行任何业务操作。处理AgentProcessor接收路由结果只做只读分析。查订单、查物流、查退款单综合分析后产出一份工单摘要和一条建议回复草稿。它不能改任何状态。行动AgentActionExecutor负责执行写操作但它不能自主判断。它拿到的是处理Agent的分析结果和业务规则只有当规则明确允许时才把操作提交给后台的二次确认API。每个Agent的Prompt都极度聚焦上下文被大幅压缩误判概率天然下降。我特意多加了一个协调层让路由Agent输出的结构化标签作为处理Agent的执行约束相当于前置了一次判断后一个Agent只能在前一个Agent画好的框里工作。资金规模不高的项目其实没必要用太重的框架这套三段式架构用纯Python服务就能跑通每个Agent独立部署成单独的服务模块好处是出了问题可以单独回滚不会整个系统瘫痪。4.2 工具收敛4个只读工具写操作全部走审批重做时我把工具从8个砍到4个全部是只读类query_order、query_logistics、query_refund、query_historical_ticket。任何一个Agent都没有直接修改状态的权限。业务上需要的“改状态、发邮件、改备注”等操作被改造成一个“建议动作”输出。Agent分析完后不是直接执行而是输出一个结构化的JSON比如{ suggested_action: close_ticket, target_ticket_id: TK20250117001, reason: 客户已确认收到商品且物流签收成功工单目标达成, suggested_reply: 很高兴您已收到商品感谢您的咨询。 }这个动作JSON先被平台接收再走一遍人工审批或者二次确认接口。对于低风险操作我配置了基于规则的自动确认对于发邮件、关单这类高风险操作一律要求人工确认后才能执行。模型输出写得再漂亮也只是“建议”不再是“操作”。4.3 参数校验与调用护栏用代码锁死风险工具侧不再是无条件执行而是在每个工具入口加了前置校验。我整理了当时的校验逻辑核心思路就是入参不合法就直接返回错误标准格式绝不让脏数据流入业务系统。def query_order(order_ref: str) - dict: if not isinstance(order_ref, str) or len(order_ref) 12: return {error: invalid_order_ref, detail: 订单号格式非法} if not order_ref.startswith(SO): return {error: invalid_order_ref, detail: 非标准订单号前缀} # 调用真实订单服务 result order_service.query(order_ref) return result除了参数校验我还加了三个调用护栏同一个工具在单轮对话中最多调用2次超出次数则终止工具调用并进入保守模式。整个工单处理流程的工具调用总次数上限为6次超出后自动转人工。工具返回异常或返回空数据时Agent被禁止猜测和编造结果必须输出“无法确认”并转人工。这些护栏都是用代码写在工具调用框架里的不依赖模型自觉。我当时的想法是永远不要把安全机制寄托在模型的“临场判断”上能放进代码的就不要写进Prompt。4.4 记忆重构工单画像代替全量历史重做时我把上下文策略彻底改了从“全量历史拼接”改成“工单画像最近几轮对话”。首先在处理工单的初期新增了一个“工单画像抽取”步骤由路由Agent完成。它会提取这样一组结构化字段客户核心诉求客户情绪状态理性/急躁/投诉相关单号订单号/物流单号/退款单号以及它们之间的对应关系客户提供的联系方式与地址信息关键时间节点下单时间、发货时间、承诺时效、当前状态已经确认过的信息比如客户已确认收到商品、已确认邮寄地址等之后每轮对话模型不再读整段历史只读这份画像加上最近两轮对话内容。画像不是固定不变的每次出现了新的已确认信息会由专门的更新逻辑写回画像。刚开始我很担心字段抽取不准确怎么办所以给画像抽取也配了校验凡是提取出单号和地址这类敏感字段必须和原始工单文本比对一次不一致则丢弃。这样做的好处非常明显上下文长度从四五千token压到一千以内模型注意力被集中到关键信息上客户地址被遗忘的情况再也没有出现过。4.5 Prompt重写把“人设”改成“SOP”重做后的System Prompt我彻底去掉了“资深客服专家”这类角色描述改成了可执行的流程规程。下面这段是处理Agent的Prompt核心逻辑我保留了当时的写法你是工单分析Agent。你只能执行以下步骤 第一步读取路由Agent提供的工单画像确认工单类型和涉及单号。 第二步按需调用query_order、query_logistics、query_refund三个工具获取业务数据。 第三步基于画像和业务数据判断客户诉求当前是否被满足。若你无法准确判断必须输出cannot_confirm。 第四步生成建议回复草稿。草稿必须以“核实结果当前进展下一步处理”三段式呈现。 禁止事项禁止修改任何工单状态、禁止发送任何消息。禁止编造物流轨迹或退款进度工具未返回信息时只能写“暂无最新动态”。禁止在没有获取到客户确认信息时推断客户已解决投诉。如果工单涉及退款、投诉升级、隐私信息变更必须在输出中附加manual_review_requiredtrue。这类Prompt的特点是它不指望模型“聪明”而是约束模型“可预期”。模型自由发挥的空间越小产出结果的一致性越高。我在改写之后做了一个直观对比同一组工单跑三次第一版三次结果经常不一样重做后基本一致。4.6 评测兜底40条回归集与置信度阈值重做后的最重要工程之一是搭了一套固定的评测集。我从历史真实工单里精心挑选了40条样本其中20条是正常可处理工单20条是故意设置的“坑”样本包括缺单号、客户情绪激烈、多轮夹带新需求、两个工单信息相似容易混淆、工具返回异常等。每次调整Prompt、工具定义或模型版本先跑这40条样本然后记录四个核心指标工具调用准确率调对了工具的次数 / 总调用次数信息提取完整率画像字段正确提取的比例目标达成率Agent是否正确判断出客户诉求违规动作数输出中包含禁用操作或高风险动作的次数评测结果不达标就不上线。这个机制看起来很简单但我第一次做Agent的时候完全没有这个概念等到出了问题才回头补救。如果一开始就有这套回归集在前面挡着第一版根本没机会跑进生产环境。打分之外我还给整个系统增加了兜底策略整体置信度低于0.6时Agent不输出回复草稿直接输出“转人工处理”。工单涉及退款、投诉、隐私修改三类情况时强制人工复核。系统层面按账号限制操作频率比如每个业务组每小时最多自动提交10次低风险操作。所有“无法确认”的工单必须保留原始状态禁止自动闭环。5. 重做后的效果稳定、可用、可维护5.1 改造前后核心指标对比重做上线后我连续观察了两周数据对比如下指标第一版重做版工单分类准确率62%92%回复可直接发送占比约50%85%工具调用错误率15%2%误标“已解决”次数一周4次0次平均单张处理时长约3分钟含人工复核约1分钟需要人工抽检比例100%每条必查约25%仅高风险转人工最让我觉得靠谱的是误标已解决次数归零。因为行动Agent再也不能直接关单所有写操作都要走审批流模型判断再离谱最后一道人工确认也能挡住。工具调用错误率从15%降到2%这里面既有工具数量收敛的功劳也有参数校验和前置格式检查的功劳。5.2 业务方体验与信任重建数据的改善只是开始真正让我感到重做有价值的是业务方从“不信任”变成了“有限信任”。他们拿到了每一张工单处理时Agent的分析依据为什么打这个电话、查了哪张单号、判断依据是什么、建议动作是什么。每次处理结果都有据可查不再是一个黑盒输出一段回复就算出错也能快速定位在哪一步出了问题。而且这套架构的可维护性好了很多。后面新增工单类型时我只需要修改路由Agent的标签规则再补充几条对应样本到评测集处理Agent和行动Agent几乎不用动。段与段之间的隔离性让改动风险变得可控这也是我从这个项目里学到的最重要工程经验之一。5.3 新引入的问题与二次调整重做也不是一帆风顺新架构上线后确实出现了几个新问题我在这里也一并记下来。第一个是信息抽取初期不够稳。路由Agent在生成工单画像的时候偶尔把“发货地址”和“收货地址”搞混导致后续处理逻辑虽然是对的但引用的信息错了。我的解法是在画像更新逻辑里加了一层字段比对凡是地址、手机号这类强校验字段必须与原始工单文本中的正则结果一致不一致则抛弃该字段。第二个问题是兜底策略初期过于保守。刚上线那两周转人工率一度到35%业务方觉得负担还是很重。原因是我把置信度阈值定得太高很多本来能处理的工单也直接踢给了人工。我花了几天分析阈值从0.75一路下调到0.62转人工率降到了25%左右同时没有出现准确率下降。阈值这种东西不能拍脑袋要靠评测集反复试。第三个问题是路由Agent误判传导。路由标签一旦错了后面整个处理流程都会跟着错。所以我给路由Agent也增加了置信度输出低于阈值时直接转人工不再往下跑全流程。这样做的结果是“宁可直接让人看也不让错误在后面环节被放大”。6. 如果你也要做Agent排查清单与避坑心得6.1 高频问题速查表做Agent项目的过程中总会遇到各种“看着奇怪”的问题。我把这次项目里遇到过的问题整理成了速查表方便排查现象可能原因排查方法解决方案Agent调用错误工具工具过多且边界重叠查看日志中工具选择置信度收敛工具数量每个工具只负责单一职责Agent反复调用同一工具缺少去重和调用次数限制统计单轮工具调用次数设置单工具调用上限与总次数护栏回复引用不存在的物流信息工具返回异常但模型编造数据核对工具返回值与回复文本增加“无数据时必须注明”的Prompt约束上下文长后遗忘关键信息全量历史拼接导致注意力偏移查看长上下文工单的画像字段完整度改为“画像最近两轮”策略Agent把低风险操作做成高风险写操作未走审批流审查权限设计写操作全部改为建议动作JSON同一工单多次处理结果不一致Prompt自由度太高重复跑同一样本对比输出Prompt改写成SOP式指令流程线上效果无法量化没有回归评测集搭建固定样本集并记录指标每次改动先跑评测再上线这个表格里最后一行的“没有评测”是我感触最深的一条。我见过太多Agent项目在demo阶段被夸得天花乱坠一上生产就露馅本质上都是因为缺少一套“能不能上线”的客观标准。6.2 我的几条实操经验第一永远不要在生产环境让Agent直接执行写操作。哪怕是低风险操作也至少要走一个规则确认或二次审批。模型可以在99%情况下正确但只要有一次错了业务方对你的信任就归零修复信任的成本远高于增加审批的成本。第二Prompt里写“请不要做XX”作用非常有限。模型的指令遵守有概率性不能当成硬约束。真正安全可靠的限制要么写在工具的代码里要么写在调用框架里。Prompt负责引导方向代码负责强制兜底。第三Demo样本必须覆盖边界情况和失败场景。光测正常路径会让你产生“系统没问题”的错觉。缺参数、超长文本、情绪化表达、工具异常这类样本才是检验Agent是否能扛住真实场景的试金石。第四日志记录是一切排查的基础。工具调用的入参、出参、模型置信度、每一步的决策理由都要完整记录。第一版上线后我最苦恼的就是日志不完整很多事故根本没法追溯。重做时我把每一步都打了结构化日志后面定位问题的速度快了十倍不止。第五不要为了省一次模型调用费把多个Agent合并。我当时也想过度节省调用成本但很快发现一个Agenr承担多个角色时上下文又重新变得混乱错误率抬头。每一次调用都有对应的职责和约束这笔钱花得很值。第六评测集要伴随线上情况持续演进。每次线上出现一个过去没有预料到的问题我做的第一件事就是把该问题样本加进回归集。这样后面每次调整都能确保这个问题不会在没人注意的情况下复发。模型能力在变业务场景也在变评测集是唯一能稳定住“标准线”的工具。这次重做前后加起来大约六周第一版只占了一周价值产出几乎为零但教训之深刻让后面所有Agent项目都受益。我现在的体会是Agent项目的成败往往不由模型能力本身决定而在于你有没有给它画好边界、定好流程、装好护栏。第一次做的时候我满脑子都是“它能做到多聪明”重做的时候想的都是“它在哪些情况下一定会犯错以及错了之后怎么兜底”。这个思路转换比任何技术技巧都重要。如果你也是第一次做Agent建议先把70%的精力放在评测集、边界和兜底上再考虑追求所谓的智能化。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑