Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


配置

所有设置均存储在 ~/.hermes/ 目录中,便于随时访问。

::提示 如何最便捷地创建可用的 config.yaml 文件 运行 hermes setup --portal 即可——只需完成一次 OAuth 认证,即可获得模型提供方以及四种 Tool Gateway 工具,无需手动编辑 YAML 文件。Portal 用户在使用按令牌计费的提供方服务时还可享受 10% 的折扣。详情请参阅 Nous Portal

::

目录结构

~/.hermes/
├── config.yaml     # Settings (model, terminal, TTS, compression, etc.)
├── .env            # API keys and secrets
├── auth.json       # OAuth provider credentials (Nous Portal, etc.)
├── SOUL.md         # Primary agent identity (slot #1 in system prompt)
├── memories/       # Persistent memory (MEMORY.md, USER.md)
├── skills/         # Agent-created skills (managed via skill_manage tool)
├── cron/           # Scheduled jobs
├── sessions/       # Gateway sessions
└── logs/           # Logs (errors.log, gateway.log — secrets auto-redacted)

配置管理

hermes config              # View current configuration
hermes config edit         # Open config.yaml in your editor
hermes config set KEY VAL  # Set a specific value
hermes config check        # Check for missing options (after updates)
hermes config migrate      # Interactively add missing options

# Examples:
hermes config set model anthropic/claude-opus-4
hermes config set terminal.backend docker
hermes config set OPENROUTER_API_KEY sk-or-...  # Saves to .env
:::提示
hermes config set 命令会自动将配置值路由到正确的文件中——API 密钥会被保存到 .env 文件中,而其他所有配置则存储在 config.yaml 中。
::

配置优先级

配置项的解析顺序如下(优先级从高到低):

  1. CLI 参数——例如 hermes chat --model anthropic/claude-sonnet-4(每次调用时可覆盖现有设置)
  2. ~/.hermes/config.yaml——所有非敏感配置的主要存储文件
  3. ~/.hermes/.env——环境变量的备用存储位置;对于敏感信息(如 API 密钥、令牌、密码)则必须使用此文件
  4. 内置默认值——当未设置任何其他配置时,将使用硬编码的安全默认值
:::信息提示
敏感信息(如 API 密钥、机器人令牌、密码)应存储在 .env 文件中;其余配置(如模型类型、终端后端、压缩设置、内存限制、工具集等)则应存放在 config.yaml 中。若两者都进行了配置,对于非敏感项,则以 config.yaml 中的设置为准。

::

::提示 组织级部署
管理员可通过系统级管理目录,锁定某些特定的配置和敏感值,防止普通用户对其进行覆盖。详情请参阅管理范围

::

环境变量替换

您可以在 config.yaml 中使用 ${VAR_NAME} 语法来引用环境变量:

auxiliary:
  vision:
    api_key: ${GOOGLE_API_KEY}
    base_url: ${CUSTOM_VISION_URL}

delegation:
  api_key: ${DELEGATION_KEY}

单个值中可包含多个引用,格式如下:url: "${HOST}:${PORT}"。若引用的变量未被设置,则该占位符将保持原样(例如 ${UNDEFINED_VAR} 仍为原格式)。仅支持 ${VAR} 这种语法——单独的 $VAR 格式不会被解析。

关于 AI 提供商的配置(如 OpenRouter、Anthropic、Copilot、自定义端点、自托管大型语言模型、备用模型等),请参阅 AI 提供商

提供商超时设置

您可以为整个提供商设置请求超时时间,即 providers.<id>.request_timeout_seconds;同时也可为特定模型设置独立的超时值,即 providers.<id>.models.<model>.timeout_seconds。该设置适用于所有传输方式下的主轮次客户端(包括 OpenAI-wire、原生 Anthropic 及兼容 Anthropic 的版本)、备用请求链、凭证更换后的重新构建过程,以及(针对 OpenAI-wire)每个请求的超时参数——因此配置的值会优先于旧的 HERMES_API_TIMEOUT 环境变量。

此外,您还可以为非流式过期调用检测器设置超时时间,即 providers.<id>.stale_timeout_seconds;并为特定模型设置独立值,即 providers.<id>.models.<model>.stale_timeout_seconds。此设置同样会覆盖旧的 HERMES_API_CALL_STALE_TIMEOUT 环境变量。

若不设置这些参数,则会沿用旧有的默认值(HERMES_API_TIMEOUT=1800HERMES_API_CALL_STALE_TIMEOUT=90,以及原生 Anthropic 的 900 秒)。对于本地端点,若未显式配置,非流式过期检测器将自动关闭;而对于处理超大上下文的情况,该检测器的阈值可相应提高。目前 AWS Bedrock 并不支持此功能(无论是 bedrock_converse 还是 AnthropicBedrock SDK,均使用带有独立超时配置的 boto3)。具体示例请参见 cli-config.yaml.example 文件中的注释说明。

更新行为

hermes update 相关设置位于 config.yaml 文件的 updates 部分:

updates:
  pre_update_backup: false       # Create a full HERMES_HOME zip before every update
  backup_keep: 5                 # Keep this many pre-update backup zips
  non_interactive_local_changes: stash  # stash | discard

在通过 Git 安装的情况下,Hermes 会在检出更新分支或拉取代码之前,自动将已跟踪的修改文件以及未跟踪的文件暂存起来。在恢复这些暂存内容之前,交互式终端会先给出确认提示。而非交互式更新方式(如桌面/聊天应用、网关,或使用 --yes 参数)则会使用 updates.non_interactive_local_changes 参数:若选择 stash,则会在成功拉取代码后恢复本地的代码修改;若选择 discard,则会在成功拉取后直接丢弃此次更新所产生的暂存内容。仅限于那些本地代码修改根本无需保留的托管式安装环境中才应使用 discard

在执行暂存操作之前,Hermes 还会恢复因 npm install/build 操作而产生的已跟踪的 package-lock.json 差异文件。在进行更新之前,请先将有意进行的锁文件修改提交或手动暂存。

终端后端配置

Hermes 支持六种终端后端。每种后端都决定了代理的 Shell 命令实际在何处执行——可以是您的本地机器、Docker 容器、通过 SSH 连接的远程服务器、Modal 云沙箱(直接连接或通过 Nous 管理的网关)、Daytona 工作空间,或是 Singularity/Apptainer 容器。

terminal:
  backend: local    # local | docker | ssh | modal | daytona | singularity
  cwd: "."          # Gateway/cron working directory (CLI always uses launch dir)
  timeout: 180      # Per-command timeout in seconds
  home_mode: auto   # auto | real | profile — subprocess HOME policy
  env_passthrough: []  # Env var names to forward to sandboxed execution (terminal + execute_code)
  singularity_image: "docker://nikolaik/python-nodejs:python3.11-nodejs20"  # Container image for Singularity backend
  modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"                 # Container image for Modal backend
  daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"               # Container image for Daytona backend

对于 Modal 和 Daytona 等云沙箱环境,container_persistent: true 的含义是 Hermes 会尝试在重新创建沙箱时保留文件系统状态。但该设置并不能保证后续仍然运行着相同的实时沙箱、进程 ID 空间或后台进程。

