☰
JetBrains Air × Hermes Agent:ACP 连接配置与 Provider 过滤实战(TaoToken 统一 Key 接入)
2026/10/18 22:20:38 网站建设 项目流程

1. JetBrains Air 接入 Hermes Agent 的真实场景与 ACP 是什么

如果你正在用 JetBrains Air 这类新一代 AI IDE,又想把自己已经配好的 Hermes Agent 直接塞进编辑器里当助手,那 ACP 就是那条必经之路。ACP 全称 Agent Client Protocol,是一个开放协议,让编辑器(客户端)和外部 AI Agent(服务端)用标准化的方式通信。传输层走 stdio,消息格式是 JSON-RPC 2.0,握手流程是 initialize → agentInfo → notifications/initialized → session/new。听起来像天书,其实你可以把它理解成"编辑器和 Agent 之间约定好的对讲机频道":Air 负责喊话,Hermes Agent 负责应答,双方按固定格式交换 JSON。

我这次的目标很明确:在 JetBrains Air 里把 Hermes Agent 接进来,并且只显示方舟 kl provider 的模型,不要出现 Anthropic、Copilot、MOA 这些无关的 provider。整个过程踩了两个大坑,一个是 acp.json 的路径不对,另一个是 Provider 过滤配置写成了字符串而不是列表。下面把完整链路拆开讲,每一步都能直接复制。

先说清楚适合谁看:你已经在本地跑通了 Hermes Agent(hermes-acp --version能出版本号),用的是 macOS,JetBrains Air 已经装好,并且你希望把 endpoint 和 Key 统一指向 TaoToken 的 API 通道,而不是散落在各个 provider 的原始地址里。如果你还没装 Hermes Agent,建议先把 Agent 本体跑起来再回来看这篇。

ACP 的核心价值在于解耦。以前每个编辑器接一个 Agent 都要写一套适配代码,现在只要 Agent 实现了 ACP 适配器,任何支持 ACP 的编辑器都能直接连。Hermes Agent 内置了hermes-acp这个适配器,不需要额外安装。Air 这边则通过一个叫fleet.plugins.ai.agent.genericacp的插件来发现和启动 ACP agent。两边对上暗号,就能在编辑器里直接调用 Agent 的模型选择、会话管理、图片输入等能力。

这里有个容易忽略的点:ACP 的握手是双向确认的。客户端发 initialize 时带上 protocolVersion 和 clientCapabilities,服务端返回 agentInfo、agentCapabilities 和 authMethods。只有 authMethods 里列出的认证方式被客户端识别,后续的 session/new 才能建立。所以如果你发现连上了但建不了会话,八成是 authMethods 没对上。

2. TaoToken 前置准备:统一 Key 与 endpoint 的接入思路

在动手改 acp.json 之前,先把 TaoToken 这一层理清楚。TaoToken 在这里扮演的是统一 API 通道的角色:你不需要为每个 provider 单独维护一套 Key 和 endpoint,而是把请求都指向https://taotoken.net/api,由它来路由。官网入口是https://taotoken.net/?utm_source=taotoken_aicg_blog_end,注册和拿 Key 都在这里完成。

具体操作分三步。第一步,登录后在控制台创建 API Key,路径是 console 页面下的 api-keys 管理。第二步,把 Key 写进 Hermes 的环境变量文件~/.hermes/.env,字段名用ARK_API_KEY(如果你沿用方舟的命名习惯)或者自定义一个,只要和 config.yaml 里的key_env对上即可。第三步,把 config.yaml 里 custom_providers 的base_url指向 TaoToken 的 API 通道。

这里要强调一个原则:endpoint 和 Key 要成对出现。你不能 base_url 指向 TaoToken,Key 却还是原来 provider 的 Key,那样鉴权一定失败。反过来也一样。统一指向 TaoToken 的好处是,后面你想换模型、换 provider,只改 config.yaml 里的 model 字段,不用动 acp.json,也不用重新在 Air 里配置。

