Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住

先花一分钟搞清楚一件事:一个 Agent 干一次活,内部到底发生了什么。

用户发一句话 → 模型理解意图 → 决定调某个工具 → 工具去查库、调接口 → 结果回填给模型 → 模型再生成答案。中间任何一环都可能翻车。

以前我们做后端,翻车了就是抛异常,try-catch 一兜、打个日志、返回默认值,万事大吉。但我把 Agent 接进生产之后发现,这套"祖传的兜底"突然不好使了------不是语法坏了,是它兜不住 Agent 特有的"错"。

为什么 try-catch 兜不住

因为 try-catch 兜的是异常------那种运行时抛出来的、一眼就知道错在哪的 Exception。但 Agent 的错误往往是"看起来对、其实是错":

  • 模型输出的 JSON 缺了个字段;
  • 调错了工具;
  • 把"退款金额"填成了"订单金额"。

这些在代码层面根本不抛异常。函数正常返回了,返回值也合法(就是个字符串),只是语义错了。你用 try-catch 拦什么?根本拦不到。

Agent 的错,大部分是"无异常的错误"。 这句话我想让你先记住,后面五个模式全是围着它转的。

我用的 5 个兜底模式

1. 不信任输出,先校验再重试

模型输出不可信,就当它是外部输入。工具入参进业务逻辑前,先过 Schema 校验 + 业务规则校验:

java 复制代码
@Tool(description = "按订单号查询订单摘要")
public OrderSummary queryOrder(@NotBlank @Pattern(regexp = "^[A-Z0-9]{16,24}$") String orderId) {
    if (!orderService.belongsTo(orderId, currentUserId())) {
        throw new BizException("无权查询该订单");
    }
    return orderService.queryByIdAndUser(orderId, currentUserId());
}

校验失败抛异常,让框架把错误回喂给模型,让它换个参数重新试。这就是"校验 + 重试"取代了"裸 catch"。

这里注意:校验本身用的是异常(抛 BizException),但它的目的是让框架接管重试,而不是打个日志就完事。这是和传统 try-catch 最大的区别。

2. 显式 fallback

网络挂了、模型 500 了、上游超时了,这些才算传统异常。但这类异常的正确姿势不是"catch 了打个日志",而是降级:

主模型不可用就切备用模型;工具 A 失败就换工具 B;实在不行,给用户一个明确提示,而不是一句冷冰冰的"系统异常"。

java 复制代码
try {
    return primaryModel.chat(req);
} catch (TimeoutException e) {
    return fallbackModel.chat(req); // 降级到备用模型
}

3. 超时 + 熔断

模型调用慢起来能把你整个线程池拖死。所以每一步调用都要有显式 timeout,连续失败还要熔断,避免雪崩。

这在普通 RPC 里是标配,但在 Agent 里特别容易被忘------因为默认 HTTP 客户端超时经常是 30 秒甚至更久,一个慢模型就能让整个 Agent 卡住。把模型当成"不可信的下游",该用的治理手段一个都别省。

4. 人机确认

有些操作,参数全对、权限也有,照样不该让 AI 决定------退款、删除、改金额。这类"不确定但影响大"的操作,兜底方式不是 catch,是升级给人:生成一条待确认的审批流,人点了才执行。

5. 记录 + 可恢复

出错了要能追溯、能重放。每次工具调用记下"谁、什么工具、什么参数(脱敏)、结果",失败尤其要记完整。这套审计不只是为了追责,更是为了你能复现和修复。

五道防线是一条有顺序的纵深

五个模式合起来,是有先后顺序的一条防御链,画出来长这样:

看这张图的关键,是分清事前 和事后:

  • 前四道(校验重试、降级、超时熔断、人机确认)是事前防御,目标是把错误拦在执行之前;
  • 最后一道(审计、可重放)是事后兜底,目标是让已经发生的错能追回去、能修。

顺序不能乱:只有事前四道都拦不住的时候,才轮到事后那一层来收拾残局。

写在最后

想明白之后,其实就一句话:try-catch 是"事后兜底",Agent 需要的是"事前防御 + 事后兜底"一起上。

try-catch 没死,只是从"唯一的兜底手段"降级成了"兜底的一部分"。真正兜住 Agent 的,是上面这一整套防御纵深。

下一篇聊聊可观测性------真出了问题,你怎么看清 Agent 到底卡在哪一步。

相关推荐
larance1 小时前
[菜鸟教程] 机器学习教程十课-Python 机器学习应用
人工智能·python·机器学习
小师兄吃牛肉1 小时前
Java 同步系列之 ZooKeeper 分布式锁
java·分布式·java-zookeeper
qq_369173631 小时前
如何将 AI 生成的 HTML 网页发布成在线链接?不用自己搭建服务器
前端·人工智能·html·效率工具·html 发布
Yyyyyy~1 小时前
【python】函数
python
外收内放1 小时前
Python基础语法练习题(62原始版本及其优化版本)
开发语言·python
风花一世月1 小时前
⚡ 我把一座含氢能源园区搬进了浏览器(五类能流实时算守恒,在线直接玩)
前端·人工智能
棉猴1 小时前
玩游戏学Python4-字符串
python·游戏·字符串·pygame·玩游戏
马剑威(威哥爱编程)1 小时前
【AI全栈后端12-12】Spring Boot 3.x 到 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·开发语言·spring boot·后端
Gauss松鼠会1 小时前
【GaussDB】破除gaussdb ugin索引支持中文模糊查询的迷思-字符序
java·运维·服务器·网络·数据库·gaussdb·经验总结