处理智能体的不确定性:重试、回退与人工介入

发布时间:2026/5/19 3:02:24

处理智能体的不确定性:重试、回退与人工介入 一个让AI“不任性”的实战手册——该认错时认错该求助时求助先讲一个让我至今心有余悸的事。去年做的一个金融Agent任务是每天自动从十几家券商网站抓取研报提取关键的投资评级和目标价然后汇总成一张表发给基金经理。上线跑了两个多月一直挺稳的。突然有一天基金经理在群里发了一张截图问我“你们这个Agent是不是该退休了它把‘卖出’评级写成了‘买入’害我差点下错单。”我赶紧查日志。那天有个券商改版了页面结构爬虫工具返回的不是研报正文而是一段报错信息“Access Denied”。Agent看到这个结果后没有报错而是“聪明”地猜测可能今天没有发布研报那就用昨天的数据吧。于是它把昨天的评级和目标价当作今天的填了进去。更巧的是昨天和今天的评级正好相反——昨天是买入今天是卖出。这一连串的“不确定性”叠加差点酿成惨剧。这件事让我深刻认识到智能体最大的敌人不是“不知道”而是“不知道自己不知道”。模型会产生幻觉工具会超时或报错用户输入会模棱两可外部API会改版……在所有这些不确定性面前一个没有“认错”和“求助”机制的Agent就像一个不会喊疼的伤员——它会带着错误硬撑着往前走直到捅出大篓子。今天这篇文章我就把这三年来处理Agent不确定性的经验——重试、回退、人工介入——彻底讲透。不堆砌理论全是挨过打才学会的。一、不确定性的三个来源模型、工具、环境在讨论解决方案之前我们先梳理一下“不确定性”到底从哪儿来。我把它分成三类。第一类模型的不确定性LLM的天然缺陷大模型不是数据库它是概率模型。即使temperature设为0也不能保证100%的确定性输出。同一个问题今天和明天的回答可能不一样。更麻烦的是幻觉——模型会以极度自信的语气输出完全错误的信息。比如你问“北京到上海的火车票多少钱”它可能编一个不存在的价格给你。在Agent场景里模型的不确定性还体现在规划偏差上。你给Agent一个目标它可能规划出一个你从未预料到的、极其诡异的执行路径。有时候这种“创造力”是惊喜但更多时候是惊吓。第二类工具的不确定性外部系统不可控Agent能干活靠的是调用外部工具——API、数据库、脚本、浏览器。但这些工具不是为你一家服务的。网络会抖动服务器会过载API会限流第三方服务会改版。你调用一个物流查询接口可能1%的概率超时0.5%的概率返回格式错误。这些在传统软件里可以通过重试和熔断处理但Agent的问题在于它不知道工具失败了该怎么办除非你提前教过它。第三类环境的不确定性任务本身的开放性用户的表达是模糊的。“帮我查一下我上次买的那个东西” —— 哪个上次哪个东西Agent需要推理推理就可能出错。任务本身也可能随着时间变化今天可用的数据源明天可能关了今天有效的规则明天可能改了。这种开放环境下的不确定性是最难对付的。这三类不确定性叠加在一起导致Agent的执行结果永远不可能是100%确定的。我们能做的不是消除不确定性——那不可能——而是建立一套机制让Agent在面对不确定性时能够优雅地降级、安全地重试、或者在必要时向人类求助。二、重试别让一次失败毁掉整个任务重试是处理不确定性的第一道防线。但“重试”这两个字看起来简单里面的门道可多了去了。2.1 什么时候该重试什么时候不该不是所有失败都值得重试。我总结了一个简单的决策树失败原因是临时性的网络超时、服务繁忙、限流 → 应该重试失败原因是永久性的参数错误、权限不足、资源不存在 → 不应该重试应该直接报错或回退失败原因不明→ 先尝试重试1次如果第二次失败同样的错误大概率是永久性的停止重试这个判断在传统软件里很容易因为你能拿到明确的错误码。但在Agent场景下工具返回的可能是自然语言“抱歉我暂时无法处理您的请求。”Agent需要自己判断这是临时还是永久。这是LLM的一个典型应用场景——我们可以让一个轻量级的“判断模型”来分析错误信息决定是否重试。2.2 重试策略指数退避与抖动如果你的Agent在高峰期频繁调用一个限流的API每次都立即重试只会把情况搞得更糟。正确的做法是指数退避第一次失败后等待1秒重试第二次失败等待2秒第三次等待4秒以此类推。同时加上随机抖动避免所有重试请求在同一时刻爆发。我们内部的标准重试参数最大重试次数3次太多会堆积延迟初始退避500ms退避倍数2抖动范围±20%超过3次还失败就放弃重试进入回退流程。2.3 重试预算防止无限重试消耗资源有些新手会在Prompt里写“如果工具调用失败请重试直到成功”。这是最危险的做法。我见过一个Agent因为调用的API返回了一个“稍后重试”的提示结果它真的“稍后”了——不是等待几秒而是立即重试循环了上千次烧掉了几百美元的token才被发现。一定要设置重试预算。每个任务的总重试次数上限每个工具调用的重试次数上限超过上限强制终止。我们通常的做法是在Agent的System Prompt里明确写“任何工具调用最多重试3次如果3次后仍然失败输出‘操作失败请稍后重试或联系客服’”并且在代码层面也有硬限制双重保险。2.4 幂等性重试会不会导致重复操作重试最怕的是“非幂等操作”——比如转账、发送邮件、创建订单。如果第一次调用已经成功了只是网络超时导致客户端没收到响应你重试一次就会执行两次操作。解决方案有两个层面。一是在工具设计上尽量实现幂等性转账操作带上幂等键idempotency key服务端根据幂等键去重。二是在Agent层面记录已成功调用的工具和参数重试前先检查是否已经执行过。我们有个血泪教训一个退款Agent因为网络抖动自动重试了退款接口。结果用户收到了两笔退款财务对账对了一个月才发现。从那以后所有涉及资金的操作都加了幂等键并且在Agent状态里标记“已执行”禁止重试。三、回退当重试不管用时还有Plan B重试解决不了所有问题。工具永久失效了或者模型反复在同一个地方犯错就需要回退——切换到备选方案确保任务能继续推进哪怕结果不那么完美。3.1 降级方案从“完美答案”到“可用答案”一个典型的例子Agent需要调用一个付费的高精度翻译API但这个API今天挂了。怎么办任务不能停。你可以降级到免费的、质量稍差的翻译API或者甚至降级到用模型自己的翻译能力虽然可能慢一些、准确率低一些。用户可能得到不是“最优”的翻译但至少能看懂。降级方案需要提前设计。每个工具都应该有一个或多个“备胎”。调用主工具失败且重试用尽后自动切换到备胎。如果备胎也失败再进入下一级降级直到最终降级到“告诉用户我搞不定”。我们内部的降级层次Level 0主工具高精度、高成本Level 1备用工具中等精度、中等成本Level 2模型自身能力低精度、低成本但总比没有好Level 3返回预设的静态答案“暂时无法获取请稍后再试”Level 4转人工每个工具在注册时就要声明它的降级链。Agent在执行时会根据当前可用资源和失败情况自动选择。3.2 简化策略放弃非核心诉求保住核心目标有时候用户的需求是多目标的。Agent可能规划出5个步骤但第3步需要的工具永久失效了。这时候不一定非要整个任务失败。你可以调整规划跳过非核心的子目标只完成最核心的那个。举个例子用户要求“帮我查一下上海的天气顺便推荐一家附近的咖啡馆”。天气查询工具正常但咖啡馆推荐工具挂了。Agent可以只回答天气然后说“我暂时无法推荐咖啡馆但您可以手动在地图上搜索”。用户可能失望但至少不会空手而归。这个“任务剪枝”能力需要在Prompt里给Agent授权“当某个子任务无法完成时你可以跳过它但要告知用户。优先保证主要任务的完成。”3.3 回退的代价什么时候值得回退回退不是免费的。切换到备用工具可能质量下降简化任务可能用户不满意。你需要判断回退带来的损失是否小于任务失败的损失对于低风险场景查天气、查新闻任务失败也没啥用户刷新一下就好不值得复杂的回退。对于高风险场景医疗诊断、金融交易任务失败可能造成重大后果哪怕降级到人工处理也比让Agent瞎猜强。这个判断应该在设计阶段就做而不是让Agent运行时决定。把每个工具标记“重要性等级”高重要的工具不允许自动降级到太低质量的备选。四、人工介入最后的“安全网”当重试和回退都无法解决问题或者问题本身超出了Agent的能力边界就需要人工介入。这不是失败而是系统的设计特性——知道什么时候该说“我不行换人上”。4.1 人在回路Human-in-the-Loop的三种模式被动模式Agent遇到无法处理的异常主动暂停向人类发送请求比如发一条消息到审批系统等待人类的指令。人类可以批准、拒绝、修改参数、或者直接接管。这种模式适合高风险操作如大额支付、删除数据。主动模式Agent在执行过程中定期向人类汇报进度人类可以随时打断、纠正、提供额外信息。这种模式适合长周期、需要人类监督的任务如自动写报告人类可以中途要求改方向。协同模式Agent和人类共同工作。Agent处理自动化部分人类处理需要判断力的部分两者无缝衔接。比如客服场景Agent先回答用户不满意可以一键转人工人工能看到完整的对话历史直接接手。4.2 什么时候应该“强制”人工介入不是所有异常都要转人工否则就失去了自动化的意义。我们根据风险等级和置信度来决定高风险 低置信度必须人工介入。比如Agent要执行一笔超过1000元的退款但它的置信度只有70%。这时候宁可让用户多等几分钟人工审核也不能自动放行。高风险 高置信度可以自动执行但事后必须人工抽检。比如批量发送营销邮件99%的情况下没问题但出一次错就是大规模客诉。所以让Agent自动发但随机抽10%由人工复核。低风险 低置信度Agent可以自动降级比如直接回答“我不知道”也可以转人工。看你的运营成本。我们通常不转人工因为低风险场景人工介入的成本比错误成本还高。低风险 高置信度全自动。置信度怎么算可以基于模型输出的logits、工具调用的成功率历史、或者一个专门训练的“置信度评估”小模型。MVP阶段用简单的规则如果工具调用连续失败超过2次置信度设为低如果模型输出中包含“不确定”“可能”等词语置信度降级。4.3 人工介入的接口设计怎么让人高效地“帮一把”人工介入最怕的是“信息孤岛”——人接手后不知道Agent之前做了什么、遇到了什么错误、已经尝试了哪些方案。如果还要人从头问一遍体验极差。所以设计人工介入接口时至少要传递三样东西上下文摘要用户原始诉求、Agent已经执行的步骤、每一步的结果。错误信息哪里失败了、失败的详细原因包括技术栈和业务栈。建议操作Agent自己觉得可能的解决方案比如“需要用户确认订单号”。这样人工接手后只需要做最关键的判断不需要重新了解背景。我们内部做了一个“人工接管面板”Agent会主动弹出一个卡片上面列着这些信息人工点一下“批准”或“拒绝”就行甚至不需要打字。4.4 人工介入的“超时”问题人工不是24小时在线的。如果Agent在凌晨三点向一个正在睡觉的审批人请求介入任务就会卡住。解决方案是设置人工超时等待N分钟比如30分钟后如果没有人响应Agent可以执行预设的默认策略比如放弃任务、转给备选审批人、或者自动重试。同时可以引入“值班人轮询”机制——配置一个值班群Agent向群里发消息谁先响应谁处理。我们一个电商退款Agent退款超过500元就需要人工审批。但凌晨没有审批人在线怎么办策略是超过500元但小于1000元等待30分钟无人审批则自动通过因为风险可控超过1000元无论是否有人审批都先冻结任务第二天人工上班后处理。五、实战案例一个“打不死”的客服Agent把上面这些串起来看一个完整的实战案例。背景一个电商客服Agent核心任务是处理用户的退款申请。不确定性来源用户可能不给订单号、订单号格式错误、退款规则变化、支付接口超时、用户情绪激动等等。设计重试层调用订单查询API时设置3次重试指数退避。如果3次都超时进入回退。回退层订单查询主API失败后切换备用API数据稍旧但稳定。备用API也失败则用缓存的订单数据可能有几秒延迟。如果缓存也没有则告诉用户“系统繁忙请稍后再试”并记录工单。人工介入退款金额超过1000元或者用户连续三次表达不满情感分析模型判断或者Agent连续两次让用户转人工说明Agent解决不了触发人工介入。介入时Agent把用户ID、订单号、对话历史、已尝试的解决方案打包成一个工单推送到客服工作台。客服一键点击即可接管对话。置信度判断Agent每次调用退款接口前会评估置信度。如果置信度低于80%比如因为用户提供的订单号模糊则走人工确认流程而不是直接执行。结果这个Agent上线半年处理了15万退款申请其中自动完成的占92%人工介入的占8%。在自动完成的案例中99.6%的用户表示满意。唯一出错的几次都是因为订单查询API返回了错误数据工具本身的问题而不是Agent的逻辑问题。六、可观测性你看不见不确定性就没法处理它最后强调一个容易被忽略的点你要知道不确定性在哪里发生了才能针对性地设计重试、回退和人工介入。这离不开可观测性。至少需要记录每个重试的触发原因和次数。如果某个工具的重试率突然升高说明它可能不稳定需要切换主备或者通知运维。每次回退的路径。从主工具降级到了哪个备选降级后的结果质量如何这能帮你评估回退策略是否有效。每次人工介入的触发条件和处理结果。哪些场景最常转人工是不是可以通过改进Prompt或增加规则来减少人工介入我们内部有一个仪表盘实时显示这些指标。每当“人工介入率”超过5%就会触发告警产品经理和开发一起分析原因。这比等用户投诉再反应快得多。写在最后回到文章开头的那个金融Agent。事故之后我们给它加了三层防护第一层爬虫工具失败后不再“聪明”地用旧数据而是明确标记失败触发重试。重试3次仍失败进入回退——从备用数据源拉取。备用数据源也没有就输出“数据获取失败”而不是猜测。第二层每次输出评级和目标价之前加一个“一致性检查”对比昨天和今天的数据如果评级发生了反转标记为“高风险”触发人工确认。人工确认前Agent不能自动填充到报表。第三层增加一个“看门狗”Agent专门监控主Agent的输出。如果发现主Agent连续输出可疑结果比如同一个商品的价格变化超过20%就主动介入暂停任务并通知运维。这套组合拳打下来那个Agent再也没有出过大的安全事故。不确定性是智能体的固有属性你永远无法彻底消除它。你唯一能做的就是设计一套机制——重试应对临时故障回退应对永久失效人工介入应对超出能力边界的情况——让Agent在不完美中依然能安全、可靠地完成任务。这就像教一个孩子走路。你不能保证他不会摔跤但你能教他摔倒了怎么爬起来什么时候该喊大人帮忙。

相关新闻