Add `ImageDetail` as a named public type alias (like `ReasoningEffort`)

这是一个类型定义缺失引发的开发体验问题:在 openai-python 中想给图像 detail 字段做类型标注或 cast 时,找不到像 ReasoningEffort 那样公开导出的 ImageDetail 别名,只能手写内联 Literal 。优先排查你使用的 SDK 版本,并改用已导出的 I

快速结论:这是一个类型定义缺失引发的开发体验问题:在 openai-python 中想给图像 detail 字段做类型标注或 cast 时,找不到像 ReasoningEffort 那样公开导出的 ImageDetail 别名,只能手写内联 Literal。优先排查你使用的 SDK 版本,并改用已导出的 ImageDetail。

适用环境:OpenAI Python SDK;Issue 中确认的核心事实是 ImageDetail 自 v3.2.0 起可从 openai.types.responses 导入。Issue 未提供操作系统、Python、CUDA、显卡等信息。

最快修复方案:升级到 v3.2.0 或更高版本后,将 from typing import Literal, cast 配合手写 Literal["low", "high", "auto"] 的写法,替换为 from openai.types.responses import ImageDetail,再 cast(ImageDetail, ...)。

注意事项:Responses 的 ImageDetail 现已包含 auto、low、high、original;但 Chat Completions 的字段注解问题Issue 关闭时仍在等待上游 OpenAPI 修正,因此单独使用该别名并不能修复 Chat 当前的字段类型标注。Chat Completions 的剩余缺口在 Issue 里被明确描述为“等待生成修正落地”。

问题场景

使用 OpenAI Python SDK 构造带图像输入的请求时,detail 字段(图像细节级别)在多个生成的文件中都是内联字面量类型,例如 types/responses/response_input_image_content.py、types/responses/response_input_image_content_param.py 以及 types/chat/chat_completion_content_part_image.py。当用户想写类型标注,或想用 typing.cast 把一个字符串值安全地转成该字段类型时,SDK 里没有公开导出的 ImageDetail 别名可用,只能重复写内联 Literal["low", "high", "auto"],或自己在项目里定义一个别名。该 Issue 就是请求 SDK 按 ReasoningEffort 的既有模式,把 ImageDetail 也做成命名的公开类型别名并导出。

报错原文

The SDK exposes `ReasoningEffort` as a named TypeAlias in openai.types, making it easy to reference in user code:

from openai.types import ReasoningEffort

cast(ReasoningEffort, reasoning_effort.value if reasoning_effort else 'minimal')

There's no equivalent for the image detail level. The detail field on image input types uses an inline literal across several generated files:

types/responses/response_input_image_content.py — detail: Optional[Literal["low", "high", "auto"]]
types/responses/response_input_image_content_param.py — detail: Optional[Literal["low", "high", "auto"]]
types/chat/chat_completion_content_part_image.py — detail: Optional[Literal["auto", "low", "high"]]

Users who need to type or cast this value are forced to repeat the inline literal or define their own alias:

cast(Literal["low", "high", "auto"], image_quality.value if image_quality else 'high')

Proposed change: Add `ImageDetail` as a named public type alias (like `ReasoningEffort`)

原因分析

最可能的原因是 SDK 的代码生成配置只为部分字面量联合类型生成了命名的公开别名,ReasoningEffort 属于已被命名的例子,而图像 detail 对应的字面量联合仍以内联形式生成在模型中,因此没有可导入的类型。另一个更具体的上游原因在后续评论中被指出:Chat Completions 对应的公开 OpenAPI 枚举漏掉了 original,而 vision 指南中为 Chat 也记录了该取值,所以 Chat 侧的字段注解需要等上游修正后再由 SDK 生成端落地。

环境排查

  • 确认当前安装的 openai-python 版本是否低于 v3.2.0;低于该版本时 openai.types.responses.ImageDetail 不存在。
  • 确认你导入的路径是 openai.types.responses,而不是 openai.types 根命名空间(Issue 中确认可用的导入是 from openai.types.responses import ImageDetail)。
  • 确认你的报错场景是 Responses API 还是 Chat Completions:Chat Completions 的字段注解在 Issue 关闭时仍等待生成修正,不能只靠导入别名解决。
  • 如果使用静态类型检查器(如 mypy/pyright),确认检查器实际解析到的是新版本 SDK 的类型存根或源码。

解决步骤

  1. 把 openai-python 升级到 v3.2.0 或更高版本。Issue 中明确说明自 v3.2.0 起该可复用类型已可用。
  2. 在需要给图像细节值做类型标注或转换的代码中,改为从 Responses 命名空间导入别名:from openai.types.responses import ImageDetail。
  3. 把原先手写的内联字面量 cast(Literal["low", "high", "auto"], image_quality.value if image_quality else 'high') 替换为 cast(ImageDetail, image_quality.value if image_quality else 'high')。
  4. 如果相关代码走的是 Chat Completions 路径,先保留原有内联 Literal 写法,不要假定新别名能同时修正 Chat 的字段类型标注;Issue 中说明 Chat 侧的修正要等上游 OpenAPI 修正并重新生成后才落地。
  5. 如果项目里已经自定义了同名别名,升级后可以改为直接复用 SDK 的 ImageDetail,避免本地别名与 SDK 取值集合长期不一致。

验证方法

在升级后的环境中执行 from openai.types.responses import ImageDetail,确认导入不再抛 ImportError;用某静态类型检查器对使用 cast(ImageDetail, ...) 的文件运行一次检查,确认没有因找不到类型而报错。若你同时给 Chat Completions 的 detail 字段做注解,注意检查它是否仍被生成为内联字面量类型——这意味着该路径尚未应用修正,不能作为已验证解决的依据。

参考来源

openai/openai-python #2889

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 26181

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注