ops: 配置自定义 OpenAI Provider 模型并受控验证 #54

Open
opened 2026-08-25 11:39:45 +08:00 by ila · 15 comments
Owner

基本信息

  • 类型:配置与受控验证
  • 所属 Epic:#3
  • 所属 MVP / 版本:#35 / MVP-2 交付验证
  • 阶段:待实施(前置 #55 已于 2026-08-27 验收通过)

原始需求

  • 来源:用户对话
  • 提出时间:2026-08-25
  • 用户目的(脱敏):读取本地受保护的 Provider/Model 配置文件,将一个 OpenAI-compatible Provider、文本模型和图片模型写入系统,并验证是否可用。

已确认方案

  • Provider:外部公开 HTTP OpenAI-compatible /v1 端点,Bearer 凭据仅从本地未跟踪文件读取。
  • 文本模型:chat 协议,能力 text。
  • 图片模型:images 协议,能力 image_generate。
  • 复用或建立对应 PromptTemplate、RoutePool 并发布活动路由。
  • 最多执行一次低成本生文和一次文生图真实请求;不循环试错。

做什么 / 不做什么

  • 做:通过现有管理 API 创建/更新 Provider、凭据、ProviderModel、模板与活动路由;通过 Portal 生成链路验证 worker、attempt 和结果;记录脱敏结果。
  • 不做:记录或回显完整 API Key;修改 SSRF、重试、限流或 Provider 协议代码;反复消耗真实额度;配置图片编辑能力(源文件没有独立编辑模型信息)。

安全边界

  • openai_provider_model.txt 已加入本仓库本地 .git/info/exclude,不提交到 Git。
  • API Key 不进入代码、命令输出、日志、工单、Wiki、截图或错误摘要。
  • 400/401/内容策略拒绝立即停止;429/5xx/超时/连接错误仅按系统既有语义处理,不人工循环重试。

验收标准

  • Provider 与两个 Model 通过管理 API 写入,列表接口只显示凭据元数据。
  • text 与 image_generate 各有一个启用并发布的活动路由。
  • 一次生文和一次文生图任务形成可审计终态;成功则核对结果,失败则记录脱敏错误和停止原因。
  • 不泄露凭据,不调用图片编辑,不影响用户已有无关配置。

文档影响

  • 若真实上游协议或运行步骤出现长期差异,更新 Wiki;仅本机配置数据和一次验证结果则记录任务归档,不写入核心文档。

风险与回退

真实请求可能产生少量上游费用。回退时停用本任务创建的路由、模型和 Provider,不删除审计或生成记录,不恢复已退役凭据。

## 基本信息 - 类型:配置与受控验证 - 所属 Epic:#3 - 所属 MVP / 版本:#35 / MVP-2 交付验证 - 阶段:待实施(前置 #55 已于 2026-08-27 验收通过) ## 原始需求 - 来源:用户对话 - 提出时间:2026-08-25 - 用户目的(脱敏):读取本地受保护的 Provider/Model 配置文件,将一个 OpenAI-compatible Provider、文本模型和图片模型写入系统,并验证是否可用。 ## 已确认方案 - Provider:外部公开 HTTP OpenAI-compatible `/v1` 端点,Bearer 凭据仅从本地未跟踪文件读取。 - 文本模型:`chat` 协议,能力 `text`。 - 图片模型:`images` 协议,能力 `image_generate`。 - 复用或建立对应 PromptTemplate、RoutePool 并发布活动路由。 - 最多执行一次低成本生文和一次文生图真实请求;不循环试错。 ## 做什么 / 不做什么 - 做:通过现有管理 API 创建/更新 Provider、凭据、ProviderModel、模板与活动路由;通过 Portal 生成链路验证 worker、attempt 和结果;记录脱敏结果。 - 不做:记录或回显完整 API Key;修改 SSRF、重试、限流或 Provider 协议代码;反复消耗真实额度;配置图片编辑能力(源文件没有独立编辑模型信息)。 ## 安全边界 - `openai_provider_model.txt` 已加入本仓库本地 `.git/info/exclude`,不提交到 Git。 - API Key 不进入代码、命令输出、日志、工单、Wiki、截图或错误摘要。 - 400/401/内容策略拒绝立即停止;429/5xx/超时/连接错误仅按系统既有语义处理,不人工循环重试。 ## 验收标准 - [x] Provider 与两个 Model 通过管理 API 写入,列表接口只显示凭据元数据。 - [x] text 与 image_generate 各有一个启用并发布的活动路由。 - [ ] 一次生文和一次文生图任务形成可审计终态;成功则核对结果,失败则记录脱敏错误和停止原因。 - [ ] 不泄露凭据,不调用图片编辑,不影响用户已有无关配置。 ## 文档影响 - 若真实上游协议或运行步骤出现长期差异,更新 Wiki;仅本机配置数据和一次验证结果则记录任务归档,不写入核心文档。 ## 风险与回退 真实请求可能产生少量上游费用。回退时停用本任务创建的路由、模型和 Provider,不删除审计或生成记录,不恢复已退役凭据。
Author
Owner

用户已于 2026-08-25 明确授权:允许对本机 chorus 数据库执行 migration 5 → 8。将先备份并停止 Portal/Admin API,迁移后核对版本,再继续配置与单次真实验证。

用户已于 2026-08-25 明确授权:允许对本机 `chorus` 数据库执行 migration 5 → 8。将先备份并停止 Portal/Admin API,迁移后核对版本,再继续配置与单次真实验证。
Author
Owner

2026-08-25 受控验证结果与阻塞

  • 已经用户明确授权,将本机 chorus 数据库从 migration 5 升级到 8;升级前已创建仓库外备份,up 执行成功。
  • Provider、两个 ProviderModel、模板和两条活动路由已通过现有管理 API 写入;凭据未进入列表响应、日志或工单。
  • 已分别提交一次文本与图片生成,均形成失败终态且各记录 1 次 provider attempt;统一脱敏错误为 route_unavailable / upstream request failed,没有输出结果。
  • 只读诊断确认:上游地址 TCP 可达,携带本地凭据读取 /models 返回 HTTP 200,说明地址与凭据有效;配置文件中的两个精确模型名不在该列表中。
  • 本地请求在约 1ms 内失败的直接原因是生产 SSRF SafeHTTP 默认只允许 80/443,而该 Provider 使用 8080,请求在连接前被拒绝。因此尚未证明两个模型能够真实生成。

停止原因

当前工单明确不修改 SSRF。建议另建高风险单元工单:增加显式的 CHORUS_PROVIDER_ALLOWED_PORTS 环境配置,默认保持 80,443,本机设为 80,443,8080;Portal worker 与管理端连通性探针共用此配置,现有 DNS 后/Dial 前私网拦截、重定向和结果 URL 校验保持不变。需要用户确认该安全边界变化后才能实施。完成后仍需先解决或确认上游模型标识,再各做至多一次受控复验。

## 2026-08-25 受控验证结果与阻塞 - 已经用户明确授权,将本机 `chorus` 数据库从 migration 5 升级到 8;升级前已创建仓库外备份,up 执行成功。 - Provider、两个 ProviderModel、模板和两条活动路由已通过现有管理 API 写入;凭据未进入列表响应、日志或工单。 - 已分别提交一次文本与图片生成,均形成失败终态且各记录 1 次 provider attempt;统一脱敏错误为 `route_unavailable / upstream request failed`,没有输出结果。 - 只读诊断确认:上游地址 TCP 可达,携带本地凭据读取 `/models` 返回 HTTP 200,说明地址与凭据有效;配置文件中的两个精确模型名不在该列表中。 - 本地请求在约 1ms 内失败的直接原因是生产 SSRF SafeHTTP 默认只允许 80/443,而该 Provider 使用 8080,请求在连接前被拒绝。因此尚未证明两个模型能够真实生成。 ### 停止原因 当前工单明确不修改 SSRF。建议另建高风险单元工单:增加显式的 `CHORUS_PROVIDER_ALLOWED_PORTS` 环境配置,默认保持 `80,443`,本机设为 `80,443,8080`;Portal worker 与管理端连通性探针共用此配置,现有 DNS 后/Dial 前私网拦截、重定向和结果 URL 校验保持不变。需要用户确认该安全边界变化后才能实施。完成后仍需先解决或确认上游模型标识,再各做至多一次受控复验。
Author
Owner

2026-08-25 用户端复现后的进一步诊断

  • 用户在 #55 部署并重启后提交了一次图片生成;generation 形成失败终态,provider attempt 耗时约 591ms,retryable=false,脱敏错误为 upstream_unknown / upstream request failed。
  • 与此前约 1ms 的 route_unavailable 不同,这次已经越过出站端口白名单并到达上游,证明 #55 的本机配置生效。
  • 再次执行不产生生成费用的 /models 元数据比对:HTTP 200,共公布 10 个模型;当前配置的文本、图片模型均不存在,公布列表中也没有名称可识别的图片生成模型。
  • 因此当前阻塞已从本地 SSRF 端口策略转为上游模型/能力不匹配。配置文件中的图片模型名疑似拼写错误,但不得猜测替换;文本模型同样未被上游公布。

停止条件

不再提交真实生成请求。需要 Provider 方提供该地址实际支持的精确文本模型、图片模型,以及图片是否实现 OpenAI-compatible /images/generations 和 b64_json/URL 响应契约。若该地址没有图片能力,则应停用 image_generate 路由并改用另一个 Provider。

## 2026-08-25 用户端复现后的进一步诊断 - 用户在 #55 部署并重启后提交了一次图片生成;generation 形成失败终态,provider attempt 耗时约 591ms,`retryable=false`,脱敏错误为 `upstream_unknown / upstream request failed`。 - 与此前约 1ms 的 `route_unavailable` 不同,这次已经越过出站端口白名单并到达上游,证明 #55 的本机配置生效。 - 再次执行不产生生成费用的 `/models` 元数据比对:HTTP 200,共公布 10 个模型;当前配置的文本、图片模型均不存在,公布列表中也没有名称可识别的图片生成模型。 - 因此当前阻塞已从本地 SSRF 端口策略转为上游模型/能力不匹配。配置文件中的图片模型名疑似拼写错误,但不得猜测替换;文本模型同样未被上游公布。 ### 停止条件 不再提交真实生成请求。需要 Provider 方提供该地址实际支持的精确文本模型、图片模型,以及图片是否实现 OpenAI-compatible `/images/generations` 和 `b64_json`/URL 响应契约。若该地址没有图片能力,则应停用 image_generate 路由并改用另一个 Provider。
Author
Owner

2026-08-25 模型改名后核对

  • 系统图片 ProviderModel 已于 14:30:52 更新为 gpt-image-2;本地受保护源文件仍保留旧拼写,二者当前不一致。
  • 最新失败 generation #4 创建于 14:29:27、完成于 14:29:29,早于模型更新时间,因此该失败任务并未使用更新后的名称;当前没有改名后的新 generation 证据。
  • 但上游 /models 实际公布的 10 个 ID 全部是 Claude 文本模型(fable/opus/sonnet/haiku 系列),没有任何 GPT 或图片模型。因此 gpt-image-2 与 gpt-5.6-sol 都不是该地址公布的模型,不能继续按这两个 ID 验证。
  • 对两个协议路径执行不带生成正文的 OPTIONS 元数据检查均被网关统一返回 403,无法用 OPTIONS 证明图片端点存在;未提交新的真实生成请求。

需要确认的配置变化

若继续使用当前地址,只能从其 /models 公布列表中选择一个文本模型做 chat 验证;图片生成需要 Provider 方提供另一个明确支持 /images/generations 的地址和精确模型 ID。不得猜测图片模型或继续反复试错。

## 2026-08-25 模型改名后核对 - 系统图片 ProviderModel 已于 14:30:52 更新为 `gpt-image-2`;本地受保护源文件仍保留旧拼写,二者当前不一致。 - 最新失败 generation #4 创建于 14:29:27、完成于 14:29:29,早于模型更新时间,因此该失败任务并未使用更新后的名称;当前没有改名后的新 generation 证据。 - 但上游 `/models` 实际公布的 10 个 ID 全部是 Claude 文本模型(fable/opus/sonnet/haiku 系列),没有任何 GPT 或图片模型。因此 `gpt-image-2` 与 `gpt-5.6-sol` 都不是该地址公布的模型,不能继续按这两个 ID 验证。 - 对两个协议路径执行不带生成正文的 OPTIONS 元数据检查均被网关统一返回 403,无法用 OPTIONS 证明图片端点存在;未提交新的真实生成请求。 ### 需要确认的配置变化 若继续使用当前地址,只能从其 `/models` 公布列表中选择一个文本模型做 chat 验证;图片生成需要 Provider 方提供另一个明确支持 `/images/generations` 的地址和精确模型 ID。不得猜测图片模型或继续反复试错。
Author
Owner

2026-08-25 API Key 更新后 /models 核对

  • 通过管理 API 单条读取系统当前 Provider 凭据并仅在内存中用于一次 /models 查询;Provider 保持 bearer 且启用。
  • 系统当前 Provider 地址 + 当前 credential version 2 返回 HTTP 401,未取得模型列表,因此不能确认 gpt-image-2。
  • 本地受保护配置文件与系统当前地址、Key 均不一致;文件中的组合查询返回 HTTP 404。
  • 未输出或记录地址、Key、响应正文,未发起生成请求。

需要先修正系统 Provider 的地址/Key 配对,使 /models 返回 200,再检查精确模型 ID。

## 2026-08-25 API Key 更新后 `/models` 核对 - 通过管理 API 单条读取系统当前 Provider 凭据并仅在内存中用于一次 `/models` 查询;Provider 保持 `bearer` 且启用。 - 系统当前 Provider 地址 + 当前 credential version 2 返回 HTTP 401,未取得模型列表,因此不能确认 `gpt-image-2`。 - 本地受保护配置文件与系统当前地址、Key 均不一致;文件中的组合查询返回 HTTP 404。 - 未输出或记录地址、Key、响应正文,未发起生成请求。 需要先修正系统 Provider 的地址/Key 配对,使 `/models` 返回 200,再检查精确模型 ID。
Author
Owner

API Key 更新为 credential version 3 后,使用系统当前 Provider 配置查询 /models 返回 HTTP 200,共 21 个模型;已确认精确包含 gpt-image-2,同时公布 gpt-image-1 和 gpt-image-1.5。本次仅查询模型元数据,未发起生成请求,未记录凭据。

API Key 更新为 credential version 3 后,使用系统当前 Provider 配置查询 `/models` 返回 HTTP 200,共 21 个模型;已确认精确包含 `gpt-image-2`,同时公布 `gpt-image-1` 和 `gpt-image-1.5`。本次仅查询模型元数据,未发起生成请求,未记录凭据。
Author
Owner

2026-08-25 credential v3 后最新图片失败诊断

  • Provider credential version 3 于 14:39:20 生效;最新 image generation #6 于 14:40:27 创建,确认使用的是新凭据时期配置。
  • provider attempt 从 14:40:28 到 14:41:13,latency 45,002ms,retryable=true,终态 route_unavailable。
  • /models 已返回 200 并精确公布 gpt-image-2,因此本次不是模型不存在或 400/401。
  • 45 秒与 Portal 当前 CHORUS_PROVIDER_HTTP_TIMEOUT_SECONDS 默认值完全吻合;ProviderModel 虽配置更长 timeout_ms,但共享 SafeHTTP 的 45 秒总超时先触发。

结论:本次失败是等待上游响应超时。建议把 Provider HTTP timeout 调到 120 秒,同时把 worker lease 调到至少 126 秒(建议 150 秒),满足“lease 必须比 HTTP timeout 多 5 秒以上”;重启 Portal 后只做一次图片复验。该配置变化尚未执行,等待用户确认。

## 2026-08-25 credential v3 后最新图片失败诊断 - Provider credential version 3 于 14:39:20 生效;最新 image generation #6 于 14:40:27 创建,确认使用的是新凭据时期配置。 - provider attempt 从 14:40:28 到 14:41:13,latency 45,002ms,`retryable=true`,终态 `route_unavailable`。 - `/models` 已返回 200 并精确公布 `gpt-image-2`,因此本次不是模型不存在或 400/401。 - 45 秒与 Portal 当前 `CHORUS_PROVIDER_HTTP_TIMEOUT_SECONDS` 默认值完全吻合;ProviderModel 虽配置更长 timeout_ms,但共享 SafeHTTP 的 45 秒总超时先触发。 结论:本次失败是等待上游响应超时。建议把 Provider HTTP timeout 调到 120 秒,同时把 worker lease 调到至少 126 秒(建议 150 秒),满足“lease 必须比 HTTP timeout 多 5 秒以上”;重启 Portal 后只做一次图片复验。该配置变化尚未执行,等待用户确认。
Author
Owner

2026-08-25 Portal YAML 重启后图片任务 #7 诊断

  • Portal 于 15:17:13 使用 --config portal/config/settings.yml 启动;generation #7 于 15:17:42 创建,确定使用新 YAML 和 credential version 3。
  • provider attempt 耗时 120,002ms 后失败,retryable=true,终态 route_unavailable;相较 #6 的 45,002ms,证明全局 HTTP timeout 已从 45 秒变为 120 秒。
  • ProviderModel #4 为 gpt-image-2 / images,启用,模型级 timeout_ms=120000。因此全局 SafeHTTP 与模型请求上下文都在 120 秒到期。
  • /models 已确认模型存在,当前凭据能返回 200;本次没有 400/401/模型不存在证据。

结论与下一步

直接原因是上游在 120 秒内没有返回。客户端侧无法区分正常生成较慢、上游排队或图片端点挂起。建议下一次受控验证同时把 YAML provider.http_timeout_seconds 调到 300、worker.lease_seconds 调到 360,并把管理端 ProviderModel timeout_ms 调到 300000;重启 Portal 后只提交一次图片任务。若仍在 300 秒整超时,应停止客户端扩时并检查 Provider 网关日志/图片协议支持。

本轮只读诊断,没有自动提交生成请求或修改配置。

## 2026-08-25 Portal YAML 重启后图片任务 #7 诊断 - Portal 于 15:17:13 使用 `--config portal/config/settings.yml` 启动;generation #7 于 15:17:42 创建,确定使用新 YAML 和 credential version 3。 - provider attempt 耗时 120,002ms 后失败,`retryable=true`,终态 `route_unavailable`;相较 #6 的 45,002ms,证明全局 HTTP timeout 已从 45 秒变为 120 秒。 - ProviderModel #4 为 `gpt-image-2 / images`,启用,模型级 `timeout_ms=120000`。因此全局 SafeHTTP 与模型请求上下文都在 120 秒到期。 - `/models` 已确认模型存在,当前凭据能返回 200;本次没有 400/401/模型不存在证据。 ### 结论与下一步 直接原因是上游在 120 秒内没有返回。客户端侧无法区分正常生成较慢、上游排队或图片端点挂起。建议下一次受控验证同时把 YAML `provider.http_timeout_seconds` 调到 300、`worker.lease_seconds` 调到 360,并把管理端 ProviderModel `timeout_ms` 调到 300000;重启 Portal 后只提交一次图片任务。若仍在 300 秒整超时,应停止客户端扩时并检查 Provider 网关日志/图片协议支持。 本轮只读诊断,没有自动提交生成请求或修改配置。
Author
Owner

#58 受控复验结果:generation #8 仅调用上游 1 次并成功,Provider 审计耗时 70331 ms,生成 1 个受保护输出。由此确认 gpt-image-2、当前凭据和 OpenAI-compatible 图片链路可用;此前 45/120 秒失败属于超时窗口过短。#58 已进入待验收,未重复消耗上游额度。

#58 受控复验结果:generation #8 仅调用上游 1 次并成功,Provider 审计耗时 70331 ms,生成 1 个受保护输出。由此确认 `gpt-image-2`、当前凭据和 OpenAI-compatible 图片链路可用;此前 45/120 秒失败属于超时窗口过短。#58 已进入待验收,未重复消耗上游额度。
Author
Owner

重启后 generation #9 失败诊断(2026-08-25)

  • Portal 进程携带 --config,实际 YAML 仍为 Provider HTTP 300 秒、worker lease 360 秒;ProviderModel #4 仍为 300000 ms。
  • generation #9 使用与成功的 #8 相同的路由池、路由成员和 ProviderModel;Prompt 长度相近,模型 extra_body 为空。
  • #9 底层 Provider attempt 仅 1 次,latency_ms=300014、retryable=true、底层错误 upstream_timeout,无输出。
  • 路由池只有 1 个成员且 max_failover=0,所以超时后没有第二家可切换,生成最终错误被汇总为 route_unavailable;页面显示通用 upstream request failed。
  • 对比:#8 同一路由和模型在 70331 ms 成功。结论是当前 Provider 图片端点响应具有明显波动或偶发挂起,不是重启后超时配置丢失,也不符合模型不存在、凭据无效或内容策略拒绝的错误特征。
  • 本次只读取本机审计和配置,没有再次调用真实上游。建议不继续提高单请求超时;优先增加第二个独立图片 Provider/模型作为 failover,或与上游确认其 300 秒挂起原因。
## 重启后 generation #9 失败诊断(2026-08-25) - Portal 进程携带 `--config`,实际 YAML 仍为 Provider HTTP 300 秒、worker lease 360 秒;ProviderModel #4 仍为 300000 ms。 - generation #9 使用与成功的 #8 相同的路由池、路由成员和 ProviderModel;Prompt 长度相近,模型 `extra_body` 为空。 - #9 底层 Provider attempt 仅 1 次,`latency_ms=300014`、`retryable=true`、底层错误 `upstream_timeout`,无输出。 - 路由池只有 1 个成员且 `max_failover=0`,所以超时后没有第二家可切换,生成最终错误被汇总为 `route_unavailable`;页面显示通用 `upstream request failed`。 - 对比:#8 同一路由和模型在 70331 ms 成功。结论是当前 Provider 图片端点响应具有明显波动或偶发挂起,不是重启后超时配置丢失,也不符合模型不存在、凭据无效或内容策略拒绝的错误特征。 - 本次只读取本机审计和配置,没有再次调用真实上游。建议不继续提高单请求超时;优先增加第二个独立图片 Provider/模型作为 failover,或与上游确认其 300 秒挂起原因。
Author
Owner

补充对比结论(2026-08-25)

  • generation #9 从创建到 Provider attempt 开始约 76 ms,300014 ms 基本全部消耗在上游 HTTP 阶段,不是 Chorus 队列、worker 认领或图片落库变慢。
  • Chorus 文生图请求固定调用 /v1/images/generations,JSON 字段为 model、prompt、n=1、response_format=b64_json;当前模型没有 size、quality 等 extra_body。
  • #8 成功输出约 0.82 MB,说明正常 Base64 响应体规模不至于解释额外 230 秒;#9 没有形成输出。
  • 本机可定位到的另一个 GPT Image 2 项目实际使用不同主机、/images/edits 图片编辑端点且默认 600 秒超时,不能作为同条件对照。本机未找到另一个使用当前主机和 /images/generations 的实现。
  • 同 URL/模型之外,API Key 对应上游租户、端点、Prompt、response_format、size/quality、代理和并发都可能改变耗时。现有安全审计没有 DNS/连接/TTFB/响应体分段,因此精确定位需要先增加不记录凭据或正文的 HTTP 阶段计时,再由用户授权一次同请求 A/B。
## 补充对比结论(2026-08-25) - generation #9 从创建到 Provider attempt 开始约 76 ms,300014 ms 基本全部消耗在上游 HTTP 阶段,不是 Chorus 队列、worker 认领或图片落库变慢。 - Chorus 文生图请求固定调用 `/v1/images/generations`,JSON 字段为 `model`、`prompt`、`n=1`、`response_format=b64_json`;当前模型没有 `size`、`quality` 等 extra_body。 - #8 成功输出约 0.82 MB,说明正常 Base64 响应体规模不至于解释额外 230 秒;#9 没有形成输出。 - 本机可定位到的另一个 GPT Image 2 项目实际使用不同主机、`/images/edits` 图片编辑端点且默认 600 秒超时,不能作为同条件对照。本机未找到另一个使用当前主机和 `/images/generations` 的实现。 - 同 URL/模型之外,API Key 对应上游租户、端点、Prompt、`response_format`、size/quality、代理和并发都可能改变耗时。现有安全审计没有 DNS/连接/TTFB/响应体分段,因此精确定位需要先增加不记录凭据或正文的 HTTP 阶段计时,再由用户授权一次同请求 A/B。
Author
Owner

补充对照结论(2026-08-25,已按用户更正核对 D:\chengma\cmhub,未执行真实上游调用):

  • cmhub 即使使用相同 Provider URL、模型名和凭据,也不代表请求协议与 Chorus 相同。
  • cmhub 的既定架构中,gpt-image-2 配置为 images_edits,调用 /v1/images/edits,使用 multipart 并要求原图;Chorus 当前任务调用 /v1/images/generations,JSON 请求且固定 response_format=b64_json。两者不是同一种生成请求。
  • 若 cmhub 中该配置实际仍为 api_type=auto 且 URL 仅到 /v1,其代码会将其解析为 chat 并调用 /v1/chat/completions,同样不会走 Chorus 当前的 images generations 路径。
  • cmhub 异步生图对 upstream_timeout/upstream_error 默认最多重试 2 次(最多 3 次调用,退避 10/30 秒);Chorus 当前 route 只有一个成员且 max_failover=0,本次只调用一次。
  • cmhub 默认单次生图上游硬截止为 180 秒;Chorus 本次 Provider 模型超时为 300 秒。
  • Chorus generation #9 的排队延迟约 76ms,Provider attempt 精确持续约 300014ms 后报 upstream_timeout,因此不是本地队列或 Portal HTTP 超时导致,时间几乎全部消耗在上游响应等待。

结论:用户观察到 cmhub 多数 150 秒内成功,不能据此判断 Chorus 本地处理慢。当前首要差异是 API 类型/请求体,其次是重试和超时策略。由于本机无法连接 cmhub 当前数据库,尚不能只读确认其线上该模型的实际 api_type;后续诊断需先确认这一字段并对齐一次脱敏请求元数据,禁止记录 URL、密钥、prompt、图片或 Provider 原始响应。

补充对照结论(2026-08-25,已按用户更正核对 `D:\chengma\cmhub`,未执行真实上游调用): - cmhub 即使使用相同 Provider URL、模型名和凭据,也不代表请求协议与 Chorus 相同。 - cmhub 的既定架构中,`gpt-image-2` 配置为 `images_edits`,调用 `/v1/images/edits`,使用 multipart 并要求原图;Chorus 当前任务调用 `/v1/images/generations`,JSON 请求且固定 `response_format=b64_json`。两者不是同一种生成请求。 - 若 cmhub 中该配置实际仍为 `api_type=auto` 且 URL 仅到 `/v1`,其代码会将其解析为 `chat` 并调用 `/v1/chat/completions`,同样不会走 Chorus 当前的 images generations 路径。 - cmhub 异步生图对 `upstream_timeout/upstream_error` 默认最多重试 2 次(最多 3 次调用,退避 10/30 秒);Chorus 当前 route 只有一个成员且 `max_failover=0`,本次只调用一次。 - cmhub 默认单次生图上游硬截止为 180 秒;Chorus 本次 Provider 模型超时为 300 秒。 - Chorus generation #9 的排队延迟约 76ms,Provider attempt 精确持续约 300014ms 后报 `upstream_timeout`,因此不是本地队列或 Portal HTTP 超时导致,时间几乎全部消耗在上游响应等待。 结论:用户观察到 cmhub 多数 150 秒内成功,不能据此判断 Chorus 本地处理慢。当前首要差异是 API 类型/请求体,其次是重试和超时策略。由于本机无法连接 cmhub 当前数据库,尚不能只读确认其线上该模型的实际 `api_type`;后续诊断需先确认这一字段并对齐一次脱敏请求元数据,禁止记录 URL、密钥、prompt、图片或 Provider 原始响应。
Author
Owner

用户于 2026-08-25 确认:cmhub 中该模型的实际 api_type=auto。结合配置使用的是仅到 /v1 的基础地址,cmhub 的 detect_api_type() 会将其解析为 chat,最终通过 ChatCompletionsProvider.generate_image() 调用 /v1/chat/completions。因此已确认 cmhub 与 Chorus 当前 /v1/images/generations + response_format=b64_json 的调用协议不同,这是两边耗时和成功率不可直接比较的首要原因。

用户于 2026-08-25 确认:cmhub 中该模型的实际 `api_type=auto`。结合配置使用的是仅到 `/v1` 的基础地址,cmhub 的 `detect_api_type()` 会将其解析为 `chat`,最终通过 `ChatCompletionsProvider.generate_image()` 调用 `/v1/chat/completions`。因此已确认 cmhub 与 Chorus 当前 `/v1/images/generations` + `response_format=b64_json` 的调用协议不同,这是两边耗时和成功率不可直接比较的首要原因。
Author
Owner

更正上一条判断:用户确认 cmhub 的模型 URL 路径已经包含 /v1/images/edits(此处不记录具体主机)。因此 api_type=auto 会在 detect_api_type() 中优先解析为 images_edits,不会解析为 chat。

已确认的实际差异:

  • cmhub:POST /v1/images/edits,multipart,包含原图、prompt、model、n、size。
  • Chorus:POST /v1/images/generations,JSON,当前任务无原图,包含 model、prompt、n、response_format=b64_json。

因此 cmhub 多数 150 秒内成功与 Chorus 本次 300 秒超时并非同一种上游请求;首要诊断结论仍是协议/输入形态不一致,而不是 Chorus 本地排队慢。上一条关于 cmhub 实际走 chat/completions 的结论作废。

更正上一条判断:用户确认 cmhub 的模型 URL 路径已经包含 `/v1/images/edits`(此处不记录具体主机)。因此 `api_type=auto` 会在 `detect_api_type()` 中优先解析为 `images_edits`,不会解析为 `chat`。 已确认的实际差异: - cmhub:`POST /v1/images/edits`,multipart,包含原图、prompt、model、n、size。 - Chorus:`POST /v1/images/generations`,JSON,当前任务无原图,包含 model、prompt、n、`response_format=b64_json`。 因此 cmhub 多数 150 秒内成功与 Chorus 本次 300 秒超时并非同一种上游请求;首要诊断结论仍是协议/输入形态不一致,而不是 Chorus 本地排队慢。上一条关于 cmhub 实际走 `chat/completions` 的结论作废。
Author
Owner

2026-08-27:前置安全工单 #55 已由用户验收并关闭,原阻塞条件解除。#54 仍缺少一次生文和一次文生图受控终态验证,现恢复为“待实施”;本次不自动发起真实 Provider 请求。

2026-08-27:前置安全工单 #55 已由用户验收并关闭,原阻塞条件解除。#54 仍缺少一次生文和一次文生图受控终态验证,现恢复为“待实施”;本次不自动发起真实 Provider 请求。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/chorus#54