Windows (原生) 指南 — 早期 Beta 版
原生 Windows 支持处于早期 beta 阶段。它可以安装、运行并通过我们的 Windows-footgun 代码检查,但尚未经过 Linux/macOS/WSL2 路径那样大规模的实战测试。可能会遇到一些问题 — 特别是在子进程处理、路径特性和非 ASCII 控制台输出方面。遇到问题时,请提交 issue并附上复现步骤。如果您想要一个经过实战检验的设置,请改用WSL2 下的 Linux/macOS 安装程序。
Hermes 在 Windows 10 和 Windows 11 上原生运行 — 无需 WSL、无需 Cygwin、无需 Docker。本页面深入介绍:原生支持什么、仅 WSL 支持什么、安装程序实际做什么,以及您可能需要调整的 Windows 特定选项。
如果您只想安装,着陆页或安装页面上的一行命令就是您所需的一切。遇到意外情况时再回到这里。
如果您更喜欢真正的 POSIX 环境(用于仪表板的嵌入式终端、fork 语义、Linux 风格的文件监视器等),请参阅**Windows (WSL2) 指南**。两者可以干净地共存:原生数据位于 %LOCALAPPDATA%\hermes,WSL 数据位于 ~/.hermes。
快速安装
打开 PowerShell(或 Windows Terminal)并运行:
irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex
无需管理员权限。安装程序会安装到 %LOCALAPPDATA%\hermes\ 并将 hermes 添加到您的用户 PATH — 安装完成后打开新终端。
安装程序选项(需要脚本块形式来传递参数):
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1))) -NoVenv -SkipSetup -Branch main
| 参数 | 默认值 | 用途 |
|---|---|---|
-Branch | main | 克隆特定分支(用于测试 PR) |
-NoVenv | 关闭 | 跳过虚拟环境创建(高级 — 您自己管理 Python) |
-SkipSetup | 关闭 | 跳过安装后 hermes setup 向导 |
-HermesHome | %LOCALAPPDATA%\hermes | 覆盖数据目录 |
-InstallDir | %LOCALAPPDATA%\hermes\hermes-agent | 覆盖代码位置 |
安装程序实际做什么
从上到下,按顺序:
- 引导
uv— Astral 的快速 Python 管理器。安装到%USERPROFILE%\.local\bin。 - 安装 Python 3.11(通过
uv)。无需现有 Python。 - 安装 Node.js 22(如果可用则使用 winget,否则将可移植的 Node tarball 解压到
%LOCALAPPDATA%\hermes\node)。用于浏览器工具和 WhatsApp 桥接。 - 安装可移植 Git — 如果
git已在 PATH 中,安装程序会使用它;否则会下载一个精简的、自包含的 PortableGit(约 45 MB,来自官方git-for-windows发布)到%LOCALAPPDATA%\hermes\git。无需管理员权限、无 Windows 安装程序注册表、不干扰系统上的其他任何东西。 - 克隆仓库到
%LOCALAPPDATA%\hermes\hermes-agent并在其中创建虚拟环境。 - 分层
uv pip install— 先尝试.[all],如果git+https依赖在 GitHub 速率限制下失败,则回退到逐步更小的集合([messaging,dashboard,ext]→[messaging]→.)。防止"单次失败导致您降到裸安装"的失败模式。 - 自动安装消息传递 SDK(基于
.env)— 如果TELEGRAM_BOT_TOKEN/DISCORD_BOT_TOKEN/SLACK_BOT_TOKEN/SLACK_APP_TOKEN/WHATSAPP_ENABLED存在,运行python -m ensurepip --upgrade和有针对性的pip install调用,使每个平台的 SDK 实际可导入。 - 设置
HERMES_GIT_BASH_PATH为解析出的bash.exe,以便 Hermes 在全新 shell 中确定性地找到它。 - 将
%LOCALAPPDATA%\hermes\bin添加到用户 PATH — 在您打开新终端后暴露hermes命令。 - 运行
hermes setup— 正常首次运行向导(模型、提供商、工具集)。使用-SkipSetup跳过。
功能矩阵
除仪表板的嵌入式终端窗格外,所有功能都在 Windows 上原生运行。
| 功能 | 原生 Windows | WSL2 |
|---|---|---|
CLI(hermes chat、hermes setup、hermes gateway 等) | ✓ | ✓ |
交互式 TUI(hermes --tui) | ✓ | ✓ |
| 消息传递网关(Telegram、Discord、Slack、WhatsApp,15+ 平台) | ✓ | ✓ |
| Cron 调度器 | ✓ | ✓ |
| 浏览器工具(通过 Node 的 Chromium) | ✓ | ✓ |
| MCP 服务器(stdio 和 HTTP) | ✓ | ✓ |
| 本地 Ollama / LM Studio / llama-server | ✓ | ✓(通过 WSL 网络) |
| Web 仪表板(会话、作业、指标、配置) | ✓ | ✓ |
仪表板 /chat 嵌入式终端窗格 | ✗(需要 POSIX PTY) | ✓ |
| 登录时自动启动 | ✓(schtasks) | ✓(systemd) |
仪表板的 /chat 标签页通过 POSIX PTY(ptyprocess)嵌入真实终端。原生 Windows 没有等效的原语;Python 的 pywinpty / Windows ConPTY 可以工作,但这是单独的实现 — 视为未来工作。仪表板的其余部分原生工作 — 只有那个标签页显示"对此使用 WSL2"的横幅。
Hermes 如何在 Windows 上运行 shell 命令
Hermes 的终端工具通过 Git Bash 运行命令,与 Claude Code 使用的策略相同。这避开了 POSIX 与 Windows 的差距,而无需重写每个工具。
bash.exe 的解析顺序:
HERMES_GIT_BASH_PATH环境变量(如果已设置)。%LOCALAPPDATA%\hermes\git\usr\bin\bash.exe(安装程序管理的 PortableGit)。%LOCALAPPDATA%\hermes\git\bin\bash.exe(较旧的 Git-for-Windows 布局)。- 系统 Git-for-Windows 安装(
%ProgramFiles%\Git\bin\bash.exe等)。 - MSYS2、Cygwin 或 PATH 上的任何
bash.exe(作为最后手段)。
安装程序显式设置 HERMES_GIT_BASH_PATH,以便新的 PowerShell 会话无需重新发现。如果您想让 Hermes 使用特定的 bash,可以覆盖它 — 例如,您的系统 Git Bash 或通过符号链接的 WSL 托管 bash。
陷阱: MinGit 的布局与完整的 Git-for-Windows 安装程序不同 — bash 位于 usr\bin\bash.exe,而不是 bin\bash.exe。Hermes 会检查两者。如果您手动解压 MinGit zip,请确保选择非 busybox 变体(MinGit-*-64-bit.zip,而不是 MinGit-*-busybox*.zip)— busybox 构建提供 ash 而不是 bash,并且大多数 coreutils 都缺失。
Windows 上的 UTF-8 控制台
Python 在 Windows 上的默认标准输入输出使用控制台的活动代码页(通常是 cp1252 或 cp437)。Hermes 的横幅、斜杠命令列表、工具提要、Rich 面板和技能描述都包含 Unicode。如果不干预,这些都会因 UnicodeEncodeError: 'charmap' codec can't encode character… 而崩溃。
修复在 hermes_cli/stdio.py::configure_windows_stdio() 中,在每个入口点(cli.py::main、hermes_cli/main.py::main、gateway/run.py::main)早期调用。它:
- 通过
kernel32.SetConsoleCP/SetConsoleOutputCP将控制台代码页翻转到 CP_UTF8 (65001)。 - 将
sys.stdout/sys.stderr/sys.stdin重新配置为 UTF-8,使用errors='replace'。 - 设置
PYTHONIOENCODING=utf-8和PYTHONUTF8=1(通过setdefault,因此显式用户值优先),以便子 Python 进程继承 UTF-8。 - 如果
EDITOR和VISUAL都未设置,则设置EDITOR=notepad(请参阅下面的编辑器部分)。
幂等。在非 Windows 系统上无操作。
退出: 环境中的 HERMES_DISABLE_WINDOWS_UTF8=1 会回退到旧的 cp1252 标准输入输出路径。用于二分编码错误;在正常操作中不太可能是正确的设置。
编辑器(Ctrl-X Ctrl-E、/edit)
在 PR #21561 之前,在 Windows 上按 Ctrl-X Ctrl-E 或键入 /edit 会静默地什么都不做。prompt_toolkit 有一个硬编码的 POSIX 绝对回退列表(/usr/bin/nano、/usr/bin/pico、/usr/bin/vi 等),在 Windows 上永远无法解析 — 即使安装了完整的 Git for Windows。
Hermes 的 Windows 标准输入输出填充程序现在将 EDITOR=notepad 设置为默认值。Notepad 随每个 Windows 安装一起提供,并作为阻塞编辑器工作 — subprocess.call(["notepad", file]) 会阻塞,直到窗口关闭。
用户覆盖仍然有效(它们在 setdefault 之前被检查):
| 编辑器 | PowerShell 命令 |
|---|---|
| VS Code | $env:EDITOR = "code --wait" |
| Notepad++ | $env:EDITOR = "'C:\Program Files\Notepad++\notepad++.exe' -multiInst -nosession" |
| Neovim | $env:EDITOR = "nvim" |
| Helix | $env:EDITOR = "hx" |
VS Code 上的 --wait 标志至关重要 — 没有它,编辑器会立即返回,Hermes 会得到一个空缓冲区。
在 PowerShell 配置文件中永久设置:
# In $PROFILE
$env:EDITOR = "code --wait"
或者作为系统设置中的用户环境变量,以便每个新 shell 都能获取它。
CLI 中的 Ctrl+Enter 换行
Windows Terminal 将 Ctrl+Enter 作为专用键序列传递。Hermes 将其绑定到"插入换行符",以便您可以在 CLI 中编写多行提示,而无需回退到 Esc-然后-Enter。在 Windows Terminal、VS Code 集成终端和任何支持 VT 转义序列的现代 Windows 控制台主机中工作。
在旧版 cmd.exe 控制台上,Ctrl+Enter 会折叠为普通 Enter — 请改用 Esc Enter,或升级到 Windows Terminal(它在 Windows 11 上免费并默认安装)。
在 Windows 登录时运行网关
Windows 上的 hermes gateway install 使用计划任务,并带有启动文件夹回退 — 无需管理员权限。
安装
hermes gateway install
幕后发生的情况:
schtasks /Create /SC ONLOGON /RL LIMITED /TN HermesGateway— 注册一个在您登录时以标准(非提升)权限运行的任务。无 UAC 提示。- 如果 schtasks 被组策略阻止,则回退到将
start /min cmd.exe /d <wrapper>快捷方式写入%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup。效果相同,只是更粗糙。 - 通过
pythonw.exe分离生成网关 — 而不是python.exe。pythonw.exe没有附加控制台,这使其免受来自兄弟进程的CTRL_C_EVENT广播(这是一个真正的问题,当您在同一进程组中 Ctrl+C 任何东西时,过去常常杀死网关)。
生成时使用的标志:DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB。
管理
hermes gateway status # 合并视图:schtasks + 启动文件夹 + 运行中的 PID
hermes gateway start # 立即启动计划任务
hermes gateway stop # 优雅的 SIGTERM 等效(通过 psutil 的 TerminateProcess)
hermes gateway restart
hermes gateway uninstall # 移除 schtasks 条目、启动文件夹快捷方式、pid 文件
hermes gateway status 是幂等的 — 连续调用一千次,它永远不会意外杀死网关。(在 PR #21561 之前,它通过 os.kill(pid, 0) 与 C 级别的 CTRL_C_EVENT 冲突而静默地这样做 — 如果您关心这个故事,请参阅下面的"进程管理内部"。)
为什么不是 Windows 服务?
服务需要管理员权限才能安装,并将网关的生命周期绑定到机器启动,而不是用户登录。典型的 Hermes 用户想要:登录 → 网关可用,注销 → 网关消失。计划任务正是这样做的,无需提升权限。如果您真的想要服务,请手动使用 nssm 或 sc create — 但您可能不需要。
数据布局
| 路径 | 内容 |
|---|---|
%LOCALAPPDATA%\hermes\hermes-agent\ | Git 检出 + 虚拟环境。可以安全地 Remove-Item -Recurse 并重新安装。 |
%LOCALAPPDATA%\hermes\git\ | PortableGit(仅当安装程序提供了它时)。 |
%LOCALAPPDATA%\hermes\node\ | 可移植的 Node.js(仅当安装程序提供了它时)。 |
%LOCALAPPDATA%\hermes\bin\ | hermes.cmd 填充程序,已添加到用户 PATH。 |
%USERPROFILE%\.hermes\ | 您的配置、身份验证、技能、会话、日志。在重新安装后保留。 |
这种拆分是故意的:%LOCALAPPDATA%\hermes 是一次性的基础设施(您可以将其清除,一行命令就能恢复它)。%USERPROFILE%\.hermes 是您的数据 — 配置、记忆、技能、会话历史 — 并且形状与 Linux 安装相同。在机器之间镜像它,您的 Hermes 就会随您移动。
覆盖 HERMES_HOME: 设置环境变量以指向不同的数据目录。与 Linux 上的用法相同。
浏览器工具
浏览器工具使用 agent-browser(一个 Node 助手)来驱动 Chromium。在 Windows 上:
- 安装程序通过 npm 将
agent-browser放到 PATH 上。 shutil.which("agent-browser", path=...)自动获取.cmd填充程序 —CreateProcessW无法执行无扩展名 shebang,因此 Hermes 始终解析到.CMD包装器。不要手动调用 shebang 脚本;始终通过.cmd。- Playwright Chromium 在首次运行时自动安装(
npx playwright install chromium)。如果安装失败,hermes doctor会显示它并给出修复提示。
在 Windows 上运行 Hermes — 实用笔记
安装后的 PATH
安装程序通过 [Environment]::SetEnvironmentVariable 将 %LOCALAPPDATA%\hermes\bin 添加到您的用户 PATH。现有终端不会获取这个 — 安装后打开新的 PowerShell 窗口(或 Windows Terminal 标签页)。关闭并重新打开,不要手动 $env:PATH += …,除非您知道自己在做什么。
验证:
Get-Command hermes # 应该打印 C:\Users\<you>\AppData\Local\hermes\bin\hermes.cmd
hermes --version
环境变量
Hermes 同时尊重 $env:X(进程范围)和用户环境变量(永久,在系统属性 → 环境变量中设置)。在 %USERPROFILE%\.hermes\.env 中设置 API 密钥是正常路径 — 与 Linux 相同:
OPENROUTER_API_KEY=***
TELEGRAM_BOT_TOKEN=***
除非您特别希望每个 Windows 进程都能看到它们,否则不要将秘密放在用户环境变量中(这不是您想要的)。
Windows 特定的环境变量
这些仅影响原生 Windows 安装:
| 变量 | 效果 |
|---|---|
HERMES_GIT_BASH_PATH | 覆盖 bash.exe 发现。指向任何 bash — 完整的 Git-for-Windows、通过符号链接的 WSL bash、MSYS2、Cygwin。安装程序会自动设置这个。 |
HERMES_DISABLE_WINDOWS_UTF8 | 设置为 1 以禁用 UTF-8 标准输入输出填充程序并回退到区域设置代码页。用于二分编码错误。 |
EDITOR / VISUAL | 您的编辑器用于 /edit 和 Ctrl-X Ctrl-E。如果两者都未设置,Hermes 默认为 notepad。 |
卸载
从 PowerShell:
hermes uninstall
这是干净的路径 — 移除 schtasks 条目、启动文件夹快捷方式、hermes.cmd 填充程序、删除 %LOCALAPPDATA%\hermes\hermes-agent\,并修剪用户 PATH。它会保留 %USERPROFILE%\.hermes\(您的配置、身份验证、技能、会话、日志),以防您要重新安装。
要清除所有内容:
hermes uninstall
Remove-Item -Recurse -Force "$env:USERPROFILE\.hermes"
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\hermes"
hermes uninstall CLI 子命令还处理 schtasks 条目以不同任务名称注册的情况(较旧的安装)— 它通过安装路径搜索,而不是通过硬编码的任务名称。
进程管理内部
这是背景材料 — 除非您在调试"它在自杀"的怪异现象,否则跳过。
在 Linux 和 macOS 上,POSIX 惯用法 os.kill(pid, 0) 是一个无操作权限检查:"这个 PID 是否存活,我可以给它发信号吗?"在 Windows 上,Python 的 os.kill 将 sig=0 映射到 CTRL_C_EVENT — 它们在整数值 0 处冲突 — 并通过 GenerateConsoleCtrlEvent(0, pid) 路由它,后者将 Ctrl+C 广播到包含目标 PID 的整个控制台进程组。这是 bpo-14484,自 2012 年以来一直开放。它不会被修复,因为更改它会破坏依赖于当前行为的脚本。
后果:在 Windows 上通过 os.kill(pid, 0) 说"检查这个 PID 是否存活"的任何代码路径都在静默地杀死目标。Hermes 将每个这样的站点(11 个文件中的 14 个)迁移到 gateway.status._pid_exists(),它使用 psutil.pid_exists()(后者在 Windows 上使用 OpenProcess + GetExitCodeProcess — 无信号)。如果您正在编写插件或补丁,请直接使用 psutil.pid_exists() 或 gateway.status._pid_exists() — 永远不要 os.kill(pid, 0)。
scripts/check-windows-footguns.py 在 CI 中强制执行此操作:除非该行带有 # windows-footgun: ok — <reason> 标记,否则任何新的 os.kill(pid, 0) 调用都会失败 Windows footguns (blocking) 检查。
常见陷阱
安装后立即出现 hermes: command not found。
打开新的 PowerShell 窗口。安装程序将 %LOCALAPPDATA%\hermes\bin 添加到用户 PATH,但现有 shell 需要重新启动才能获取它。同时,您可以运行 & "$env:LOCALAPPDATA\hermes\bin\hermes.cmd"。
运行工具时出现 WinError 193: %1 is not a valid Win32 application。
您遇到了绕过 .cmd 填充程序的 shebang 脚本调用。Hermes 通过 shutil.which(cmd, path=local_bin) 解析命令,因此 PATHEXT 会获取 .CMD — 如果您通过硬编码路径调用工具,请切换到 .cmd 变体(例如,npx.cmd,而不是 npx)。
[scriptblock]::Create(...) 失败,显示 The assignment expression is not valid。
您下载的 install.ps1 获取了 UTF-8 BOM。irm | iex 形式会自动去除 BOM;[scriptblock]::Create((irm ...)) 则不会。使用简单的 irm | iex 形式重新运行,或手动下载脚本并通过 [IO.File]::WriteAllText($path, $text, (New-Object Text.UTF8Encoding $false)) 保存而不带 BOM。
重启后网关无法保持运行。
检查 hermes gateway status — 它合并 schtasks 条目、启动文件夹快捷方式(如果使用)和活动 PID。如果 schtasks 已注册但未运行,组策略可能阻止 ONLOGON 触发器。运行 schtasks /Query /TN HermesGateway /V /FO LIST 以查看任务的失败原因,或通过卸载并重新安装并使用 HERMES_GATEWAY_FORCE_STARTUP=1 回退到启动文件夹路径。
设置 $env:EDITOR 后 /edit 仍然什么都不做。
您仅在当前进程中设置了它;关闭并重新打开 shell,或在系统属性 → 环境变量中在用户范围设置它。在新的 PowerShell 窗口中使用 echo $env:EDITOR 验证。
浏览器工具启动但工具超时。
Chromium 在首次运行时自动安装。如果安装失败(GitHub 速率限制、Playwright CDN 故障),运行 hermes doctor — 它会显示缺少的 Chromium 并打印确切的 npx playwright install chromium 命令来修复它。
agent-browser 失败,显示奇怪的 Node 版本错误。
安装程序在 %LOCALAPPDATA%\hermes\node 提供 Node 22,但您的 PATH 可能首先有较旧的系统 Node 18。要么将 Hermes 的 node 目录在 PATH 上移前,要么如果您不在其他地方使用 Node,则删除系统安装。
CLI 中的中文 / 日文 / 阿拉伯文字符显示为 ?。
UTF-8 标准输入输出填充程序未激活。检查 HERMES_DISABLE_WINDOWS_UTF8 是否未设置(Get-ChildItem env:HERMES_DISABLE_WINDOWS_UTF8)。如果它是空的,而您仍然看到 ?,则控制台主机(非常旧的 cmd.exe)可能根本不支持 UTF-8 — 切换到 Windows Terminal。
网关无法发送 Telegram 照片 — "BadRequest: payload contains invalid characters"。
这与 Windows 无关,但有时首先在那里出现。通常这意味着您的文件路径在 JSON 正文中包含未转义的反斜杠。Telegram 应该接收 Hermes 规范化的路径,而不是原始 Windows 路径 — 如果您在自定义插件中看到这个,请确保您传递的是 Hermes 提供的路径,而不是来自用户输入的 str(Path(...))。
git pull 后出现"在我的其他机器上工作"编码怪异现象。
如果您在 Windows 上使用非 UTF-8 编辑器(旧版 Windows 上的记事本、某些中文 IME)编辑了 Hermes 配置或技能,文件可能已保存带有 BOM。Hermes 在大多数配置读取中容忍 utf-8-sig,但折叠 YAML 标量(description: >)中的 BOM 会静默地破坏 YAML 解析。将文件重新保存为不带 BOM 的纯 UTF-8。
下一步去哪里
- 安装 — 完整安装页面,包括 Linux/macOS/WSL2/Termux。
- Windows (WSL2) 指南 — 如果您想要 POSIX 语义或仪表板终端窗格。
- CLI 参考 — 每个
hermes子命令。 - FAQ — 常见非 Windows 特定问题。
- 消息传递网关 — 在 Windows 上运行 Telegram/Discord/Slack。