# R2.2.6 任务报告 ## 结果 - 完成纯分析 CLI 增强,未修改 Sub2API 配置、账号 runtime、YAML 或运行面。 - `runtime errors --all-groups` 默认使用 Kubernetes 风格概要表,支持所有分组概览和 `--group ` 精确下钻。 - 指定分组详情新增原生 `openai-token-stats` 模型时延表,以及原生 `request-errors` 的模型、账号、状态、同步/流式、阶段、入口和精确路径分布。 - 客户错误画像由 CLI 自动读取原生分页并完成统计,只对 request ID 样本做有界渐进披露,不要求用户手工调整 limit。 - `trace` 继续以原生 requests 和 system-logs 为主;requests 缺记录时只在同一 `--since` 窗口查询原生 request-errors,runtime 日志仅补原生索引缺失的事件。 ## 最近 60 分钟全分组证据 - 三个分组合计约 468 个请求、11 个客户可见错误,客户错误率约 2.35%,上游错误率约 4.70%。 - `unidesk-codex-pool`:约 61 至 67 个请求、7 个客户错误,窗口滚动错误率约 10.45% 至 11.48%。 - `自用`:407 个请求、4 个客户错误,错误率 0.98%。 - `grok`:窗口内无流量、无错误。 - 查询时并发约 8/218、队列为 0;当前快照不能代表错误瞬间,但没有证据支持把全局并发不足作为近期主因。 ## 分组根因 - `unidesk-codex-pool` 的 7 个客户错误全部是: - 模型 `gpt-5.6-luna`; - 账号 27; - 同步 `/v1/responses`; - 上游阶段; - 5 个 502、2 个 503。 - `自用` 的 4 个客户错误全部是: - 模型 `gpt-5.6-sol`; - 流式 `/responses`; - 账号 15 占 3 个 504,账号 27 占 1 个 502。 - 近期失败不是所有模型、账号和路径均匀恶化,而是两个窄错误簇。 ## request trace 证据 - `c76b05df-ad84-4055-bb5a-d363a77e94a1`:约 197.056 秒后账号 27 返回 503,首次 failover、下一次选号失败和最终 502 发生在同一毫秒,选号错误为 `context canceled`。 - `2c1211b5-1f9f-441a-9ef8-1f80795097cd`:约 50.863 秒后账号 27 返回 502,failover 与 `context canceled` 同时发生。 - `d66d7ea7-4e78-475c-8f93-b315435b79f7`:约 1772.971 秒后账号 15 返回上游 504,随后立即 `context canceled` 并包装成最终 502。 - `4ee54daa-f41c-4f50-bd72-11080c38e299`:约 730.835 秒后账号 27 返回 502,约 1 毫秒后 `context canceled`。 - 四个近期代表请求都已进入 failover;临时不可调度规则也有真实命中。直接传播点是 failover 开始时原请求上下文已经取消,不是缺少规则或没有触发切号。 ## v0.1.153 官方源码判断 - OpenAI Responses handler 的转发和下一次账号选择都复用 `c.Request.Context()`。 - 收到 `UpstreamFailoverError` 后 handler 记录失败账号并直接继续选号;若客户请求上下文已经取消,下一次选择会立即返回 `context canceled`。 - `gateway.openai_response_header_timeout` 是 v0.1.153 已有配置,作用范围是等待 OpenAI 上游 HTTP 响应头,不影响响应头之后的流式传输。 - v0.1.153 发布说明没有修复上述 failover 上下文生命周期问题,因此没有证据支持回退版本。 ## 候选方案 1. 配置级有界缓解,不涉及 Sub2API 源码变更: - 设置 OpenAI 专用 response-header timeout,可让真正卡在响应头前的 730 秒或 1773 秒请求更早转成 failover,从而保留切号窗口。 - 它不能解决 50 至 197 秒内已经返回的 502/503,也不能解决流式内容已经提交后的失败。 - 近期 TTFT P99 在分组 2 约 231 至 245 秒、分组 3 约 101 秒;TTFT 不是响应头时延,因此 255/270 秒只能作为排除过低值的观测下限,不能直接视为安全配置。 2. 精确源码方案,涉及 Sub2API 源码变更: - 增加响应头实际等待时长与首个语义流事件时长,区分响应头前等待和响应头后无事件。 - 在下游尚未提交且客户 deadline 仍有预算时,为单次上游尝试使用更短的 attempt context;超时后在原客户 context 内切号。 - 明确禁止在客户已经断开后继续后台重试,避免无效上游消耗。 3. 窄路由治理: - 分组 2 优先治理账号 27 的 `gpt-5.6-luna` 能力和错误分类;分组 3 优先治理账号 15/27 的 `gpt-5.6-sol` 长流式等待。 - 不建议用降低全池并发、账号 pinning、扩大临时不可调度时长或版本回退替代根因治理。 ## 验证 - `bun --check` 通过:`runtime.ts`、`remote-python-sync.ts`、`output.ts`。 - `bun test scripts/src/output.test.ts`:2 通过、0 失败。 - `git diff --check` 通过。 - 原入口读取验证通过:全分组概要、分组 2/3 详情、四个近期 request trace。 - 超过 3000 行的既有 `remote-python-sync.ts` 拆分已登记为 R2.2.7,本任务未混入大范围机械重构。