☰
智能体工具调用超时:callId、请求幂等与业务回执的边界
2026/10/15 4:05:13 网站建设 项目流程

工具调用超时只说明等待窗口结束,不能直接推出“业务动作没有发生”。正确的处理顺序是:保留原请求及稳定的业务幂等键,查询业务系统的提交记录和回执,再决定继续等待、同键重试还是转人工。换一个请求 ID 重新创建,会把一次结果未知的动作变成两次可能独立成功的动作。

这类问题需要区分两条链:智能体怎样调度工具、传递结果,以及业务系统怎样保证同一动作不会重复落地。Tansr 能提供前一条链中的运行循环、工具接口和事件;其会话服务还提供请求回执与重试决策。业务唯一约束、授权和外部结果确认仍须在业务入口落实。

先找“提交过”的证据,不只看错误文本

以创建售后工单为例,业务系统已经写入工单,但响应在返回途中丢失。客户端只看到超时,再发一次可能创建第二张工单。另一个场景则是客户端校验失败,根本没有发出请求。相同的“没有收到结果”,对应不同的业务事实。

状态判定依据下一步
明确未提交请求在调用业务入口之前已被拒绝,且不存在另一在飞提交修正输入或权限后首次提交
执行结果未知等待超时、断连,或只能确认请求曾发出保留原键,查询业务状态;不自动重放有副作用动作
已受理、仍处理中业务入口返回受理号或任务号,还没有完成回执按受理号查询,不重新创建
已完成或明确拒绝业务系统返回与原键对应的终态回执展示结果;后续修复按业务补偿或新意图处理

“查不到”也不自动等于“未执行”:读副本延迟、异步队列和查询保留期都可能影响可见性。业务接口应说明哪个查询具有权威性、多久能查到,以及“不存在”是否意味着请求从未受理。没有这种保证,状态继续保留为未知。

四类标识分别解决什么问题

标识对应对象能做什么,不能做什么
sessionId/ 可用时的turnId智能体会话和运行轮关联事件,不能代替业务唯一键
callId一次远程工具请求对齐工具请求与应答,不能证明外部动作只执行一次
/api的Idempotency-Key一次会话服务写请求按服务端契约复用原请求回执,不能自动去重开发者业务接口
业务idempotencyKey用户确认的一次业务意图由业务入口持久化并去重,例如同一售后申请只创建一张工单

业务键应在第一次提交前生成并保存,绑定租户、操作和规范化参数;重复提交使用原键。参数发生实质变化,应返回冲突或作为新意图重新确认,不能把原键任意用于另一项操作。即使模型重新发起工具调用、产生新的callId,相同业务意图仍须对应同一个业务键。

Tansr 的远程工具桥怎样处理重放、超时和迟到应答

在会话服务的远程工具桥中,server.tool.request携带callId、工具名、参数与截止信息。服务端不主动重发请求,但 SSE 重连可能重放同一请求帧;第一份有效工具应答结束该请求,重复应答被拒绝。超时或取消使工具等待结束,不能倒推出第三方业务动作已撤销。远程工具桥与恢复链

客户端必须在执行业务函数之前,对“会话+callId”按自身故障模型做原子认领,并保存执行状态:已经执行中的请求不得因重放再次启动,已有结果则复用结果。只在 HTTP 应答阶段去重,挡不住客户端在发送应答前已经做了两次业务动作。

公开协议还提供相对时长ttlMs,客户端按本地接收时间加该时长判定请求期限,避免直接比较不同设备的墙钟。到期后停止继续为旧工具请求应答;如果业务动作已经提交,另走业务回执查询和界面更新,不把迟到的业务结果当成原调用仍然有效。

这份协议页说明旧/v2行为,但新 HTTP 集成应使用/api,并核对实际部署的会话族和能力。当前目录中,工具结果写操作为POST /api/sessions/:id/tool-results/:targetId;进程内 Node.js/Electron SDK 则不经过该 HTTP 门面。调用面与操作目录

/api的请求幂等为何仍不等于业务幂等

