Skip to content

[BUG]ac run --prompt(Codex)在 LLM 上游异常时因 guest 侧重试过多,无法在 LLM_TIMEOUT 内有界失败 #264

Description

@qinhn525

摘要

Runtime LLM Facade 已按 LLM_TIMEOUT 对单次上游 HTTP 快速失败/超时返回,但 guest 内 Codex 配置了很高的重试次数。上游持续异常时,Codex 会反复重试,整条 ac run --prompt 长时间挂起,CLI 无法在合理时间内非 0 退出,也难以给出可诊断的上游错误信息。

现象

provider: codex 的 agent 执行:

ac run <agent> --prompt '...'

当上游(经 Runtime LLM Facade)出现断连、读超时、HTTP 503、畸形响应等时:

  • Facade 单次调用能按 LLM_TIMEOUT 较快返回错误;
  • 整次 CLI / run 仍会长时间挂起;
  • 用户侧更像“卡住”,而不是快速失败并看到清晰的上游错误。

对照:上游返回 HTTP 429 时,Codex 会较快放弃重试,CLI 能较快非 0 退出。

预期行为

LLM 上游持续不可用或明确失败时:

  1. 整条 ac run --prompt 应在有界时间内结束(受 LLM_TIMEOUT + 有限重试预算约束);
  2. CLI 非 0 退出;
  3. 错误信息能说明是上游超时、5xx、断连或响应无法解析。

实际行为

上游故障 Facade 单次 整条 CLI / run
断连 约在 LLM_TIMEOUT 内失败 长时间挂起
延迟超过 LLM_TIMEOUT 客户端超时 长时间挂起
503 透传 503 长时间挂起
畸形响应 快速失败/透传 长时间挂起
429 透传 429 较快非 0 退出

根因

调用链:ac run --prompt → guest Codex → Runtime LLM Facade → 上游 LLM

  • Facade:按 LLM_TIMEOUT 发起单次 HTTP,不重试;网络错误返回 502,非 2xx 透传。
  • Codex 运行时配置(WriteCodexRuntimeConfig)写死了较高重试:
request_max_retries = 30
stream_max_retries = 50
stream_idle_timeout_ms = 120000

因此 Facade 已经“快失败”,但 Codex 把多数上游失败当成可重试错误,在 guest 侧把延迟放大了几十倍。再加上 agent 默认超时很长、CLI 前台 run 无整体 deadline,最终表现为整次执行被重试拖死。

Daemon 对 429 与 503 都是透传;差异主要在 Codex:429 会较快停重试,503/断连/畸形响应会长时间重试。

影响

  • 上游异常时 CLI 像卡死,体验差、难排查;
  • 异常上游会被重试打满,放大错误流量。

建议方向

  1. 下调或可配置 Codex 的 request_max_retries / stream_max_retries / stream_idle_timeout_ms
  2. 对明确不可恢复错误快速失败,并与 429 的失败策略对齐;
  3. 为 prompt run 增加合理的 run/agent 级 timeout;
  4. CLI run --prompt 增加可选整体 deadline。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions