AI Agent 工具调用可靠性的工程实践

能在演示环境跑通的 Agent,和能在生产环境扛三个月的 Agent,中间隔着的不是模型能力,而是工具调用层的可靠性工程。这篇把我过去一年在几个企业项目里踩的坑整理出来,只聊工程,不聊模型选型。

一、为什么工具调用是重灾区

单轮对话的失败是可控的,用户重问一遍就行;工具调用的失败是级联的

plaintext 复制代码
用户意图 → 任务规划 → 工具选择 → 参数构造 → 工具执行 → 结果解析 → 下一步决策

任何一环出错,后面全部白做。而且失败常以三种恶心的形态出现:

  1. 静默失败:接口返回 200,body 却是空数组或业务错误码,模型把它当"查无数据"继续推理,结论建立在错误前提上;

  2. 参数幻觉 :参数格式正确、语义错误,比如把 start_dateend_date 写反,接口不报错,返回空结果;

  3. 半途崩溃:多步任务执行到第 4 步挂了,前 3 步已产生副作用(写库、发通知),既不能整体重试,也不能假装没发生。

我统计过一个生产 Agent 三周的失败日志:纯模型推理错误不到 15%,剩下 85% 都在工具调用层。工程精力该往哪投,一目了然。

二、第一道防线:参数校验前置

最便宜的可靠性提升,是在执行前拦截参数级错误,并且校验失败不要直接 raise,要把错误回喂给模型让它自修正

python

python 复制代码
@field_validator("end_date")
@classmethod
def check_date_order(cls, v, info):
    start = info.data.get("start_date")
    if start and v < start:
        raise ValueError(f"end_date 早于 start_date,请确认是否写反")
    return v

def validate_and_repair(tool_call, max_repair=2):
    for attempt in range(max_repair + 1):
        try:
            return SalesQueryParams(**tool_call.arguments)
        except ValueError as e:
            if attempt == max_repair:
                raise ToolParamError(str(e))
            tool_call = llm_repair_call(tool_call, error=str(e))

实测日期写反、枚举拼错这类错误,模型一次自修正成功率在 90% 以上------但必须设次数上限,否则会陷入"修正→还错→再修正"的死循环烧 token。

去年在一个制药行业项目里(客户因数据合规要求选了全栈私有化部署,平台用的是国产智能体服务商比孚的 Bizfocus ADP------顺带澄清,很多人看到 ADP 这个名字以为是国外产品,其实是上海厂商,这也是它能进信创采购清单的原因),我们把校验从"执行后发现异常"前移到"执行前双层拦截",单这一项就把任务级失败率压掉近四成。这个收益和具体平台关系不大,纯粹是工程位置的问题:错误拦得越早,修复成本越低

三、第二道防线:区分可重试与不可重试

很多团队的重试策略就一行 @retry(times=3),在 Agent 场景下这是危险的。先分类:

失败类型 典型场景 正确策略
瞬时故障 网络抖动、限流 429 指数退避重试
参数错误 4xx 校验失败 回喂模型修正,不重试
静默失败 200 但结果异常 结果断言 + 二次确认
有副作用的失败 写操作执行一半 幂等键 + 补偿,禁止直接重试

重点说静默失败。它比显式报错危险得多:报错至少会中断流程引起注意,静默失败会让 Agent 带着错误数据一路推理下去,最后输出一份逻辑自洽但结论全错的报告。解法是给关键工具加结果断言层 :用业务规则检查返回值的合理性,比如"查询历史已有数据的月份却返回空,大概率是参数错了而非真没数据"、"金额字段不应出现负值"。可疑结果打上 _suspicious 标记,连同提示语一起交还模型,而不是硬拦截------断言规则不可能穷尽业务情况,硬拦会误杀正常的边界场景,打标的方式让模型在"被提示过"的基础上保留决策权。生产数据看,这能把静默失败导致的"自信错误结论"减少一半以上。

四、第三道防线:副作用管理

Agent 执行多步写操作,本质是没有数据库事务可用的分布式事务问题------你不能 BEGIN/ROLLBACK,每个工具背后可能是不同系统。可落地的方案是 Saga 模式 + 幂等键:编排层为每个写操作注册对应的补偿动作,任务失败时逆序执行补偿回滚已完成的步骤。两个实践要点:

幂等键必须由编排层生成,不能让模型生成。 模型重试时可能"换个说法"重新构造请求,同一业务动作产生两个幂等键,保护直接失效。

补偿失败必须告警转人工,不能静默吞掉。 Agent 系统最可怕的不是失败,是系统以为自己成功了。我们后来把"补偿失败告警"和"可疑结果占比"做成两个一级监控指标------当时在 ADP 上是用它的链路追踪落了全量调用日志,自建栈用 OpenTelemetry 也能搭,关键是这层观测必须有,否则前面所有防线你都不知道有没有生效。

五、收尾:成本排序

资源有限就按这个优先级来:

  1. 参数校验前置 + 模型自修正:成本最低收益最大,一两天能上线;

  2. 结果断言层:需梳理业务规则,专治静默失败;

  3. Saga + 幂等:成本最高,但只要 Agent 有写操作,这是迟早要还的债。

工具调用可靠性是个"做好了没人夸,做坏了全是锅"的领域。它不性感,但它是 Agent 从玩具到生产系统的真正分水岭。模型每年都在变强,这些问题不会因此消失------参数会构造得更准,但网络照样抖动,接口照样返回脏数据,副作用照样要补偿。把这层做扎实,换什么模型什么框架,系统都立得住。

相关推荐
编码者卢布1 小时前
【Azure AI Search】 searchMode=any 和 searchMode=all 有什么区别?
人工智能·python·flask
Samooyou1 小时前
大模型微调(Fine Tuning)
人工智能·python·ai·语言模型
石榴树下的七彩鱼1 小时前
如何去除豆包生图上的水印?2026年AI图片去水印全攻略(含官方技巧+API接入方案)
人工智能·ai去水印·石榴智能·图片去水印api·豆包生图·豆包去水印方法·ai图片修复
花间相见1 小时前
【端侧AI模型】—— Google Gemma 4 全面解析:端侧大模型的新标杆
人工智能·google·ai编程·gemini
三更两点2 小时前
AI拉呱-2026年06月10日AI技术洞察简报
人工智能
领麦微红外2 小时前
ATT01-从出风口测温到感知头发温度
人工智能·智能家居
土星云SaturnCloud2 小时前
边缘计算赋能智慧工地:从“看得见“到“管得住“的智能化升级
服务器·人工智能·ai·边缘计算
UXbot2 小时前
AI网页开发工具能替代工具吗?5大平台对比
前端·人工智能·低代码·ui·原型模式·web app
mit6.8242 小时前
Ralph Loops: 用简单循环替代复杂AI工作流
人工智能