0. 前言
最近在捣鼓 AI Agent 方向的内容, 接触到 Hermes Agent —— 一个由 Nous Research 开源的 AI Agent 框架. 它和 Claude Code、OpenAI Codex 属于同一个赛道, 但有一个核心差异点让我很感兴趣: 多平台网关.
也就是说, 我可以通过微信直接给它发消息, 它就帮我去执行命令、操作浏览器、管理文件. 听起来很酷, 对吧?
但实际搞起来, 坑还真不少. 本篇博客记录了从零开始在 WSL (Windows Subsystem for Linux) 上部署 Hermes Agent 的完整过程, 包括几个核心环节:
- Hermes 的安装与基础配置
- 微信网关的对接
- Windows 保活机制(解决 WSL 休眠/重启后服务中断的问题)
- Camoufox 反爬浏览器的集成(绕过 Google、百度等网站的反爬检测)
希望对你有帮助.
NOTE阅读前, 需要你 : 熟悉 Linux 命令行, 了解 WSL 的基本使用, 对 AI Agent 概念有基本认识.
1. Hermes Agent 是什么
简单来说, Hermes Agent 就是一个可以跑在终端和聊天软件里的 AI 助手.
它不是又一个聊天机器人 —— 它能真正帮你干活. 你可以让它帮你查资料、写代码、操作浏览器、管理文件, 甚至写博客(这篇就是). 支持的工具调用挺丰富的:
- 20+ 模型供应商: OpenRouter、Anthropic、DeepSeek……想用哪个用哪个
- 10+ 平台网关: 微信、Telegram、Discord、Slack 都能连
- 跨会话记忆: 它会记住你的偏好, 不用每次都重新说
- 技能系统: 复杂的操作流程可以自动保存下来, 下次直接复用
架构上其实就两层, 不复杂:
- Gateway (网关): 常驻后台的进程, 负责接收和转发消息. 你可以理解为 7x24 小时值班的”接线员”
- Agent (代理): 每次对话创建一个新的 Agent 实例, 执行具体的任务. 相当于”干活的人”
2. 在 WSL 上安装
我的环境是 Windows 11 + WSL2 (Ubuntu). 安装非常简单, 一行命令搞定:
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash安装完之后, 需要配置模型供应商. 我这边用的是 OpenRouter 做中转, 因为它的模型选择多, 而且不用绑定某一家:
hermes setup或者直接编辑配置文件 ~/.hermes/config.yaml:
model: default: deepseek-v4-flash provider: custom base_url: https://your-api-endpoint/v1 api_key: your_api_key这里有几个我觉得值得调的配置项, 分享一下我的取值:
| 配置 | 说明 | 我的值 |
|---|---|---|
agent.max_turns | 每次对话最大工具调用轮次, 默认 90 | 100 |
terminal.timeout | 单条命令最大执行时间, 默认 180s | 600s (10分钟) |
display.language | 界面语言 | zh (中文) |
memory.memory_enabled | 跨会话记忆 | true |
3. 微信网关配置
这一步的体验还挺神奇的 —— 配好之后, 你给 Hermes 发微信就像给朋友发消息一样自然.
Hermes 用的是 iLink Bot 协议, 通过扫码登录微信:
hermes gateway setup选择 WeChat 平台, 终端里会出现一个二维码, 掏出手机扫一下就行.
关键的配置项在 ~/.hermes/.env 中:
WEIXIN_ACCOUNT=你的微信账号WEIXIN_GROUP_POLICY=open然后启动网关:
hermes gateway run看到类似下面的日志, 说明网关启动成功了:
[INFO] Weixin gateway connected[INFO] Gateway running on ...之后就可以在微信里给 Hermes 发消息了. 它会在微信里直接回复你, 就像在和联系人聊天一样.
不过有一点需要提前知道 —— iLink Bot 协议有一些限制:
- ✅ 收发文本消息
- ✅ 发送图片和文件
- ✅ 执行任意终端命令
- ✅ 操作浏览器(导航、截图、点击、输入)
- ❌ 不支持群聊
- ❌ 不支持给陌生人主动发消息
对我来说, 这些限制基本不影响日常使用. 大多数场景就是自己跟它对话, 不需要群聊功能.
4. 保活机制
这是整个部署过程中最折腾的部分, 没有之一. 问题很简单:
WSL 在 Windows 休眠或重启后, Gateway 进程就挂了. 下次打开微信想用它的时候, 发现没反应了.
为了解决这个问题, 我搞了一个三层保活架构:
NOTE以下各层的代码片段为核心流程展示, 实际脚本包含了更多的边界处理、错误恢复和安全保护(互斥锁降级、进程状态检测、多级 fallback 等)。
第一层: Windows Startup 启动
在 Windows 的启动文件夹里放一个 VBS 脚本, 每次开机自动运行:
C:\Users\<用户名>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\start-hermes-watchdog.vbsVBS 脚本使用动态路径检测, 自动找同目录下的 hermes-watchdog.ps1, 不需要硬编码路径:
' 自动检测脚本所在目录,无需硬编码路径Set objFSO = CreateObject("Scripting.FileSystemObject")Set objShell = CreateObject("Wscript.Shell")
strPath = objFSO.GetParentFolderName(Wscript.ScriptFullName)strPS1 = objFSO.BuildPath(strPath, "hermes-watchdog.ps1")
' 参数: 隐藏窗口(0), 不等待(False)objShell.Run "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File """ & strPS1 & """", 0, False0 这个参数是关键 —— 表示不显示窗口, 后台静默运行.
第二层: PowerShell 自循环守护脚本
核心剧本是 hermes-watchdog.ps1, 它每隔 5 分钟调用 WSL 端的 /root/hermes-watchdog.sh 检查 Gateway 的状态. v2.0 版本做了几个重要改进:
- 分片睡眠 + 60s 心跳: 每 5 分钟的主循环间隔被拆成 60 秒一片, 每片写一次
heartbeat.txt, 这样随时可以从 Windows 端确认看门狗是否还活着(即使主循环 sleep 期间) - WSL 可达性预检: 调用 WSL 前先检查 WSL 是否可达, 不可达时尝试唤起而非直接超时跳过
- 兜底启动: WSL 脚本返回 exit=2(重启失败)时, PS1 直接尝试
hermes gateway run &兜底启动 - exit code 正确捕获: 通过 Job 的 hashtable 返回值修复 Start-Job 中
$LASTEXITCODE丢失问题
以下是简化版逻辑(完整脚本含互斥锁、日志、兜底恢复等辅助功能):
# 全局命名 Mutex 防止多实例竞跑$mutex = New-Object System.Threading.Mutex($false, "Global\HermesGatewayWatchdog")if (-not $mutex.WaitOne(0)) { exit 0 }
# 主循环: 分片睡眠 + 60s 心跳while ($true) { # 分片 60s 睡眠, 每片写心跳文件 for ($i = 0; $i -lt 5; $i++) { Start-Sleep -Seconds 60 Get-Date -Format "yyyy-MM-dd HH:mm:ss" | Out-File $heartbeatFile -Encoding utf8 -Force }
# Step 1: WSL 可达性预检 if (-not (Test-WslAlive)) { # 尝试唤起 WSL, 失败则跳过本轮 wsl.exe -d Ubuntu -- echo "kick" 2>&1 continue }
# Step 2: 调用 WSL 侧的检测脚本 $output, $exitCode, $timedOut = Invoke-WslScript
if ($timedOut) { continue } # WSL 超时 if ($exitCode -eq 0) { /* 正常 */ } # 仅每5周期写一次日志 if ($exitCode -eq 1) { Write-Log "Gateway 已重启" } if ($exitCode -eq 2) { # 兜底: WSL 脚本失败, PS1 直接启动 Invoke-WslScript -Command "hermes gateway run &" -TimeoutSeconds 15 }}完整的 WSL 端检测脚本 /root/hermes-watchdog.sh 负责真正的进程检查与重启(以下展示核心流程, 完整脚本含 PID 文件 inode 保护、多级别启动降级等额外加固):
#!/bin/bash# 锁: flock + PID 文件, 防多实例也防 inode 替换绕过LOCKFILE="/var/run/hermes-watchdog.lock"exec 200>"$LOCKFILE"; flock -n 200 || exit 0echo "$$" > "$LOCKFILE"
# find_gateway_pid: 遍历 pgrep 结果# 用 /proc/PID/exe 确认是 Python 进程 (排除 shell 包装)# 用 /proc/PID/status 跳过 Zombie 和 D 状态find_gateway_pid() { for pid in $(pgrep -f "hermes gateway run"); do [ ! -d "/proc/$pid" ] && continue [ "$pid" = "$$" ] && continue # 跳过自身 state=$(grep -o '^State:\\s*[A-Z]' /proc/$pid/status | grep -o '[A-Z]$') case "$state" in Z|D) continue ;; esac exe=$(readlink /proc/$pid/exe) case "$exe" in */python|*/python3|*/python3.*) echo "$pid"; return 0 ;; esac done; return 1}
GW_PID=$(find_gateway_pid)[ -n "$GW_PID" ] && echo "0" && exit 0 # 正常运行
# 三级 fallback 启动VENV="/usr/local/lib/hermes-agent/venv/bin/hermes"for cmd in "$VENV" "hermes" "python3 -m hermes"; do nohup $cmd gateway run </dev/null >/dev/null 2>&1 & for i in {1..15}; do sleep 2 [ -n "$(find_gateway_pid)" ] && echo "1" && exit 1 # 启动成功 donedoneecho "2" && exit 2 # 启动失败第三层: Windows 计划任务(兜底)
即使 PowerShell 脚本意外退出了, 还有计划任务兜底. 兜底脚本 check-watchdog.ps1 做了双重确认: 先尝试获取互斥锁, 若能获取(说明 PS1 可能死了), 再检查 heartbeat.txt 是否新鲜——只有心跳也过期了才确认 PS1 死亡, 接手启动 Gateway.
# 任务: 开机启动看门狗 (启动目录备用入口)$action = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-ExecutionPolicy Bypass -WindowStyle Hidden -File `"C:\...\hermes-watchdog.ps1`""Register-ScheduledTask -TaskName "HermesWatchdog" -Action $action -Force
# 兜底: 每5分钟检查 (通过独立的 check-watchdog.ps1)$action = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-File `"C:\...\check-watchdog.ps1`""$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) ` -RepetitionInterval (New-TimeSpan -Minutes 5) ` -RepetitionDuration ([TimeSpan]::FromDays(365))Register-ScheduledTask -TaskName "HermesWatchdogHealthCheck" -Action $action -Trigger $trigger -Force兜底脚本 check-watchdog.ps1 会先尝试获取互斥锁 Global\HermesGatewayWatchdog——如果能拿到(说明 PS1 可能死了), 再检查 heartbeat.txt 是否在 7 分钟内更新过. 只有 Mutex 释放 && 心跳过期 才确认 PS1 已死, 接手重启 Gateway.
这解决了 TOCTOU 竞态问题: 兜底脚本在 持有 Mutex 期间 执行 WSL 检查, 防止并发冲突.
全链路故障恢复
这三层下来, 我做了两轮共 63 项压力测试 + 攻击测试, 包括:
- kill -9 Gateway: 看门狗检测到进程死亡, 自动重启 ✅ (实测 PID 从 287817 恢复到 290825)
- pgrep 误匹配: 修复为通过
/proc/PID/exe确认 Python 进程, 排除 bash 包装进程 - PS1 崩溃: 计划任务检测到 Mutex 释放后接管, 5 分钟内恢复
- 锁文件 inode 替换: flock + PID 文件双重保护, 防绕过
- 僵尸 / D 状态进程:
/proc/PID/status状态检查, 跳过不可用进程 - venv 二进制被删: 三级 fallback (
venv/hermes→hermes→python3 -m hermes)
即使电脑重启、休眠、甚至脚本崩了, Hermes 都会在 5 分钟内自动恢复. 实测下来, 基本能做到”无感恢复”.
5. Camoufox 反爬浏览器
这是另一个让我踩了不少坑的部分.
Hermes 内置的浏览器工具默认用的是 Playwright 的浏览器. 问题在于: 很多国内网站(百度、天气网)和 Google 都会检测并拦截自动化浏览器. 我第一次试的时候就碰了一鼻子灰 —— 打开百度直接给个验证码, 天天气网直接 403.
解决方案是装一个反检测浏览器: Camoufox.
Camoufox 本质上就是 一个经过魔改的 Firefox, 它通过随机化浏览器指纹(屏幕分辨率、WebGL、字体、时区、语言等)来伪装成普通用户. 简单理解就是 —— 它让网站以为你是一个真实的用户在浏览.
安装过程
# 1. 安装 Camoufox Python 包pip install camoufox
# 2. 安装 camofox-browser (Node.js REST API 服务)git clone https://github.com/jo-inc/camofox-browser.git ~/.hermes/camofox-browsercd ~/.hermes/camofox-browser && npm install这里有个小坑: camoufox server 命令存在一个已知的 Node.js/Playwright 兼容性问题(报错 “proxy: expected object, got null”), 所以推荐用 camofox-browser 这个方案.
启动服务
cd ~/.hermes/camofox-browser && PORT=9377 npm start检查服务是否正常:
curl http://localhost:9377/health# {"ok":true,"engine":"camoufox","browserConnected":true,"browserRunning":true}集成到 Hermes
在 .env 中设置环境变量:
CAMOFOX_URL=http://localhost:9377然后在配置文件中启用:
browser: engine: auto camofox: managed_persistence: false重启 Hermes 会话后, browser_navigate 等命令就会自动通过 Camoufox 执行了.
效果对比
安装前后的差别还是很明显的:
| 测试站点 | 默认 Playwright 浏览器 | Camoufox |
|---|---|---|
| baidu.com | ❌ 被拦截 | ✅ 正常访问 |
| weather.com.cn | ❌ 被拦截 | ✅ 正常访问 + 搜索 |
| google.com | ❌ 验证码 | ✅ 正常搜索 |
为了方便日常管理, 我写了个简单的启动脚本 camofoxctl.sh:
/root/.hermes/camofoxctl.sh start # 启动/root/.hermes/camofoxctl.sh status # 查看状态/root/.hermes/camofoxctl.sh stop # 停止6. 灵魂画手: 架构总览
下面用一张图总结整个系统的架构:

上图展示了从用户手机微信端 → WeChat Gateway → Hermes Agent → Camoufox 浏览器 → 外部 Web 服务的完整链路, 以及底部的三层保活系统.
7. 总结
整个部署过程踩了不少坑, 总结几个关键经验:
- WSL 的稳定性: 电脑休眠后 WSL 可能丢网络或进程, 保活脚本是必需品, 别偷懒
- 网关协议有限制: iLink Bot 不支持群聊、不能主动给陌生人发消息, 但核心功能——收发消息、传文件——完全够用
- 反爬是个绕不过去的坎: 默认的 Playwright 浏览器在中文互联网上基本寸步难行, Camoufox 是目前试下来最省心的方案
- Hermes 的技能系统是真香: 用多了它会自己积累工作流, 越来越顺手
最终的效果就是——我躺在沙发上, 掏出来手机打开微信, 就可以让 Hermes 帮我查天气、搜 Google、管理代码、甚至写博客. 这感觉, 确实爽. 👍
如果你也在折腾 AI Agent, 欢迎交流.