responses.parse() throws a PydanticSerializationUnexpectedValue error in v2.21.0

这个报错通常出现在调用 OpenAI Python SDK v2.21.0 的 responses.parse() 并传入自定义 Pydantic 模型(例如 text_format=GuardrailDecision )时,序列化解析后的响应会触发 PydanticSerializationUne

快速结论:这个报错通常出现在调用 OpenAI Python SDK v2.21.0 的 responses.parse() 并传入自定义 Pydantic 模型(例如 text_format=GuardrailDecision)时,序列化解析后的响应会触发 PydanticSerializationUnexpectedValue 警告。优先排查 SDK 版本与 Pydantic 联合类型/泛型的序列化行为,而不是怀疑业务逻辑或 API 返回结果本身。

适用环境:OpenAI Python SDK v2.21.0;Python 3.12(Issue 报错路径中显示 .venv/lib/python3.12/site-packages/pydantic/main.py);使用 responses.parse() 并传入自定义 Pydantic 模型。Issue 中未确认 CUDA、显卡或操作系统信息。

最快修复方案:暂无确认的一步修复方案。Issue 中有用户反馈 v2.21.0 引入更严格的嵌套模型校验,并将版本回退到 openai==2.20.0 作为临时稳定方案;维护者侧尚未确认根因或给出正式补丁。

注意事项:该警告多数情况下属于日志噪声,解析结果可能仍然正确,有评论明确指出“这是表面问题,功能应正常”。回退版本属于未经验证的临时手段,可能在后续版本仍然复现;屏蔽警告会掩盖真实的序列化异常,不建议在需要审计日志的生产环境中无差别使用。

问题场景

用户在将 OpenAI Python SDK 升级到 v2.21.0 后,调用 responses.parse()(例如配合 text_format=GuardrailDecision 的自定义结构化输出)时,Pydantic 在序列化解析后的响应对象时抛出大量 PydanticSerializationUnexpectedValue 用户警告。警告集中在 parsedcontentoutput 字段上,output 会针对多个联合类型成员(如 ResponseOutputRefusalParsedResponseFunctionToolCallResponseFileSearchToolCallMcpCall 等)反复告警。

报错原文

.venv/lib/python3.12/site-packages/pydantic/main.py:464: UserWarning: Pydantic serializer warnings:
  PydanticSerializationUnexpectedValue(PydanticSerializationUnexpectedValue: Expected `none` - serialized value may not be as expected [field_name='parsed', input_value=GuardrailDecision(trigger...est (admin/non-churn).'), input_type=GuardrailDecision]
PydanticSerializationUnexpectedValue: Expected `ResponseOutputRefusal` - serialized value may not be as expected [field_name='content', input_value=ParsedResponseOutputText[...st (admin/non-churn).')), input_type=ParsedResponseOutputText[TypeVar]])
  PydanticSerializationUnexpectedValue(Expected `ParsedResponseFunctionToolCall` - serialized value may not be as expected [field_name='output', input_value=ParsedResponseOutputMessa...pleted', type='message'), input_type=ParsedResponseOutputMessage[TypeVar]])
  PydanticSerializationUnexpectedValue(Expected `ResponseFileSearchToolCall` - serialized value may not be as expected [field_name='output', input_value=ParsedResponseOutputMessa...pleted', type='message'), input_type=ParsedResponseOutputMessage[TypeVar]])
  ...

原因分析

结合 Issue 讨论,最可能的原因是 v2.21.0 对联合类型和泛型的 Pydantic 序列化处理更严格。SDK 的 ParsedResponseOutputMessage[T] 是泛型,会随用户传入的 schema 替换类型,但 output 字段的联合判别器仍然期望所有原始工具调用变体(ResponseFunctionToolCallResponseFileSearchToolCallMcpCall 等)。Pydantic 在序列化时会逐个尝试联合成员,匹配不上就发出 PydanticSerializationUnexpectedValue 警告。

另外几个可能原因:

  • v2.21.0 对嵌套 Pydantic 模型和自定义校验器采用了更严格的校验逻辑。
  • v2.21.0 对联合类型中 None 的处理方式发生变化,str | None 之类的写法可能更容易触发告警。
  • SDK 的 output 联合类型缺少判别字段,序列化器也未对泛型解析场景做显式处理。

需要注意,Issue 中维护者表示在自己环境中无法复现该警告,因此以上均为基于讨论的推测。

环境排查

  • 确认 OpenAI Python SDK 版本:是否正好为 v2.21.0。
  • 确认 Python 版本:Issue 环境为 Python 3.12。
  • 确认 Pydantic 版本及是否与 SDK 声明的依赖范围一致。
  • 确认调用方式:是否使用 responses.parse() 并传入自定义 Pydantic 模型(如 text_format=GuardrailDecision)。
  • 检查自定义模型中的联合类型与 Optional 字段写法,例如 str | NoneOptional[str] = None 的差异。
  • Issue 中未提供 CUDA、PyTorch、显卡信息,这些项与本次问题没有明确证据关联。

解决步骤

  1. 先确认警告是否影响功能:读取 response.output_parsed 获取解析后的自定义模型实例,验证业务数据是否正确,而不是对整条响应做序列化。
  2. 如果只是日志噪声且不影响功能,可缩小告警范围而不是全局屏蔽。例如针对 Pydantic serializer warnings 这类 UserWarning 做定向过滤,或将 pydantic 日志级别调高。此做法未在 Issue 中被维护者确认,属于可优先尝试的社区方案。
  3. 如果需要在生产环境中稳定运行,可参考社区反馈将 SDK 临时固定到 openai==2.20.0,该版本被反馈未出现同类警告。
  4. 如果使用 client.beta.chat.completions.parse(...) 并遇到类似问题,可尝试改为先调用原始 create,再用 YourModel.model_validate_json(raw_response.choices[0].message.content) 手动解析。此方案来自社区评论,未在官方维护者处得到验证。
  5. 检查自定义模型中的联合类型,尽量使用显式的 Optional[str] = None,避免仅用 str | None 触发 v2.21.0 对 None 的差异处理。该建议来自社区反馈,属于可优先尝试项。
  6. 关注该 Issue 的后续更新,等待维护者对联合类型添加 discriminator 字段或在序列化器中使用 model_serializer(mode="wrap") 的正式修复。这类改动在评论中被列为“可能的方向”,尚未合并。

验证方法

重新运行原先触发警告的 responses.parse() 调用,观察控制台是否仍然输出 PydanticSerializationUnexpectedValue 及相关 UserWarning: Pydantic serializer warnings。同时确认 response.output_parsed 返回的对象仍然是期望的自定义模型类型,字段值与 API 返回一致,说明解析逻辑没有被破坏。如果只是屏蔽了警告,需要额外确认屏蔽范围足够窄,避免掩盖其他 Pydantic 序列化异常。

参考来源

openai/openai-python #2872

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 24506

发表回复

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