Prhub

#38519 Fix Responses JSON schema alias serialization

原始 PR 作者 noobHappylife 合并时间 2026-04-09 10:50 文件变更 6 提交数 13 评论 7 代码增减 +104 / -32

执行摘要

修复 Responses API JSON Schema 序列化中别名使用问题,确保公开字段 'schema' 正确输出。

根据PR body,修复Responses API JSON Schema别名序列化,使流式和非流式响应都输出公开字段'schema'而不是内部'schema_',解决非Harmony /v1/responses tool-calling with tool_choice="required"的中断问题。关联Issue #38245描述了此bug,PR #38262尝试修复但未完全解决。

该PR值得精读,特别是序列化设计决策部分,如使用by_alias=True确保API兼容性,以及测试更新中处理Harmony消息格式差异的方法。建议关注protocol.py中serialize_message的修改,它修复了回归并返回JSON对象,这对消息序列化路径有重要影响。

讨论亮点

Review讨论中,gemini-code-assist[bot]总结了变更,确认添加by_alias=True确保字段别名正确输出,无反馈。chaunceyjiang批准了PR。在Issue评论中,noobHappylife和chaunceyjiang深入讨论了Harmony消息序列化的差异:noobHappylife指出非流式测试假设嵌套author格式,而流式测试使用Message.from_dict期望扁平格式,这导致了数据丢失。chaunceyjiang确认变更正确,并指导更新测试以使用Message.from_dict,确保消息格式符合openai_harmony期望。结论是修复了序列化不一致问题,更新了测试。

实现拆解

实现拆解为三个层次:1) API路由层(api_router.py):在_create_responses、_retrieve_responses、_cancel_responses和_convert_stream_to_sse_events函数中,为model_dump和model_dump_json添加by_alias=True参数,确保响应序列化使用字段别名。2) 协议层(protocol.py):修改serialize_message函数,使用model_dump(mode="json", by_alias=True)替代model_dump_json,修复消息序列化回归。3) 服务层(serving.py):在生成ResponseCreatedEvent时添加by_alias=True。测试更新包括添加新测试test_response_created_event_uses_public_json_schema_alias验证别名序列化,并调整Harmony相关测试使用Message.from_dict正确处理消息格式。

文件 模块 状态 重要度
vllm/entrypoints/openai/responses/api_router.py frontend/responses modified 7.0
vllm/entrypoints/openai/responses/protocol.py frontend/responses modified 6.0
tests/entrypoints/openai/responses/test_serving_responses.py test modified 5.0
vllm/entrypoints/openai/responses/serving.py frontend/responses modified 6.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

serialize_message _convert_stream_to_sse_events create_responses retrieve_responses cancel_responses test_response_created_event_uses_public_json_schema_alias

评论区精华

Harmony 消息序列化格式差异 正确性

noobHappylife 在 Issue 评论中指出,非流式 Harmony 测试假设消息格式为嵌套 author 对象(如 {"author": {"role": ...}}),而流式测试使用 Message.from_dict 期望扁平格式(如 {"role": ...}),这导致了数据丢失和不一致。chaunceyjiang 验证后确认正确格式应为扁平结构。

结论:确认变更正确,更新测试以使用 Message.from_dict 确保消息格式符合 openai_harmony 期望,修复了序列化不一致问题。 · 已解决

风险与影响

技术风险包括:1) 序列化逻辑变更可能影响API响应格式,如果其他Pydantic模型字段有别名但未处理,可能引入类似问题;2) 在protocol.py中修改serialize_message返回JSON对象而非字符串,可能影响依赖此函数的其他组件,但添加了单元测试覆盖;3) 多次rebase提交历史显示代码合并频繁,可能引入冲突或回归,但最终变更集中。风险相对可控,因为变更局限于Responses API前端模块,并有测试验证。