后端概述

后端类型命令执行位置隔离级别最佳适用场景
本地直接在您的机器上运行无隔离开发、个人使用
Docker单个持久化 Docker 容器(跨会话、/new 模式及子代理共享)完全隔离(命名空间、权限限制)安全的沙箱环境、CI/CD 流水线
SSH通过 SSH 连接的远程服务器网络级隔离远程开发、高性能硬件环境
ModalModal 云沙箱完全隔离(云虚拟机)临时性云计算任务、代码评估
DaytonaDaytona 工作空间完全隔离(云容器)受管理的云开发环境
SingularitySingularity/Apptainer 容器命名空间隔离(–containall 参数)高性能计算集群、共享机器环境

本地后端

为默认后端类型。命令直接在您的机器上运行,且不进行任何隔离处理。无需特殊配置即可使用。

terminal:
  backend: local

默认情况下,本地工具的子进程会保留您真实操作系统用户的主目录 HOME。这样一来,诸如 gitsshghaznpm、Claude Code 以及 Codex 等外部 CLI 就能使用其在常规终端中已有的凭证和配置。Hermes 的状态仍通过 HERMES_HOME 按配置文件进行管理;而 HOME 并非配置文件选择配置、内存、会话或技能的依据。

Hermes 不会更改您系统级的主目录 HOME、shell 启动文件或操作系统账户的主目录。该设置仅用于控制通过 terminal、后台终端进程、execute_code 以及 ACP 辅助进程等工具所启动的子进程所接收的环境。

terminal.home_mode

模式主机环境容器环境权衡点
auto保留真实操作系统用户的主目录 HOME使用 {HERMES_HOME}/home推荐的默认模式。主机 CLI 可继续正常工作,且容器状态也能得以保留。
real强制使用真实操作系统用户的主目录 HOME若可见则强制使用真实操作系统用户的主目录 HOME当父进程意外以指向配置文件主目录的 HOME 值启动时,此模式非常有用。
profile若存在则使用 {HERMES_HOME}/home若存在则使用 {HERMES_HOME}/home能实现严格的按配置文件隔离 CLI 配置,但除非在配置文件主目录内进行初始化或关联,否则常规的 ~/.ssh~/.gitconfig~/.azure~/.config/gh、Claude/Codex 认证信息、npm 状态等将不可见。

默认模式的缺点在于,不同配置文件会共享位于 ~ 下的相同用户级 CLI 凭证和配置。如果您需要为某个配置文件设置独立的 git 身份、SSH 密钥、GitHub CLI 登录信息、npm 配置或云服务 CLI 登录信息,建议使用 home_mode: profile 并在该配置文件主目录内主动初始化这些工具。

如果您确实需要严格的按配置文件隔离工具配置,可设置为:

terminal:
  home_mode: profile

在该模式下,工具的子进程会将 {HERMES_HOME}/home 作为 HOME 环境变量使用。Hermes 还会设置 HERMES_REAL_HOME,以便脚本在需要时仍能找到真正的用户主目录。在“自动”模式下,容器后端依然会使用 {HERMES_HOME}/home,因为该目录位于持久化的 Hermes 数据卷中。

那些需要区分配置文件所在位置与真实用户主目录的脚本,建议将 Hermes 数据存储路径设为 HERMES_HOME,而将账户主目录路径设为 HERMES_REAL_HOME

from pathlib import Path
import os

hermes_home = Path(os.environ["HERMES_HOME"])
real_home = Path(os.environ.get("HERMES_REAL_HOME", os.environ["HOME"]))
:::warning 该智能体拥有与您的用户账户相同的文件系统访问权限。如需禁用不需要的工具,可使用 hermes tools;若希望实现沙箱隔离,则可切换至 Docker 环境。
::

Docker 后端

命令将在经过安全加固的 Docker 容器中执行(所有特殊权限均已移除,不存在权限提升风险,同时设置了 PID 限制)。

采用单个持久化容器,供 Hermes 的所有进程共享。 Hermes 在首次使用时会启动一个长期运行的容器,随后所有的终端操作、文件操作以及 execute_code 调用,都会通过 docker exec 命令指向同一个容器——无论是在不同会话之间、使用 /new/resetdelegate_task 子智能体时皆是如此。工作目录、已安装的软件包、/workspace 目录中的文件以及后台进程,都会在连续的命令调用之间以及不同的 Hermes 进程之间保持一致。当您关闭 TUI 会话、运行 /quit 命令或启动新的 hermes 实例时,该容器仍会继续运行,下一个 Hermes 进程会通过标签查找机制重新使用它。具体的容器销毁规则请参见下文的“容器生命周期”部分。

terminal:
  backend: docker
  docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
  docker_mount_cwd_to_workspace: false  # Mount launch dir into /workspace
  docker_run_as_host_user: false   # See "Running container as host user" below
  docker_forward_env:              # Host env vars to forward into container
    - "GITHUB_TOKEN"
  docker_env:                      # Literal env vars to inject (KEY=value)
    DEBUG: "1"
    PYTHONUNBUFFERED: "1"
  docker_volumes:                  # Host directory mounts
    - "/home/user/projects:/workspace/projects"
    - "/home/user/data:/data:ro"   # :ro for read-only
  docker_extra_args:               # Extra flags appended verbatim to `docker run`
    - "--gpus=all"
    - "--network=host"
  docker_network: true             # false = air-gap the container (--network=none)

  # Resource limits
  container_cpu: 1                 # CPU cores (0 = unlimited)
  container_memory: 5120           # MB (0 = unlimited)
  container_disk: 51200            # MB (requires overlay2 on XFS+pquota)
  container_persistent: true       # Persist /workspace and /root bind-mount dirs

  # Cross-process container reuse (defaults match the "one long-lived
  # container shared across sessions" contract — see Container lifecycle).
  docker_persist_across_processes: true   # Reuse container across Hermes restarts
  docker_orphan_reaper: true              # Sweep abandoned Exited containers at startup

  # Cross-backend lifecycle settings (apply to docker as well)
  timeout: 180                     # Per-command timeout in seconds
  lifetime_seconds: 300            # Idle-reaper window; also feeds 2× orphan-reaper threshold

docker_envdocker_forward_env 的区别:前者会注入你在配置中指定的原始 KEY=value 对(这些值来自 config.yaml,或通过 TERMINAL_DOCKER_ENV='{"DEBUG":"1"}' 以 JSON 字典形式传递)。后者则从你的 shell 或 ~/.hermes/.env 中读取值,因此敏感信息永远不会出现在配置文件中。对于令牌类凭证,建议使用 docker_forward_env;而对于容器所需的静态参数,则可使用 docker_env

terminal.docker_extra_args(也可通过 TERMINAL_DOCKER_EXTRA_ARGS='["--gpus=all"]' 覆盖)允许你传递那些 Hermes 未将其作为标准键项提供的任意 docker run 参数——如 --gpus--network--add-host,以及自定义的 --security-opt 设置等。每个参数都必须是字符串形式,该参数列表会被追加到最终生成的 docker run 命令中,以便在需要时覆盖 Hermes 的默认设置。请谨慎使用此功能——任何与沙箱安全机制相冲突的参数(如权限降级、--user 设置、工作区绑定挂载等)都可能悄悄削弱隔离效果。

terminal.docker_network(默认值为 true;环境变量为 TERMINAL_DOCKER_NETWORK)——将其设置为 false 可以让沙箱容器以 --network=none 的方式运行,从而切断代理命令的所有网络出口。这一设置适用于 terminalexecute_code 以及各类文件处理工具所使用的执行容器。由于容器会在 Hermes 进程之间保持存在,因此在已有联网容器的情况下将此值设为 false,会移除原有容器并启动一个全新的隔离容器(系统会记录警告信息);此时运行在旧容器中的后台进程也会丢失。相比通过 docker_extra_args 传递 --network=none,推荐使用此键进行设置。

要求: 需要已安装并正在运行的 Docker Desktop 或 Docker Engine。Hermes 会遍历 $PATH 及 macOS 上常见的 Docker 安装路径(如 /usr/local/bin/docker/opt/homebrew/bin/docker、Docker Desktop 应用程序包)。Podman 也支持直接使用:若系统中同时安装了 Docker 和 Podman,可设置 HERMES_DOCKER_BINARY=podman(或完整路径)来强制使用 Podman。

容器生命周期

每个由 Hermes 管理的容器都会被标记上三个标签,以便后续进程及孤儿清理机制能够识别它:

  • hermes-agent=1 —— 标识该容器由 Hermes 管理;
  • hermes-task-id=<经过过滤的任务ID> —— 用于实现按任务重用的识别;
  • hermes-profile=<经过过滤的配置文件名> —— 将重用和清理操作限制在当前活跃的 Hermes 配置文件范围内。

启动时,Hermes 会执行 docker ps --filter label=hermes-task-id=<id> --filter label=hermes-profile=<profile> 命令,一旦找到对应的容器就会直接附加到该容器上。如果容器已“退出”(例如 Docker 守护进程重启后),Hermes 会重新启动该容器并继续使用——文件系统状态及已安装的软件包会保留,但容器内的后台进程则不会。

当某个 Hermes 进程退出——无论是通过 /quit 命令、关闭 TUI 会话、网关关闭,还是收到 SIGKILL 信号——在默认模式下,该容器不会被清理,仍会继续运行。下一个 Hermes 进程会通过标签识别机制在几毫秒内再次附加到该容器上。这正是“跨会话共享一个长期运行的容器”这一设计理念所要求的:只有这样,后台进程(如 npm 监听器、开发服务器、长时间运行的 pytest 测试等)才能在会话切换后依然存活。

只有在以下情况下,容器才会被终止(即先停止,再执行 docker rm -f 命令删除):

触发条件触发时机
docker_persist_across_processes: false显式要求进程级隔离。此时每个 cleanup() 函数都会执行 stop + rm -f 操作,行为与版本 #20561 发布前的设置一致。
死机清理机制(lifetime_seconds,默认为 300 秒)仅当环境变量设置为 persist_across_processes=false 时才会触发。处于持久模式下的容器不会被清理,可顺利度过空闲期。
下次启动时的孤儿清理机制会清理所有已“退出”且年龄超过 2 × lifetime_seconds(默认为 600 秒,即 10 分钟)的、带有 hermes 标签的容器,清理范围限于当前活跃的配置文件。正在运行的容器绝不会被清理,这是为了确保进程间的安全性。如需禁用此功能,可设置 docker_orphan_reaper: false
用户直接操作通过 docker rm -fdocker system prune 命令,或重启 Docker Desktop。由于我们未设置 --restart=always,因此主机重启后容器会处于“已退出”状态(其写时复制层仍会保留,并在下次启动时被重新使用,但后台进程已消失)。

一些值得注意的边缘情况:

  • 如果容器内的 PID 1 进程因内存不足而被系统杀死,容器状态会变为“已退出”。下次重新使用时,Hermes 会再次启动该容器;文件系统状态会保留,但后台进程则不会。
  • 切换 Hermes 配置文件会实现容器间的隔离——一个标记为 hermes-profile=work 的容器,对于正在使用 hermes-profile=research 配置文件运行的 Hermes 进程来说是不可见的。孤儿清理机制同样遵循配置文件隔离原则,因此跨配置文件的容器不会被意外清理;不过在重新以原有配置文件启动 Hermes 之前,这些容器也不会被自动清除。

通过 delegate_task(tasks=[...]) 生成的并行子代理会共享同一个容器——因此同时进行的 cd 操作、环境变量修改以及对同一路径的写入都可能发生冲突。如果某个子代理需要独立的沙箱环境,就必须通过 register_task_env_overrides() 方法注册针对该任务的镜像覆盖设置;而强化学习任务及基准测试环境(如 TerminalBench2、HermesSweEnv 等)则会自动为其各自的任务 Docker 镜像完成此类设置。

安全加固措施:

  • 使用 --cap-drop ALL 禁用所有权限,仅保留 DAC_OVERRIDECHOWNFOWNER 这三项权限;
  • 设置 --security-opt no-new-privileges
  • 限制进程数量为 256 个;
  • /tmp(512MB)、/var/tmp(256MB)、/run(64MB)目录使用大小受限的临时文件系统。

凭证传递机制: 列在 docker_forward_env 中的环境变量会首先从你的 shell 环境中读取,若未找到则从 ~/.hermes/.env 中查找。技能组件也可以声明 required_environment_variables,这些变量也会被自动合并进来。

环境变量覆盖方式

terminal: 下的每个键都对应一个形式为 TERMINAL_<KEY_UPPERCASE> 的环境变量覆盖项。对于 Docker 后端而言,最常用的覆盖项如下:

环境变量对应的配置键说明
TERMINAL_DOCKER_IMAGEdocker_image基础镜像
TERMINAL_DOCKER_FORWARD_ENVdocker_forward_envJSON 数组形式,例如 '["GITHUB_TOKEN","OPENAI_API_KEY"]'
TERMINAL_DOCKER_ENVdocker_envJSON 字典形式,例如 '{"DEBUG":"1"}'
TERMINAL_DOCKER_VOLUMESdocker_volumesJSON 数组,元素为 "host:container[:ro]" 格式的字符串
TERMINAL_DOCKER_EXTRA_ARGSdocker_extra_argsJSON 数组
TERMINAL_DOCKER_MOUNT_CWD_TO_WORKSPACEdocker_mount_cwd_to_workspace取值 truefalse
TERMINAL_DOCKER_RUN_AS_HOST_USERdocker_run_as_host_user取值 truefalse
TERMINAL_DOCKER_NETWORKdocker_network取值 truefalse,默认为 truefalse 等价于 --network=none
TERMINAL_DOCKER_PERSIST_ACROSS_PROCESSESdocker_persist_across_processes取值 truefalse,默认为 true
TERMINAL_DOCKER_ORPHAN_REAPERdocker_orphan_reaper取值 truefalse,默认为 true
TERMINAL_CONTAINER_CPUcontainer_cpu指定的 CPU 核心数
TERMINAL_CONTAINER_MEMORYcontainer_memory指定的内存大小,单位为 MB
TERMINAL_CONTAINER_DISKcontainer_disk指定的磁盘空间大小,单位为 MB
TERMINAL_CONTAINER_PERSISTENTcontainer_persistent取值 truefalse,用于控制工作区目录的绑定挂载,与 docker_persist_across_processes 功能不同
TERMINAL_LIFETIME_SECONDSlifetime_seconds容器空闲后的清理等待时间
TERMINAL_TIMEOUTtimeout每条命令的执行超时时间
HERMES_DOCKER_BINARY无对应配置键用于强制指定特定的 Docker 或 Podman 可执行文件路径