如果你还没决定用哪种接入方式,可以先在模型对话页面验证一下 Key 是否可用,确认能正常返回再往下走。对于长期编码和 Agent 场景,Coding Plan 会更合适,因为它针对多轮会话和工具调用做了优化。接入文档里有完整的字段说明,遇到不确定的参数先去查文档,比在日志里猜要快得多。

需要提醒的是,TaoToken 是合规的 API 聚合通道,不是所谓的"中转"。它的作用是帮你把多个 provider 的调用统一到一个入口,减少配置分散带来的维护成本。你在 config.yaml 里写的 base_url 就是它的标准 API 地址,不要加任何额外路径后缀,除非文档明确说明。

准备好 Key 之后,先别急着改 Air 的配置。建议先用命令行验证一次 Hermes Agent 本身能不能通过 TaoToken 拿到模型列表。这一步能排除掉大部分"到底是 Agent 的问题还是编辑器的问题"的纠结。验证命令后面会给出。

3. 可复制配置:acp.json 与 config.yaml 完整片段

这一节是全文的核心,所有配置都能直接复制。先给 Air 的 ACP 配置文件,路径是~/Library/Application Support/JetBrains/Air/acp.json。注意不是acp-agents/installed.json,那个路径是错的,我一开始就是栽在这里。

{ "agent_servers": { "hermes-agent": { "command": "/Users/你的用户名/.hermes/hermes-agent/venv/bin/hermes-acp", "args": [], "env": {} } } }

字段说明:command是 hermes-acp 可执行文件的绝对路径,用which hermes-acp能查到;args是启动参数,一般留空;env是环境变量,如果你不想用.env文件,也可以在这里直接写 Key,但推荐用.env统一管理。type字段是可选的,不写也能识别。

然后是 Hermes 的主配置~/.hermes/config.yaml,重点是 custom_providers 和 model_catalog 两块:

model: default: ark-code-latest api_mode: codex_responses provider: kl context_length: 128000 custom_providers: - name: kl base_url: https://taotoken.net/api api_mode: codex_responses model: ark-code-latest key_env: ARK_API_KEY discover_models: false models: auto: name: "Auto - 智能调度模型" doubao-seed-evolving: name: "Doubao-Seed-Evolving (1M ctx, Coding/Agent)" doubao-seed-2.1-turbo: name: "Doubao-Seed-2.1-turbo (Coding/Agent/多形态)" doubao-seed-2.0-lite: name: "Doubao-Seed-2.0-lite (通用生产级, thinking)" doubao-seed-2.0-mini: name: "Doubao-Seed-2.0-mini (低时延, thinking)" deepseek-v4-flash: name: "DeepSeek-V4-Flash (Agent增强)" kimi-k3: name: "Kimi-K3 (1M ctx, 原生视觉理解)" glm-5.2: name: "GLM-5.2 (1M ctx, 智谱旗舰) 当前" kimi-k2.7-code: name: "Kimi-K2.7-Code (小鲜, 图片+视频输入)" minimax-m3: name: "MiniMax-M3 (编程/Agent顶尖)" deepseek-v4-pro: name: "DeepSeek-V4-Pro (thinking)" minimax-m2.7: name: "MiniMax-M2.7 (即将下线)" kimi-k2.6: name: "Kimi-K2.6 (即将下线, thinking)" model_catalog: enabled: true url: https://hermes-agent.nousresearch.com/docs/api/model-catalog.json ttl_hours: 1 excluded_providers: - anthropic - copilot - moa

关键点有三个。第一,base_url指向https://taotoken.net/api,这是 TaoToken 的标准 API 地址,不要加/v1之类的后缀。第二,discover_models: false很重要,因为方舟端点不支持/v1/models探测,设成 true 会导致模型列表被清空,只能靠下面声明的 models 列表。第三,excluded_providers必须是 YAML 列表,不能是字符串。

环境变量文件~/.hermes/.env:

ARK_API_KEY=你的TaoToken_API_Key

三件套齐了:Base URL 是https://taotoken.net/api,Key 是ARK_API_KEY对应的值,Model ID 是ark-code-latest。这三个字段在 config.yaml 里都能找到对应位置,改的时候一起改,别只改一个。

如果你用的是 Cline MCP 或者 Codex 的 auth.json,思路是一样的:Base URL 填 TaoToken 的 API 地址,Key 填 TaoToken 的 Key,Model ID 填你要用的模型。三件套缺一不可,缺哪个都会在鉴权或模型列表阶段报错。

4. 验证请求:一次最小 ACP 握手确认连接与过滤生效

配置写完,先别急着开 Air。用命令行做一次最小 ACP 握手,确认 hermes-acp 本身能正常响应。这条命令直接管道输入 initialize 请求:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}' | hermes-acp

正常返回应该包含 agentInfo 和 authMethods,类似这样:

{ "jsonrpc": "2.0", "id": 1, "result": { "agentCapabilities": { "loadSession": true, "promptCapabilities": {"image": true}, "sessionCapabilities": {"fork": {}, "list": {}, "resume": {}} }, "agentInfo": { "name": "hermes-agent", "version": "0.20.0" }, "authMethods": [ { "id": "custom", "name": "custom runtime credentials", "description": "Authenticate Hermes using the currently configured custom runtime credentials." }, { "id": "hermes-setup", "name": "Configure Hermes provider", "type": "terminal", "args": ["--setup"] } ], "protocolVersion": 1 } }

看到agentInfo.name是hermes-agent,说明适配器正常。接下来验证 Provider 过滤是否生效。先重启 Hermes serve 进程让 config.yaml 生效:

kill <serve_pid>

Hermes 桌面应用会自动重启 serve 进程。然后查 Air 日志确认连接:

grep -i "acp\|hermes\|agent" ~/Library/Logs/JetBrains/Air/air.log | tail -10

正常日志会显示ACP client connected、Initialize from air (protocol v1)、Caching 2 auth methods、New session等字样。如果看到No agents connected,说明 acp.json 路径或内容有问题,回到第 3 节检查。

验证模型列表过滤,可以查 Hermes 的模型选择 API。先拿到 serve 进程的端口和 token:

ps aux | grep "[h]ermes.*serve" lsof -p <serve_pid> -iTCP -sTCP:LISTEN | grep python TOKEN=$(ps eww <serve_pid> | tr ' ' '\n' | grep HERMES_DASHBOARD_SESSION_TOKEN | cut -d= -f2) curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:<port>/api/model/options

返回的 provider 列表里应该只有custom:kl,Anthropic、Copilot、MOA 都不见了。如果还看到它们,说明 excluded_providers 没生效,大概率是写成了字符串。用 Python 检查一下类型:

import yaml with open("/Users/你的用户名/.hermes/config.yaml") as f: cfg = yaml.safe_load(f) print(type(cfg["model_catalog"]["excluded_providers"]))

输出应该是<class 'list'>。如果是<class 'str'>,说明被hermes config set存成了字符串,需要手动改回列表。

最后在 Air 里打开模型选择器,应该只看到 kl provider 的 14 个模型(13 个语言模型 + auto 智能调度)。到这一步,连接和过滤都验证通过了。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

配置过程中最容易撞上的几类报错,逐个拆解。

401 Unauthorized。这个基本是 Key 的问题。先确认~/.hermes/.env里的ARK_API_KEY和 config.yaml 里key_env指向的字段名一致。然后确认这个 Key 是 TaoToken 控制台创建的,不是原来 provider 的 Key。如果 base_url 指向 TaoToken 但 Key 用的是别家的,必然 401。还有一种情况是 Key 有空格或换行,用cat -A ~/.hermes/.env检查一下有没有隐藏字符。

local proxy failed。这个报错通常出现在 base_url 写错的时候。比如你写成了https://taotoken.net/api/v1,多了一层路径,请求就打到不存在的端点上了。TaoToken 的标准 API 地址就是https://taotoken.net/api,不要自作主张加后缀。另外检查一下有没有在系统层面配了什么本地转发,如果有,先关掉再试。

reading choices 报错。这个一般出现在模型返回格式不符合预期的时候。常见原因是api_mode设错了。方舟的 codex_responses 模式要求api_mode: codex_responses,如果你写成了chat_completions,返回结构对不上,解析就会失败。检查 config.yaml 里 model 和 custom_providers 两处的 api_mode 是否一致。

OAuth 相关报错。Hermes 桌面应用如果之前登录过 Anthropic 或 Copilot 的 OAuth,这些 provider 会被标记为"已配置",即使你设了explicit_only=True也会出现在列表里。这就是为什么必须用excluded_providers显式排除。如果你看到 OAuth token 过期的报错,要么重新登录,要么直接在 excluded_providers 里把对应 provider 排除掉,眼不见为净。

模型列表为空。如果discover_models: true且端点不支持/v1/models,列表会被清空。方舟端点就是这种情况,所以必须设discover_models: false,然后靠 models 字段手动声明。声明的时候注意缩进,YAML 对缩进敏感,少一个空格就解析失败。

acp.json 不生效。再强调一次路径:~/Library/Application Support/JetBrains/Air/acp.json。不是acp-agents/installed.json。如果你不确定 Air 读的是哪个文件,可以用javap反编译插件字节码找线索:

jar xf /Applications/Air.app/Contents/app/code-cache/<hash>/fleet.plugins.ai.agent.genericacp.workspace.jar javap -p -c fleet/plugins/ai/agent/genericacp/workspace/GenericAcpConfigWatcherKt.class | grep "String"

字节码里会出现acp.json not present这样的字符串常量,顺着就能找到正确路径。这个方法有点硬核,但比在文档里翻要快。

hermes config set 的 YAML 类型陷阱。这个坑我踩过两次。hermes config set model_catalog.excluded_providers '["anthropic", "copilot", "moa"]'会把值存成字符串,而不是列表。正确做法是用 Python 的 yaml.dump 直接写入:

import yaml config_path = "/Users/你的用户名/.hermes/config.yaml" with open(config_path) as f: cfg = yaml.safe_load(f) cfg["model_catalog"]["excluded_providers"] = ["anthropic", "copilot", "moa"] with open(config_path, "w") as f: yaml.dump(cfg, f, default_flow_style=False, allow_unicode=True, sort_keys=False)

写完再读回来验证类型是 list。这个坑和之前 custom_providers 的问题是同一个根源:CLI 对嵌套列表类型会存成 str。

6. 语义一致 CTA:把 Key 和 endpoint 统一到 TaoToken

配置跑通之后,日常使用中最省心的做法就是把所有请求都统一走 TaoToken 的 API 通道。这样你换模型、加 provider、调参数,都只改 config.yaml 一处,acp.json 完全不用动。Air 那边只认 hermes-acp 这个可执行文件,至于 hermes-acp 背后连的是哪个 provider,Air 不关心。

如果你还没拿 Key,去 API Keys 页面创建一个,然后按第 3 节的配置写进.env和 config.yaml。接入文档里有完整的字段对照表,遇到不确定的参数先查文档。想先验证模型能不能正常返回,可以在模型对话页面发一条测试消息,确认通了再往编辑器里接。对于长期编码和 Agent 场景,Coding Plan 的多轮会话优化会更适合,尤其是你要在 Air 里跑复杂的重构任务时。

统一到 TaoToken 之后,你的配置就变成了一个稳定的三件套:Base URL 是https://taotoken.net/api,Key 是 TaoToken 控制台创建的 Key,Model ID 是ark-code-latest(或你声明的其他模型)。这三个字段在 config.yaml 里各出现一次,改的时候一起改。Air 的 acp.json 只负责告诉编辑器去哪里找 hermes-acp,不涉及任何鉴权信息,所以 Key 轮换的时候你只需要更新.env,不用碰 Air 的配置。

最后留一个实用技巧:把~/.hermes/config.yaml和~/Library/Application Support/JetBrains/Air/acp.json这两个文件加入你的 dotfiles 备份。下次换机器或者重装 Air,直接恢复这两个文件,再补一个.env里的 Key,五分钟就能把整套环境重建起来。比重新走一遍反编译找路径的流程要快得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询