DeepAI Paper Hermes Agent 教程,Hermes 上下文、流式与输出,Hermes 多模态与工具调用 Hermes 多模态排错:image_url 发给非视觉模型为什么会 400?

Hermes 多模态排错:image_url 发给非视觉模型为什么会 400?

Hermes Agent 接入 DeepAI 或其他 OpenAI-compatible API 时,很多用户会先关心文本模型能不能聊、工具能不能跑。

但还有一个容易踩坑的场景:图片消息。

你在 Discord、Web UI 或其他平台里给 Hermes 发了一张图,Hermes 把消息转换成 OpenAI-compatible 的 image_url content part,然后请求发给 provider。

如果后端模型是 vision model,理论上可以正常理解图片。

如果后端模型不是 vision model,就可能直接报:

HTTP 400
unsupported image_url
model does not support vision
invalid content type

这类错误不一定是 DeepAI API Key 错,也不一定是 Base URL 错,而是“消息里带了图片字段,但当前模型不支持图片”。

本文基于 Hermes GitHub PR #23750,专门讲 Hermes 的 vision / non-vision 兼容性排错。


相关 Issue / PR:provider profile path 没剥离 image_url

相关 PR:

https://github.com/NousResearch/hermes-agent/pull/23750

这个 PR 的核心修复是:

strip image parts for non-vision models on provider profile path

PR 里描述的问题是:

_prepare_messages_for_non_vision_model 只在 legacy flag path 被调用,但 provider profile path 跳过了这一步。

结果就是:当请求走 provider profile path 时,带有 image_url parts 的 /v1/chat/completions 请求会原样发给 non-vision models。

涉及的 provider 示例包括:

deepseek
kimi
openrouter

这些 non-vision 模型收到图片字段后,会返回 HTTP 400。

修复方式是在 provider profile path 也调用同样的预处理逻辑:

_msgs_for_profile = self._prepare_messages_for_non_vision_model(api_messages)
messages = _msgs_for_profile

这样 legacy path 和 provider profile path 对图片消息的处理保持一致。


这个问题为什么容易误判?

因为用户看到的只是:

Hermes 请求模型失败
HTTP 400

如果同时使用 DeepAI / OpenAI-compatible 中转站,很多人会第一时间怀疑:

  • API Key 是不是错了;
  • Base URL 是不是错了;
  • DeepAI 是不是不兼容 Hermes;
  • 模型名是不是写错了;
  • 中转站是不是坏了。

但如果请求 payload 里带着:

{
  "type": "image_url",
  "image_url": {
    "url": "..."
  }
}

而你选的模型并不支持视觉输入,那 400 是正常的。

真正的问题是:Hermes 是否应该在发给非视觉模型前,把图片部分剥离、降级或改写成文本提示。


OpenAI-compatible 不等于自动支持多模态

OpenAI-compatible API 只说明接口结构大体兼容,比如:

/v1/chat/completions
Authorization: Bearer ...
messages
model
stream

但不代表每个模型都支持:

  • image_url;
  • audio;
  • file input;
  • tool call;
  • reasoning_content;
  • JSON mode;
  • vision embedding;
  • 超长上下文。

同一个 /v1/chat/completions endpoint 下,有的模型支持图片,有的模型只支持文本。

所以多模态排错的第一步不是看接口是否 OpenAI-compatible,而是看当前 model ID 是否 vision-capable。


典型报错场景

场景 1:用户在 Discord 里发图

链路可能是:

Discord 图片附件
  ↓
Hermes Gateway 转换消息
  ↓
OpenAI-compatible messages 中出现 image_url
  ↓
Hermes provider profile path
  ↓
非视觉模型
  ↓
HTTP 400

如果 Hermes 没有正确剥离图片字段,non-vision 模型会拒绝请求。

场景 2:Web UI 上传图片

Web UI 支持图片上传,不代表后端模型支持视觉。

前端能上传,只说明平台能接收图片;真正能不能理解图片,取决于 Hermes 最终选用的 provider/model。

场景 3:OpenRouter / 聚合商里选错模型

聚合商里模型很多,有些支持 vision,有些不支持。

如果模型名看起来很强,但实际不是 vision model,image_url 一样会 400。

场景 4:DeepAI 中转站模型能力没确认

DeepAI API 中转站提供 OpenAI-compatible 入口,但具体模型是否支持图片,要以 DeepAI 控制台里的模型能力为准。

不要看到 endpoint 兼容 OpenAI,就默认所有模型都能吃图片。


怎么判断是不是 image_url 导致的 400?

可以按这个顺序查。

1. 看请求是否包含 image_url

如果日志、debug payload 或错误上下文里出现:

image_url
input_image
content part type=image_url

就要进入多模态排查分支。

2. 看当前模型是否支持 vision

确认 model ID 是不是视觉模型。

不要靠名字猜。

去 provider 控制台、DeepAI 控制台或模型文档确认。

3. 换纯文本消息测试

同一个会话,不发图,只发:

请回复 ok

如果纯文本正常,发图 400,基本就是 vision 兼容性问题。

4. 换 vision model 测试

如果你有明确支持图片的模型,切过去再发同一张图。

如果 vision model 正常,non-vision model 400,就说明不是 DeepAI Key / Base URL 问题。

5. 检查 Hermes 版本

确认你的 Hermes 是否包含 provider profile path 上的 non-vision preprocessing 修复。

PR #23750 的重点就是:legacy path 做了处理,但 provider profile path 曾经漏掉。


用户能做的临时规避

如果你还没升级 Hermes,可以先这样规避。

不给非视觉模型发图片

最简单。

如果当前模型只支持文本,就不要在同一轮消息里附图。

用文字描述图片

可以让用户先手动描述:

