Prhub

#36254 [Misc] Use VLLMValidationError consistently in chat completion and completion protocol validators

原始 PR 作者 umut-polat 合并时间 2026-06-01 12:04 文件变更 3 提交数 2 评论 10 代码增减 +100 / -24

执行摘要

统一使用 VLLMValidationError 并修复 structured_outputs 校验逻辑

该变更旨在统一 API 验证错误处理,使用 VLLMValidationError 取代 ValueError,使得错误响应能包含 parameter 字段,帮助 API 用户更快速定位验证失败来源。同时修复了已有代码中的一个死代码 bug:check_structured_outputs_count 中的第二个条件 count > 1 始终不成立(因为如果 count > 1,第一个条件已经抛出了 ValueError),导致 structured_outputs 与命名 tool_choice 的组合被静默允许,违反了预期行为。改为 count > 0 后,该冲突能被正确拒绝。

此 PR 变更清晰,修复了一个实际 bug,并提升了 API 错误诊断能力。值得精读的点包括:如何通过统一的异常类型和 parameter 字段提高错误信息的可操作性,以及如何通过细粒度的 parameter 值提供更精确的错误定位。建议在类似验证场景中推广此模式。

讨论亮点

在 code review 中,DarkLight1337parameter 字段的指定提出了细化建议:对于 tool_choice 内部特定字段的错误(如 function 不存在或 name 无效),应使用 parameter="tool_choice.function"parameter="tool_choice.function.name",以精准指出错误来源。对于涉及多个参数的错误(如 check_structured_outputs_count 中的多约束错误和与工具冲突的错误),则应移除 parameter 字段。作者根据反馈进行了调整,最终获得了批准。

实现拆解

  1. 在 chat_completion/protocol.py 中,将 check_structured_outputs_countcheck_tool_usage 等方法中的 ValueError 替换为 VLLMValidationError,并为每条错误添加适当的 parameter 字段。关键修改包括:将第二个条件从 count > 1 改为 count > 0,修复了死代码问题;内部参数错误使用更细粒度的 parameter 值(如 tool_choice.functiontool_choice.function.name)。
  2. 在 completion/protocol.py 中,将 validate_prompt_and_prompt_embedscheck_cache_salt_support 中的 ValueError 替换为 VLLMValidationError,并添加 parameter 字段。
  3. 在测试文件 test_chat_completion_request_validations.py 中,新增三个测试用例:test_structured_outputs_with_named_tool_choice_rejectedtest_structured_outputs_with_auto_tool_choice_allowedtest_multiple_structured_outputs_rejected,分别验证修复后的验证行为。
文件 模块 状态 重要度
vllm/entrypoints/openai/chat_completion/protocol.py 请求验证 modified 6.89
vllm/entrypoints/openai/completion/protocol.py 请求验证 modified 6.08
tests/tool_use/test_chat_completion_request_validations.py 测试 modified 6.55

关键符号

check_structured_outputs_count check_tool_usage check_generation_prompt validate_prompt_and_prompt_embeds check_cache_salt_support test_structured_outputs_with_named_tool_choice_rejected test_structured_outputs_with_auto_tool_choice_allowed test_multiple_structured_outputs_rejected

关键源码片段

vllm/entrypoints/openai/chat_completion/protocol.py core-logic

核心变更文件:替换 ValueError 为 VLLMValidationError,修复 check_structured_outputs_count 条件逻辑,调整 parameter 字段精度。

@model_validator(mode="before")
@classmethod
def check_structured_outputs_count(cls, data):
    # 如果 data 是从其它验证器传来的 ValueError ,先重新抛出
    if isinstance(data, ValueError):
        raise data
    # 没有使用 structured_outputs 时直接跳过
    if data.get("structured_outputs", None) is None:
        return data
​
    # 计算当前使用了多少种约束(json / regex / choice)
    structured_outputs_kwargs = data["structured_outputs"]
    is_dataclass = isinstance(structured_outputs_kwargs, StructuredOutputsParams)
    count = sum(
        (
            getattr(structured_outputs_kwargs, k, None)
            if is_dataclass
            else structured_outputs_kwargs.get(k)
        )
        is not None
        for k in ("json", "regex", "choice")
    )
​
    # 不允许同时使用多种约束
    if count > 1:
        raise VLLMValidationError(
            "You can only use one kind of constraints for structured "
            "outputs ('json', 'regex' or 'choice').",
        )
​
    # 当工具选择是命名函数时,禁止与 structured_outputs 混用
    # 【关键修复】原条件 count > 1 导致此分支永远不可达(已被上一条拦截),
    # 现改为 count > 0 ,使得任何非 none / auto / required 的 tool_choice 均会触发。
    if count > 0 and data.get("tool_choice", "none") not in (
        "none", "auto", "required",
    ):
        raise VLLMValidationError(
            "You can only either use constraints for structured outputs "
            "or tools, not both.",
        )
​
    return data

评论区精华

为 tool_choice 内部错误指定更精确的 parameter 值 设计

DarkLight1337 建议将 tool_choice 下 function 和 name 的错误分别使用 parameter='tool_choice.function' 和 parameter='tool_choice.function.name',以精确定位错误来源。最初作者使用了 parameter='tool_choice',后根据建议修改。

结论:作者采纳建议,更新了相应的 parameter 值。 · 已解决

移除 check_structured_outputs_count 中多参数错误的 parameter 设计

DarkLight1337 指出 check_structured_outputs_count 中的错误涉及多个参数(structured_outputs 和 tool_choice),不应指定单一 parameter,应移除。作者移除了 parameter 字段。

结论:作者移除 parameter 字段。 · 已解决

风险与影响

异常类型替换不会改变 HTTP 状态码(两者都返回 400),因此对 API 响应状态无影响。但是,错误响应体将新增 parameter 字段,客户端若依赖精确的错误消息字符串匹配,可能因 VLLMValidationError 的格式差异而受影响(尽管文本内容一致)。另外,条件修正可能使得之前被误允许的请求现在被拒绝,可能导致原本正常工作的客户端出现 400 错误,应考虑向后兼容性。建议在合并前确认依赖此行为的用户,并在发布说明中明确此变更。

对用户:API 错误响应更详细,有助于调试;修复了一个可能导致静默错误行为的 bug。对系统:无性能影响,仅修改了请求验证阶段的异常处理。对团队:统一了错误处理模式,为后续类似工作提供了参考。

验证逻辑修正 异常处理标准化 测试覆盖补充

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论