DeepSeek V4-Flash-Vision-Exp 把视觉能力加进了 API:你的路由层需要做什么

DeepSeek 8 月 21 日上线了首个多模态模型。真正的路由问题不是模型本身,而是视觉请求要求 content 字段必须是数组,而你的代理中间层可能只处理了字符串。

发布于 来源 DeepSeek

归档条目:由 AI 根据所引信源辅助生成,发布时未经逐篇审阅。责任编辑:Joe Werner。

抽象技术图:图像 token 流经 API 路由层,文本请求和多模态请求走向两条不同路径

DeepSeek 在 8 月 21 日上线了 deepseek-v4-flash-vision-exp,这是它第一个可以处理图像输入的模型。从跑分来看,纯文本 agent 任务上的表现与 V4-Flash 基本持平,视觉 agent 能力则接近 Opus-4.8。对路由团队来说,跑分那一行反而最不重要。真正的问题出在消息格式上,更早。

API 层发生了什么变化

模型 ID 是 deepseek-v4-flash-vision-exp,base URL 仍然是 https://api.deepseek.com,OpenAI 兼容的 /chat/completions 接口和 Anthropic 兼容的 /anthropic/messages 接口都支持。

变化在 content 字段。纯文本请求通常把 content 传成一个字符串。

{"role": "user", "content": "请总结这段文档。"}

视觉请求则必须把 content 传成类型化 block 的数组。

{
  "role": "user",
  "content": [
    {"type": "text", "text": "这张图表说明了什么?"},
    {"type": "image_url", "image_url": {"url": "https://example.com/chart.png"}}
  ]
}

任何把 content 强制转为字符串的代理中间层,或者只处理了字符串情况的封装代码,发出去的都是一个格式错误的请求,DeepSeek 会回 400。这包括所有在多模态流行之前写的薄层 OpenAI proxy,也包括自建网关里做了 content = str(message) 的日志或 token 估算逻辑。

Anthropic 兼容端点的图像 block 格式不同。这里不用 image_url,改成带 source 对象的 image block,source.type 可以是 base64、url 或 file。如果你的路由管道里同时走 DeepSeek 和 Claude,就需要在同一套代码里处理两种不同的图像格式。

三种图像传输方式,各有不同的路由影响

DeepSeek 支持三种发图方式,哪种适合你的路由层,文档里看不太出来。

inline base64 把图像数据直接嵌进请求体。它计入 48 MiB 的请求体限制,单张图最大 32 MiB。对单次请求而言延迟最低,不需要预先上传,但请求体会很大,在限速代理里序列化表现很差。

外部 URL 让 DeepSeek 模型自己去下载图像。URL 最长 8192 个字符,图像最大 32 MiB,下载必须在 60 秒内完成。如果图像放在需要鉴权的地址,或者 CDN 有爬虫频率限制,请求会间歇性失败。用于公开资源没问题,用于带短效签名 URL 的资源就很不可靠。

Files API 的 file_id 适合反复使用同一张图,或者图像超过 32 MiB 的情况。通过 Files API 上传的文件最大 64 MiB,不计入 inline 请求体的限制。代价是第一次请求前需要一个上传步骤,而且 file ID 绑定的是你的 DeepSeek 账号,不能通过替换凭据的通用代理透传。

每次请求最多放 600 张图,使用 file ID 时总大小上限 200 MiB,否则是 64 MiB。图像按 token 计费,DeepSeek 会在推理前把每张图归一化到大约 800×800,所以 5000×5000 和 1000×1000 的图消耗 token 数相同,每张图最多 384 个 token。

detail 参数是一个廉价的分流开关

对 image_url 类型的输入,DeepSeek 提供了 detail 字段,可选 low、high、original、auto。设成 low 会在推理前把图缩到 512×512,速度更快、成本更低,适用于不需要像素级精度的场景。

这个参数对路由有实际意义。如果你的管道在正式处理前需要先判断上传内容的类型,比如判断这是表格、图表还是照片,可以用 detail: "low" 跑分类调用,只有分类结果需要进一步处理时才走全分辨率。对上传量大、大部分都是简单截图或表单的管道,成本差异会很明显。

high 和 original 效果相同,都保留原始图像。auto 目前等同于 original。

experimental 状态对路由策略意味着什么

exp 后缀在这里是有实际含义的。这个模型没有生产级 SLA,DeepSeek 也没有公布它的频率限制档位。也就是说,不能不加 fallback 就把它当 V4-Flash 的直接替代品来路由。

一个可行的做法是把 deepseek-v4-flash-vision-exp 设为需要处理图像的请求的主路由,在收到 429、503 或 model-not-found 错误时 fallback 到其他支持视觉输入的 provider,比如 Gemini 3.5 Flash 或者任何支持 image_url 的模型。同时保留 V4-Flash 作为纯文本路由,这样当视觉能力对场景来说不是必须的,也能降级到文本路径而不是直接报错。

迁移前后的请求格式

迁移前的纯文本请求,任何模型都兼容。

response = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "请总结这段内容。"}]
)

迁移后的视觉请求,需要把模型 ID 换成 vision 版本。

response = client.chat.completions.create(
    model="deepseek-v4-flash-vision-exp",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "请总结这份文档。"},
            {"type": "image_url", "image_url": {"url": image_url, "detail": "low"}}
        ]
    }]
)

图像只能放在 user 消息里。system 或 assistant 消息里放图像会返回 400。如果你的 agent 在 system prompt 里用了图像,比如品牌头图或参考图表,需要把它移到第一条 user 消息里。

TheRouter 用户需要关注什么

DeepSeek 的视觉路由目前还比较早期,没有基于消息内容自动判断是否含图的路由机制,需要在网关层显式指定模型。合理的做法是在分发前检查每条消息,判断是否存在 type: "image_url" 或 type: "image" 的 content block,有的话就路由到 deepseek-v4-flash-vision-exp 或你偏好的视觉 provider。

鉴于 experimental 状态和未知的频率限制档位,建议保持多 provider 的 fallback,而不是把它当成稳定的主路由。完整的限制参数表可以查看 DeepSeek Vision 文档。

帮助与联系