本节摘要:军团要有粮草。
plugins/model-providers/下恰好 37 个 provider 插件目录,每个是"一个__init__.py注册一份ProviderProfile+ 一份 plugin.yaml 清单"的自包含单元;发现机制扫描该目录与$HERMES_HOME/plugins/model-providers/(用户插件同名覆盖内置)。其中国内模型七家原生支持:deepseek、kimi-coding(月之暗面)、minimax、qwen-oauth(阿里通义)、xiaomi(MiMo)、zai(智谱 GLM)、alibaba——中国开发者可以全栈国产。API 差异由 5 种适配器抹平:chat_completions(默认,OpenAI 兼容)、anthropic_messages、gemini native、bedrock、vertex、codex_responses。最后讲 profile 路由:gateway/profile_routing.py按 Discord guild/频道/线程等层级把不同入口路由到不同 profile(各配各的模型、工具、记忆、人格)。
内容来源:原项目源码
plugins/model-providers/(README 与 deepseek/zai 等插件)、providers/base.py、providers/__init__.py、agent/anthropic_adapter.py、agent/gemini_native_adapter.py、agent/bedrock_adapter.py、agent/codex_responses_adapter.py、gateway/profile_routing.py、website/docs/user-guide/profiles.md。
⚠️ 注意:区分两个"provider"概念——
providers/base.py的ProviderProfile是厂商画像(endpoint、凭据、quirk 钩子),而api_mode是协议形态(五种适配器)。一个厂商画像声明走哪种协议;国产厂商几乎全部走 chat_completions 兼容协议,这正是它们接入成本低的原因。
阅读完本节,你应当能够:
reasoning_content 回显陷阱与 profile 的解法。ProviderProfile 上五个以上 quirk 钩子字段的用途。plugins/model-providers/ 下 37 个目录(actual、ai-gateway、alibaba、alibaba-coding-plan、anthropic、arcee、azure-foundry、bedrock、commandcode、copilot、copilot-acp、custom、deepinfra、deepseek、fireworks、gemini、gmi、huggingface、kilocode、kimi-coding、meta-ai、minimax、nous、novita、nvidia、ollama-cloud、openai-codex、opencode-free、opencode-zen、openrouter、qwen-oauth、stepfun、upstage、vertex、xai、xiaomi、zai)。README 给出接一个新厂商的全部代码量:
plugins/model-providers/README.md: my_provider = ProviderProfile( name="your-provider", aliases=("alias1", "alias2"), env_vars=("YOUR_PROVIDER_API_KEY", ...), base_url="https://api.your-provider.example.com/v1", default_aux_model="your-cheap-model", ) register_provider(my_provider)
发现机制(providers/__init__.py 的 _discover_providers)首次调用 get_provider_profile() 或 list_providers() 时扫描目录、import 每个子目录的 __init__.py;$HERMES_HOME/plugins/model-providers/<name>/ 的用户插件同名覆盖内置(last-writer-wins)。README 的承诺是"Nothing else needs to change"——auth.py、config.py、models.py、doctor.py、model_metadata.py、chat_completions 传输层全部从注册表自动接线。
ProviderProfile(providers/base.py:39)的 quirk 钩子密度惊人,选几个代表:fixed_temperature(Kimi 由服务端管温度,请求必须整个省略 temperature 字段)、supports_vision_tool_messages(小米 MiMo 收图片但拒绝列表型 tool 消息内容,会 400 "text is not set")、supports_prompt_cache_key(只有明确文档化的端点才敢发这个顶层字段)、build_api_kwargs_extras(请求级改写钩子,下文 DeepSeek 实例)。厂商差异被锁死在画像一个类里,与网关的平台差异锁死在适配器里是同一设计语法。
国产 provider 清单:deepseek、kimi-coding、minimax、qwen-oauth、xiaomi、zai、alibaba(含 alibaba-coding-plan 定向子档)。各家 profile 不只是填 endpoint,还把真实生产事故修在了钩子里。DeepSeek 是最佳教材——模块 docstring 讲了一个完整的故事:
deepseek/__init__.py:3 DeepSeek's V4 family defaults to thinking-mode ON when 4 ``extra_body.thinking`` is unset. The API then returns 5 ``reasoning_content`` and starts enforcing the contract that subsequent 6 turns echo it back; combined with how Hermes replays history this lands on 7 the notorious HTTP 400 ``reasoning_content must be passed back`` error 8 after the first tool call (#15700, #17212, #17825).
V4 家族默认开思考模式,API 返回 reasoning_content 并要求后续轮次回显;Hermes 回放历史的方式撞上这个契约,第一次工具调用后必然 400。解法是 DeepSeekProfile.build_api_kwargs_extras(deepseek/init.py:52):对 V4+ 模型显式写 extra_body.thinking = {"type": "enabled"|"disabled"},effort 经 agent.reasoning_effort 的共享词表夹取到 low/medium/high/max;V3 系列(不支持 thinking)原样放行不动线格式。退役别名 deepseek-chat/deepseek-reasoner 由 hermes_cli.model_normalize 重映射到 v4-flash/v4-pro——profile 连模型目录的兴衰都管。
zai(智谱 GLM)是同型故事的第二幕:GLM-4.5+ 默认开思考,Hermes 的 reasoning_config={"enabled": False} 在基础画像上是静默 no-op——用户在桌面端关了思考、/reasoning none 也设了,token 照烧。ZaiProfile.build_api_kwargs_extras 把关掉的意愿真正翻译成 thinking: {"type": "disabled"};GLM-5.2+ 的 reasoning_effort 只有两档(high/max),更细的档位向上折叠。版本探测全靠正则(_GLM_VERSION_RE 匹配 glm-4.5/4.6/5…),还兼容各家中转拼法(glm-5-2、glm-5p2、z-ai/glm-5.2)。

