Skip to content

hermes agent 贡献指南

感谢你为 Hermes Agent 做出贡献!本指南涵盖如何设置开发环境、理解代码库,以及让你的 PR 被合并。

我们按以下顺序重视贡献:

  1. Bug 修复 —— 崩溃、错误行为、数据丢失
  2. 跨平台兼容性 —— macOS、不同 Linux 发行版、WSL2
  3. 安全加固 —— shell injection、prompt injection、path traversal
  4. 性能和健壮性 —— retry logic、error handling、graceful degradation
  5. 新 skills —— 广泛有用的 skills(参见 Creating Skills)
  6. 新 tools —— 很少需要;大多数能力应该通过 skills 实现
  7. 文档 —— 修复、澄清、新示例
  • 不修改 Hermes core,构建自定义 / 本地 tool?从 Build a Hermes Plugin 开始
  • 为 Hermes 本身构建新的内置核心 tool?从 Adding Tools 开始
  • 构建新的 skill?从 Creating Skills 开始
  • 构建新的 inference provider?从 Adding Providers 开始
要求说明
Git支持 --recurse-submodules,并已安装 git-lfs 扩展
Python 3.11+如果缺失,uv 会安装它
uv快速 Python 包管理器(安装)
Node.js 20+可选 —— browser tools 和 WhatsApp bridge 需要(与根目录 package.json 的 engines 匹配)
Terminal window
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
# Create venv with Python 3.11
uv venv venv --python 3.11
export VIRTUAL_ENV="$(pwd)/venv"
# Install with all extras (messaging, cron, CLI menus, dev tools)
uv pip install -e ".[all,dev]"
# Optional: browser tools
npm install
Terminal window
mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills}
cp cli-config.yaml.example ~/.hermes/config.yaml
touch ~/.hermes/.env
# Add at minimum an LLM provider key:
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env
Terminal window
# Symlink for global access
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
# Verify
hermes doctor
hermes chat -q "Hello"
Terminal window
pytest tests/ -v
  • PEP 8,但有实际例外(不强制严格行长度)
  • 注释:只在解释非显而易见的意图、权衡或 API 特性时使用
  • 错误处理:捕获具体异常。对于意外错误,使用 logger.warning() / logger.error() 并设置 exc_info=True
  • 跨平台:永远不要假设 Unix(见下文)
  • Profile-safe paths:永远不要硬编码 ~/.hermes —— 代码路径使用 hermes_constants 中的 get_hermes_home(),面向用户的消息使用 display_hermes_home()。完整规则见 AGENTS.md

Hermes 官方支持 Linux、macOS、WSL2,以及原生 Windows(早期 beta —— 通过 PowerShell 安装)。原生 Windows 使用 Git Bash(来自 Git for Windows)来执行 shell 命令。少数功能需要 POSIX 内核原语,因此会被限制:dashboard 的嵌入式 PTY terminal pane(/chat tab)仅支持 WSL2。原生 Windows 路径是新的,并且变化很快 —— 如果你进行大量 Windows 相关开发,预期会遇到并修复一些粗糙边角。

贡献代码时,请记住这些规则:

  • 不要添加未保护的 signal.SIGKILL 引用。它在 Windows 上未定义。要么通过 gateway.status.terminate_pid(pid, force=True)(集中式 primitive,在 Windows 上执行 taskkill /T /F,在 POSIX 上执行 SIGKILL),要么使用 getattr(signal, "SIGKILL", signal.SIGTERM) 回退。
  • os.kill(pid, 0) 探测中,除了 ProcessLookupError,也要捕获 OSError。Windows 会对已经不存在的 PID 抛出 OSErrorWinError 87,“parameter is incorrect”),而不是 ProcessLookupError
  • 不要强制 terminal 使用 POSIX 语义。os.setsidos.killpgos.getpgidos.fork 在 Windows 上都会抛错 —— 请使用 if sys.platform != "win32":if os.name != "nt": 进行门控。
  • 打开文件时显式使用 encoding="utf-8"。Windows 上 Python 默认使用系统 locale(通常是 cp1252),这会导致非拉丁文本乱码或崩溃。
  • 使用 pathlib.Path / os.path.join —— 永远不要手动用 / 拼接路径。对于 OS 返回给我们的字符串来说影响较小,但对于我们构造后传给 subprocesses 的字符串来说更重要。

关键模式:

始终同时捕获 ImportErrorNotImplementedError

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

某些环境可能会用非 UTF-8 编码保存 .env 文件:

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

os.setsid()os.killpg() 和 signal handling 在不同平台上有所不同:

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

使用 pathlib.Path,而不是用 / 进行字符串拼接。

Hermes 拥有 terminal 访问权限。安全很重要。

层级实现
Sudo password piping使用 shlex.quote() 防止 shell injection
Dangerous command detectiontools/approval.py 中的 Regex patterns,并带有用户 approval flow
Cron prompt injectionScanner 会阻止 instruction-override patterns
Write deny list通过 os.path.realpath() 解析受保护路径,防止 symlink 绕过
Skills guard针对 hub-installed skills 的 security scanner
Code execution sandbox子进程运行时会剥离 API keys
Container hardeningDocker:移除所有 capabilities、禁止 privilege escalation、设置 PID limits
  • 将用户输入插入 shell commands 时,始终使用 shlex.quote()
  • 在进行 access control checks 之前,使用 os.path.realpath() 解析 symlinks
  • 不要记录 secrets
  • 在 tool execution 周围捕获 broad exceptions
  • 如果你的变更涉及 file paths 或 processes,请在所有平台上测试
fix/description # Bug fixes
feat/description # New features
docs/description # Documentation
test/description # Tests
refactor/description # Code restructuring
  1. 运行测试:pytest tests/ -v
  2. 手动测试:运行 hermes,并执行你修改过的代码路径
  3. 检查跨平台影响:考虑 macOS 和不同 Linux 发行版
  4. 保持 PR 聚焦:每个 PR 只做一个逻辑变更

包含:

  • 变更了什么,以及为什么
  • 如何测试
  • 你在哪些平台上测试过
  • 引用任何相关 issues

我们使用 Conventional Commits:

<type>(<scope>): <description>
Type用途
fixBug 修复
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
  • 包含:OS、Python 版本、Hermes 版本(hermes version)、完整错误 traceback
  • 包含复现步骤
  • 创建重复 issue 前,请先检查已有 issues
  • 对于安全漏洞,请私下报告
  • Discord:discord.gg/NousResearch
  • GitHub Discussions:用于设计提案和架构讨论
  • Skills Hub:上传专用 skills,并与社区分享

通过贡献,你同意你的贡献将基于 MIT License 授权。

-
0:000:00