所有设置均存储在 ~/.hermes/ 目录中,便于访问。目录结构#
~/.hermes/
├── config.yaml # 设置(模型、终端、TTS、压缩等)
├── .env # API 密钥和机密
├── auth.json # OAuth provider 凭据(Nous Portal 等)
├── SOUL.md # 主要 agent 身份(系统提示词第 #1 槽位)
├── memories/ # 持久记忆(MEMORY.md、USER.md)
├── skills/ # Agent 创建的技能(通过 skill_manage 工具管理)
├── cron/ # 定时任务
├── sessions/ # Gateway 会话
└── logs/ # 日志(errors.log、gateway.log — 机密自动脱敏)
管理配置#
hermes config set 命令会自动将值路由到正确的文件 —— API 密钥保存到 .env,其他所有内容保存到 config.yaml。
配置优先级#
1.
CLI 参数 —— 例如 hermes chat --model anthropic/claude-sonnet-4(单次调用覆盖)
2.
~/.hermes/config.yaml —— 所有非机密设置的主配置文件
3.
~/.hermes/.env —— 环境变量的回退;机密(API 密钥、token、密码)必须放这里
4.
内置默认值 —— 未设置任何内容时的硬编码安全默认值
机密(API 密钥、bot token、密码)放入 .env。其他所有内容(模型、终端后端、压缩设置、内存限制、工具集)放入 config.yaml。当两者都设置时,config.yaml 对非机密设置优先。
环境变量替换#
可以在 config.yaml 中使用 ${VAR_NAME} 语法引用环境变量:单个值中可以有多个引用:url: "${HOST}:${PORT}"。如果引用的变量未设置,占位符将保持原样(${UNDEFINED_VAR} 保持不变)。仅支持 ${VAR} 语法 —— 裸 $VAR 不会被展开。关于 AI provider 设置(OpenRouter、Anthropic、Copilot、自定义端点、自托管 LLM、回退模型等),请参阅 AI Providers。Provider 超时#
可以为 provider 设置 providers.<id>.request_timeout_seconds 作为全局请求超时,以及 providers.<id>.models.<model>.timeout_seconds 作为特定模型的覆盖值。适用于每种传输方式(OpenAI-wire、原生 Anthropic、Anthropic 兼容)上的主轮次客户端、回退链、凭据轮换后的重建,以及(对于 OpenAI-wire)每请求超时 kwarg —— 因此配置值优先于旧版 HERMES_API_TIMEOUT 环境变量。还可以设置 providers.<id>.stale_timeout_seconds 用于非流式陈旧调用 检测器,以及 providers.<id>.models.<model>.stale_timeout_seconds 作为特定模型的覆盖值。此值优先于旧版 HERMES_API_CALL_STALE_TIMEOUT 环境变量。不设置这些值将保持旧版默认值(HERMES_API_TIMEOUT=1800s、HERMES_API_CALL_STALE_TIMEOUT=300s、原生 Anthropic 900s)。目前不适用于 AWS Bedrock(bedrock_converse 和 AnthropicBedrock SDK 路径均使用 boto3 及其自身的超时配置)。请参阅 cli-config.yaml.example 中的注释示例。终端后端配置#
Hermes 支持六种终端后端。每种后端决定 agent 的 shell 命令实际在哪里执行 —— 本地机器、Docker 容器、通过 SSH 的远程服务器、Modal 云沙箱(直接或通过 Nous 托管的 gateway)、Daytona 工作区,或 Singularity/Apptainer 容器。对于 Modal 和 Daytona 等云沙箱,container_persistent: true 表示 Hermes 将尝试在沙箱重建后保留文件系统状态。这并不保证相同的活跃沙箱、PID 空间或后台进程之后仍在运行。后端概览#
| 后端 | 命令运行位置 | 隔离性 | 最适合 |
|---|
| local | 直接在您的机器上 | 无 | 开发、个人使用 |
| docker | 单个持久 Docker 容器(跨会话、/new、子 agent 共享) | 完全(命名空间、cap-drop) | 安全沙箱、CI/CD |
| ssh | 通过 SSH 的远程服务器 | 网络边界 | 远程开发、强大硬件 |
| modal | Modal 云沙箱 | 完全(云 VM) | 临时云计算、评估 |
| daytona | Daytona 工作区 | 完全(云容器) | 托管云开发环 境 |
| singularity | Singularity/Apptainer 容器 | 命名空间(--containall) | HPC 集群、共享机器 |
Local 后端#
默认后端。命令直接在您的机器上运行,无隔离。无需特殊设置。Agent 拥有与您的用户账户相同的文件系统访问权限。使用 hermes tools 禁用不需要的工具,或切换到 Docker 进行沙箱隔离。
Docker 后端#
在具有安全加固的 Docker 容器内运行命令(所有权限已删除、无权限提升、PID 限制)。单个持久容器,而非每条命令一个容器。 Hermes 在首次使用时启动一个长期运行的容器,并通过 docker exec 将每个终端、文件和 execute_code 调用路由到同一容器中 —— 跨会话、/new、/reset 和 delegate_task 子 agent,贯穿 Hermes 进程的整个生命周期。工作目录更改、已安装的包以及 /workspace 中的文件会从一次工具调用延续到下一次,就像本地 shell 一样。容器在关闭时停止并删除。详情请参阅下方的容器生命周期。terminal.docker_extra_args(也可通过 TERMINAL_DOCKER_EXTRA_ARGS='["--gpus=all"]' 覆盖)允许传递 Hermes 未作为一级键公开的任意 docker run 标志 —— --gpus、--network、--add-host、替代 --security-opt 覆盖等。每个条目必须是字符串;该列表最后附加到组装好的 docker run 调用中,因此可以在需要时覆盖 Hermes 的默认值。请谨慎使用 —— 与沙箱加固(权限删除、--user、workspace 绑定挂载)冲突的标志将悄然削弱隔离性。要求: 已安装并运行 Docker Desktop 或 Docker Engine。Hermes 会探测 $PATH 以及常见的 macOS 安装位置(/usr/local/bin/docker、/opt/homebrew/bin/docker、Docker Desktop 应用包)。开箱即用支持 Podman:设置 HERMES_DOCKER_BINARY=podman(或完整路径)以在两者都安装时强制使用它。容器生命周期: Hermes 为每个终端和文件工具调用重用单个长期运行的容器(docker run -d ... sleep 2h),跨会话、/new、/reset 和 delegate_task 子 agent,贯穿 Hermes 进程的整个生命周期。命令通过带登录 shell 的 docker exec 运行,因此工作目录更改、已安装的包以及 /workspace 中的文件都会从一次工具调用延续到下一次。容器在 Hermes 关闭时(或空闲清理回收时)停止并删除。通过 delegate_task(tasks=[...]) 生成的并行子 agent 共享这一个容器 —— 并发的 cd、环境变量修改以及对同一路径的写入会发生冲突。如果子 agent 需要隔离的沙箱,必须通过 register_task_env_overrides() 注册每任务镜像覆盖,RL 和基准测试环境(TerminalBench2、HermesSweEnv 等)会自动为其每任务 Docker 镜像执行此操作。--cap-drop ALL,仅添加回 DAC_OVERRIDE、CHOWN、FOWNER
--security-opt no-new-privileges
/tmp(512MB)、/var/tmp(256MB)、/run(64MB)的大小限制 tmpfs
凭据转发: docker_forward_env 中列出的环境变量首先从您的 shell 环境解析,然后回退到 ~/.hermes/.env。技能也可以声明 required_environment_variables,这些变量会自动合并。SSH 后端#
通过 SSH 在远程服务器上运行命令。使用 ControlMaster 进行连接复用(5 分钟空闲保活)。默认启用持久 shell —— 状态(cwd、环境变量)在命令之间保持。| 变量 | 默认值 | 描述 |
|---|
TERMINAL_SSH_PORT | 22 | SSH 端口 |
TERMINAL_SSH_KEY | (系统默认) | SSH 私钥路径 |
TERMINAL_SSH_PERSISTENT | true | 启用持久 shell |
工作原理: 使用 BatchMode=yes 和 StrictHostKeyChecking=accept-new 在初始化时连接。持久 shell 在远程主机上保持单个 bash -l 进程存活,通过临时文件进行通信。需要 stdin_data 或 sudo 的命令会自动回退到单次模式。Modal 后端#
在 Modal 云沙箱中运行命令。每个任务获得一个具有可配置 CPU、内存和磁盘的隔离 VM。文件系统可以跨会话快照/恢复。必需: MODAL_TOKEN_ID + MODAL_TOKEN_SECRET 环境变量,或 ~/.modal.toml 配置文件。持久化: 启用后,沙箱文件系统在清理时快照,并在下次会话时恢复。快照在 ~/.hermes/modal_snapshots.json 中跟踪。这保留文件系统状态,而非活跃进程、PID 空间或后台任务。凭据文件: 自动从 ~/.hermes/ 挂载(OAuth token 等),并在每条命令前同步。Daytona 后端#
在 Daytona 托管工作区中运行命令。支持停止/恢复以实现持久化。必需: DAYTONA_API_KEY 环境变量。持久化: 启用后,沙箱在清理时停止(而非删除),并在下次会话时恢复。沙箱名称遵循 hermes-{task_id} 模式。磁盘限制: Daytona 强制执行 10 GiB 最大值。超过此值的请求将被截断并发出警告。Singularity/Apptainer 后端#
要求: $PATH 中有 apptainer 或 singularity 二进制文件。镜像处理: Docker URL(docker://...)自动转换为 SIF 文件并缓存。现有 .sif 文件直接使用。临时目录: 按顺序解析:TERMINAL_SCRATCH_DIR → TERMINAL_SANDBOX_DIR/singularity → /scratch/$USER/hermes-agent(HPC 惯例)→ ~/.hermes/sandboxes/singularity。隔离: 使用 --containall --no-home 实现完全命名空间隔离,不挂载宿主 home 目录。常见终端后端问题#
Local —— 无特殊要求。入门时最安全的默认选项。
Docker —— 运行 docker version 验证 Docker 是否正常工作。如果失败,修复 Docker 或执行 hermes config set terminal.backend local。
SSH —— TERMINAL_SSH_HOST 和 TERMINAL_SSH_USER 都必须设置。如果缺少任一项,Hermes 会记录清晰的错误。
Modal —— 需要 MODAL_TOKEN_ID 环境变量或 ~/.modal.toml。运行 hermes doctor 检查。
Daytona —— 需要 DAYTONA_API_KEY。Daytona SDK 处理服务器 URL 配置。
Singularity —— 需要 $PATH 中有 apptainer 或 singularity。HPC 集群上常见。
如有疑问,将 terminal.backend 设回 local 并首先验证命令在那里运行。拆卸时远程到宿主文件同步#
对于 SSH、Modal 和 Daytona 后端(agent 的工作树位于与运行 Hermes 的宿主不同的机器上),Hermes 跟踪 agent 在远程沙箱中触及的文件,并在会话拆卸/沙箱清理时,将修改的文件同步回宿主,存放在 ~/.hermes/cache/remote-syncs/<session-id>/ 下。触发时机:会话关闭、/new、/reset、gateway 消息超时、子 agent 使用远程后端时 delegate_task 子 agent 完成。
覆盖 agent 修改的整个树,而不仅仅是它明确打开的文件。添加、编辑和删除都会被捕获。
远程沙箱可能在您查找时已被拆除;本地 ~/.hermes/cache/remote-syncs/… 副本是 agent 更改内容的权威记录。
大型二进制输出(模型检查点、原始数据集)按大小限制 —— 同步跳过超过 file_sync_max_mb(默认 100)的文件。如果您期望更大的工件返回,请调高该值。
这是从会话结束后被销毁的临时云沙箱中恢复结果的方式,无需告诉 agent 显式地 scp 或 modal volume put 每个工件。Docker 卷挂载#
使用 Docker 后端时,docker_volumes 允许您与容器共享宿主目录。每个条目使用标准 Docker -v 语法:host_path:container_path[:options]。向 agent 提供文件(数据集、配置、参考代码)
从 agent 接收文件(生成的代码、报告、导出)
如果您使用消息 gateway 并希望 agent 通过 MEDIA:/... 发送生成的文件,建议使用专用的宿主可见导出挂载,例如 /home/user/.hermes/cache/documents:/output。在 Docker 中将文件写入 /output/...
在 MEDIA: 中发出宿主路径,例如:MEDIA:/home/user/.hermes/cache/documents/report.txt
不要发出 /workspace/... 或 /output/...,除非该确切路径在宿主上对 gateway 进程也存在
YAML 重复键会静默覆盖之前的键。如果您已有 docker_volumes: 块,请将新挂载合并到同一列表中,而不是在文件后面再添加一个 docker_volumes: 键。
也可以通过环境变量设置:TERMINAL_DOCKER_VOLUMES='["/host:/container"]'(JSON 数组)。Docker 凭据转发#
默认情况下,Docker 终端会话不继承任意宿主凭据。如果您需要在容器内使用特定 token,请将其添加到 terminal.docker_forward_env。Hermes 首先从您当前的 shell 解析每个列出的变量,然后回退到通过 hermes config set 保存的 ~/.hermes/.env。docker_forward_env 中列出的任何内容都会对容器内运行的命令可见。只转发您愿意暴露给终端会话的凭据。
以宿主用户身份运行容器#
默认情况下,Docker 容器以 root(UID 0)身份运行。在 /workspace 或其他绑定挂载中创建的文件在宿主上归 root 所有,因此会话结束后您必须 sudo chown 才能从宿主编辑器编辑它们。terminal.docker_run_as_host_user 标志解 决了这个问题:启用后,Hermes 将 --user $(id -u):$(id -g) 附加到 docker run 命令,使写入绑定挂载目录(/workspace、/root、docker_volumes 中的任何内容)的文件归您的宿主用户所有,而非 root。权衡:容器将无法再 apt install 或写入 /root/.npm 等 root 拥有的路径 —— 如果您同时需要这两者,请使用 HOME 归非 root 用户所有的基础镜像(或在镜像构建时添加所需工具)。保持 false(默认)以获得向后兼容的行为。当您的工作流主要是"编辑挂载的宿主文件"且厌倦了 sudo chown -R 时,请开启此选项。可选:将启动目录挂载到 /workspace