我今年有一段时间特别迷信一个思路:给大模型配尽量多的工具,把任务说明书写得尽量详细,然后让它“自己想办法”跑完一整条业务链路。demo阶段一切都很丝滑——我让它在模拟环境里自动处理工单、查数据库、调用外部接口、整理结果,它像模像样地走完了全流程。当时我还跟同事说,这个方向再打磨两个月就能上生产。
结果生产环境的第一个星期就给了我足够的教训。真实数据、真实接口、真实的脏数据一进来,原本“聪明”的Agent开始不断做出让人匪夷所思的决策。查不到客户信息,它不报错,而是编一个出来;外部接口超时,它会换个参数继续重试,试到把下游数据库锁住;任务执行到一半进程重启,它完全记不住自己做到哪一步,只能从头再来。排障那几天,我反复在想同一个问题:是不是我们对“Agent”这三个字的理解,从第一天就偏了?
后来我把自研项目里所有“大模型自主决策”的模块全部推倒重做,结论也慢慢清晰了。AI Agent难以真正落地,差的根本不是模型能力,而是我们把“智能”放在了它不该在的位置上,又没给它补上一套可靠系统该有的机制。下面就把这几个月的排查过程、架构调整和踩坑记录完整摊开来说。
1. Demo版Agent和生产版之间,差了一条“系统设计”的鸿沟
1.1 为什么同样的模型,换个环境就从“聪明”变“失控”
先说一个自己反复踩过的对比现象。在demo里,我常用一套很简单的验证标准:给定输入,看Agent能不能给出合理输出。只要它走通了主流程,我就认为方案可行。但生产环境的评价标准完全不是这样,生产系统真正关心的是:边界输入会不会崩、并行任务会不会互相干扰、失败之后能不能恢复、每一步操作能不能追溯。
举个具体例子。Demo里我让Agent自动修改订单状态,它调用接口成功,输出“已经修改”,我就觉得完成度很高。但生产环境里,订单可能处于锁单状态,可能已经被其他流程改过,可能接口返回了一个伪装成成功的错误码,Agent却完全没有校验这些前提条件的能力。它依据的是“模型对文本的统计规律”,而不是“系统真实的状态”。这就导致同一个模型、同一套prompt,在干净环境里表现良好,到真实环境里频繁跳步、编造中间状态、做出不可逆操作。
后来我意识到一个特别扎心的结论:大多数Agent demo,验证的不是系统的可靠性,而是“模型恰好能在这个样本上走通”。一旦样本换成生产流量,模型对任务的理解没有变,但环境变了,一切就都失控了。
1.2 Demo天然的“幸存者偏差”掩盖了三个隐患
做demo的时候,开发者和模型之间其实有一种无形的默契:我会下意识避开那些语义模糊的测试用例,输入的样例都是信息完整的,工具的返回也都是及时且格式规范的。生产环境完全相反。
我总结下来,至少有三个隐患是demo阶段很难暴露的:
- 模型幻觉被当成正常输出。Agent查不到某条数据时,会基于常识“推断”一个合理值,demo里这种推断刚好是对的,因为样例数据本身就符合常识;生产数据千奇百怪,常识推断完全不可靠。
- 工具调用的副作用被忽略了。demo里调用接口不产生真实后果,参数传错了也不影响全局;生产环境调用一次就可能产生订单、扣减库存、发送通知,不可逆操作一旦出错,代价是实打实的。
- 长链路的状态丢失。demo通常一次跑完,几分钟内结束,进程稳定,不涉及中断恢复;生产环境任务可能持续数小时,中间可能宕机、重启、网络中断,Agent对“我进行到哪一步”完全没有概念。
这些隐患叠加在一起,让生产环境的Agent变成了一颗定时炸弹。表面看它还在一本正经地执行任务,实际上它已经在用自己的“语义联想”填补各种系统缺口了。
2. 一开始就搞错的三件大事:自主、长链、重编排
如果说上面说的是“环境差异”,那下面要聊的是“方向问题”。我复盘过自己早期失败的那版方案,发现它正好踩中了三个经典误区:过分强调自主、盲目追求长链自动化、依赖重编排框架。
2.1 把“自主决策”当目标,最后得到的是不可预测
早期设计Agent时,我最喜欢的卖点是“它能自己决定调用哪些工具”。感觉这才是智能的体现。现在回头看,这种自由度在生产环境里就是灾难源头。
自主决策意味着结果不可穷举。我可以在测试环境准备几十个用例,却无法穷举生产环境的全部输入组合。一旦Agent在某个未覆盖的组合下做出意外决策,系统就得承担这个意外带来的后果。而且大模型的决策受token分布影响很大,同样的输入,换个模型版本或者温度参数,决策路径就可能完全不同。不可预测的系统,在工程上是没法被信任的。
更关键的是,业务系统对可预测性有硬性要求。订单不能因为模型“觉得应该退款”就直接退款,库存不能因为模型“猜测会取消”就提前释放。凡是涉及资金、权限、状态的变更,都必须走明确规则。把这类决策交给模型,等于把确定性业务交给概率性引擎去赌。
2.2 长任务链是隐患源,不是能力体现
我做过的另一个错误设计,是把十来个步骤串成完整工作流,让Agent一口气执行下去。设计时觉得这是“多步推理能力”的体现,实际运行里每一步都可能出错,错一步之后的所有步骤都建立在错误前提上。
我花了两周时间试图用更详细的prompt、更强的模型来缓解这个问题,效果都有限。后来想明白了,问题不在于模型推理能力弱,而在于链条本身太长。信息在传递过程中会丢失、变形。当Agent在第7步发现第2步的数据其实有误时,它不会自动回溯修正,更多时候会硬着头皮继续编下去,因为“按原计划完成任务”对模型而言是更符合当前上下文的做法。
长链任务还有个隐形问题:上下文窗口有限,步骤越多,早期信息被挤占得越严重。到后面几步,模型已经快忘了最初的需求细节,只能凭着局部信息做判断。这种“局部最优”每个单步看起来都合理,整体结果却常常偏离目标。
2.3 重编排框架把复杂度转移到了配置层
第三件让我后悔的事,是迷信各种重量级Agent编排框架。框架本身没问题,但我当时误以为“框架能解决Agent的一切工程问题”。
实际用起来才发现,框架把控制的复杂性转移到了抽象配置里。节点之间怎么流转、状态怎么传递、工具怎么注册、异常怎么处理,全都分布在框架配置代码里。业务逻辑一变,配置就跟着变,调试的时候还要同时盯住模型输出和框架日志。而且底层细节被封装得太严实,出了问题很难定位,到底是框架bug、prompt写得差,还是大模型输出格式错误,排查成本极高。
后来我回归了很朴素的工程路线:用普通的函数调用来编排流程,每个环节显式调用模型,模型只负责一个狭窄的子任务,流程控制全部用代码写死。代码逻辑一眼可见,任何一步出现问题,都能快速定位是模型问题还是业务逻辑问题。这个转变是整体思路的转折点。
3. 把Agent装进确定性管道:小任务、验证器、人工兜底
好吧,那既然上面的方向是错的,正确的方向到底是什么?我最终实践下来的方案,一句话概括就是:Agent不是流水线的拥有者,它只是流水线里的一个执行单元。流水线本身必须是确定的、可校验的、可人工干预的。
3.1 从“让AI自己跑完一切”改为“把任务切成最小验证单元”
我重新设计了任务拆解方式。不再期望Agent一次性完成“从客户投诉到自动退款”的全部环节,而是把它拆成一个个独立的小任务,每个小任务只做一件事,比如:抽取出客户编号、判断投诉类型、生成回复初稿、提取退款金额。
每个任务都定义清晰的输入和输出,以及一条硬性的验收规则。输出必须通过验收规则,才算任务完成。例如“生成回复初稿”的验收规则包括:必须包含处理方案、必须点名具体问题、不得出现经理姓名以外的捏造信息。这这些规则全部通过后,才允许进入流程的下一步。
这种做法的好处很直接:问题可以被精确锁定到某一个任务。投诉内容没有提取出来,只改抽取逻辑;回复初稿态度不对,只改生成prompt。而不是像以前那样,整个流程跑完,发现结果一团乱,却说不清问题出在哪个环节。
3.2 验证器比提示词重要十倍
如果只能分享一条经验,我会选这句:把写提示词的精力分一半去写验证器。
所谓验证器,就是一段普通的程序代码,用来检查模型的输出是否满足硬性要求。它可以很简单,比如解析JSON并校验必填字段;也可以很复杂,比如把抽取出的实体拿去数据库核对,看客户编号是否真实存在。
我以前有一个致命习惯:模型返回什么,我就默认接受什么。现在倒过来了:模型返回的每一段关键信息,都必须经过至少一道程序化校验。校验通过,才认为是有效输出;校验不通过,就触发重试或者人工介入,绝不会直接拿着模型的输出去执行下一步。
这样设计之后,模型幻觉的伤害被限制在一个极小范围内。就算模型在某一刻编造了一个不存在的客户,校验器也会在它造成真实影响前把它拦截下来。而且这类校验器写起来并不困难,无非是:schema校验、枚举值校验、存在性校验、业务规则校验。技术含量不高,但对整个系统的稳定性贡献是决定性的。
3.3 人工兜底不是退步,而是必要设计
我早期总觉得,一旦加人工审核,这个系统的“智能化程度”就不够看了。实际跑了生产才发现,完全没有人工介入的Agent自动化,在业务线上根本待不住。业务方不会因为模型“大多数时候正确”就放心让它自主执行有风险的操作。
目前我采用的设计是分层兜底:低风险操作,比如自动摘取信息、生成草稿,可以全自动放行;中风险操作,比如发送正式邮件,会让模型生成结果并给出置信度,人工一键确认;高风险操作,比如修改订单状态、处理退款,必须由系统生成建议方案,再由业务人员审核后执行。
这套模式在业务方那里的接受度高了很多。对业务的员工来说,Agent从一个“抢活的怪物”变成了一个“能帮忙打草稿的好帮手”;对我来说,即便模型偶尔出错,最终弹出的都是人审环节的修正,不会造成不可逆结果。这个取舍非常值得。
4. 实战复盘:一次从“看起来不错”到“稳定可用”的改造
理论说了一大堆,还是要复盘一个具体项目才够实在。我给某内部系统做过一个工单自动分类与回复助手,第一版和第二版的方案截然不同,效果也给了我很直观的对比数据。
4.1 第一版:让模型负责全流程,失败得很典型
第一版设计是这样的:模型读取工单全文,自己判断工单属于哪一类、紧急程度如何、应该回复什么内容,然后直接调用接口创建回复,标为处理完毕。听起来很自动化,实际运行却状况百出。
分类偶尔偏差一个类别,导致工单被指派给错误的处理组;回复邮件里偶尔出现工单里根本不存在的“我方承诺48小时解决”,但项目并没有这条承诺;更严重的是,有几次模型把“用户抱怨”误判成了“用户要求退款”,直接生成了一张退款申请单。虽然因为下游流程需要人工确认所以没有造成实际损失,但已经足够让我冷汗直冒。
这个版本的准确率看起来不低,工单分类准确率大概能到85%,但如果把这些错误集中起来看,那15%的错误率中,相当一部分是“看似合理但完全跑偏”的,它们带给业务方的感受是“这个系统不能信”。
4.2 第二版:确定性流程介入,模型只管一步
第二版更克制。我不再让模型全链路自主,而是把它嵌进一段明确代码流程:
- 第一步:用一段专门的抽取模型,提取工单中的客户编号、问题关键词、产品线、期望时间。
- 第二步:用程序代码去数据库校验客户编号存在性,确认产品线属于有效枚举值;校验不通过则直接转人工,不走后续流程。
- 第三步:把第一步提取到的结构化信息放入分类模型,让它只输出一个类别字段,且类别必须是预定义集合中的值。
- 第四步:程序根据分类结果,去取对应的回复模板,把模板交由生成模型填充事实性内容。
- 第五步:所有填充后的内容必须经过“事实一致性检查”——把回复中出现的客户名、产品名、日期、金额和工单原文做比对,任何一项不一致都视为生成失败。
- 第六步:无论成功还是失败,都先以草稿状态存入系统,业务人员进行一次人工核验后发送。
改造之后的效果是立竿见影的。同样一批工单,自动化的“可用输出率”从第一版的七成多直接上升到99%以上,剩下不到1%全部走人工兜底。分类准确率从85%提升到97%左右,更重要的是,没有任何一条拟回复包含工单原始信息里不存在的事实。
我复盘这次改造,核心差异就是四个字:少管闲事。让模型在每一个环节里只负责“理解语言”这一件事,剩下的事务逻辑全交给代码和校验器处理,问题一下子就变得可控了。
4.3 一个反向指标:人工修改率比模型准确率更有意义
这个项目让我养成了一个新习惯,除了看准确率,我会专门追踪一个指标:人工核验时修改AI输出的比例。准确率只告诉我“模型自己觉得对了多少”,而人工修改率告诉我“业务人员真正接受的有多少”。
第一版里,虽然模型准确率有85%,但业务人员几乎每条都要修改措辞,实际接受率很低。第二版里,模型错误率很高,但业务更愿意接受,因为语义平台,拟稿已经能被使用了。这个指标比纯模型指标更能反映Agent的落地水平。
5. 五个设计原则,任何Agent项目都值得提前想清楚
开工到现在,我总结出五个必须在第一天就定下来的设计原则。如果让我回到项目最初,我会按这份清单做。
5.1 原则一:先定边界,再提智能
Agent的边界必须用代码和规则写死,而不是交给模型自觉。允许它操作什么、调用什么、修改什么,必须全部在代码里显式声明。任何超出边界的请求,一律拒绝并告警。大模型确实“能力很强”,但能力越强的工具越需要给装个护栏,否则它发挥想象力的空间也越大。
5.2 原则二:每一层输出都要验证
模型输出的验证,应该和业务入库、调用外部接口处于同等地位。定义几类基础验证器:字段格式验证器、枚举白名单验证器、实体存在性验证器、业务状态机验证器、事实一致性验证器。把它们做成可复用组件,任何Agent任务进来,直接组合使用。
5.3 原则三:Agent只能动“非关键工序”
对生产系统而言,Agent应该被放在“非关键路径”上。最佳的使用场景是:信息抽取、摘要生成、初稿撰写、数据整理。这些工序出错的影响可控,且容易人工复核。关键路径上需要明确规则的操作,还是用传统代码实现,不要硬塞给AI。
5.4 原则四:为失败设计,而不是为成功设计
我以前的流程设计全是“成功路径”:模型调用工具→模型拿到结果→继续下一步。现在要求自己必须先回答:调用失败怎么办?结果校验失败怎么办?进程中断怎么办?重试配额用完怎么办?所有这些路径都要写进代码里,而不是让模型“灵活处理”。
5.5 原则五:可观测性要覆盖每个步骤
每一步的模型输入、输出、验证结果、耗时、消耗token数,全部记录下来,方便事后追溯一条工单从进来之前的每一步是什么。生产环境里Agent调试最大的困难就是因为过程像黑盒,可说的事情说不清。有了完整的追踪日志,很多问题一眼就能定位,业务方再有疑问,也可以直接拉到证据。
这套方法配合一段时间之后,我会觉得自己的项目方向完全换了。早期缓解焦虑的是“模型又变强了”,现在缓解焦虑的是“验证器又多拦截了一个幻觉”。回归到“少让AI自己做主”的原则后,系统反而更像“智能系统”了。它能替人完成一大部分繁琐而耗时的环节,但每个环结果都在人检查的掌控里。
如果你也在做Agent类项目,建议你早点想清楚两件事:你要解决的是“从无到有”的生成问题,还是“从有到优”的执行问题?你的系统在模型出错时,到底有没有兜底机制?想清楚这两件事,可能比换更大参数的模型更管用。