Files
pikasTech-unidesk/.agents/skills/unidesk-sub2api/references/troubleshooting-accounts.md
T
pikastech 31106a2ee0
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success
Pipelines as Code CI / platform-infra-gitea-nc01- Success
Pipelines as Code CI / unidesk-host- Success
chore: 合并并行工作区更新
2026-07-18 05:36:52 +02:00

12 KiB
Raw Blame History

账号池排障

客户可见错误与配置调优

  1. 先用 runtime errors --since <window> 获取全账号同窗口证据:
    • 以 Sub2API 原生 dashboard overview 的请求分母、客户错误率和上游错误率为主。
    • 以 account availability、concurrency 和 upstream errors 解释账号可用性、排队、状态码与根因。
    • 内部 monitor 使用真实 API key 和正式入口产生的错误必须纳入正式错误率、账号归因、trace 和调优判断;只单独标注调用方类别,不得因其不是外部客户而剔除或降级为测试噪声。
    • 原生 system-log 索引缺少策略事件时,才使用 target runtime 日志补临时不可调度、failover、account_select_failedforward_failed,并保留 fallback 披露。
  2. 从客户可见错误中选有限 request id 运行 trace,按请求链区分:
    • 上游失败后成功切号。
    • 切号后候选耗尽。
    • 首次选号即无候选。
    • HTTP 200 已提交流式响应后出现 forward_failed 的 degraded 请求。
  3. 规则证据必须同时包含真实 HTTP 状态码与响应体关键词:
    • 只有状态码、通用包装文案或推断出的原因不能扩展关键词。
    • 只有 account_temp_unschedulable 才证明规则命中;不能用相同状态码再次出现来推断规则失效。
    • 优先使用精确短语,避免把 context window、认证失败、模型不支持等不可互换错误混入通用不可用规则。
  4. 无候选或模型路由错误使用现有正式只读入口:
    • runtime get --account <selector> 读取账号配置和调度状态;runtime errors --account <selector> --full 读取原生 Ops 已观测模型证据。
    • 配置声明与已观测模型必须分开报告,不能把历史请求模型误当作实时上游能力。
    • 没有账号真实支持目标模型时,保持池不声明该模型并快速失败,不映射到名称相近的其他模型。
    • 没有原生实时能力接口时只能标记证据不足,不能据此补映射。
  5. 调优按所有权下发:
    • 非 auth 上游错误优先抽象为通用临时不可调度模板:
      • 规则同时使用真实状态码和已证实的稳定响应短语;
      • 先从当前 Sub2API 源码确认规则命中会在响应提交前触发当前请求 failover;
      • 禁止在模板、CLI 或源码中硬编码账号名称、账号 ID、provider URL 或分组特例;
      • 禁止用通用 400、通用 invalid request 或宽泛关键词覆盖真实客户参数错误;
    • auth、token revoked、余额不足、分组删除和凭据失效使用专门的认证与账号状态路径,不混入通用非 auth 模板;
    • 通用模板先修改 owning YAML,并保持冷却保守;默认从一分钟开始,没有新证据和明确授权不得超过三分钟。
    • YAML-managed 账号走 syncruntime-manual 账号走显式 runtime apply|delete
    • 多账号使用 --accounts 精准集合;例外账号从 selector 中显式排除,不使用隐式全量操作。
    • 先 dry-run 核对 change、before/after 和账号集合,再加 --confirm,最后逐账号 get 或批量 noop dry-run 对账。
  6. 不把当前并发快照当作错误时并发:
    • 只有错误原文明确指向 concurrency,或存在错误时历史并发证据,才把降低上游并发作为有界对照实验。
    • 缺少直接证据时先处理主导上游根因。
  7. 下发后立即拉短窗口只做回归检查:
    • 效果判定必须等待新的完整窗口。
    • 同时比较请求分母、客户错误率、上游错误率、规则命中、切号成功、候选耗尽和 degraded 流式请求。
  8. 版本回退必须有源码差异或版本对照证据证明当前版本引入回归:
    • 旧版具有同一选择或错误传播逻辑时,不用回退替代配置治理。
    • 新版包含相关 failover 修复时,优先保留新版并治理真实根因。
  • Codex pool 哨兵、账号冻结/恢复、marker-only 判断或 probe 周期看不清:第一步跑 bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-report。这个报表是主观察面;只有报表缺字段或需要底层证据时,才继续看 --raw、CronJob log、state ConfigMap 或 Sub2API 管理 UI。若看到“临时不可调度状态”且包含规则序号/匹配关键词,检查 Sub2API account_temp_unschedulable 日志和账号 temp_unschedulable_* 字段;sentinel 只解释 schedulable=false 的 active quarantine,不解释这类内置临时冷却。
  • 只加强监控、不让哨兵自动冻结账号时,把 YAML sentinel.actions.enabled=falsecodex-pool sync --confirm。此时 marker probe 和 gateway failure monitor 仍记录 would-freeze / observe-only 证据,但不会通过 Sub2API admin 写 schedulable=false/responses/compactcodex.remote_compact.failed 和 compact 上游 5xx failover 只作为 gateway-compact-* 观察事件记录,不作为哨兵自动切换触发器。
  • 单个 request id 报 502/503/中断/没有自动切号:第一步跑 bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id <requestId>。先看 outcomereasonFAILOVERSELECT-FAILEDACCOUNT SIGNALSWINDOW STATS;只有 trace 报表缺字段或需要审计原始日志时,才加 --show-lines--raw。若 reason=failover-attempted-no-candidate,说明切号动作已发生,但 scheduler 在排除失败账号后没有可用候选;继续用 sentinel-reportvalidate --full 区分 sentinel quarantine、request-path temp-unschedulable、账号 status 或容量耗尽。
  • profile invalid:先修 ~/.codex/config.toml.<profile>base_urlwire_apimodelauth.json.<profile> 的 API key;不要在 YAML 中写密钥。
  • 手动 OAuth/API-key 账号的 WebUI account test 连 chatgpt.com 超时,但目标运行面显式 HTTP proxy 探针可通:不要只看 Pod 或容器环境变量,按“受保护手动账号代理与分组绑定”小节确认 manualAccounts.protected[].proxyBinding,跑 codex-pool sync --target <id> --confirm 后再用原账号测试复测。若复测不再 reset/timeout,而是 gpt-5.2-pro 这类指定模型返回 ChatGPT OAuth Codex 不支持的能力错误,用默认/受支持模型或统一 key smoke 验证代理,不要把模型错误当作代理仍坏。
  • 手动 OAuth/API-key 账号 WebUI account test 正常,但 PC Codex 客户端通过统一 key 访问 /responses 返回 503 且 trace 是 account-select-failed / no available accounts:按“受保护手动账号代理与分组绑定”小节确认该账号已绑定统一 key 使用的 pool group。WebUI group 列表和账号详情不一定足以证明 scheduler 可调度;必要时核对 admin account availability 与 account_groups join。k3s target 和 PK01 host-Docker target 都通过 codex-pool sync --target <id> --confirm 后用 codex-pool validate --target <id> --full 复测统一 key;如果 MANUAL=N 指向受保护手动账号缺失,先按账号所有权恢复或退役该手动账号,不把它混同为 YAML-managed pool 账号失败。
  • pool key 401:跑 codex-pool sync --confirm 重建 Sub2API key 与 k3s Secret 绑定,再跑 codex-pool validate
  • pool key、admin password 或 k8s Secret .data 被 stdout、日志、issue 或本地 transcript 打印时,按泄露处理:撤销对应 Sub2API key 或 token,删除/重建受影响的 target Secret,通过 codex-pool sync --target <id> --confirm 或相应 YAML sourceRef 重新下发,再用 fingerprint、presence 和 valuesPrinted=false 作为 closeout 证据;不要复述旧值或新值。
  • 运行中过去的验证探针残留:只用 codex-pool cleanup-probes --confirm 清理 unidesk-probe-* 临时资源;不要把真实 managed account 删除当作探针清理或可用性恢复。
  • default profile 递归:检查 YAML default entry 是否使用 *.pre-sub2api 备份文件;必要时恢复备份后重新 configure-local --confirm
  • 上游需要 WebSocket v2:先做 direct Codex WSv2 probe;通过后才给该 profile 配 openaiResponsesWebSocketsV2Mode: ctx_pool|passthrough 并跑 sync --confirm;把它当 capability candidate,容量仍以 YAML 中的 capacity 或默认值为准。
  • Codex 启动 WebSocket 回退:用原入口 Codex smoke 复现,再用 bounded Sub2API 日志确认 account;对 WS handshake 4xx/5xx、openai.websocket_account_select_failed 或 close-before-response.completed 的账号关闭 YAML WSv2 能力后同步。若没有剩余 WSv2-capable account,把 localCodex.supportsWebSocketslocalCodex.responsesWebSocketsV2 一起关掉,不把临时可用性推断写成调度配置。
  • 上游要求 Codex User-Agent:只给该 profile 配 upstreamUserAgent,跑 sync --confirm
  • 上游报 capacity/rate-limit/overload/Bad Gateway/Gateway Timeout 后没有隔离或频繁先失败再恢复:先看 codex-pool sentinel-report 的 marker、动作、冻结 TTL 和下一次 probe,也看 codex-pool validate --full 的 recent gateway failover/forward failure 证据;同时对照当前 Sub2API 源码里 /v1/responses handler、ForwardshouldFailoverOpenAIUpstreamResponsehandleOpenAIAccountUpstreamError 的真实传播路径。不要手动禁用账号、删除账号、改 membership/priority/capacity/loadFactor 或从 YAML 移除问题账号来替代通用 failover 与哨兵隔离/恢复。
  • Codex 报 weekly-limit、less than 10% of your weekly limit leftRun /status for a breakdown 等账号状态/软配额提示并要求切号:不要把新关键词写成 Sub2API 内置临时不可调度策略来恢复可用性;由 marker-only 哨兵按非 marker 响应统一冻结,并用 sentinel-report / sentinel-probe 验证。
  • 上游 400/503 响应体出现 invalid_encrypted_contentbad_response_status_codeinvalid_request_error + 稳定 unsupported-model 文案、unsupported-model、暂不支持 / 可用模型model_not_foundNo available channel for model ... 或同类稳定模型路由 / Responses encrypted-content 兼容性失败:按通用 temp-unschedulable/failover 加哨兵 marker 证据处理,不用 account membership、priority、capacity、loadFactor、WebSocket mode、User-Agent 或 provider pinning 掩盖该错误族。
  • 上游错误反复触发:invalid_encrypted_content、unsupported-model、Recovered upstream error ...Bad GatewayGateway Timeout、Cloudflare 524、Codex-facing Upstream request failedUnknown errorcontext deadline exceededcontext canceledmodel_not_foundNo available channel for model、大上下文 413openai_error 这类稳定包装文案,先确认 YAML temp-unschedulable 已同步、Sub2API 源码会把该错误族传播成 UpstreamFailoverError、运行日志出现 openai.upstream_failover_switching。若匹配规则后仍只看到 openai.forward_failed,根因是 Sub2API HTTP /responses 没把该错误传播成 UpstreamFailoverError,应修 Sub2API failover classifier/error propagation,不硬编码账号或给 only 特权。
  • Codex auto compact 后丢上下文:先确认 YAML localCodex 是否声明启用 WSv2;若启用,再确认本机 ~/.codex/config.toml 是否有 supports_websockets = trueresponses_websockets_v2 = true,并看 codex-pool validate 的 WSv2 candidate 和 Sub2API 日志里的 transport=responses_websockets_v2。若 YAML 当前禁用 WSv2,则按 HTTP Responses 稳定性排查,不把旧 WS 口径当成验收要求。
  • Codex smoke 有 reconnect/1013:这是上游并发/可用性问题,和 HTTP-only compact context-loss 分开处理;记录 session/log 证据并关联专项 issue,不要用运行时手补覆盖 YAML 容量。