第 2 章讲过内循环把三种 API 模式收敛到 OpenAI 消息格式;本节从 provider 侧补全这张地图。api_mode 的取值与对应适配器模块:
| api_mode | 适配器 | 服务对象 |
|---|---|---|
| chat_completions(默认) | OpenAI SDK 直连 | 绝大多数厂商(含全部国产七家) |
| anthropic_messages | agent/anthropic_adapter.py |
Anthropic 原生 Messages API |
| gemini native | agent/gemini_native_adapter.py |
Google 原生(含 thinking_config 翻译、gemini_schema.py 工具 schema 净化) |
| bedrock | agent/bedrock_adapter.py |
AWS Bedrock(boto3 SigV4) |
| vertex | agent/azure_identity_adapter.py 等 |
GCP Vertex(OAuth 应用默认凭据) |
| codex_responses | agent/codex_responses_adapter.py |
OpenAI Responses API(Codex 系) |
注意 anthropic/bedrock/vertex/openai-codex/gemini 同时也有 provider 插件目录——画像(谁)与适配器(说什么话)正交组合。国产七家全部走 chat_completions 兼容协议,这是国内大模型 API 生态的事实标准红利:Hermes 零专有代码即可接入,profile 里写的全是 quirk 修正而非协议翻译。
同一个网关实例,不同聊天入口用不同模型/工具/记忆/人格——gateway/profile_routing.py 头部给出四级匹配(最specific优先):
profile_routing.py:7 Matching priority (most specific first): 8 1. platform + chat_id + thread_id (exact thread) — specificity 14 9 2. platform + chat_id (channel route) — specificity 6 10 3. platform + guild_id (guild/server route) — specificity 2 11 4. No match → default profile
配置在 config.yaml 的 gateway.profile_routes 列表里逐条声明(name/platform/guild_id/chat_id/thread_id/profile),Discord 线程与论坛帖还支持 parent_chain:绑在频道上的路由同时命中频道直聊与其下所有线程。命中后消息进入该 profile 的会话键命名空间(第 7 章的 agent:<profile> 前缀,两个 profile 服务同一聊天永不碰撞),模型、工具集、记忆、SOUL 人格全套换装。用法举隅:工作群路由到 glm-5.2 + 全工具 + 编程技能;家庭群路由到 kimi + 轻工具 + 闲聊人格——一套部署,多个 Agent 人格,按聊天窗口自动切换。
💡 循环要点:provider 层的中文生态不只是"能用国产模型",而是把国产模型的生产事故修进了代码——reasoning_content 回显、thinking 静默失效、两档 effort 折叠,每个 quirk 钩子背后都是真实 issue 编号。这与外循环的哲学同构:经验不只沉淀进技能,也沉淀进接线的每一个角落。对国内开发者,deepseek+kimi+qwen+glm 的全家桶意味着从模型到 IM(第 7 章)到检索(第 5 章 FTS5 中文分词)的完整国产替代路径。
__init__.py 注册 Profile + plugin.yaml 清单);发现扫描内置与 $HERMES_HOME 两处,用户同名覆盖内置;README 承诺"其余全部自动接线"。下一节收拢 CLI 侧的中文体验:17 种语言本地化(zh.yaml)、
hermes命令大家族,以及 mcp_serve 如何把整个 Hermes 反向变成别的 agent 的工具。