这张图大概是一个报错截图,错误内容是 ...
请帮我分析

这对纯文本模型更稳定。

切换到 vision-capable 模型

如果任务确实需要看图,换支持图片的模型。

但模型 ID 必须以 DeepAI 控制台或 provider 文档为准,不要凭印象写。

在平台侧提示用户

如果你给团队部署 Hermes,可以在机器人说明里写清:

当前模型不支持图片。请发送文字,或切换到视觉模型后再上传图片。

升级 Hermes

如果你命中了 provider profile path 的 bug,升级到包含 PR #23750 修复的版本更靠谱。


DeepAI 接 Hermes 时怎么测多模态?

如果你用 DeepAI API 中转站作为 Hermes 的模型入口,建议分三步测。

第一步:文本直连

先确认文本接口可用:

curl https://api.deepai.wang/v1/chat/completions \
  -H "Authorization: Bearer YOUR_DEEPAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "YOUR_MODEL_ID",
    "messages": [{"role": "user", "content": "reply ok"}]
  }'

这只证明文本 chat completions 正常。

第二步:确认模型能力

去 DeepAI 控制台确认这个模型是否支持:

文本
图片输入
工具调用
长上下文
流式输出

不要把“接口兼容”当成“能力全开”。

第三步:只对 vision model 测图片

如果模型明确支持图片,再测试 image_url

如果模型不支持图片,不要强行测;400 不是故障,而是能力不匹配。


多模态问题和前几类问题怎么区分?

Hermes 排错很容易混在一起。可以用这个表区分。

现象更可能原因优先检查
纯文本正常,发图 400非视觉模型收到 image_url模型 vision 能力、Hermes preprocessing
curl 文本正常,Hermes 发图失败Hermes payload 含图片字段messages content parts
主聊天正常,标题生成失败auxiliary client 问题title generation / proxy / aux provider
Discord 长回复发两遍delivery 幂等问题Gateway / Discord adapter
403 ForbiddenWAF / headers / auth 策略headers、provider、Cloudflare
404 endpointbase_url / api_mode 路由/v1、provider path、api_mode

如果只有图片触发错误,就不要先改 API Key。


给站长和开发者的建议

如果你把 Hermes 部署给团队用,建议把模型能力写清楚。

例如:

当前默认模型:文本模型
支持:文本问答、代码、工具调用
不支持:图片理解、音频理解

如果提供多个 profile,可以分开:

profile/text:默认文本模型,稳定便宜
profile/vision:支持图片,成本更高
profile/long-context:适合长文档

这样用户不会把图片发给文本模型,也不会把 400 当成系统故障。

如果你在 Hermes 里配置 DeepAI,可以在内部文档里写:

DeepAI Base URL: https://api.deepai.wang/v1
模型能力以 DeepAI 控制台为准
图片任务必须选择 vision-capable 模型
非视觉模型遇到 image_url 可能返回 400

这比事后排错更省时间。


相关文章

Hermes PR #23750:strip image parts for non-vision models on provider profile path

https://github.com/NousResearch/hermes-agent/pull/23750

DeepAI API 中转站:

https://api.deepai.wang/

Hermes 接入 DeepAI 基础教程:

Hermes Agent 接入 DeepAI 教程:用 Custom Endpoint 配 OpenAI Compatible API

Hermes Provider 兼容性排错:

Hermes Provider 兼容性排错:reasoning_content、custom headers、上下文长度和 api_mode 继承

Hermes Auxiliary 任务排错:

Hermes Auxiliary 任务排错:主聊天正常,为什么标题生成、压缩和后台 review 会失败?


总结

Hermes 多模态报 400,很多时候不是 Key 错,也不是 DeepAI Base URL 错,而是 image_url 被发给了非视觉模型。

OpenAI-compatible 只代表接口形态兼容,不代表每个模型都支持图片。

PR #23750 的价值就在于:Hermes 需要在所有请求路径上,对 non-vision model 做一致的图片字段预处理。legacy path 处理了,provider profile path 也必须处理。

用 DeepAI 接 Hermes 时,建议先确认文本调用,再确认模型是否支持 vision,最后再测试图片。不要把“能走 /v1/chat/completions”误解成“所有多模态输入都能吃”。

Related Post

只有思考没有正文,Hermes 流式输出也会崩:Gemini reasoning-only delta 的 .content 空洞只有思考没有正文,Hermes 流式输出也会崩:Gemini reasoning-only delta 的 .content 空洞

Gemini Code Assist streaming 中 reasoning-only delta 先于正文到达,Hermes 旧版 _make_stream_chunk 没有补 content=None,导致 downstream 访问 delta.content 时报 AttributeError。本文复盘 #24974:为什么流式 chunk schema 必须稳定。

Hermes zsh 补全报 _arguments: invalid argument:短选项和长选项不能这样写Hermes zsh 补全报 _arguments: invalid argument:短选项和长选项不能这样写

Hermes 的 hermes completion zsh 曾生成不合法的 Zsh _arguments 语法,例如 (-h --help){-h,--help},导致 _arguments:comparguments: invalid argument。本文客观复盘 #22686:为什么 exclusion group 不能混入长选项、如何改成 (-){-h,--help},以及如何用 zsh -n 做回归验证。

没装 Claude,Agent 却偏要调用 Claude:Hermes delegate_task 的“示例诱导”问题没装 Claude,Agent 却偏要调用 Claude:Hermes delegate_task 的“示例诱导”问题

Hermes delegate_task 在工具 schema 中把 claude 和 Claude Code 写成显眼示例,可能诱导 Agent 在未安装 Claude 的环境里尝试 Claude ACP。本文复盘 #22013:为什么工具说明本身也是 prompt surface,以及如何用环境检测和 schema gating 降低误调用。