用 Hermes Agent 有一段时间了。主模型选的 DeepSeek v4 pro,推理强、成本低、中文丝滑——各方面都很满意,直到需要它「看」一张图。
Error 400: unknown variant
image_url, expectedtext
不是配置问题,是 DeepSeek 模型本身不支持多模态输入。传图片给它,API 直接拒收。
但这不代表只能盲打。
Hermes 的关键设计:主模型和视觉模型可分开配置
Hermes 的架构有一个关键特性:主模型和辅助视觉模型可以分开配置。
model.provider控制日常文本推理用哪个模型auxiliary.vision.provider控制看图任务交给谁
两者互不干扰。用 vision_analyze 工具或者浏览器截图分析时,Hermes 自动把图片发给 vision provider,拿到文字描述后再交还给主模型继续推理。
DeepSeek 继续做它擅长的文本推理,看图的事外包给 Claude Haiku。主模型纹丝不动,成本几乎不增加。
配置 custom provider
Haiku 是 Anthropic 的模型,用的是 Anthropic Messages API 格式,不是 OpenAI 兼容格式。如果有直接的 Anthropic API Key,可以跳过中转这一步。如果在国内或者想用中转服务——
作者用的 Dragon Code,支持 Anthropic Messages 协议。选它的理由很简单:文档里明确写了 api_mode: anthropic_messages,Hermes 的 custom_providers 原生支持这个模式。
需要拿到:
- 中转服务的
base_url - 你的
api_key - 要用的模型 ID(比如
claude-haiku-4-5-20251001)
打开 ~/.hermes/config.yaml,在合适位置加入:
custom_providers:
- name: custom-dragoncode-codes
base_url: https://your-proxy-endpoint.com/v1
api_key: sk-your-api-key-here
api_mode: anthropic_messages
models:
- claude-haiku-4-5-20251001
坑点一:api_mode 必须写对
api_mode 必须写 anthropic_messages,不能写 openai。
Anthropic 的 API 请求体和响应体结构和 OpenAI 完全不一样。Hermes 在 anthropic_messages 模式下会自动处理这些差异——请求时把 messages 数组转成 Anthropic 格式,响应时把 content blocks 转回标准格式。写错了模式,请求直接 400。
坑点二:api_key_env 不稳定
api_key_env 引用环境变量在 custom_providers 里偶尔不稳定,直接把 key 写在 api_key 字段里更稳妥。
配置 vision provider
继续在 config.yaml 里,找到或新增 auxiliary 块:
auxiliary:
vision:
provider: custom-dragoncode-codes
model: claude-haiku-4-5-20251001
注意 provider 的值要和上面 custom_providers 里的 name 完全一致。
这时候配置是这样的:
model.provider还是deepseek—— 日常对话、代码、推理,全部走 DeepSeekauxiliary.vision.provider指向custom-dragoncode-codes—— 只有在看图的时候才调用 Haiku
两套完全独立,互不干扰。
关掉智能路由
一个容易被忽略但必须做的配置:
smart_model_routing:
enabled: false
Hermes 有一个智能路由功能,会根据消息长度和复杂度自动切换模型。问题是它切的是主模型,不是你配置的 vision provider。开着它,某些短消息场景下可能出现预期外的行为。保守起见关掉,保证一切行为可预测。
验证三步
改完配置后,重启 Hermes(或者直接开始新对话),然后逐项验证:
① 测文本 —— 确认 Haiku 能正常调用
curl -s -X POST "https://your-proxy-endpoint.com/v1/messages" \
-H "x-api-key: sk-your-api-key-here" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-haiku-4-5-20251001",
"max_tokens": 100,
"messages": [{"role": "user", "content": "say hello"}]
}'
返回正常文本响应,说明中转链路通畅。
② 测视觉 —— 确认能读图
同上,把 messages 里的 content 换成多模态格式(text + image base64),确认返回了正确的图片描述。
③ 在 Hermes 内实际调用
发一张图,然后说「看看这张图里有什么」。如果不再报 unknown variant image_url 而是正确描述了图片内容——配置成功。
方案价值
成本隔离。 视觉调用是低频场景。日常使用中 95% 以上的调用都是纯文本,走 DeepSeek 的极低成本。只有偶尔截图分析时才走 Haiku。不用为了「可能需要看图」就把整个主模型换成昂贵的多模态模型。
模型解耦。 文本模型和视觉模型可以独立升级。DeepSeek 出新版本,换 model 字段就行。Haiku 出更强版本,换 vision 的 model 字段就行。两条线互不影响。
一个 YAML 文件搞定。 不需要改代码,不需要装插件,不需要配代理。三处配置,纯声明式。
适用场景
- 用 DeepSeek 等纯文本模型作为主力的 Hermes 用户
- 偶尔需要截图分析、PDF 图表解读、UI 审查
- 国内用户通过中转服务访问 Anthropic 模型
- 不想因为视觉需求就整体迁移到更贵的多模态模型
如果日常大量使用视觉功能(比如频繁做截图审查),直接换一个原生支持多模态的主模型可能更合适。但对于「偶尔看图」的典型场景,这个解耦方案是最优解。
配置量不到 20 行 YAML。主模型跑得快,眼睛看得清,两不耽误。