跳到主要內容

Windows 原生安裝指南 — Early Beta

Early BETA

原生 Windows 支持仍處於 early beta 階段。它能裝、能跑,並通過了我們的 Windows footgun lint,但還沒有像 Linux/macOS/WSL2 那樣經歷過同等規模的實戰考驗。請預期會有一些粗糙的邊緣——尤其是子進程處理、路徑細節和非 ASCII 控制檯輸出方面。遇到問題時請提交 issue,並附上覆現步驟。如果你今天就需要一套久經考驗的配置,請改用 WSL2 下的 Linux/macOS 安裝器

Hermes 在 Windows 10 和 Windows 11 上原生運行——不需要 WSL,不需要 Cygwin,也不需要 Docker。這一頁是深入說明:哪些功能原生可用、哪些只能在 WSL 下用、安裝器實際上做了什麼,以及你可能需要調整的 Windows 專屬開關。

如果你只是想安裝,首頁安裝頁上的一行命令就夠了。等到有什麼讓你困惑時再回來看這一頁。

想用 WSL?

如果你更想要一個真正的 POSIX 環境(比如使用 Dashboard 內嵌終端、fork 語義、Linux 風格的文件監聽等),請參見 Windows (WSL2) 指南。兩者可以乾淨地共存:原生數據存放在 %LOCALAPPDATA%\hermes 下,WSL 數據存放在 ~/.hermes 下。

一行命令安裝

打開 PowerShell(或 Windows Terminal),運行:

irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex

不需要管理員權限。安裝器會把 Hermes 安裝到 %LOCALAPPDATA%\hermes\,並把 hermes 加入你的 User PATH——安裝完成後請打開一個新的終端窗口。

安裝器選項(要傳參數必須使用 scriptblock 形式):

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1))) -NoVenv -SkipSetup -Branch main
參數默認值用途
-Branchmain克隆指定分支(用於測試 PR)
-NoVenv關閉跳過 venv 創建(高級用法——你自己管理 Python)
-SkipSetup關閉跳過安裝後的 hermes setup 嚮導
-HermesHome%LOCALAPPDATA%\hermes覆蓋數據目錄
-InstallDir%LOCALAPPDATA%\hermes\hermes-agent覆蓋代碼目錄

安裝器到底做了什麼

從上到下依次執行:

  1. 引導 uv —— Astral 的高性能 Python 管理器。安裝到 %USERPROFILE%\.local\bin
  2. 通過 uv 安裝 Python 3.11。不需要預先安裝任何 Python。
  3. 安裝 Node.js 22(優先 winget,否則從可移植 Node tarball 解壓到 %LOCALAPPDATA%\hermes\node)。用於 browser tool 和 WhatsApp 橋接。
  4. 安裝可移植版 Git —— 如果 PATH 上已經有 git,安裝器會直接複用;否則會從官方 git-for-windows release 下載一個精簡、自包含的 PortableGit(約 45 MB)到 %LOCALAPPDATA%\hermes\git。無需管理員權限,不寫入 Windows 安裝註冊表,不會干擾機器上的其他東西。
  5. 克隆倉庫%LOCALAPPDATA%\hermes\hermes-agent,並在內部創建 virtualenv。
  6. 分級 uv pip install —— 先嚐試 .[all],如果某個 git+https 依賴在被限流的 GitHub 上抽風,會回退到逐步縮小的依賴集合([messaging,dashboard,ext][messaging].)。避免"一個依賴出問題就掉到裸裝"這種失敗模式。
  7. 基於 .env 自動安裝消息平臺 SDK —— 如果存在 TELEGRAM_BOT_TOKEN / DISCORD_BOT_TOKEN / SLACK_BOT_TOKEN / SLACK_APP_TOKEN / WHATSAPP_ENABLED,會運行 python -m ensurepip --upgrade 和針對性的 pip install 調用,確保每個平臺的 SDK 都能真正 import。
  8. 設置 HERMES_GIT_BASH_PATH 指向解析到的 bash.exe,這樣 Hermes 在新的 shell 裡也能確定性地找到 bash。
  9. %LOCALAPPDATA%\hermes\bin 加入 User PATH —— 在你打開新終端後,hermes 命令就能直接使用。
  10. 運行 hermes setup —— 正常的首次運行嚮導(模型、provider、toolset)。可用 -SkipSetup 跳過。

能力矩陣

除了 Dashboard 內嵌終端面板之外,所有功能在 Windows 上都原生可用。

功能Windows 原生WSL2
CLI(hermes chathermes setuphermes gateway、…)
交互式 TUI(hermes --tui
消息 Gateway(Telegram、Discord、Slack、WhatsApp,15+ 平臺)
Cron 調度器
Browser tool(通過 Node 驅動 Chromium)
MCP servers(stdio 和 HTTP)
本地 Ollama / LM Studio / llama-server✓(通過 WSL 網絡)
Web Dashboard(會話、任務、指標、配置)
Dashboard /chat 內嵌終端面板✗(需要 POSIX PTY)
登錄時自啟動✓(schtasks)✓(systemd)

Dashboard 的 /chat 標籤頁通過 POSIX PTY(ptyprocess)嵌入了一個真實終端。原生 Windows 沒有等價原語;Python 的 pywinpty / Windows ConPTY 理論上可以工作,但需要一份獨立實現——目前作為後續工作處理。Dashboard 的其他部分都原生可用——只有這一個標籤頁會顯示"請改用 WSL2"的提示。

Hermes 在 Windows 上是怎麼跑 shell 命令的

Hermes 的 terminal tool 通過 Git Bash 來執行命令,和 Claude Code 是同一套策略。這避免了重寫每一個工具就能填平 POSIX-vs-Windows 的鴻溝。

bash.exe 的解析順序:

  1. 設置了 HERMES_GIT_BASH_PATH 環境變量時優先使用它。
  2. %LOCALAPPDATA%\hermes\git\usr\bin\bash.exe(安裝器自帶的 PortableGit)。
  3. %LOCALAPPDATA%\hermes\git\bin\bash.exe(舊版 Git-for-Windows 佈局)。
  4. 系統的 Git-for-Windows 安裝(%ProgramFiles%\Git\bin\bash.exe 等)。
  5. 兜底: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 上默認的 stdio 使用控制檯的當前代碼頁(通常是 cp1252 或 cp437)。Hermes 的橫幅、斜槓命令列表、tool feed、Rich 面板和 skill 描述裡都包含 Unicode。如果不做處理,任何一處都可能報 UnicodeEncodeError: 'charmap' codec can't encode character…

修復在 hermes_cli/stdio.py::configure_windows_stdio() 裡完成,每個入口點(cli.py::mainhermes_cli/main.py::maingateway/run.py::main)都會在很早期調用它。它會:

  1. 通過 kernel32.SetConsoleCP / SetConsoleOutputCP 把控制檯代碼頁切到 CP_UTF8(65001)。
  2. sys.stdout / sys.stderr / sys.stdin 重新配置為 UTF-8,且 errors='replace'
  3. 設置 PYTHONIOENCODING=utf-8PYTHONUTF8=1(用 setdefault,所以用戶顯式設置的值優先),讓 Python 子進程也繼承 UTF-8。
  4. 如果 EDITORVISUAL 都沒設置,則設 EDITOR=notepad(參見下面的 Editor 一節)。

冪等。在非 Windows 上是 no-op。

關掉它: 在環境裡設 HERMES_DISABLE_WINDOWS_UTF8=1 會回退到舊的 cp1252 stdio 路徑。用於二分定位編碼 bug 時有用;正常使用基本不需要。

編輯器(Ctrl-X Ctrl-E/edit

#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 stdio 墊片現在會把 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 拿到的是個空 buffer。

把它寫進 PowerShell profile,讓設置永久生效:

# 在 $PROFILE 裡
$env:EDITOR = "code --wait"

或者在系統設置裡把它設成 User 環境變量,這樣每個新開的 shell 都能看到。

在 CLI 裡用 Ctrl+Enter 換行

Windows Terminal 會把 Ctrl+Enter 作為一個獨立的按鍵序列透傳過來。Hermes 把它綁定為"插入換行",讓你能在 CLI 裡組合多行 prompt,而不必退回到 Esc-然後-Enter。在 Windows Terminal、VS Code 集成終端,以及任何遵守 VT 轉義序列的現代 Windows 控制檯裡都能用。

在老式 cmd.exe 控制檯裡,Ctrl+Enter 會被摺疊成普通 Enter——這種情況下用 Esc Enter,或者升級到 Windows Terminal(免費,Windows 11 默認安裝)。

讓 Gateway 在 Windows 登錄時自動啟動

hermes gateway install 在 Windows 上使用 Scheduled Tasks,並以 Startup 文件夾作為兜底——不需要管理員權限。

安裝

hermes gateway install

幕後發生的事情:

  1. schtasks /Create /SC ONLOGON /RL LIMITED /TN HermesGateway —— 註冊一個登錄時以標準(非提權)權限運行的任務。無 UAC 彈窗。
  2. 如果 schtasks 被組策略禁用,會回退到把一個 start /min cmd.exe /d /c <wrapper> 快捷方式寫入 %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup。效果一樣,做法稍粗糙。
  3. 通過 pythonw.exe 以 detached 方式啟動 gateway——而不是 python.exepythonw.exe 沒有附帶控制檯,因此能免疫來自兄弟進程的 CTRL_C_EVENT 廣播(這是個真實問題,過去曾經在你 Ctrl+C 同進程組裡任何東西時把 gateway 順帶殺死)。

啟動時使用的 flag:DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB

管理

hermes gateway status      # 合併視圖:schtasks + Startup 文件夾 + 運行中 PID
hermes gateway start # 立即啟動計劃任務
hermes gateway stop # SIGTERM 的等價(通過 psutil 調 TerminateProcess)
hermes gateway restart
hermes gateway uninstall # 移除 schtasks 項、Startup 快捷方式、pid 文件

hermes gateway status 是冪等的——連著調一千次也絕不會意外殺掉 gateway。(PR #21561 之前它確實會靜默殺掉,因為 os.kill(pid, 0) 在 C 層和 CTRL_C_EVENT 撞到一起——如果你想了解前因後果,請看下面"進程管理內部細節"。)

為什麼不用 Windows Service?

服務需要管理員權限來安裝,並且把 gateway 的生命週期綁定到機器開機,而不是用戶登錄。典型的 Hermes 用戶想要的是:登錄 → gateway 可用,登出 → gateway 退出。Scheduled Tasks 正好做到了這一點,且不需要提權。如果你確實想要一個 service,可以手動用 nssmsc create——但你大概率並不需要。

數據目錄佈局

路徑內容
%LOCALAPPDATA%\hermes\hermes-agent\Git 檢出 + venv。可以放心 Remove-Item -Recurse 然後重裝。
%LOCALAPPDATA%\hermes\git\PortableGit(僅在安裝器自動配置時存在)。
%LOCALAPPDATA%\hermes\node\可移植 Node.js(僅在安裝器自動配置時存在)。
%LOCALAPPDATA%\hermes\bin\hermes.cmd 墊片,已加入 User PATH。
%USERPROFILE%\.hermes\你的配置、auth、skills、會話、日誌。重裝也不會動它。

這種切分是有意為之:%LOCALAPPDATA%\hermes 是可丟棄的基礎設施(你可以整個刪掉,一行命令再裝回來)。%USERPROFILE%\.hermes 才是你的數據——配置、記憶、技能、會話歷史——它的形狀和 Linux 安裝完全一致。把它在多臺機器之間鏡像,你的 Hermes 就跟著你走。

覆蓋 HERMES_HOME 設置該環境變量指向其他數據目錄。和 Linux 上行為相同。

Browser tool

Browser tool 通過 agent-browser(一個 Node helper)驅動 Chromium。在 Windows 上:

  • 安裝器通過 npm 把 agent-browser 加到 PATH。
  • shutil.which("agent-browser", path=...) 會自動選到 .cmd 墊片——CreateProcessW 無法直接執行沒有擴展名的 shebang 腳本,所以 Hermes 總是解析到 .CMD wrapper。不要手動調用 shebang 腳本本身,永遠走 .cmd
  • Playwright Chromium 會在第一次運行時自動安裝(npx playwright install chromium)。如果安裝失敗,hermes doctor 會把它報出來並給出修復提示。

在 Windows 上運行 Hermes —— 實踐要點

安裝後的 PATH

安裝器通過 [Environment]::SetEnvironmentVariable%LOCALAPPDATA%\hermes\bin 加到了你的 User PATH。已經打開的終端拿不到這個變化——安裝完成後請新開一個 PowerShell 窗口(或 Windows Terminal 標籤頁)。是關掉重開,而不是手動 $env:PATH += …,除非你清楚自己在做什麼。

驗證:

Get-Command hermes        # 應該輸出 C:\Users\<你>\AppData\Local\hermes\bin\hermes.cmd
hermes --version

環境變量

Hermes 同時尊重 $env:X(進程級)和 User 環境變量(永久級,在系統屬性 → 環境變量裡設置)。把 API key 放到 %USERPROFILE%\.hermes\.env 裡是常規做法——和 Linux 一致:

OPENROUTER_API_KEY=sk-or-...
TELEGRAM_BOT_TOKEN=...

不要把密鑰放到 User 環境變量裡,除非你確實希望每個 Windows 進程都能看到它(這通常不是你想要的)。

Windows 專屬環境變量

這些只對 Windows 原生安裝生效:

變量作用
HERMES_GIT_BASH_PATH覆蓋 bash.exe 的解析。可以指向任意 bash——完整 Git-for-Windows、通過軟鏈指向 WSL bash、MSYS2、Cygwin。安裝器會自動設置。
HERMES_DISABLE_WINDOWS_UTF8設為 1 禁用 UTF-8 stdio 墊片,回退到 locale 代碼頁。用於二分定位編碼 bug。
EDITOR / VISUAL/editCtrl-X Ctrl-E 使用的編輯器。兩者都未設置時 Hermes 默認用 notepad

卸載

在 PowerShell 裡:

hermes uninstall

這是乾淨路徑——會移除 schtasks 項、Startup 文件夾快捷方式、hermes.cmd 墊片,刪除 %LOCALAPPDATA%\hermes\hermes-agent\,並精簡 User PATH。它不會動 %USERPROFILE%\.hermes\(你的配置、auth、skills、會話、日誌),方便你之後重裝。

要全部清乾淨:

hermes uninstall
Remove-Item -Recurse -Force "$env:USERPROFILE\.hermes"
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\hermes"

hermes uninstall 子命令也能處理 schtasks 任務名不一樣的情況(老版本可能註冊了不同的名字)——它按安裝路徑而不是按硬編碼任務名來搜。

進程管理內部細節

這部分是背景資料——除非你在排查"它把自己殺了"這種詭異問題,否則可以跳過。

在 Linux 和 macOS 上,POSIX 習慣用法 os.kill(pid, 0) 是一個 no-op 權限檢查:"這個 PID 還活著嗎?我能向它發信號嗎?"在 Windows 上,Python 的 os.kill 會把 sig=0 映射到 CTRL_C_EVENT——它們在整數值 0 上撞車——並通過 GenerateConsoleCtrlEvent(0, pid) 路由出去,這個調用會向整個包含目標 PID 的控制檯進程組廣播 Ctrl+C。這就是 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 裡把這條規則強制執行:任何新的 os.kill(pid, 0) 調用都會讓 Windows footguns (blocking) 檢查失敗,除非該行帶 # windows-footgun: ok — <reason> 標記。

常見坑

安裝完立刻報 hermes: command not found 打開一個新的 PowerShell 窗口。安裝器把 %LOCALAPPDATA%\hermes\bin 加到了 User 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 的版本。

重啟之後 Gateway 跑不起來。 看一眼 hermes gateway status——它會把 schtasks 項、Startup 文件夾快捷方式(如果有)和實時 PID 合併展示。如果 schtasks 已註冊但沒在跑,可能是組策略禁掉了 ONLOGON 觸發器。運行 schtasks /Query /TN HermesGateway /V /FO LIST 看任務的失敗原因,或者卸載後用 HERMES_GATEWAY_FORCE_STARTUP=1 重裝回退到 Startup 文件夾路徑。

設了 $env:EDITOR 之後 /edit 還是沒反應。 你只是設到了當前進程;關掉再開一個 shell,或者在系統屬性 → 環境變量裡以 User scope 設置。在新 PowerShell 窗口裡用 echo $env:EDITOR 驗證。

Browser tool 起得來,但工具調用超時。 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 的情況下卸載系統 Node。

中文 / 日語 / 阿拉伯字符在 CLI 裡顯示成 ? UTF-8 stdio 墊片沒有生效。檢查 HERMES_DISABLE_WINDOWS_UTF8 是否沒有被設置(Get-ChildItem env:HERMES_DISABLE_WINDOWS_UTF8)。如果它確實是空的但仍然出現 ?,說明控制檯宿主(極舊的 cmd.exe)根本不支持 UTF-8——切到 Windows Terminal。

Gateway 發不了 Telegram 圖片——報 "BadRequest: payload contains invalid characters"。 這並非 Windows 特有,但有時候在 Windows 上首先暴露。通常是因為你的文件路徑在 JSON body 裡帶了未轉義的反斜槓。Telegram 應該收到的是 Hermes 標準化過的路徑,而不是原始 Windows 路徑——如果你在自定義插件裡看到這個錯誤,請確認你傳的是 Hermes 提供的路徑,而不是來自用戶輸入的 str(Path(...))

git pull 之後出現"在另一臺機器上能跑"的編碼詭異問題。 如果你用非 UTF-8 編輯器(老版本 Windows 上的 Notepad、某些中文輸入法)在 Windows 上編輯過 Hermes 配置或 skill,文件可能被存成了帶 BOM 的版本。Hermes 在大多數配置讀取時會容忍 utf-8-sig,但摺疊 YAML 標量(description: >)裡的 BOM 會讓 YAML 解析靜默失敗。把文件重新存成不帶 BOM 的純 UTF-8。

接下來去哪裡

  • 安裝 —— 完整的安裝頁,覆蓋 Linux/macOS/WSL2/Termux。
  • Windows (WSL2) 指南 —— 如果你想要 POSIX 語義或 Dashboard 終端面板。
  • CLI 參考 —— 每個 hermes 子命令。
  • FAQ —— 與 Windows 無關的常見問題。
  • 消息 Gateway —— 在 Windows 上跑 Telegram/Discord/Slack。