对用户的影响:修复了tool-calling功能中断,提升API兼容性和用户体验,特别是使用JSON Schema和tool_choice="required"的场景。对系统的影响:确保Responses API响应符合OpenAI规范,避免字段泄漏,增强系统稳定性。对团队的影响:需要关注测试更新,确保其他前端功能不受影响;变更展示了Pydantic别名序列化最佳实践,可供团队参考。

API 响应格式变更 潜在回归风险

关联 Issue

#38245 [Bug]: Responses API `text.format.type="json_schema"` leaks `schema_` in non-stream responses and breaks streaming
#38262 [frontend] dump openai responses type by alias

完整报告

执行摘要

本PR修复了vLLM Responses API中JSON Schema序列化的bug,通过添加by_alias=True参数确保Pydantic模型字段别名正确使用,避免了内部字段schema_泄漏,恢复了非Harmony tool-calling功能。变更影响前端Responses模块,涉及API路由、协议和测试更新,是一个有意义的改进,值得关注序列化设计决策。

功能与动机

为什么做:Responses API在使用JSON Schema时,非流式响应和流式响应会错误地输出内部字段schema_而非公开字段schema,导致非Harmony tool-calling(当tool_choice="required"时)中断。Issue #38245报告了此bug,PR #38262尝试修复但未完全解决流式响应问题。

实现拆解

按模块拆解改动

  • API路由模块 (vllm/entrypoints/openai/responses/api_router.py):在_convert_stream_to_sse_eventscreate_responsesretrieve_responsescancel_responses函数中,为model_dump_jsonmodel_dump添加by_alias=True,确保事件流和JSON响应序列化使用别名。
  • 协议模块 (vllm/entrypoints/openai/responses/protocol.py):修改serialize_message函数,用model_dump(mode="json", by_alias=True)替代model_dump_json(by_alias=True),返回Python字典而非JSON字符串,修复消息序列化回归。
  • 服务模块 (vllm/entrypoints/openai/responses/serving.py):在生成ResponseCreatedEvent时添加by_alias=True,确保初始响应正确序列化。
  • 测试模块 (tests/entrypoints/openai/responses/test_serving_responses.py):新增test_response_created_event_uses_public_json_schema_alias测试,验证别名序列化;更新Harmony相关测试使用Message.from_dict处理消息格式。

评论区精华

提炼review讨论

  • 在Issue评论中,noobHappylife和chaunceyjiang发现了Harmony消息序列化不一致问题:非流式测试假设嵌套author格式,而流式测试使用Message.from_dict期望扁平格式。chaunceyjiang确认:> "使用嵌套author结构会导致数据丢失。" 最终结论是更新测试以使用Message.from_dict,确保消息格式正确。
  • Review中,gemini-code-assist[bot]总结变更:> "更新序列化以使用字段别名,确保如schema字段正确命名。" chaunceyjiang批准PR。

风险与影响

具体风险

  1. 序列化逻辑变更:API响应格式可能因其他未处理别名字段而受影响,但变更局限于Responses模块,风险较低。
  2. 回归风险serialize_message函数修改返回类型,可能影响依赖组件,但添加了单元测试test_serialize_message_pydantic_model_returns_dict覆盖。
  3. 兼容性影响:修复后,API响应将严格遵循OpenAI规范,提升工具调用兼容性,对用户透明。

影响范围

  • 用户:修复tool-calling中断,提升使用JSON Schema和tool_choice="required"场景的体验。
  • 系统:确保Responses API输出一致性,减少字段泄漏,增强可靠性。
  • 团队:测试更新强调了消息格式处理,为类似序列化问题提供参考。

关联脉络

与历史PR的关系

  • PR #38262("[frontend] dump openai responses type by alias")直接关联,它尝试修复同一Issue但未解决流式响应问题,本PR是后续完善。
  • 结合近期PR分析,如PR #39114("[Bugfix] Fix Gemma4 streaming tool call corruption")也涉及tool-calling修复,显示团队在前端和工具调用模块持续优化兼容性和稳定性。本PR是这一趋势的一部分,专注于API响应序列化细节,以确保与OpenAI标准对齐。

参与讨论