从一个最小 Runtime Demo 看懂:陌生的 599 为什么不能重试

完整案例代码:多供应商 Adapter 与有限重试 Runtime

最近几天学习 Agent Runtime 时,我一直在反复接触同一套骨架:LLM 生成候选动作,Runtime 校验并执行,工具参数先经过 Schema,循环和权限由代码控制。

我开始觉得每天都在说差不多的东西。今天真正增加的新内容,是把供应商差异挡在 Runtime 外面的 adapter。

不同供应商可能用不同的状态码和错误码表达失败。如果 Runtime 直接理解每家供应商的原始错误,它的重试逻辑就会逐渐和供应商耦合。今天的 Demo 增加了一个 provider-error-adapter.mjs,先把原始错误转换成 Runtime 认识的内部错误:

js 复制代码
if (status === 429 || code === "ETIMEDOUT") {
  return new TransientToolError("TRANSIENT_PROVIDER_FAILURE");
}

if (status === 401 || status === 403) {
  return new ToolAuthorizationError("PROVIDER_AUTHORIZATION_FAILED");
}

return new UnknownProviderError("UNKNOWN_PROVIDER_FAILURE");

这里的 429、401、403 只是教学 Demo 定义的 HTTP 供应商契约,不是所有供应商都必须遵守的通用标准。换一家供应商时,应该由它自己的 adapter 根据正式错误契约完成映射,Runtime 不需要解析供应商的自然语言报错。

错误进入 Runtime 后,是否重试仍然由两个条件共同决定:

js 复制代码
const canRetry = error instanceof TransientToolError;
const hasAttemptsLeft = attempt < maxToolAttempts;

if (!canRetry || !hasAttemptsLeft) {
  throw error;
}

canRetry 表示这种错误是否允许重试,hasAttemptsLeft 表示允许重试以后是否还有尝试次数。任一条件为假,当前操作都会立即终止。

测试里注入了一个 adapter 从未见过的 HTTP 599。它被转换成 UnknownProviderError,所以即使 maxToolAttempts = 3canRetry 仍然是 false,供应商实际只被调用了一次。

这也纠正了我当时的一个回答:代码里的 for 循环只能说明静态上限,测试中的 providerCalls === 1 才是这次 599 没有重复调用的运行证据。

今天还把 maxToolRetries 改成了 maxToolAttempts。前者需要记住"重试两次等于总共尝试三次"的隐含换算;后者直接表示包含首次调用在内的总尝试次数:

js 复制代码
for (let attempt = 1; attempt <= maxToolAttempts; attempt += 1) {
  // 执行工具
}

非法配置也会在第一次模型调用前显式失败:

js 复制代码
if (!Number.isInteger(maxToolAttempts) || maxToolAttempts < 1) {
  throw new InvalidRetryPolicyError(
    "MAX_TOOL_ATTEMPTS_MUST_BE_A_POSITIVE_INTEGER",
  );
}

因此 0、负数、小数和 NaN 都不会被静默修正,也不会继续进入模型与工具循环。对应测试观察到模型调用和工具调用都为零。

完整 Demo 一共有十条测试:429 在有限预算内重试,403 立即终止,陌生 599 立即终止,暂时性错误达到总尝试次数后停止,非法配置在生命周期开始前失败。实际运行结果是十条全部通过。

这些代码由 AI 生成并运行。我完成的是选择 maxToolAttempts 的计数语义、要求非法配置前置失败、决定在 provider adapter 统一供应商错误,并根据代码和调用计数解释 429、403 和 599 的不同结果。

我现在真正形成的判断是:供应商错误先由 adapter 归一化,Runtime 再依据稳定的内部错误类型和明确的尝试预算决定重试或终止。有剩余次数不等于获得重试授权;陌生错误在正式契约确认前应该失败关闭。对于可能已经成功的非幂等写操作,次数预算更不能代替幂等键、权限或人工确认。

相关推荐
AI小白Lin1 小时前
33 个 AI 专家全票通过?那问题才刚开始
人工智能·架构
Spey_Events1 小时前
【核心议题发布】聚焦深度维修与 AI 智慧革新!2026中国民用航空维修智造展——议题重磅发布!
大数据·人工智能
中杯可乐多加冰1 小时前
我把整个机器人足球仓库交给 Doubao-Seed-Evolving,它帮我优化了一套足球战术
人工智能
量化吞吐机1 小时前
2026年交易想法转Python,中间先补规则转译
人工智能·python
俊哥V1 小时前
每日 AI 研究简报 · 2026-07-22
人工智能·ai
XMAIPC_Robot1 小时前
RK3588四路1080P工业MIPI相机视觉网关,同时支持RK3588+FPGA的24路相机同步方案
人工智能·数码相机
决战灬1 小时前
langgraph之interrupt(事例篇)
人工智能·python·agent
czzxxxxxx1 小时前
创客匠人AI智能体:知识付费从“重人力”走向“自动化”的拐点
大数据·人工智能
依然范特东1 小时前
强化学习笔记2--bellman equation
人工智能·笔记