ByteNoteByteNote

字节笔记本

2026年6月21日

hermes教程-贡献指南

API中转
¥120

贡献优先级

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

  1. Bug 修复 — 崩溃、错误行为、数据丢失
  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 的引擎要求一致)

使用标准安装程序安装

对于大多数贡献者,最佳开发引导方式与用户相同:运行标准安装程序,然后在其克隆的仓库内工作。安装程序会创建 Hermes 虚拟环境、绑定 hermes 命令、标记安装方法以便 hermes update 使用,并将完整的 git 项目克隆到 $HERMES_HOME/hermes-agent(通常是 ~/.hermes/hermes-agent)。这使你的开发环境与 CLI、更新器、懒加载依赖安装器、网关和文档所期望的布局保持一致。

bash
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
cd "${HERMES_HOME:-$HOME/.hermes}/hermes-agent"
## 在标准安装基础上添加开发/测试额外依赖
uv pip install -e ".[all,dev]"
## 可选:浏览器工具 / 文档站点依赖
npm install

之后,从该检出目录创建分支并运行测试:

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

手动克隆备用方案

仅当你故意不想要 Hermes 的托管安装布局时使用(例如,在容器或 CI 作业中的一次性克隆)。如果以这种方式安装,请确保从此虚拟环境运行 hermes 入口点;运行系统 python3 -m hermes_cli.main 可能会拾取无关的系统 Python 包。

bash
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"
## 安装所有额外依赖(消息、cron、CLI 菜单、开发工具)
uv pip install -e ".[all,dev]"
## 可选:浏览器工具
npm install

配置开发环境

bash
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

运行

bash
## 标准安装程序已将 `hermes` 添加到 PATH
hermes doctor
hermes chat -q "Hello"

如果你使用了手动克隆备用方案,请从检出目录运行 ./hermes,或显式符号链接此克隆的虚拟环境:

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

运行测试

bash
scripts/run_tests.sh

代码风格

  • PEP 8,但允许实际例外(不严格限制行长度)
  • 注释:仅在解释非显而易见的意图、权衡或 API 怪癖时添加
  • 错误处理:捕获特定异常。对意外错误使用 logger.warning()/logger.error() 并带上 exc_info=True
  • 跨平台:绝不假设 Unix(见下文)
  • 配置文件安全路径:绝不硬编码 ~/.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) 探测时同时捕获 OSErrorProcessLookupError。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 — 绝不手动拼接 /。对于操作系统返回的字符串影响较小,但对于我们构造并传递给子进程的字符串则很重要。

关键模式:

1. termiosfcntl 仅限 Unix

始终同时捕获 ImportErrorNotImplementedError

python
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("选择: ")) - 1

2. 文件编码

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

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

3. 进程管理

os.setsid()os.killpg() 和信号处理在不同平台上有所不同:

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

4. 路径分隔符

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

安全考虑

Hermes 具有终端访问权限。安全很重要。

现有保护措施

实现
Sudo 密码管道使用 shlex.quote() 防止 shell 注入
危险命令检测tools/approval.py 中的正则模式,带有用户批准流程
Cron 提示注入扫描器阻止指令覆盖模式
写入拒绝列表通过 os.path.realpath() 解析受保护路径,防止符号链接绕过
技能守卫对中心安装的技能进行安全扫描
代码执行沙箱子进程运行时剥离 API 密钥
容器加固Docker:删除所有能力,无特权提升,PID 限制

贡献安全敏感代码

  • 在将用户输入插入 shell 命令时始终使用 shlex.quote()
  • 在访问控制检查之前使用 os.path.realpath() 解析符号链接
  • 不要记录密钥
  • 在工具执行周围捕获宽泛的异常
  • 如果更改涉及文件路径或进程,在所有平台上测试

拉取请求流程

分支命名

text
fix/description        # Bug 修复
feat/description       # 新功能
docs/description       # 文档
test/description       # 测试
refactor/description   # 代码重构

提交前

  1. 运行测试pytest tests/ -v
  2. 手动测试:运行 hermes 并执行你更改的代码路径
  3. 检查跨平台影响:考虑 macOS 和不同 Linux 发行版
  4. 保持 PR 聚焦:每个 PR 只做一项逻辑更改

PR 描述

包括:

  • 什么发生了变化以及为什么
  • 如何测试
  • 在哪些平台上测试过
  • 引用相关 issue

提交信息

我们使用 Conventional Commits

<类型>(<作用域>): <描述>
类型用途
fixBug 修复
feat新功能
docs文档
test测试
refactor代码重构
chore构建、CI、依赖更新

作用域:cligatewaytoolsskillsagentinstallwhatsappsecurity

示例:

text
fix(cli): 防止在 model 为字符串时 save_config_value 崩溃
feat(gateway): 添加 WhatsApp 多用户会话隔离
fix(security): 防止 sudo 密码管道中的 shell 注入

报告问题

  • 使用 GitHub Issues
  • 包括:操作系统、Python 版本、Hermes 版本(hermes version)、完整错误回溯
  • 包括重现步骤
  • 在创建重复问题前检查现有问题
  • 对于安全漏洞,请私下报告

社区

  • Discorddiscord.gg/NousResearch
  • GitHub Discussions:用于设计提案和架构讨论
  • 技能中心:上传专业技能并与社区分享

许可证

通过贡献,你同意你的贡献将根据 MIT 许可证 进行许可。



分享: