H繁中版
<!-- Source: https://hermesbible.com/docs/developer-guide/contributing -->

感謝你為 Hermes Agent 做出貢獻!本指南涵蓋設定開發環境、理解程式碼庫,以及讓你的 PR 被合併。

貢獻優先順序

我們按以下順序重視貢獻:

  1. 錯誤修正 — 崩潰、不正確的行為、資料遺失
  2. 跨平台相容性 — macOS、不同的 Linux 發行版、WSL2
  3. 安全性強化 — shell 注入、提示注入、路徑遍歷
  4. 效能與穩健性 — 重試邏輯、錯誤處理、優雅降級
  5. 新技能 — 廣泛有用的技能(參見建立技能
  6. 新工具 — 很少需要;大部分功能應該用技能實作
  7. 文件 — 修正、說明、新範例

常見貢獻路徑

開發環境設定

前置需求

需求備註
Git需安裝 git-lfs 擴充
Python 3.11+若缺少,uv 會自動安裝
uv快速 Python 套件管理器(安裝方式
Node.js 20+選用——瀏覽器工具和 WhatsApp 橋接需要(與根目錄 package.json engines 一致)

使用標準安裝器安裝

對於大多數貢獻者,最佳的開發引導方式與使用者相同:執行標準安裝器,然後在它克隆的儲存庫內工作。安裝器會建立 Hermes 虛擬環境、連接 hermes 命令、標記安裝方法供 hermes update 使用,並將完整的 git 專案克隆到 $HERMES_HOME/hermes-agent(通常是 ~/.hermes/hermes-agent)。這讓你的開發環境與 CLI、更新器、延遲安裝器、閘道器和文件所假設的佈局保持一致。

curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
cd "${HERMES_HOME:-$HOME/.hermes}/hermes-agent"

# 在標準安裝之上加入 dev/test 額外套件。
uv pip install -e ".[all,dev]"

# 選用:瀏覽器工具 / 文件網站依賴。
npm install

之後,建立分支並從該簽出執行測試:

git checkout -b fix/description
scripts/run_tests.sh

手動克隆回退

僅在你刻意不想要 Hermes 的管理式安裝佈局時使用(例如,容器或 CI 工作中的暫時克隆)。如果你用這種方式安裝,請確保從此虛擬環境執行 hermes 入口點;使用系統的 python3 -m hermes_cli.main 可能會載入不相關的系統 Python 套件。

git clone https://github.com/NousResearch/hermes-agent.git
cd hermes-agent

# 用 Python 3.11 建立虛擬環境
uv venv venv --python 3.11
export VIRTUAL_ENV="$(pwd)/venv"

# 安裝所有額外套件(訊息、排程、CLI 選單、開發工具)
uv pip install -e ".[all,dev]"

# 選用:瀏覽器工具
npm install

設定開發環境

mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills}
cp cli-config.yaml.example ~/.hermes/config.yaml
touch ~/.hermes/.env

# 至少加入一個 LLM 供應商金鑰:
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env

執行

# 標準安裝器已經將 `hermes` 放在 PATH 上。
hermes doctor
hermes chat -q "Hello"

如果你使用了手動克隆回退,從簽出處執行 ./hermes 或明確地建立此克隆的虛擬環境符號連結:

mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes

執行測試

scripts/run_tests.sh

程式碼風格

  • PEP 8 搭配實務例外(不強制行長度限制)
  • 註解:僅在解釋非顯然的意圖、取捨或 API 特性時使用
  • 錯誤處理:捕捉特定例外。對預期外的錯誤使用 logger.warning()/logger.error() 搭配 exc_info=True
  • 跨平台:永遠不要假設 Unix(見下文)
  • Profile 安全路徑:永遠不要硬編碼 ~/.hermes——程式碼路徑使用 hermes_constants 中的 get_hermes_home(),面向使用者的訊息使用 display_hermes_home()。完整規則參見 AGENTS.md

跨平台相容性

Hermes 官方支援 Linux、macOS、WSL2 和原生 Windows(透過 PowerShell 安裝)。原生 Windows 使用 Git Bash(來自 Git for Windows)執行 shell 命令。部分功能需要 POSIX 核心原語並受到閘控:儀表板的嵌入式 PTY 終端機面板(/chat 標籤頁)僅限 WSL2。如果你大量進行 Windows 開發,在推送前執行 Windows 殺手檢查(scripts/check-windows-footguns.py)。

撰寫貢獻程式碼時,請牢記以下規則:

  • 不要加入未受保護的 signal.SIGKILL 引用。 它在 Windows 上未定義。改用 gateway.status.terminate_pid(pid, force=True)(在 Windows 上執行 taskkill /T /F、在 POSIX 上執行 SIGKILL 的集中化原語),或使用 getattr(signal, "SIGKILL", signal.SIGTERM) 做回退。
  • os.kill(pid, 0) 探測中,除了 ProcessLookupError 外也要捕捉 OSError Windows 對已結束的 PID 拋出 OSError(WinError 87,「參數不正確」)而非 ProcessLookupError
  • 不要強制終端機使用 POSIX 語義。 os.setsidos.killpgos.getpgidos.fork 在 Windows 上都會拋出異常——用 if sys.platform != "win32":if os.name != "nt": 來閘控。
  • 使用明確的 encoding="utf-8" 開啟檔案。 Windows 上的 Python 預設值是系統語系(通常是 cp1252),對非拉丁文字會產生亂碼或崩潰。
  • 使用 pathlib.Path / os.path.join——永遠不要手動用 / 串接。 這對 OS 回傳的字串影響較小,但對我們建構並傳給子程序的字串很重要。

關鍵模式:

1. termiosfcntl 僅限 Unix

永遠要同時捕捉 ImportErrorNotImplementedError

try:
    from simple_term_menu import TerminalMenu
    menu = TerminalMenu(options)
    idx = menu.show()
except (ImportError, NotImplementedError):
    # 回退:編號選單
    for i, opt in enumerate(options):
        print(f"  {i+1}. {opt}")
    idx = int(input("Choice: ")) - 1

2. 檔案編碼

某些環境可能以非 UTF-8 編碼儲存 .env 檔案:

try:
    load_dotenv(env_path)
except UnicodeDecodeError:
    load_dotenv(env_path, encoding="latin-1")

3. 程序管理

os.setsid()os.killpg() 和訊號處理在不同平台上有所差異:

import platform
if platform.system() != "Windows":
    kwargs["preexec_fn"] = os.setsid

4. 路徑分隔符

使用 pathlib.Path 而非用 / 串接字串。

安全性考量

Hermes 擁有終端機存取權限。安全性至關重要。

現有防護

層級實作方式
Sudo 密碼管線使用 shlex.quote() 防止 shell 注入
危險指令偵測tools/approval.py 中的正則表達式模式,搭配使用者審核流程
排程提示注入掃描器阻擋指令覆寫模式
寫入拒絕清單受保護路徑透過 os.path.realpath() 解析以防止符號連結繞過
技能防護針對 hub 安裝技能的安全掃描器
程式碼執行沙箱子程序以移除 API 金鑰的狀態運行
容器強化Docker:移除所有能力、禁止權限提升、PID 限制

負責安全敏感程式碼的貢獻

  • 將使用者輸入插值到 shell 命令時,永遠使用 shlex.quote()
  • 在存取控制檢查前,使用 os.path.realpath() 解析符號連結
  • 不要記錄密鑰
  • 在工具執行周圍捕捉廣泛例外
  • 如果你的變更涉及檔案路徑或程序,請在所有平台上測試

Pull Request 流程

分支命名

fix/description        # 錯誤修正
feat/description       # 新功能
docs/description       # 文件
test/description       # 測試
refactor/description   # 程式碼重構

提交前

  1. 執行測試pytest tests/ -v
  2. 手動測試:執行 hermes 並測試你修改的程式碼路徑
  3. 檢查跨平台影響:考慮 macOS 和不同的 Linux 發行版
  4. 保持 PR 專注:每個 PR 一個邏輯變更

PR 描述

包含:

  • 改了什麼以及為什麼
  • 如何測試
  • 在哪些平台上測試過
  • 引用任何相關的 issue

提交訊息

我們使用 Conventional Commits

<type>(<scope>): <description>
類型用途
fix錯誤修正
feat新功能
docs文件
test測試
refactor程式碼重構
chore建構、CI、依賴更新

Scopes:cligatewaytoolsskillsagentinstallwhatsappsecurity

範例:

fix(cli): prevent crash in save_config_value when model is a string
feat(gateway): add WhatsApp multi-user session isolation
fix(security): prevent shell injection in sudo password piping

回報問題

  • 使用 GitHub Issues
  • 包含:作業系統、Python 版本、Hermes 版本(hermes version)、完整的錯誤回溯
  • 包含重現步驟
  • 建立前先檢查現有 issues
  • 安全性漏洞請私下回報

社群

  • Discorddiscord.gg/NousResearch
  • GitHub Discussions:設計提案和架構討論
  • Skills Hub:上傳專業技能並與社群分享

授權條款

透過貢獻,你同意你的貢獻將在 MIT License 下授權。



架構