参与贡献
感谢你为 Hermes Agent 做出贡献。本指南介绍如何搭建开发环境、理解代码库,并顺利提交和合并 PR。
贡献优先级
我们更优先欢迎以下类型的贡献:
- Bug 修复 — 崩溃、行为错误、数据丢失
- 跨平台兼容性 — macOS、不同 Linux 发行版、WSL2
- 安全加固 — shell 注入、prompt 注入、路径遍历
- 性能与健壮性 — 重试逻辑、错误处理、优雅降级
- 新技能 — 面向广泛用户的通用技能(见 Creating Skills)
- 新工具 — 通常较少需要;大多数能力更适合做成技能
- 文档 — 修正、澄清和示例补充
常见贡献路径
- 想新增工具?从 Adding Tools 开始
- 想新增技能?从 Creating Skills 开始
- 想新增推理大模型提供商(provider)?从 Adding Providers 开始
开发环境设置
前置要求
| Requirement | Notes |
|---|---|
| Git | 需要支持 --recurse-submodules,并安装 git-lfs |
| Python 3.11+ | 如果本地没有,uv 会安装 |
| uv | 快速 Python 包管理器(install) |
| Node.js 20+ | 可选;浏览器工具和 WhatsApp bridge 需要它(与根目录 package.json 的 engines 保持一致) |
克隆与安装
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]"
uv pip install -e "./tinker-atropos"
# Optional: browser tools
npm install
开发配置
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
运行
# Symlink for global access
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
# Verify
hermes doctor
hermes chat -q "Hello"
运行测试
pytest tests/ -v
代码风格
- 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 不受支持,但代码库包含一些防御性写法,以避免在边缘场景下直接崩溃。关键规则如下:
1. termios 与 fcntl 仅适用于 Unix
始终同时捕获 ImportError 与 NotImplementedError:
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
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 具备终端访问能力,因此安全问题非常重要。
现有防护
| Layer | Implementation |
|---|---|
| Sudo 密码管道 | 使用 shlex.quote() 防止 shell 注入 |
| 危险命令检测 | tools/approval.py 中的正则模式 + 用户审批流程 |
| Cron prompt injection | 扫描器会拦截指令覆盖模式 |
| 写入拒绝列表 | 通过 os.path.realpath() 解析保护路径,防止符号链接绕过 |
| 技能防护 | 对 Hub 安装技能做安全扫描 |
| 代码执行沙箱 | 子进程运行时会剥离 API Key |
| 容器加固 | Docker 默认丢弃全部 capabilities、禁止权限升级、限制 PID |
贡献安全敏感代码时
- 在 shell 命令中插入用户输入时,一律使用
shlex.quote() - 做访问控制前,先用
os.path.realpath()解析符号链接 - 不要记录 secret
- 围绕工具执行加上足够稳妥的异常处理
- 如果改动涉及路径或进程,请在多平台上测试
Pull Request 流程
分支命名
fix/description # Bug fixes
feat/description # New features
docs/description # Documentation
test/description # Tests
refactor/description # Code restructuring
提交前检查
- 运行测试:
pytest tests/ -v - 手动验证:运行
hermes,覆盖你改动到的代码路径 - 检查跨平台影响:至少考虑 macOS 与不同 Linux 发行版
- 保持 PR 聚焦:一个 PR 只做一类逻辑改动
PR 描述
请包含:
- 改了什么,以及 为什么这样改
- 如何测试
- 在哪些平台上测试过
- 相关 issue 的引用
Commit Message
我们使用 Conventional Commits:
<type>(<scope>): <description>
| Type | Use for |
|---|---|
fix | Bug 修复 |
feat | 新功能 |
docs | 文档 |
test | 测试 |
refactor | 代码重构 |
chore | 构建、CI、依赖更新 |
常见 scope 包括:cli、gateway、tools、skills、agent、install、whatsapp、security
示例:
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)、完整错误堆栈 - 请附上复现步骤
- 创建前先搜索是否已有重复问题
- 安全漏洞请私下报告
社区
- Discord: discord.gg/NousResearch
- GitHub Discussions: 用于设计提案和架构讨论
- Skills Hub: 可上传专业技能并与社区共享
License
提交贡献即表示你同意,这些贡献将以 MIT License 授权。