Prhub

#51997 [Bugfix] Bound Anthropic stop sequences

原始 PR 作者 taneem-ibrahim 合并时间 2026-08-13 00:05 文件变更 1 提交数 1 评论 3 代码增减 +6 / -2

执行摘要

限制 Anthropic stop_sequences 数量,500 错误转 422

PR body 明确指出:PR #51447 bounded OpenAI stop parameters with VLLM_MAX_STOP_STRINGS,而 Anthropic requests remained unbounded, despite being converted internally into a bounded ChatCompletionRequest。实际表现是 5 个 stop_sequences 能通过 Anthropic 入口校验,却在 OpenAI 请求转换时报 List should have at most 4 items 并返回 HTTP 500。本 PR 的目的就是把同样的限制应用到 Anthropic API 边界,避免把客户端参数问题误报为服务器错误。

小而清晰的 bugfix,值得快速阅读学习两点:一是在 Pydantic 模型上使用 Annotated + Field(max_length=...) 表达字段级约束的写法;二是跨入口复用统一 env 校验边界、避免硬编码重复的做法。由于缺少测试覆盖,评审或合入后可以顺手补一条 Anthropic 入口超限用例,防止回归。

讨论亮点

实质技术讨论较少:claude[bot] 仅提示 fork 仓库自动 review 被禁用,需维护者手动触发;yewentao256 直接批准并回复 LGTM, thanks for the work!。PR body 还说明改动由 Codex 辅助起草,但所有变更行均经人工 review 与测试。讨论焦点实际上是行为取舍:把错误从 500 改为 422,属于对客户端友好且与 #52246 的 4xx 化方向一致的收紧。

实现拆解

  1. 变更入口:唯一改动文件 vllm/entrypoints/anthropic/protocol.py,核心对象是 AnthropicMessagesRequest 请求模型。
  2. 导入链路:新增 from typing import Annotated 和 import vllm.envs as envs,让字段定义能直接引用统一的 VLLM_MAX_STOP_STRINGS 环境变量,避免在 Anthropic 侧硬编码第二个上限常量。
  3. 字段约束:stop_sequences 的类型由 list[str] | None 改为 Annotated[list[str], Field(max_length=envs.VLLM_MAX_STOP_STRINGS)] | None,Pydantic 会在请求解析阶段对列表长度做校验,超限请求直接走 422。
  4. 配套情况:本次没有测试、配置或部署配套变更;该字段与 OpenAI 侧共用同一 env 开关,部署方只要调整 VLLM_MAX_STOP_STRINGS,两个入口行为会同步变化。建议后续补充 Anthropic 边界超限用例。

注意:VLLM_MAX_STOP_STRINGS 的具体默认值定义在 vllm.envs 中,本次变更材料未给出数值。

文件 模块 状态 重要度
vllm/entrypoints/anthropic/protocol.py 入口协议 modified 5.44

关键源码片段

vllm/entrypoints/anthropic/protocol.py input-validation

唯一变更文件,AnthropicMessagesRequest.stop_sequences 从无约束的 list[str] | None 改为带 Field(max_length=VLLM_MAX_STOP_STRINGS) 的 Annotated 类型,在入口完成数量校验。

"""vllm/entrypoints/anthropic/protocol.py 关键片段(整理版)"""import time
from typing import Annotated, Any, Literalfrom pydantic import BaseModel, Field, field_validator, model_validatorimport vllm.envs as envs # 读取全局统一的 VLLM_MAX_STOP_STRINGS
​
​
class AnthropicMessagesRequest(BaseModel):
    """Anthropic Messages API 请求模型"""
​
    model: str
    messages: list[AnthropicMessage] # AnthropicMessage 等辅助模型在同文件上方定义
    max_tokens: int
    metadata: dict[str, Any] | None = None
    output_config: AnthropicOutputConfig | None = None
​
    # 与 OpenAI 入口(PR #51447)复用同一上限: VLLM_MAX_STOP_STRINGS。
    # 此前这里不设限制,超限请求能通过 Anthropic 校验,却在内部转换为
    # ChatCompletionRequest 时才报错,最终以 HTTP 500 返回给客户端。
    # 现在由 Pydantic 在请求解析阶段直接拦截,错误码变成 422。
    stop_sequences: (
        Annotated[list[str], Field(max_length=envs.VLLM_MAX_STOP_STRINGS)] | None
    ) = None
​
    stream: bool | None = False
    system: str | list[AnthropicContentBlock] | None = None
    temperature: float | None = None
    tool_choice: AnthropicToolChoice | None = None
    tools: list[AnthropicTool] | None = None
    top_k: int | None = None
    top_p: float | None = None
    # 其余 vLLM 扩展字段(cache_salt、kv_transfer_params 等)从略

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 对外行为变化:此前能通过 Anthropic 入口的参数组合(超过上限的 stop_sequences)现在会被拒绝,属于预期的 API 收紧,但仍是客户可见变化,需要同步更新文档或客户端契约。
  2. 配置耦合:字段上限直接读取 envs.VLLM_MAX_STOP_STRINGS,若该环境变量在 Anthropic 路径未被正确加载(例如不同部署方式下 env 初始化顺序不同),会导致校验行为与 OpenAI 侧不一致;不过 vllm.envs 是全局统一加载,此风险较低。
  3. 回归风险:改动集中在入口协议层,不影响采样、调度与推理内核,回归面很小;但缺少新增测试,后续若有人重构 stop_sequences 转换逻辑,可能绕过该约束,建议补一条 entrypoint 级别的测试。

对用户:通过 Anthropic /v1/messages 发送超过 VLLM_MAX_STOP_STRINGS 个 stop_sequences 时,会从 500 Internal Server Error 变为明确的 422 请求校验错误,便于客户端提前修正。对系统:仅入口校验层变化,不触碰推理路径;两个 API 入口(OpenAI 与 Anthropic)对 stop 序列数量的约束首次对齐。对团队:这是入口校验前移的一个小样本,与 #52246、#52528 等前端错误码收敛工作形成系列,后续类似边界校验可以复用同一 env 开关模式。

入口校验行为收紧 缺少测试覆盖 依赖统一 env 配置

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论