SSH 后端

通过 SSH 在远程服务器上执行命令。该后端使用 ControlMaster 技术实现连接复用,具备 5 分钟的空闲保持活跃机制。默认情况下会启用持久化 shell——这样命令执行过程中的当前工作目录及环境变量等信息都会被保留下来。

terminal:
  backend: ssh
  persistent_shell: true           # Keep a long-lived bash session (default: true)

必需的环境变量:

TERMINAL_SSH_HOST=my-server.example.com
TERMINAL_SSH_USER=ubuntu

可选参数:

参数名默认值说明
TERMINAL_SSH_PORT22SSH 端口
TERMINAL_SSH_KEY(系统默认值)SSH 私钥路径
TERMINAL_SSH_PERSISTENTtrue启用持久化 shell

工作原理: 在初始化时以 BatchMode=yesStrictHostKeyChecking=accept-new 的参数建立连接。持久化 shell 会在远程主机上保持一个 bash -l 进程运行,通过临时文件进行通信。需要 stdin_datasudo 权限的命令会自动切换为一次性执行模式。

Modal 云沙箱中执行命令。每个任务都会获得一个独立的虚拟机,其 CPU、内存和磁盘资源均可配置。文件系统支持在不同会话之间进行快照创建与恢复。

terminal:
  backend: modal
  container_cpu: 1                 # CPU cores
  container_memory: 5120           # MB (5GB)
  container_disk: 51200            # MB (50GB)
  container_persistent: true       # Snapshot/restore filesystem

必需项: 要么提供 MODAL_TOKEN_ID + MODAL_TOKEN_SECRET 环境变量,要么提供 ~/.modal.toml 配置文件。

状态持久化: 开启该功能后,沙箱文件系统会在清理时生成快照,并在下次会话时恢复。这些快照会存储在 ~/.hermes/modal_snapshots.json 文件中。此功能可保留文件系统状态,但无法保存正在运行的进程、PID 空间或后台任务。

凭证文件: 会自动从 ~/.hermes/ 目录加载凭证文件(如 OAuth 令牌等),并在执行每个命令之前进行同步。

Daytona 后端

Daytona 管理的工作空间中运行命令。支持暂停/继续操作以实现状态持久化。

terminal:
  backend: daytona
  container_cpu: 1                 # CPU cores
  container_memory: 5120           # MB → converted to GiB
  container_disk: 10240            # MB → converted to GiB (max 10 GiB)
  container_persistent: true       # Stop/resume instead of delete

必需: DAYTONA_API_KEY 环境变量。

持久性: 当该功能启用时,沙箱会在清理时被暂停(而非删除),并在下次会话时重新启动。沙箱的名称遵循 hermes-{task_id} 的格式。

磁盘限制: Daytona 设定的最大磁盘使用量为 10 GiB。超过此限制的请求将会被限制并同时发出警告。

Singularity/Apptainer 后端

Singularity/Apptainer 容器中执行命令。该后端专为那些无法使用 Docker 的高性能计算集群及共享机器设计。

terminal:
  backend: singularity
  singularity_image: "docker://nikolaik/python-nodejs:python3.11-nodejs20"
  container_cpu: 1                 # CPU cores
  container_memory: 5120           # MB
  container_persistent: true       # Writable overlay persists across sessions

系统要求: $PATH 环境变量中需包含 apptainersingularity 可执行文件。

