# PR #49214 完整报告

- 仓库：`vllm-project/vllm`
- 标题：[Misc] Use VLLMValidationError in chat completion tool and batch validators
- 合并时间：2026-07-21 19:38
- 原文链接：http://prhub.com.cn/vllm-project/vllm/pull/49214

---

# 执行摘要

- 一句话：统一改用 VLLMValidationError 改进错误响应
- 推荐动作：可以直接合并且无需深度审查。这是一个干净、有明确动机的小型重构。值得关注的是 `parameter` 参数的命名约定，可供后续类似迁移参考。

# 功能与动机

PR body 指出，部分校验仍抛出普通 ValueError，而同级校验已使用 VLLMValidationError。VLLMValidationError 携带 parameter 名（和可选的 value），使 API 层能返回结构化错误响应。保持所有校验一致，避免不一致。

# 实现拆解

1. **修改 `check_tool_usage`**：将 `raise ValueError(...)` 替换为 `raise VLLMValidationError(..., parameter="tools")`，消息文本保持不变。
2. **修改 `check_batch_mode` 中的三个校验**：
 - beam search 校验：改用 `VLLMValidationError(parameter="use_beam_search")`
 - `logprob_token_ids` 与 `logprobs` 校验：改用 `VLLMValidationError(parameter="logprob_token_ids")`
 - `n > 1` 校验：改用 `VLLMValidationError(parameter="n", value=n)`，传递具体的错误值
3. **格式化调整**：顺便将 `output_kind` 的三元表达式用括号包裹，提高可读性。
4. **无需测试修改**：因消息文本不变且 VLLMValidationError 是 ValueError 的子类，现有 `pytest.raises(ValueError, match=...)` 用例依然通过。

关键文件：
- `vllm/entrypoints/openai/chat_completion/protocol.py`（模块 前端协议；类别 source；类型 core-logic；符号 check_tool_usage, check_batch_mode）: 该文件是唯一的变更文件，包含 `check_tool_usage` 和 `check_batch_mode` 两个 validator 中的 4 处 ValueError 到 VLLMValidationError 替换。

关键符号：check_tool_usage, check_batch_mode

## 关键源码片段

### `vllm/entrypoints/openai/chat_completion/protocol.py`

该文件是唯一的变更文件，包含 `check_tool_usage` 和 `check_batch_mode` 两个 validator 中的 4 处 ValueError 到 VLLMValidationError 替换。

```python
# vllm/entrypoints/openai/chat_completion/protocol.py
@model_validator(mode="before")
@classmethod
def check_tool_usage(cls, data):
    if isinstance(data, ValueError):
        raise data
    if not isinstance(data, dict):
        return data
    # 拒绝空 tools 数组，与 OpenAI API 行为一致
    if data.get("tools") == []:
        raise VLLMValidationError(
            "`tools` must not be an empty array. "
            "Either provide at least one tool or omit the field entirely.",
            parameter="tools",  # 新增参数名，便于 API 层返回结构化错误
        )
    ...
    return data

@model_validator(mode="before")
@classmethod
def check_batch_mode(cls, data: Any) -> Any:
    ...
    if data.get("use_beam_search"):
        raise VLLMValidationError(
            "Batch chat completions do not support beam search. "
            "Please set `use_beam_search` to False.",
            parameter="use_beam_search",
        )
    if data.get("logprob_token_ids") and not data.get("logprobs"):
        raise VLLMValidationError(
            "when using `logprob_token_ids`, `logprobs` must be set to true.",
            parameter="logprob_token_ids",
        )
    ...
    n = data.get("n", 1)
    if n is not None and n != 1:
        raise VLLMValidationError(
            "Batch chat completions do not support `n > 1`. Please set `n` to 1.",
            parameter="n",
            value=n,  # 传递具体的错误值
        )
    return data

```

# 评论区精华

没有实质性 review 讨论。只有 Claude bot 自动评论（由于来自 fork 而未执行自动 review）和维护者 DarkLight1337 的简单批准。

- 暂无高价值评论线程

# 风险与影响

- 风险：风险极低。VLLMValidationError 继承自 ValueError，所以任何捕获 ValueError 的现有异常处理都不会受到影响。消息文本保持不变，因此测试断言依然有效。唯一的潜在风险是，如果外部代码直接 `except ValueError as e` 并依赖异常类型以外的属性（例如假定没有 `parameter` 属性），但这种情况在标准 API 使用中几乎不会出现。
- 影响：对用户无直接可见影响（错误消息不变）。对系统的影响是未来 API 层可以通过 `VLLMValidationError.parameter` 构建更丰富的结构化错误响应。对团队的影响是继续清理技术债务，使校验逻辑更一致。影响范围小：仅一个文件，4 处校验。
- 风险标记：暂无

# 关联脉络

- PR #36254 [Feature] Use VLLMValidationError in request validators: 此 PR 是 #36254 的后续清理，继续迁移校验逻辑使用 VLLMValidationError。