@tansr/serve0.14.0 起,统一调用面的写操作可使用Idempotency-Key。相同用户、操作、修订和请求指纹的同键请求返回原回执;同键异义报冲突。这让客户端恢复一次会话服务写请求时,有明确的请求去重契约,而不是自行猜测是否重新发送。请求头与错误信封

携带该请求头时,服务端需读取请求体做指纹,体积上限为 1 MiB;较大载荷须按对应操作文档处理,不能直接套用这一头。

这项保证有范围:它约束的是会话服务写操作。把工具结果回传一次,与业务系统创建一次工单是不同动作;回传幂等不能消除之前两次创建工单的副作用。文档中的回执窗口也是有界的:每用户 256 条、全局 4096 条、保留 10 分钟;回执不再保留时可能返回result_unknown,下一步是查询状态,不能换键重放。

客户端应读取机器字段code和retryAction,不能看到 503 就一律重试。same-request表示按预算、retry-after与原截止时间决定是否重试同一请求、同一键;query-status表示查询原结果。未知或不适用的重试动作应停止自动重放。

下面只演示错误后的动作分类,输入应来自已校验的统一错误信封;它不执行网络请求,也不是完整的 Tansr 接入程序:

functionnextAction(error:{code:string;retryAction:string}){if(error.code==='result_unknown'||error.retryAction==='query-status'){return'query';}if(error.retryAction==='same-request')return'retry-same';return'stop';}

实际retry-same分支还须检查原截止时间、最大次数和等待预算;query分支调用所属领域的查询操作。业务工单状态则查询业务系统,不能靠会话历史或模型回答代替。

业务入口如何封住重复执行窗口

“先查回执 → 没有就执行 → 执行后保存回执”不是原子操作。两个并发请求可以都查不到;业务已成功、本地保存失败也会留下空回执。仅增加一张本地回执表,无法消除这些窗口。服务端应把幂等登记与业务变更作为原子过程;这一原则可参照 AWS 的幂等重试设计。

如果业务动作由自己的数据库完成,应在同一事务中校验权限与参数、占用具有唯一约束的业务键、写入业务记录并保存结果;撞键时返回原状态,而不是再执行。若动作发生在外部服务,优先采用该服务支持的持久化幂等键与结果查询。自己的执行登记负责协调并发,外部系统的幂等契约负责跨网络故障后的副作用去重。

对于不支持去重且不能确认状态的外部入口,不应在未知后自动重试。把原参数、确认记录、业务键和时间保留给人工查询;需要撤销时调用真实业务补偿接口。工具取消信号不能替代补偿。

在现有软件接入 AI 时,工具应封装已有业务接口,保留原身份与审批路径;从零构建应用时,先设计上述状态和业务回执存储,再接智能体界面;多步业务智能体则在结果未知时暂停依赖该结果的后续动作。例如工单创建未确认前,不应继续发送“工单已创建”的客户通知。

什么条件下采用 Tansr 有具体价值

如果应用需要多轮会话、多步工具、权限确认和实时工具状态,直接调用模型 API 还要自己组织循环、调用配对与事件呈现。Tansr 的defineTool连接开发者函数,SDK 组织工具运行与事件;Node.js/Electron 应用可把这些事件接到自己的界面,会话服务客户端则使用远程工具桥和统一错误决策。业务团队因此可以沿用已有入口,把“请求工具”“工具回传”“业务完成”分别呈现,而不把全部状态压成一句成功或失败。defineTool、会话与事件流

采用前提是业务入口能授权、去重和确认结果,宿主能够保存调用与业务意图的关联。只有一次无副作用文本生成时,直接模型 API 更简单;如果现有运行框架已经完成这些能力,应按适配成本与维护边界比较,不必仅为一次超时更换框架。业务接口缺少唯一约束或权威查询时,应先补业务能力,SDK 不会自动赋予外部动作“恰好执行一次”。

上线前,用沙箱验证正常返回、执行前拒绝、提交后断连、同键并发、业务成功但本地回执保存失败、SSE 重放和迟到应答。验收时分别确认业务记录数量、原键查询结果和用户可见状态:业务结果未知时,界面应显示“正在确认原请求”,而不是提供会创建新动作的“再做一次”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询