Prhub

#45048 [Bugfix] GPT-OSS Autodrop reasoning in Response API and cleanup

原始 PR 作者 yzong-rh 合并时间 2026-06-23 21:36 文件变更 5 提交数 3 评论 8 代码增减 +137 / -46

执行摘要

修复 Responses API 多轮对话中推理消息未正确丢弃

Harmony prompts should drop reasoning from completed turns, but keep reasoning from the current in-progress turn so tool-calling can continue correctly. Responses API previously only relied on Harmony's default filter, which only drops analysis messages when the conversation ends with an assistant final message, leaving stale reasoning from all previous turns when the prompt ends mid-turn on a tool call or tool result. (PR body)

建议关注render_for_completion的改动与新增测试,理解如何跨API共享逻辑并精确控制库默认行为。该PR是一个典型的bugfix + cleanup示例,展示了修复多路径不一致问题的策略。

讨论亮点
  • bug发现:bbrowning 在 review 中指出 responses/harmony.py 中调用了不存在的方法 Message.from_author_and_contents,作者确认并称是通过 Claude 发现的。
  • 测试适配:bbrowning 报告 CI 捕获 test_serving_chat.py 中的失败。作者解释因自动丢弃逻辑移动导致消息序列变化,并更新测试期望以匹配新行为。

实现拆解

  1. 移动自动丢弃逻辑:从parse_chat_inputs_to_harmony_messages中移除auto_drop_analysis_messages调用,改为在共享的render_for_completion函数中调用该函数,使两个API路径在渲染input tokens前都丢弃已完成轮次的analysis消息。
  2. 禁用Harmony库的默认丢弃:在render_for_completion中向render_conversation_for_completion传递RenderConversationConfig(auto_drop_analysis=False),防止Harmony编码器重复丢弃。
  3. 简化Responses上下文构建:删除_construct_input_messages_with_harmony中一个复杂的slice-delete-reappend循环(实际是no-op),避免混淆。
  4. 修复构造方法调用:在responses/harmony.py中将Message.from_author_and_contents(不存在的方法)改为Message(author=..., content=...)
  5. 更新测试:新增test_completed_turns_drop_reasoning验证多轮推理正确丢弃;调整test_serving_chat.py中多轮测试期望,反映当前轮分析消息被保留。
文件 模块 状态 重要度
tests/entrypoints/openai/parser/test_harmony_render_parity.py 渲染测试 modified 6.28
vllm/entrypoints/openai/responses/serving.py 服务层 modified 6.2
tests/entrypoints/openai/chat_completion/test_serving_chat.py 聊天测试 modified 5.48
vllm/entrypoints/openai/parser/harmony_utils.py 解析器 modified 5.43
vllm/entrypoints/openai/responses/harmony.py 服务层 modified 4.89

关键符号

auto_drop_analysis_messages render_for_completion _construct_input_messages_with_harmony _parse_harmony_format_message parse_chat_inputs_to_harmony_messages test_completed_turns_drop_reasoning

关键源码片段

tests/entrypoints/openai/parser/test_harmony_render_parity.py test-coverage

新增 `test_completed_turns_drop_reasoning` 测试用例,验证多轮对话中推理消息正确丢弃,是此修复的关键验证。

def test_completed_turns_drop_reasoning(self):
    """验证已完成轮次的推理被丢弃,而当前正在进行的推理保留。"""
    first_reasoning = "FIRST_TURN_REASONING"
    second_reasoning = "SECOND_TURN_REASONING"
​
    # Chat Completions 路径
    chat_msgs = self._build_chat_msgs(first_reasoning, second_reasoning)
    chat_tokens = render_for_completion([_system()] + chat_msgs)
    rendered = get_encoding().decode(chat_tokens)
    # 第一轮推理应被丢弃,第二轮推理应保留
    assert first_reasoning not in rendered
    assert second_reasoning in rendered
​
    # Responses 路径
    resp_msgs = self._build_response_msgs(first_reasoning, second_reasoning)
    resp_tokens = render_for_completion([_system()] + resp_msgs)
    rendered_resp = get_encoding().decode(resp_tokens)
    assert first_reasoning not in rendered_resp
    assert second_reasoning in rendered_resp
vllm/entrypoints/openai/parser/harmony_utils.py core-logic

核心逻辑:将 auto_drop_analysis_messages 移到 render_for_completion 并禁用 Harmony 默认丢弃。

def render_for_completion(messages: list[Message]) -> list[int]:
    # 先应用 vLLM 的自动丢弃逻辑(丢弃已完成轮次的分析消息,保留当前轮)
    messages = auto_drop_analysis_messages(messages)
    conversation = Conversation.from_messages(messages)
    # 禁用 Harmony 编码器自带的自动丢弃,因为我们已经处理
    token_ids = get_encoding().render_conversation_for_completion(
        conversation,
        Role.ASSISTANT,
        config=RenderConversationConfig(auto_drop_analysis=False),
    )
    return token_ids

评论区精华

不存在的方法调用 正确性

bbrowning 在 review 中指出 `Message.from_author_and_contents` 方法不存在,会抛出错误。作者确认并通过 Claude 发现。

结论:已改用正确的 `Message(author=..., content=...)` 构造修复。 · 已解决

CI 测试期望不匹配 测试

bbrowning 在 issue 中报告 `test_serving_chat.py` 测试因自动丢弃逻辑移动而失败。作者解释这是预期的行为变化,并更新了测试期望。

结论:已更新测试以匹配新行为,测试恢复通过。 · 已解决

风险与影响

自动丢弃逻辑移至render_for_completion后,所有调用该函数的路径都会应用丢弃,可能影响其他未预期场景,但已有测试覆盖。禁用Harmony默认丢弃依赖 RenderConversationConfig 参数,若未来升级 openai-harmony 版本导致该参数行为变化,需重新验证。移除的循环虽注释为no-op,但考虑其编写时可能另有考虑,不过已有补充测试保障。重构仅针对GPT-OSS Harmony路径,其他模型不受影响。

直接影响使用GPT-OSS模型和Responses API的用户,修复了多轮工具调用中推理消息残留导致模型行为异常的问题;Chat Completions路径行为不变;清理冗余代码降低了维护成本;统一推理丢弃策略使两条API路径行为一致。

核心路径变更 依赖库默认行为关闭 测试覆盖新增

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论