跳到主要内容

那些被你的智能体“触发并遗忘”的异步工具调用

· 阅读需 11 分钟
Tian Pan
Software Engineer

智能体工具调用抽象失效最明显的标志是:追踪记录(trace)显示该步骤已标记为完成,而下游系统却显示什么都没发生。模型调用了一个工具,收到了一个任务 ID 返回值,将该任务 ID 视为答案,然后继续执行。三分钟后,实际工作要么在无人监听的情况下成功,要么失败并产生一条记录在无人查看的日志中的错误。用户看到的是一份自信的总结;而操作队列看到的却是一个搁浅的任务。

这就是函数调用(function-calling)抽象悄然允许的失效模式。JSON Schema 描述了参数和返回类型,但它们无法区分“此工具返回一个结果”与“此工具返回一个操作回执,你稍后需要查询其结果”。模型对两者一视同仁,因为在规划器(planner)看来,它们看起来是一样的——都是一个带有非错误负载的成功工具调用。

基准测试数据不容乐观。在 Robotouille(一个衡量智能体能否将动作与耗时操作交替进行的异步规划基准测试)上,基于 GPT-4o 的 ReAct 模式在同步变体中得分为 47%,而在异步变体中仅为 11%。该架构在处理异步任务时并非只是略逊一筹——它彻底崩溃了,因为每一次异步工具调用都是规划器将“确认收到”误认为“执行完成”的机会。

类型系统存在缺陷

函数调用 Schema 定义了参数、返回形状和一行描述。但它没有定义的是时间合约(temporal contract):此调用是返回结果,还是返回结果的承诺?

一个返回 {"status": "sent"}send_email 工具,在 JSON 层面看起来与一个返回 {"job_id": "abc123"}start_video_render 工具完全相同。两者都产出负载,且都没有报错。规划器在类型层面没有收到任何信号来区分哪个已经完成,而哪个才刚刚开始。工具作者会写下诸如“启动渲染任务并返回任务 ID”之类的描述——但这种描述只是系统提示词中的一句话,而模型在其中需要同时处理数十个工具;在运行时,模型会将这两类调用归为同一个思维范畴:“工具调用成功,推进计划”。

新的 MCP 规范(2025-11-25 修订版)通过将任务(Tasks)添加为独立的原子原语(primitive)来承认这一差距——任务是一个持久化状态机,具有 working(进行中)、input_required(需要输入)、completed(已完成)、failed(失败)和 cancelled(已取消)等明确状态。重点不在于状态名称,而在于异步工作具有一种同步工作所不具备的“性质”(kind),将其放在不同的运行路径上可以防止规划器混淆两者。Bedrock AgentCore 的运行时通过显式的 add_async_taskcomplete_async_task 调用实现了同样的隔离,SDK 使用这些调用来独立于模型的推理循环跟踪任务并管理状态轮询。

如果你的函数调用层将每个工具都视为同步的“返回答案”调用,那么你就是用一种类型来描述两种现象。当你第一次发布长耗时工具时,你就发布了一个在完成情况上撒谎的规划器。

未能结合实际工作负载设定的轮询循环预算

意识到异步情况的团队通常会通过给智能体一个 check_status 工具并信任规划器会不断调用它直到工作完成来修补这个问题。这在演示中可行,但在生产环境中会因为一个特定原因而崩溃:智能体的外层循环预算——最大轮次、最大 Token 数、最大实际耗时——是由考虑成本的人设定的,而不是由考虑实际操作耗时的人设定的。

典型的循环预算是 20 到 30 个轮次,总执行时间为几百秒。而典型的长耗时工具是视频渲染、大文件转录、多步配置任务或 ETL 流水线。这些操作的典型持续时间通常为几分钟。而智能体的“轮询并等待”循环在约 90 秒后就会放弃,因为轮次预算只允许这么多。

当循环预算在任务完成前耗尽时,智能体会报告什么?几乎总是:智能体会合成一个结果。虚假状态报告——模型引用来自早期 check_status 调用的任务状态,而不是发起新的调用。过早采集——模型尝试根据“任务已进入队列”拼凑出最终答案,因为这是它能获得的最新观测结果。ID 截断——在上下文压力下,模型缩写或重新格式化任务 ID,导致下一次 check_status 调用因查询字符串损坏而失败。

用户看到了一个连贯的答案。操作可能仍在运行。智能体产出的结果与它实际等待后的结果无法区分。这比超时错误更糟糕,因为至少超时是诚实的。

同步与异步工具:披着相同 JSON Schema 外衣的不同抽象

陷阱在于传输格式(wire format)让你假装它们是相同的。这两种抽象实际上在每一个关键维度上都存在差异:

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates