01 问题:消息到了,但全跑偏了
我在本地跑了 Hermes Agent,用微信给它发了一条"日语学习"的指令,附带了一段多邻国里听不懂的日语对话。
预期结果:Hermes 调用 japanese-learning skill,按指定格式解析语法和单词,存到日语学习的 Obsidian 库里。
实际结果:Hermes 确实解析了日语,也给了教学解释——但格式完全不对,文件存到了默认的 GalaxyMe 库里,而不是日语专用库。
同一个提示词,在 Hermes 终端里直接输入,行为完全正确。加了微信通道,就全跑偏了。
问题不在 AI 的理解能力,在于路由——微信消息进来时,Hermes 拿到的上下文跟终端里不一样。
02 微信是怎么连上 Hermes 的
先说连接这一步。Hermes 内置了微信 iLink 网关,一条命令搞定:
hermes gateway setupHermes 会自己连微信 iLink 服务器,生成二维码。用微信扫码授权后,微信好友列表里会多一个叫"微信 ClawBot"、带 AI 标识的联系人。之后你给它发消息,它就收。
但这里有个坑:
如果你不是跑 hermes gateway setup,而是直接在 Hermes 终端里用 prompt 让它自己连微信,Hermes 会写脚本尝试连接,然后终端无限等待。原因是 Hermes 在等你扫码,但二维码在终端里没有正确渲染出来。
这时候去看日志:
tail -f ~/.hermes/logs/gateway.log把卡住的命令拖到 shell 里自己跑,扫码,就能过。
03 微信和 Hermes 是怎么互联的
扫码之后发生了什么?你的消息是怎么从手机跑到本地电脑上的 Hermes 的?
这里用到的不是传统的 Webhook 推送,而是腾讯 iLink Bot API 的长轮询 (Long-Polling) 机制。
简单来说:Hermes 不等着微信推消息过来,而是自己不停地问微信服务器"有没有新消息"。

整个链路的完整细节(包括文件消息的 AES-128-ECB 解密、sync_buf 持久化、context_token 机制)篇幅比较长,这篇先不展开了。如果感兴趣的话评论区说一声,后面单开一篇讲透。
04 路由问题的根因
连接通了,消息能收到,但行为不对。问题出在这里:
微信消息进来时,Hermes 只读到了全局的 Memory 和 User Profile,没有加载 Project 级别的 Context——也就是某个目录下的 AGENTS.md。
AGENTS.md 是什么?它是项目级的规则文件,里面记录了操作 Obsidian 库的正确方式:
### Obsidian Vault Access**CRITICAL**: All interactions with the Obsidian vault must use the `Obsidian` command.**Available Commands:**- `Obsidian vault=japanese create name="..." path="..." content="..."`- `Obsidian read file="..."`- `Obsidian append file="..." content="..."`没有这个文件,Agent 就不知道 vault=japanese 这个参数的存在,也不知道写文件必须走 Obsidian CLI。它按默认行为处理,自然存错了地方。
为什么终端里正常,微信通道不正常?
关键在 terminal.cwd 这个配置:
# ~/.hermes/config.yamlterminal: backend: local cwd: . timeout: 180Gateway 模式下,cwd: . 被解析成了 home 目录。home 目录下没有 AGENTS.md。终端模式下,你通常是在项目目录里启动的,cwd 就是项目根目录,AGENTS.md 自然能加载。
| 根因 | terminal.cwd: . 解析为 home 目录,该目录下无 AGENTS.md |
| 直接后果 | |
| 表现 |
05 怎么 debug
遇到 Hermes 行为不符合预期,第一步是确认它到底看到了什么。
确认 skill 是否加载:
python3 -c "import jsonwith open('sessions/session_20260516_091120.json') as f: data = json.load(f)print(data['system_prompt'])"System Prompt 的实际结构:
System Prompt 结构(18,486 chars):├── # Hermes Agent Persona(SOUL.md)├── ## Skills (mandatory) + <available_skills> 索引├── ═══ MEMORY ═══(6 条持久化笔记)└── ═══ USER PROFILE ═══(4 条用户信息)在 <available_skills> 里确认 japanese-learning 确实在:
education: - japanese-learning: 日语学习助手 - 当用户发送"学习日语"或"日语学习"时...Skill 加载了,但它内部的规则依赖 AGENTS.md 里的 Obsidian CLI 用法——而 AGENTS.md 没被加载。问题定位清楚了。
06 修复方案
让 Hermes 正确路由,有两条路:
方案一:在全局 Memory 里写好路由规则
# ~/.hermes/memories/MEMORY.md默认 Obsidian vault: GalaxyMe(/Users/caohong/Documents/memo/GalaxyMe)。日语学习 vault: japanese(~/family/japanese/),使用 vault=japanese 参数。写文件必须用 Obsidian CLI。Obsidian CLI 的 vault=japanese 参数必须放在子命令之前。我选的是这个方案。不改变 Hermes 的默认工作目录,把关键的 CLI 用法写进 Memory,所有通道共享。
方案二:设置 terminal.cwd 为绝对路径
terminal: cwd: /Users/caohong/Documents/memo/GalaxyMe这样 Gateway 启动时就能找到 AGENTS.md。缺点是你只有一个项目目录,如果你有多个 vault、多个项目,这个方案就不够灵活。
07
微信通道和终端通道的差异,本质是 cwd 不同导致 Project Context 加载不同。debug 的关键不是猜 AI 怎么想的,是看它的 system prompt 里到底有什么。
tail -f ~/.hermes/logs/gateway.log 看日志,dump session JSON 看 system prompt。这两步能解决 80% 的"AI 为什么不按我说的做"的问题。
夜雨聆风