镜像处理: Docker 链接(docker://...)会自动转换为 SIF 格式文件并予以缓存;现有的 .sif 文件则可直接使用。

临时存储目录: 优先级顺序如下:TERMINAL_SCRATCH_DIRTERMINAL_SANDBOX_DIR/singularity/scratch/$USER/hermes-agent(适用于高性能计算环境)→ ~/.hermes/sandboxes/singularity

隔离机制: 通过 --containall --no-home 参数实现完整的命名空间隔离,同时避免挂载主机用户主目录。

常见终端后端问题

如果终端命令立即失败,或系统提示终端工具不可用:

  • 本地模式(Local) — 无特殊要求,是入门时的最安全默认选项。
  • Docker模式 — 运行 docker version 命令确认 Docker 正常运行。若失败,请修复 Docker 环境,或通过 hermes config set terminal.backend local 强制使用本地模式。
  • SSH模式 — 必须同时设置 TERMINAL_SSH_HOSTTERMINAL_SSH_USER 参数。缺少任一参数时,Hermes 会输出明确的错误信息。
  • Modal模式 — 需要 MODAL_TOKEN_ID 环境变量或 ~/.modal.toml 配置文件。可通过运行 hermes doctor 命令进行检查。
  • Daytona模式 — 需要 DAYTONA_API_KEY。Daytona SDK 负责处理服务器地址的配置。
  • Singularity模式 — 需要 $PATH 中包含 apptainersingularity 可执行文件,此模式在高性能计算集群中较为常见。

如有疑问,可先将 terminal.backend 设置回 local 模式,确认命令在该模式下能正常运行。

会话关闭时的远程到主机文件同步

对于 SSHModalDaytona 后端(即代理的工作目录位于与运行 Hermes 的主机不同的机器上),Hermes 会跟踪代理在远程沙箱中修改过的文件。在会话关闭或沙箱清理时,这些被修改的文件会同步回主机,存储路径为 ~/.hermes/cache/remote-syncs/<session-id>/

  • 触发条件包括:会话关闭、执行 /new/reset 命令、网关消息超时,以及子代理使用远程后端完成 delegate_task 任务时。
  • 同步范围涵盖代理修改过的所有文件,而不仅限于其明确打开的文件;文件的添加、修改和删除操作都会被记录下来。
  • 等您查看时,远程沙箱可能已被销毁,此时本地的 ~/.hermes/cache/remote-syncs/… 文件才是反映代理实际修改内容的权威记录。
  • 对于体积较大的二进制输出文件(如模型检查点、原始数据集),同步时会根据 file_sync_max_mb(默认值为 100 MB)设置大小上限。如果预计会有更大的文件被同步回来,可调整该阈值。
terminal:
  file_sync_max_mb: 100     # default — sync files up to 100 MB each
  file_sync_enabled: true   # default — set false to skip the sync entirely

如此即可从会在会话结束后被销毁的临时云沙箱中恢复数据,而无需每次都明确指示智能体使用 scpmodal volume put 命令来传输各个文件。

Docker卷挂载

在使用Docker后端时,docker_volumes功能可让你将主机目录与容器共享。每条配置项均采用标准的Docker -v语法:host_path:container_path[:options]

terminal:
  backend: docker
  docker_volumes:
    - "/home/user/projects:/workspace/projects"   # Read-write (default)
    - "/home/user/datasets:/data:ro"              # Read-only
    - "/home/user/.hermes/cache/documents:/output" # Gateway-visible exports

此功能适用于以下场景:

  • 向智能体提供文件(数据集、配置文件、参考代码);
  • 从智能体接收文件(生成的代码、报告、导出结果);
  • 共享工作空间,让您与智能体能够访问相同的文件。

如果您使用消息网关,并希望让智能体通过 MEDIA:/... 发送生成的文件,建议使用主机可访问的专用导出挂载路径,例如 /home/user/.hermes/cache/documents:/output

  • 在 Docker 容器中,将文件写入 /output/...
  • MEDIA: 中指定主机路径,例如:MEDIA:/home/user/.hermes/cache/documents/report.txt
  • 除非网关进程在主机上确实存在该路径,否则请勿使用 /workspace/.../output/...
:::warning
YAML 文件中重复的键会自动覆盖之前的值。如果您已存在 docker_volumes: 块,请将新的挂载项合并到同一列表中,而不要在文件后部再添加另一个 docker_volumes: 键。
::

该设置也可通过环境变量配置:TERMINAL_DOCKER_VOLUMES='["/host:/container"]'(JSON 数组格式)。

Docker 凭证转发

默认情况下,Docker 终端会话不会继承主机的任意凭据。如果您需要在容器内使用特定令牌,请将其添加到 terminal.docker_forward_env 中。

terminal:
  backend: docker
  docker_forward_env:
    - "GITHUB_TOKEN"
    - "NPM_TOKEN"
Hermes 会首先从您当前的 shell 中解析列出的各个变量,如果这些变量是通过 hermes config set 保存的,则会回退到 ~/.hermes/.env 文件中查找。

::warning 在 docker_forward_env 中列出的任何内容都会被容器内的命令所读取。请仅转发那些您愿意在终端会话中公开的凭据。

::

以主机用户身份运行容器

默认情况下,Docker 容器是以 root(UID 0)用户身份运行的。在 /workspace 或其他绑定挂载目录中创建的文件,其所有权最终属于主机上的 root 用户。因此,在结束会话后,您需要先使用 sudo chown 命令更改文件所有权,才能通过主机上的编辑器对其进行修改。terminal.docker_run_as_host_user 参数可解决这一问题:

terminal:
  backend: docker
  docker_run_as_host_user: true   # default: false

启用该功能后,Hermes 会在 docker run 命令中添加 --user $(id -u):$(id -g) 参数,这样一来,写入绑定挂载目录(如 /workspace/root 以及 docker_volumes 中的任何目录)的文件将归属于宿主机用户而非 root 用户。相应的代价是:容器将无法再执行 apt install 操作,也无法向 root 所拥有的路径(如 /root/.npm)写入数据。如果需要同时满足这两点需求,可使用 HOME 目录归属于非 root 用户的基础镜像(或是在构建镜像时自行添加所需的工具)。

若希望保持向后兼容性,可将其保持为默认值 false。只有当您的工作流程主要以“编辑宿主机挂载的文件”为主,且厌倦了频繁使用 sudo chown -R 命令时,才建议启用此功能。

可选:将启动目录挂载到 /workspace

默认情况下,Docker 沙箱是相互隔离的。除非您明确选择,否则 Hermes 不会将当前宿主机的工作目录传递给容器。

可在 config.yaml 中启用该功能:

terminal:
  backend: docker
  docker_mount_cwd_to_workspace: true

启用该功能时:

  • 若从 ~/projects/my-app 启动 Hermes,该主机目录将会被绑定挂载到 /workspace
  • Docker 后端将在 /workspace 中启动;
  • 文件操作工具与终端命令都能访问同一个已挂载的项目目录。

若禁用该功能,则 /workspace 仍由沙箱环境拥有,除非通过 docker_volumes 显式挂载其他目录。

相关的安全权衡如下:

  • 设置为 false 可保持沙箱隔离边界;
  • 设置为 true 则允许沙箱直接访问用于启动 Hermes 的目录。

仅当您确实希望容器能够操作宿主机上的实时文件时,才应启用此功能。

持久化 Shell

默认情况下,每个终端命令都在独立的子进程中运行——工作目录、环境变量以及 shell 变量会在不同命令之间重置。当启用持久化 Shell后,一个长期运行的 bash 进程会在多次 execute() 调用之间保持活跃,从而使命令间的状态得以保留。

这一功能对于SSH 后端尤为实用,因为它还能消除每次命令执行时的连接开销。SSH 后端默认启用持久化 Shell,而本地后端则默认禁用该功能。

terminal:
  persistent_shell: true   # default — enables persistent shell for SSH

如需禁用:

hermes config set terminal.persistent_shell false

跨命令持续有效的内容:

  • 工作目录(执行 cd /tmp 后,该设置会在后续命令中保持不变)
  • 导出的环境变量(如 export FOO=bar
  • Shell 变量(如 MY_VAR=hello

优先级规则:

级别变量名默认值
配置文件terminal.persistent_shelltrue
SSH 覆盖值TERMINAL_SSH_PERSISTENT以配置文件中的值为准
本地覆盖值TERMINAL_LOCAL_PERSISTENTfalse

后端特定的环境变量具有最高优先级。若希望在本地后端也实现持久化 Shell 环境,可进行相应设置:

export TERMINAL_LOCAL_PERSISTENT=true
:::note 由于持久化shell的stdin已被IPC协议占用,因此那些需要stdin_data参数或sudo权限的命令会自动切换为单次执行模式。
::

如需了解各后端的详细信息,请参阅代码执行功能以及README中的终端相关章节

技能设置

技能可通过其SKILL.md前置内容自行定义配置选项。这些非敏感值(如路径、偏好设置、域名配置等)会被存储在config.yaml文件中的skills.config命名空间下。

skills:
  config:
    myplugin:
      path: ~/myplugin-data   # Example — each skill defines its own keys

技能设置的工作原理:

  • hermes config migrate 会扫描所有已启用的技能,找出未配置的设置,并提示您进行输入。
  • hermes config show 会在“技能设置”栏目下显示所有技能设置及其所属的技能名称。
  • 当某个技能加载时,其解析后的配置值会自动注入到该技能的上下文中。

手动设置值:

hermes config set skills.config.myplugin.path ~/myplugin-data

如需了解在自定义技能中声明配置设置的详细信息,请参阅创建技能 — 配置设置

对智能体创建的技能内容的写入进行防护

当智能体使用 skill_manage 功能来创建、编辑、修改或删除某个技能时,Hermes 可以选择性地扫描新生成或已更新的内容,以检测是否存在危险的关键词模式(如凭证窃取、明显的提示词注入、数据外传指令等)。该扫描功能默认处于关闭状态——因为那些确实需要访问 ~/.ssh/ 目录或包含 $OPENAI_API_KEY 的真实智能体工作流,常常会误触发该检测机制。如果您希望在智能体写入技能内容之前收到提醒,可以重新开启此功能:

skills:
  guard_agent_created: true   # default: false

当该功能开启后,所有被标记为 skill_manage 类型的写入操作都会以审批提示的形式出现,并附带扫描器给出的理由。获批准的写入操作会成功执行;而被拒绝的写入操作则会向智能体返回说明性的错误信息。

对技能写入操作的审批机制

独立于上述内容扫描器之外,skills.write_approval 会要求对所有智能体技能相关的写入操作(创建、编辑、修补、删除及相关文件)进行手动批准——其审批/拒绝机制与处理危险命令的机制完全相同。

skills:
  write_approval: false   # false = write freely (default) | true = stage every write for review

当该功能处于开启状态时,技能写入操作会被暂存于 ~/.hermes/pending/skills/ 目录中,随后可通过 CLI 或任何消息平台,使用 /skills pending/skills diff <id>/skills approve <id>/skills reject <id> 等命令对其进行审核。也可在运行时通过 /skills approval on|off 来切换此功能状态。内存相关操作同样遵循相同的审批机制(即下文的 memory.write_approval)。完整操作指南请参阅:对代理技能写入操作进行管控

内存配置

memory:
  memory_enabled: true
  user_profile_enabled: true
  memory_char_limit: 2200   # ~800 tokens
  user_char_limit: 1375     # ~500 tokens
  write_approval: false     # true = require approval before any memory write

当设置 memory.write_approval: true 时,所有内存写入操作在生效前都需要经过您的确认:交互式 CLI 会直接在提示语中显示相关选项;而对于消息交流会话及后台自我优化阶段,则会将写入内容暂存为 /memory pending,随后进入 /memory approve <id> / /memory reject <id> 的审核流程。您可以在运行时通过 /memory approval on|off 来切换此功能。详情请参阅控制内存写入

上下文文件截断设置

该选项用于控制 Hermes 在对上下文文件进行开头/结尾截断处理之前,会加载多少内容。这一设置适用于注入系统提示语中的各类文件,例如 SOUL.md.hermes.mdAGENTS.mdCLAUDE.md 以及 .cursorrules。需要注意的是,它不会影响 read_file 工具的功能。

context_file_max_chars: 20000  # default

当您有意保留较大的身份信息或项目上下文文件,并使用具有足够上下文窗口的模型来处理这些数据时,应设置该参数。

context_file_max_chars: 25000

文件读取安全性

该机制用于控制单次 read_file 调用可返回的内容量。超出限制的读取请求将会被拒绝,并给出错误提示,建议智能体使用 offsetlimit 参数来指定更小的读取范围。这样即可避免一次性读取压缩后的 JS 包或大型数据文件导致上下文窗口被过度占用。

file_read_max_chars: 100000  # default — ~25-35K tokens

如果您使用的是上下文窗口较大的模型且经常需要读取大型文件,请将其数值调高。而对于上下文窗口较小的模型,则建议降低该数值,以提升读取效率。

# Large context model (200K+)
file_read_max_chars: 200000

# Small local model (16K context)
file_read_max_chars: 30000

该智能体还会自动实现文件读取的去重处理——如果同一文件区域被读取了两次且文件内容并未发生变化,它将返回一个轻量级的占位内容,而无需重新发送实际文件内容。当上下文被压缩后,这一机制会重置,从而使智能体能够在文件内容被汇总后再次读取这些文件。

工具输出截断限制

有三个相关的上限参数用于控制工具在Hermes进行截断之前可以返回的原始输出长度:

tool_output:
  max_bytes: 50000        # terminal output cap (chars)
  max_lines: 2000         # read_file pagination cap
  max_line_length: 2000   # per-line cap in read_file's line-numbered view
  • max_bytes — 当某个 terminal 命令输出的 stdout 和 stderr 合计字符数超过此值时,Hermes 会保留前 40% 和后 60% 的内容,并在两者之间添加 [OUTPUT TRUNCATED] 的提示。默认值为 50000(使用常见分词器处理后约相当于 12,000–15,000 个标记)。
  • max_lines — 单次 read_file 调用中 limit 参数的上限值。超过此限制的请求会被限制,以避免单次读取操作占用过大的上下文窗口空间。默认值为 2000。
  • max_line_length — 当 read_file 以带行号的形式输出内容时,每行内容的最大长度限制。超过此长度的行会被截断,仅保留指定数量的字符,其后附加 ... [truncated] 的提示。默认值为 2000。

对于那些具备较大上下文窗口、且每次调用能够处理更多原始输出数据的模型,可适当提高这些限制值;而对于上下文窗口较小的模型,则应降低这些限制,以保持工具输出结果的简洁性。

# Large context model (200K+)
tool_output:
  max_bytes: 150000
  max_lines: 5000

# Small local model (16K context)
tool_output:
  max_bytes: 20000
  max_lines: 500

全局工具集禁用

若需在单个位置禁止 CLI 及所有网关平台中使用特定的工具集,只需在 agent.disabled_toolsets 下列出这些工具集的名称即可:

agent:
  disabled_toolsets:
    - memory       # hide memory tools + MEMORY_GUIDANCE injection
    - web          # no web_search / web_extract anywhere

该配置会在各平台工具设置(由 hermes tools 生成的 platform_toolsets)之后生效,因此此处列出的工具集将会被移除——即便该平台的已保存配置中仍保留有相关设置。当您希望通过一个简单的开关来“在所有地方关闭X功能”,而无需在 hermes tools 的界面中编辑15行以上的平台配置时,可使用此方法。

若将列表留空或省略该键,则不会产生任何效果。

Git工作树隔离

启用Git工作树隔离功能,即可在同一个仓库上并行运行多个Agent。

worktree: true    # Always create a worktree (same as hermes -w)
# worktree: false # Default — only when -w flag is passed

启用该功能后,每个 CLI 会话都将在 .worktrees/ 目录下创建一个包含独立分支的新工作树。各个 Agent 可以独立编辑文件、执行提交、推送操作以及创建 Pull Request,而互不干扰。退出时会自动删除干净的工作树,而状态未同步的工作树则会保留以便后续手动恢复。

默认情况下,新工作树会从最新拉取的远程分支尖端(即当前分支的上游分支,若不存在则使用远程仓库的默认分支)创建分支,这样它就能与项目保持同步,而非基于本地克隆中可能已过时的 HEAD 分支。这样一来,Pull Request 的差异对比就会仅针对实际发生的更改,而不会受到本地克隆滞后状态的影响。如需以本地 HEAD 分支作为基础,可设置 worktree_sync: false——这在离线环境下或需要以克隆版本的精确当前状态为基准时非常有用。如果无法连接到远程仓库,系统会自动回退到使用本地 HEAD 分支。

worktree_sync: true    # Default — branch from the fetched remote tip
# worktree_sync: false # Branch from local HEAD (offline / pinned base)

您还可以在仓库根目录中使用 .worktreeinclude 文件,列出需要复制到工作树的 gitignored 文件。

# .worktreeinclude
.env
.venv/
node_modules/

上下文压缩功能

Hermes 会自动对较长的对话内容进行压缩,以确保其长度在模型上下文窗口的限制之内。该压缩功能通过独立的 LLM 调用实现——您可以选择将其连接到任何提供商或接口端点。

所有压缩相关设置均保存在 config.yaml 文件中(无需使用环境变量)。

完整参考文档

compression:
  enabled: true                                     # Toggle compression on/off
  threshold: 0.50                                   # Compress at this % of context limit
  target_ratio: 0.20                                # Fraction of threshold to preserve as recent tail
  protect_last_n: 20                                # Min recent messages to keep uncompressed
  protect_first_n: 3                                # Non-system head messages pinned across compactions (0 = pin nothing)
  hygiene_hard_message_limit: 5000                  # Gateway safety valve — see below

# The summarization model/provider is configured under auxiliary:
auxiliary:
  compression:
    model: ""                                       # Empty = use main chat model. Override with e.g. "google/gemini-3-flash-preview" for cheaper/faster compression.
    provider: "auto"                                # Provider: "auto", "openrouter", "nous", "codex", "main", etc.
    base_url: null                                  # Custom OpenAI-compatible endpoint (overrides provider)
:::info 旧配置迁移说明
对于包含 compression.summary_modelcompression.summary_providercompression.summary_base_url 的旧版本配置,在首次加载时(配置版本为17)会自动迁移为 auxiliary.compression.* 格式,无需手动操作。

::
hygiene_hard_message_limit 是仅适用于网关的预压缩安全机制。其存在目的是避免恶性循环:当会话数据量过大导致API调用频繁中断时,网关无法接收到令牌使用情况数据,因此基于令牌数量的阈值机制无法触发,结果就是转录内容持续增加,断连问题愈发严重。该机制仅根据消息数量来触发(这一数值始终可知,不受API故障影响),从而强制进行压缩并恢复会话。默认值为 5000,远高于普通会话的需求,即便是处理大量上下文(100万字符以上)且包含数千次短轮次对话的场景也是如此,因为这类场景早在达到令牌阈值之前就会自动触发压缩。对于特殊平台可适当提高该值,若需更强制的压缩效果则可降低该值。在正在运行的网关上修改此值后,变更将于下一条消息开始时生效(详见下文)。

protect_first_n 用于控制每次压缩操作中需要保留的非系统提示词数量。默认值为 3,即每次摘要生成后,最初的用户/助手对话内容都会被保留,以确保初始目标始终可见。在那些会话持续时间较长、初始对话已不再相关的场景中,可将 protect_first_n 设置为 0,仅保留系统提示词、摘要及最后几条消息。无论是否设置此参数,系统提示词本身始终会被保留。

::tip 网关上压缩参数与上下文长度的热重载方法
在最新版本中,无需重启网关、无需执行 /reset 操作,也无需刷新会话,只需在正在运行的网关上的 config.yaml 文件中修改 model.context_length 或任何 compression.* 相关参数,变更即会在下一条消息开始时生效。由于缓存中的代理签名已包含这些参数,因此网关在检测到变化时会自动重新构建代理模型。而API密钥以及工具/技能相关配置仍需通过常规的重载方式来更新。

::

常见配置方案

默认方案(自动检测)——无需任何配置:

compression:
  enabled: true
  threshold: 0.50

该功能会使用您配置的主提供商与主模型。如果您希望在使用成本低于主聊天模型的情况下实现压缩功能,可针对特定任务进行覆盖设置(例如:auxiliary.compression.provider: openrouter + model: google/gemini-2.5-flash)。

强制指定提供商(基于 OAuth 或 API 密钥):

auxiliary:
  compression:
    provider: nous
    model: gemini-3-flash

可兼容各类提供商:nousopenroutercodexanthropicmain 等。

自定义端点(自托管环境、Ollama、zai、DeepSeek 等):

auxiliary:
  compression:
    model: glm-4.7
    base_url: https://api.z.ai/api/coding/paas/v4

指向自定义的 OpenAI 兼容端点。认证时使用 OPENAI_API_KEY

三个参数的交互方式

auxiliary.compression.providerauxiliary.compression.base_url最终效果
auto(默认值)未设置自动检测最优的可用提供方
nous / openrouter未设置强制使用指定提供方,并采用其认证方式
任意值已设置直接使用自定义端点(忽略提供方设置)
:::warning 摘要模型上下文长度要求 摘要模型必须拥有至少与主智能体模型相同大小的上下文窗口。压缩器会将对话的中间完整部分发送给摘要模型——如果该模型的上下文窗口小于主模型,摘要生成操作将会因上下文长度不足而失败。出现这种情况时,中间的对话内容将被直接丢弃且不会生成摘要,从而导致对话上下文在无声无息中丢失。如果您自行指定模型,请务必确认其上下文长度不低于主模型。
::

上下文引擎

上下文引擎用于控制在接近模型令牌限制时如何管理对话。内置的 compressor 引擎采用有损摘要技术(详见上下文压缩)。插件引擎则可以替换它,采用其他策略来实现相同功能。

context:
  engine: "compressor"    # default — built-in lossy summarization

若要使用插件引擎(例如用于实现无损上下文管理的 LCM):

context:
  engine: "lcm"          # must match the plugin's name

插件引擎绝不会自动激活——您必须明确将 context.engine 设置为插件名称。可通过 hermes plugins → Provider Plugins → Context Engine 来查看并选择可用的引擎。

关于内存插件所采用的类似单选系统,请参阅内存插件

迭代预算

当智能体处理需要多次工具调用的复杂任务时,其迭代预算(默认为90轮)可能会被耗尽。Hermes不会在任务进行过程中发出压力警告——早期版本会在预算使用达到70%/90%时向模型发出警告,这导致模型过早放弃复杂任务,该功能已于2026年4月被移除。

取而代之的是,当预算真正耗尽(90/90)时,Hermes会发送一条消息要求模型完成当前任务,并允许其进行一次补充调用以输出最终响应。如果这次补充调用仍无法生成文本,系统会要求智能体总结其已完成的工作。

agent:
  max_turns: 90                # Max iterations per conversation turn (default: 90)
  api_max_retries: 3           # Retries per provider before fallback engages (default: 3)

当迭代预算被完全耗尽时,CLI会向用户显示如下提示:⚠ 迭代预算已用完(90/90)——响应可能不完整

agent.api_max_retries用于控制Hermes在触发备用提供者切换之前,针对临时性错误(如速率限制、连接中断、5xx错误)会对提供者API调用进行多少次重试。其默认值为3,即总共尝试4次。如果您已配置了备用提供者并希望更快地切换到备用方案,可将该值设置为0,这样主提供者出现首次临时错误时就会立即切换到备用提供者,而无需继续对不可靠的端点进行重试。

持续目标(/goal

当某个持续目标处于激活状态时,Hermes会判断每个助手的响应是否满足该目标。如果未满足,它会将延续提示反馈至同一会话中,并持续处理,直到目标完成、轮次预算耗尽,或用户暂停/取消该目标为止。轮次预算才是真正的保障——失败时会选择“继续处理”而非终止当前流程,从而避免因判断机制出现故障而阻碍任务进展。

goals:
  max_turns: 20   # Max continuation turns before Hermes auto-pauses the goal (default: 20)

max_turns 参数用于限制目标在 Hermes 自动暂停并要求用户执行 /goal resume 前可以进行的连续回复轮数。该设置可避免判定错误(即目标实际上已完成,但系统仍指示继续处理),同时防止模型在处理模糊或无法实现的目标时过度消耗资源。如需了解完整功能信息,请参阅 目标管理

API 超时设置

Hermes 为流式请求设置了独立的超时机制,同时针对非流式请求提供了过期检测功能。当您将相关参数设置为默认值时,仅本地提供商会自动适用这些过期检测机制。

超时类型默认值本地提供机配置/环境变量
Socket 读取超时120秒自动延长至1800秒HERMES_STREAM_READ_TIMEOUT
流式数据过期检测180秒自动关闭HERMES_STREAM_STALE_TIMEOUT
非流式数据过期检测300秒默认情况下自动关闭providers.<id>.stale_timeout_secondsHERMES_API_CALL_STALE_TIMEOUT
API 调用(非流式)1800秒不变providers.<id>.request_timeout_seconds / timeout_secondsHERMES_API_TIMEOUT

Socket 读取超时决定了 httpx 需要等待提供方发送下一批数据的时长。由于本地大语言模型在生成第一个token之前可能需要数分钟时间来预加载大量上下文,因此当检测到是本地端点时,Hermes 会将此超时值设置为30分钟。如果您明确设置了 HERMES_STREAM_READ_TIMEOUT,则无论是否检测到端点类型,都将始终使用该自定义值。

流式数据过期检测用于终止那些收到 SSE 保持连接信号但未收到实际数据的连接。由于本地提供机在预加载过程中不会发送保持连接信号,因此此功能对本地提供机完全无效。

非流式数据过期检测用于终止长时间无响应的非流式请求。默认情况下,Hermes 会在本地端点上关闭此功能,以避免在长时间预加载过程中出现误判。如果您明确设置了 providers.<id>.stale_timeout_secondsproviders.<id>.models.<model>.stale_timeout_secondsHERMES_API_CALL_STALE_TIMEOUT,则即使在本地端点上也会优先使用这些自定义值。

上下文压力警告

除了迭代预算限制外,上下文压力还会监控对话内容距离压缩阈值的接近程度——即触发上下文压缩以总结旧消息的临界点。这一功能有助于您和智能体及时了解对话是否已变得过长。

进度占比等级后果
距离阈值 ≥ 60%信息提示CLI界面显示青色进度条;网关会发送提示信息
距离阈值 ≥ 85%警告提示CLI界面显示加粗的黄色进度条;网关会警告即将进行上下文压缩

在CLI界面中,上下文压力会以进度条的形式显示在工具输出中:

  ◐ context ████████████░░░░░░░░ 62% to compaction  48k threshold (50%) · approaching compaction

在消息平台中,系统会发送一条纯文本通知:

◐ Context: ████████████░░░░░░░░ 62% to compaction (threshold: 50% of window).

如果禁用了自动压缩功能,系统会发出警告,提示上下文内容可能会被截断。

上下文压力检测是自动进行的——无需任何配置。它仅作为面向用户的通知机制触发,不会修改消息流,也不会向模型的上下文中注入任何内容。

凭证池策略

当您为同一提供商拥有多个 API 密钥或 OAuth 令牌时,可配置相应的轮换策略:

credential_pool_strategies:
  openrouter: round_robin    # cycle through keys evenly
  anthropic: least_used      # always pick the least-used key

选项包括:fill_first(默认值)、round_robinleast_usedrandom。详细文档请参阅凭证池

提示词缓存

当当前使用的提供方支持跨会话提示词缓存时,Hermes会自动启用该功能——无需用户进行任何配置。

对于运行在原生AnthropicOpenRouterNous Portal上的Claude,Hermes会在系统提示词和技能模块中设置缓存控制指令,其有效时间为1小时(ttl: "1h")。在当前时段内首次发送消息时,将按正常费率计费;而在同一时段内的后续任何会话发送,则会从缓存中读取内容,享受较低的缓存读取费率。这意味着系统提示词、加载的技能内容以及长上下文消息的开头部分,在首个小时内可在不同的hermes会话之间,甚至在不同子代理之间重复使用。

Qwen Cloud(阿里达斯阔)的上游服务将缓存有效时间限制为5分钟,因此Hermes在该平台上也会采用5分钟的缓存时效。其他通过第三方实现的Claude版本(如AWS Bedrock、Azure Foundry)则遵循相应提供方的默认缓存设置。xAI Grok则采用独立的会话绑定对话ID机制——详情请参见xAI提示词缓存

目前不存在关闭此功能的选项——缓存功能始终处于开启状态,即便在单轮对话中也能节省成本,因为仅系统提示词所占的输入token数量就已相当可观。

唯一可手动设置的参数是Hermes在Anthropic风格的缓存控制指令中请求的缓存有效时间长度。

prompt_caching:
  cache_ttl: "5m"   # "5m" or "1h" (Anthropic-supported tiers); other values are ignored

cache_ttl用于指定Hermes通过原生Anthropic API、OpenRouter及Nous Portal为Claude设置的断点缓存时间。仅支持Anthropic规定的两种时间值("5m""1h"),其他任何值均会被忽略。那些有自身时间限制的提供商(例如最大缓存时间为5分钟的Qwen Cloud)仍需遵循上游平台的规定。

辅助模型

Hermes会使用“辅助”模型来处理诸如图像分析、网页摘要生成、浏览器截图分析、会话标题生成以及上下文压缩等辅助任务。默认情况下(auxiliary.*.provider: "auto"),Hermes会将所有辅助任务转发给您的主聊天模型——即您在hermes model中选择的同一提供商/模型。起步时无需进行任何配置,但请注意,在计算成本较高的推理模型(如Opus、MiniMax M2.7等)上,执行辅助任务会显著增加费用。如果您希望无论使用何种主模型都能快速且低成本地完成辅助任务,可以明确指定auxiliary.<task>.providerauxiliary.<task>.model的参数(例如,在OpenRouter上使用Gemini Flash进行图像处理和网页信息提取)。

::note 为何“auto”模式会使用主模型 在早期版本中,聚合服务用户(使用OpenRouter或Nous Portal的用户)会被默认分配到成本较低的提供商侧模型。这一做法令许多用户感到意外——那些购买了聚合服务订阅的用户,其辅助任务却由不同的模型处理。现在,“auto”模式对所有用户都统一使用主模型,不过仍可通过config.yaml中的任务级覆盖设置来改变这一行为(详见下文的完整辅助模型配置参考)。

::

交互式配置辅助模型

无需手动编辑YAML文件,只需运行hermes model,然后从菜单中选择**“配置辅助模型”**。系统将提供一个交互式的任务选择界面:

$ hermes model
→ Configure auxiliary models

[ ] vision               currently: auto / main model
[ ] web_extract          currently: auto / main model
[ ] title_generation     currently: openrouter / google/gemini-3-flash-preview
[ ] tts_audio_tags       currently: auto / main model
[ ] compression          currently: auto / main model
[ ] approval             currently: auto / main model
[ ] triage_specifier     currently: auto / main model
[ ] kanban_decomposer    currently: auto / main model
[ ] profile_describer    currently: auto / main model

选择任务,选定提供方(OAuth流程会自动打开浏览器;使用API密钥的提供方则会弹出提示),再挑选模型。这些设置会同步保存到config.yaml文件中的auxiliary.<task>.*路径下。其操作逻辑与选择主模型的方式相同——无需学习额外的语法。

视频教程