配置文件——让 Hermes 按你的喜好工作
Hermes Agent 官方教程第七篇:配置管理。config.yaml 详解。
好的,没问题!这是为您重写的博客文章,完全符合您的要求:
配置文件——让 Hermes 按你的喜好工作
嘿,朋友们!上次我们聊了怎么把 Hermes 请进家门,今天咱们来聊聊怎么给它“装修”一下,让它完全按你的喜好来工作。别担心,这事儿比你想的简单多了,咱们的目标是轻松上手,拒绝头秃。
你的私人控制台:~/.hermes/ 文件夹
所有魔法都发生在一个叫 ~/.hermes/ 的文件夹里。你可以把它想象成 Hermes 的大脑和储物间,里面整整齐齐地放着各种重要文件:
config.yaml:这是主控台!模型、终端、语音、压缩……所有非秘密的设置都在这里。.env:保险箱!专门存放 API 密钥、令牌、密码这类敏感信息。auth.json:OAuth 提供商的凭据(比如 Nous Portal)。SOUL.md:Hermes 的“人设”,定义它的身份和行为。memories/:它的长期记忆库。skills/:它学会的技能都存这儿。cron/:定时任务。sessions/:网关会话。logs/:日志(errors.log、gateway.log,密钥会自动打码)。
偷懒大法:一条命令搞定一切
手动编辑 YAML 文件听起来有点麻烦?没问题,官方给了一条捷径:
hermes setup --portal
运行这条命令,通过一次 OAuth 授权,就能帮你搞定模型提供商和四个 Tool Gateway 工具,完全不用碰配置文件。而且,Portal 订阅用户还能享受 10% 的折扣,简直美滋滋。
配置命令:你的魔法棒
不想用 setup?那就用下面这些命令来管理配置,它们就像魔法棒一样好用:
hermes config # 查看当前配置
hermes config edit # 用编辑器打开 config.yaml
hermes config get model # 查看当前模型
hermes config set model anthropic/claude-opus-4 # 切换模型
hermes config set terminal.backend docker # 设置终端后端
hermes config unset terminal.backend # 取消设置
hermes config check # 检查是否有遗漏的配置项和过期的已保存选择
hermes config migrate # 交互式添加缺失的配置项
划重点:hermes config set 命令非常聪明,它会自动判断该把值写到哪个文件里。凡是全大写下划线格式的名字(比如 OPENROUTER_API_KEY、DISCORD_HOME_CHANNEL、HERMES_TIMEZONE)都当成环境变量,一律存进 .env,绝不写进 config.yaml;带点号的设置才进 config.yaml。其他全大写名字也会原样存进 .env(会导出给插件和技能用),但像 HERMES_YOLO_MODE、PATH 这种在黑名单上的名字会被拒绝。要是你把一个已知的键写错了前缀(比如 gateway.discord.foo,而 discord.foo 本身是个已知键),它会直接拒绝并提示你是不是想写别的,除非加 --force 硬写。其他未知路径(比如手滑打成 agent.max_turnz)会照写,但附带一条“你是不是想写……”的提醒。用 hermes config get 读这类路径时,它会把文件里的值打出来,同时在 stderr 提醒你 Hermes 可能根本不读它——所以残留的键不会悄悄冒充生效的设置。
配置的“江湖规矩”:优先级
当多个地方都有同一个设置时,听谁的?记住这个顺序(从高到低):
- 命令行参数:比如
hermes chat --model xxx,只在本次对话中生效,权力最大。 config.yaml:你的主配置文件。.env:环境变量的后备军。- 内置默认值:Hermes 自带的“保底”设置。
一句话总结:秘密放 .env,其他放 config.yaml。如果两边都设了,非秘密设置以 config.yaml 为准。
进阶玩法:环境变量和数据库调优
你还可以在 config.yaml 里引用环境变量,比如 ${GOOGLE_API_KEY},这样就能把密钥藏在环境里,更安全。如果引用的变量没设置,占位符会原样保留(${UNDEFINED_VAR} 还是 ${UNDEFINED_VAR}),并记录一条警告;裸写的 $VAR 不会被展开。Cursor 风格的 ${env:VAR_NAME} 写法也支持,效果和 ${VAR_NAME} 一样;而 ${file:...}、${vault:...}、${bitwarden:...} 这类外部密钥后端不会内联解析,需要在 secrets: 块里注入环境后以 ${env:NAME} 引用。另外,在多 profile 网关下,某个 profile 的 config.yaml 里的引用只在该 profile 自己的 .env 里查找,不会去读共享的进程环境。由网关托管的本地 hermes chat / TUI 会话,这些引用、provider_routing 和 prefill_messages_file 会在网关创建会话时按该 profile 当前的 config.yaml 和 .env 解析:改动对下一个新会话生效,无需重启网关,已打开的会话保留创建时的值;网关重启也不会重新读取——重启后恢复的会话沿用随会话存储的路由和 prefill 路径,并在首次需要时从该路径重新读取 prefill 文件内容。在网关启动时所用的 profile 上,从 .env 删掉的变量仍会解析为网关启动时加载的值(未命中会回退到进程环境),要彻底去掉得重启网关。
另外,database: 部分可以微调 SQLite 数据库的性能,比如日志模式(journal_mode)和同步级别(synchronous),不过这些对新手来说可以先放一放,等玩熟了再研究也不迟。顺带一提,在 Docker Desktop、macOS 上的 Podman、OrbStack 这类 virtiofs/9p 挂载上,Hermes 会自动检测并把新建的数据库设成 delete 模式;但已经存在的 WAL 数据库不会被在线降级——你设了 journal_mode: delete 它也不会自动改,hermes doctor 会一直提醒你,直到你停掉所有 Hermes 进程、跑一次 hermes sessions set-journal-mode delete(只要还有进程占着数据库文件它就会拒绝执行,转换完成后还会校验文件头)。这个提醒还会告诉你当前是哪些进程占着数据库(<db> is held by PID <n> (<command>)),方便你知道该关谁;如果进程扫描不完整或不可用,它会说 cannot prove the database is quiet,而不是给你一个“一切正常”的假象。
沙箱镜像:容器跑在哪儿,屏幕就在哪儿
Singularity/Apptainer 后端已经从核心移出,变成官方 singularity 插件(hermes update 会给已经在用它的 profile 自动装上)。手动安装:
hermes plugins install singularity
它需要 singularity 插件,外加 $PATH 里有 apptainer 或 singularity 二进制。临时目录的解析顺序也变了:TERMINAL_SCRATCH_DIR → /scratch 可写时的 /scratch/$USER/hermes-agent(HPC 惯例)→ TERMINAL_SANDBOX_DIR/singularity(默认 ~/.hermes/sandboxes/singularity)。
如果你用 Docker、Modal、Daytona 或 Vercel 这类沙箱后端,terminal 下面有几个镜像相关的键值得认识(Singularity 现在是官方插件,镜像键不在核心配置里了):
terminal:
docker_image: "nousresearch/hermes-sandbox:desktop" # Docker 后端镜像
modal_image: "nousresearch/hermes-sandbox:desktop" # Modal 后端镜像
daytona_image: "nousresearch/hermes-sandbox:desktop" # Daytona 后端镜像
vercel_image: vercel/sandbox/universal:latest # Vercel 托管镜像或 VCR 仓库[:tag]
Hermes 自带六个终端后端(local | docker | ssh | modal | daytona | vercel_sandbox),插件还能再加,比如官方的 Singularity/Apptainer 后端。默认镜像 nikolaik/python-nodejs(Python 3.13 / Node 26)外加一套显示栈,所以 Bot Screen、computer_use 和浏览器都是在这个沙箱里跑的。换成别的镜像也能跑 shell 命令,但屏幕就得靠 bot_desktop.placement: gateway 挪到网关那边去。写这个键本身就是一个决定:一旦你指定了别的镜像,下次终端调用时那个持久化的容器就会被重建;不写的话,现有容器会保留,CLI / Screen 面板会先问你。
Vercel 后端这边,terminal.vercel_image 挑的是新沙箱用的镜像:可以是 Vercel 托管镜像(默认 vercel/sandbox/universal:latest,Ubuntu + Node.js 24 + Python 3.14,也有 vercel/sandbox/node:26、vercel/sandbox/python:3.14),也可以是你项目 Vercel Container Registry 里的仓库(裸名字解析成 latest,带 tag 或 digest 就钉死)。旧的 terminal.vercel_runtime 预设(node24、node22、python3.13)已经被 Vercel 弃用;钉了 runtime 仍然能用,而且会覆盖镜像,但两者不能同时设。快照恢复自带文件系统,两个都不发。
还有个细节:Hermes 自己管理的容器会带标签,方便后续进程(和孤儿回收器)认出它们。其中 hermes-environment=<digest> 这个标签,在没有显式共享 key 时,会把容器复用范围限定在“请求的镜像 + 挂载参数 + 当前 HERMES_HOME”上——主机路径和卷来源会被哈希,不会明文暴露。也就是说,改了镜像、挂载参数或 HERMES_HOME,就会开一个新容器,而不是悄悄复用另一个配置的旧容器。升级前创建的旧容器没有这个标签,所以升级后第一次会话会开新容器,但正在跑的旧容器不会被删掉。
Modal 后端还有个持久化开关:打开后,沙箱文件系统会在清理时打快照、下次会话恢复。快照记在 ~/.hermes/modal_snapshots.json,会一直留着直到你自己删(Hermes 主动退出了 Modal SDK 的 30 天快照过期)。注意它保的是文件系统状态,不是活着的进程、PID 空间或后台任务。
上下文压缩:给 token 花销上个保险
压缩触发除了按比例(threshold),现在还支持一个绝对 token 上限:
threshold_tokens: null # 绝对 token 上限(可选)——取比例与绝对值的较小者
设了之后,压缩会在“比例阈值”和“这个绝对数”里取更小的那个触发,所以不管当前用的是哪个模型,压缩都不会晚于这个 token 数发生。想给每次调用定个固定的成本天花板时就用它,比如 threshold_tokens: 256000,能让 1M 窗口的模型在 256K 就压缩,而不是等到 500K。这个上限会被夹到模型上下文长度以内,设得比窗口还大等于没设。默认 null(关闭,只按比例)。它跨模型切换和 fallback 激活都有效。
流式进度超时:别让沉默的摘要器拖死会话
压缩的摘要现在是流式跑的(chat-completions 和 Responses 路由都走流式,比如 openai-codex 或自定义的 OpenAI 兼容端点),这里有两个互相独立的超时:
auxiliary.compression.timeout—— 整个请求的总预算(默认 120 秒)。auxiliary.compression.no_progress_timeout—— 流可以多久没有实质性事件(文本/推理增量,或一个完成的输出项)才中止本次尝试(报... stream stalled: no new output for Ns),然后交给正常的重试 / fallback 链。不设时默认 60 秒。在 chat-completions 流上,这个窗口从第一个 token 开始算;在那之前,远端端点享受主循环的“耐心值”(提供商设了providers.<id>.stale_timeout_seconds就用它,否则大 prompt 是 180 秒、o3 或 DeepSeek R1 这类推理模型是 600 秒,且不超过timeout),所以模型默默思考不会被掐。本地端点(localhost、局域网、Tailscale)的静默预填充只受timeout约束。同一条规则适用于所有流式辅助任务,包括 MoA 参考调用。保活和生命周期帧(response.in_progress、ping)不算进度;每个实质性事件都会重置窗口,所以慢但在推进的摘要永远不会被它切断。
只调大 timeout 并不会放宽进度窗口——一个配了 600 秒的请求,遇到 60 秒空档照样中止。要改这个空档就设 no_progress_timeout;生效窗口会被夹到 timeout 以内,宿主自己的硬截止 / 取消仍然优先。宿主自己的不活动预算才是这里的外层上限:智能体内部压缩在 compression.context_timeout_seconds(默认 120 秒,下限是生效的 auxiliary.compression.timeout,而后者至少 300 秒)后放弃沉默的摘要器,网关会话卫生则走 compression.hygiene_timeout_seconds(默认 30 秒),所以 no_progress_timeout 设得比适用的宿主预算还大,会被它悄悄截短。这个键是按任务的(auxiliary.<task>.no_progress_timeout),给压缩放宽不会影响其他辅助任务。非正数的值会被忽略,日志里记一条警告,然后套用 60 秒默认值。
auxiliary:
compression:
provider: openai-codex
timeout: 600
no_progress_timeout: 180 # 容忍长推理摘要 3 分钟的静默空档
注意:摘要模型的上下文窗口必须不小于你的主智能体模型。压缩器会把对话的整个中间段发给摘要模型——如果它的窗口比主模型小,摘要调用会因上下文长度报错,中间那几轮会被静默丢弃、不留摘要。覆盖模型时务必确认它的上下文长度够用。
快速模式:花钱买速度
Fast 模式会向提供商请求更快的输出,代价是更贵:OpenAI 的 Priority Processing(service_tier: priority)和支持的模型上的 Ultrafast(service_tier: ultrafast)、Grok 4.6 上的 xAI Priority Processing、以及 Anthropic 的 Fast Mode(speed: fast,仅 Opus 4.8 / Opus 5 / Opus 5.5)。openai 和 openai-api 两个提供商会走 OpenAI 一方端点。默认是关的。
service_tier: "" # "" / normal | fast | priority | ultrafast | auto | cold
会话里可以用 /fast normal|fast|ultrafast|auto|cold 切换模式,加 --global 就持久化写进 config.yaml;光敲 /fast 显示当前模式。
辅助任务的端点路由
给辅助任务(比如压缩、标题生成)单独指定端点时,base_url 的优先级高于 provider,这是最明确的指定方式。直接覆盖端点时,Hermes 用配置里的 api_key,没有就退回 OPENAI_API_KEY——它不会拿 OPENROUTER_API_KEY 去喂这个自定义端点。两个都没有的话,只有当 base_url 和主端点完全同源(scheme、host、port 全一致)时才会复用主模型的 key。主端点指的是当前会话正在跑的那个(/model 切换后就跟着变),配的是它自己的 key,绝不会拿别的端点的 key 来凑。
界面语言:不止中英两种
display.language 决定界面语言,内置可选值有:en(默认)、zh(简体中文)、zh-hant(繁体中文)、ja、de、es、fr、tr、uk、af、ko、it、ga、pt、ru、hu、ar。这个列表是可插拔的:装一个语言包插件(provides_locales),或者往 <HERMES_HOME>/locales/<lang>.yaml 放一个局部覆盖文件,就能加语言或改措辞。hermes config set display.language <id> 接受任何内置目录、你的覆盖文件或已装语言包提供的 id;不认识的 id 会被拒绝并列出可用语言,运行时解析不出来的值会退回英文。
工具进度提示:按平台分别设置
display.tool_progress 是全局的工具进度提示开关,但你可以给单个平台单独覆盖,没覆盖的平台就沿用全局值。合法的平台键有:telegram、discord、slack、signal、whatsapp、matrix、mattermost、email、sms、dingtalk、feishu、wecom、weixin、bluebubbles、qqbot,再加上任何插件平台的名字(比如 Home Assistant 插件的 homeassistant)。旧的 display.tool_progress_overrides 键为了向后兼容还能读,但已经弃用,首次加载时会被迁移进 display.platforms。
语音聊天:让说话的那一轮换个模型
Voice chat 这一项挑的是语音模式下回答问题的模型(工具照样能用);打字的那一轮还是走主模型。想了解细节可以看 Voice chat model。
# no_progress_timeout: 60 # 流式摘要可以多久没有实质性分片
# # 才快速失败进入重试/fallback
streaming: false # 说话时实时显示部分文本(openai、xai、elevenlabs)
model: "base" # tiny, base, small, medium, large-v3, turbo
model: "grok-voice-transcribe-2.0" # 或 grok-voice-transcribe-1.0;每个请求都会带上
language: "" # 按提供商覆盖 stt.language
超过提供商单请求上传上限的录音(OpenAI/Groq/DeepInfra 是 25 MB,Mistral 和 xAI 是 500 MB,ElevenLabs 大约 5 GB,另外 OpenAI 的 gpt-4o-transcribe 系列和 whisper-1 还有各自的时长限制)会被重新编码成紧凑的 AAC,如果还是太大,就在停顿处切开、逐段转写。详见 Long recordings and upload limits。
STT_XAI_MODEL=grok-voice-transcribe-2.0
网页搜索后端:选过就固定
后端选择:运行时永远用存下来的 web.backend 选择(通过 hermes tools 设置;nous 走托管的 Tool Gateway)。只有在从来没选过网页后端时,才会从可用的 API key 里自动探测:只设了 SEARXNG_URL 就用 SearXNG;只设了 EXA_API_KEY 就用 Exa;只设了 TAVILY_API_KEY 就用 Tavily;只设了 PERPLEXITY_API_KEY 就用 Perplexity;只设了 PARALLEL_API_KEY 就用 Parallel;只设了 KEENABLE_API_KEY 就用 Keenable。完全没选、也没任何凭据时,请求会在无密钥免费环(Exa / Parallel / Firecrawl / Keenable)里轮询,遇到限流(搜索还会在厂商拒绝时)自动切下一个——细节看 Web Search guide。一旦有了选择,往 .env 里加 key 也不会改变路由。在 hermes tools 里选 Tavily、Firecrawl 或 Keenable 也是不需要 key 就能用的。
密钥打码与网站黑名单
密钥打码和网站黑名单的配置见安全相关文档。早先版本还有一套 tirith_* 键,用于内置的命令扫描器;它已经被移除,升级时这些键会被丢弃。内容级命令检查的说明在 Content-Level Command Checks。
首次接触的引导提示和首条消息的提议
profile_build—— 控制有史以来第一条消息时的提议,出现在 TUI、桌面应用和消息私聊里(群聊里永远不出现)。"ask"(默认)会提议构建用户画像;这个提议是自愿且需同意的——智能体在查询前会先问,绝不会偷偷读已连接的账号,确认过的事实会存进用户记忆。在 Microsoft Store 桌面应用里,这个提议改成一行收尾提示,指向/initiate-setup(Telegram 上是/initiate_setup,Slack 上是/hermes initiate-setup)。当第一条消息本身就是/initiate-setup时会跳过提议,桌面应用的 setup profile 里也永远跳过。"off"只关掉提议;智能体还是会做一段简单的自我介绍。每个 profile 最多触发一次。/initiate-setup会发一小段关于这台电脑的事实;详见 What the setup chat knows about your computer。seen—— 内部状态。Hermes 把每个展示过的提示记在这里,保证它不会再触发;首条消息的提议展示过之后也会记在这儿。别手动改它——想重新看所有提示,就把整个onboarding段清掉。ssh_isolated_idle_grace_s(默认900)—— 一个通过 SSH 访问的、由桌面端拥有的hermes serve --isolated后端,是故意从 SSH 会话里脱离的,所以笔记本中途睡眠不会把它拆掉;但每次暗唤醒重连过去都会留下另一个占着state.db的后端。现在,只要有一段时间没有任何客户端 WebSocket 连着、也没有智能体轮次在跑,后端就会自行退休(有轮次在跑就保活;轮次状态读不出来也保活)。如果你依赖脱离的后端在笔记本睡眠后继续完成长任务,就把它设高一点。这类后端还会发慢速 WebSocket ping(60 秒,10 分钟超时),好让半开的隧道被发现。独立于这个宽限期,后端也会退休(篇幅所限,详见官方文档)。
网关重启时的排空等待
网关停止或重启时(SIGTERM、hermes update、hermes gateway stop,或 hermes gateway restart / /restart 的最后阶段),agent.restart_drain_timeout 决定它让正在跑的对话轮次继续跑多少秒再打断:
agent:
restart_drain_timeout: 0 # 默认:立刻打断进行中的对话轮次
cron_drain_timeout: 30 # cron 任务和 api_server(/v1)运行的保底值
restart_after_turn_timeout: 1800 # /restart 和 `gateway restart`:先等轮次跑完再停
默认 0 时,重启会立刻打断正在跑的轮次;该轮次按“已打断”结算且不会重跑,TUI 和桌面端会在那一轮显示“Gateway restarting”(或“Gateway shutting down”)提示,等 Hermes 重连后你再发一次消息即可。排在它后面的消息会保留,并在新网关上按顺序执行。想让它跑完就把值设成正数,比如 restart_drain_timeout: 60——排空越久,每次重启和更新就等得越久。HERMES_RESTART_DRAIN_TIMEOUT 环境变量会覆盖配置值。注意生成的 systemd 单元会据此推算 TimeoutStopSec(取 restart_drain_timeout 与 cron_drain_timeout + 10 秒中的较大者,再加 30 秒余量,且至少 60 秒);调大 restart_drain_timeout 后要重跑 hermes gateway install,否则 systemd 会在排空中途 SIGKILL 网关。launchd 的停止超时上限是 60 秒,所以 macOS 上排空只能在这个范围内。
更新这件事,也值得说两句
Hermes 的后台更新检查(CLI 横幅、TUI 徽章、仪表盘、桌面应用)是直接问 GitHub REST API 要 main 分支的最新提交,不会跑 git fetch——在部分克隆(--filter=blob:none)里它也不会去 promisor 远端下载缺失的对象(需要 Git 2.44 或更新版本)——而且每 24 小时最多查一次(失败后一小时重试)。想立刻查,可以用 hermes update --check,或者桌面端的“Check for Updates…”菜单、Settings → About → “Check now”,这些都会绕过缓存。
更新相关的设置都在 config.yaml 的 updates 下面:
updates:
pre_update_backup: quick # quick(状态快照,默认)| full(快照 + HERMES_HOME 打包)| off
backup_keep: 5 # 保留多少个完整更新前备份 zip
non_interactive_local_changes: stash # stash | discard
auto_switch_parked_branch: true # 干净且已完全合并的 parked 分支自动切回 main
pre_update_backup 是更新前唯一的安全开关:quick(默认)会把关键状态文件(配对数据、cron 任务、配置、认证;超过 1 GiB 的文件会跳过)快照到 state-snapshots/;full 还会把整个 HERMES_HOME 打包进 backups/,目录大的话可能要多等几分钟;off 则两者都关掉。旧的布尔写法也认(true → full,false → off)。
另外,config.yaml 本身也会留下时间点副本(在 hermes setup 重写前、hermes migrate 修改前、每次解析成功时、以及解析失败时),放在 backups/config/config.yaml.<原因>.<时间戳>。重复内容会跳过,每种原因只保留最新的五份。如果 config.yaml 坏了,Hermes 会用最新的 good 副本而不是内置默认值,并在每次启动时提醒你,直到 YAML 修好为止;坏掉的文件本身不会被改动。
对了,git 安装版在更新前会自动把改动的和未跟踪的文件 stash 起来,交互式更新会问你要不要恢复;非交互式更新(桌面/聊天应用、网关或 --yes)则看 updates.non_interactive_local_changes 这个设置:stash 会在拉取成功后恢复你本地的源码改动,discard 则直接丢掉更新时创建的 stash——后者只建议用在“本地源码改动本来就不该保留”的托管安装上。
临时目录与压缩超时
Hermes 会给会话准备一个受管的临时目录,它会自动清理:闲置 24 小时(目录里任何地方都没有写入)的产物,会被网关的后台清理每小时扫一次,纯 CLI 安装则每个进程扫一次。想改位置,把 temp_dir 设成一个已存在的绝对路径就行;由你或操作系统自己管理的目录(macOS 的 /var/folders、Windows 的 %TEMP%)Hermes 不会碰。清理在启动时进行(每小时最多一次),判定标准是闲置满 24 小时:只要目录里任何地方在最近一天内被写过,它就留着,最后一次写入满一天后才删。删除一个闲置条目之前,Hermes 还会先停掉工作目录仍在其中的进程(或停掉指向已不存在临时路径的进程,比如测试跑完留下的无头浏览器),并清掉指向它的 git worktree 注册。hermes doctor 会报告这个目录及其大小,并对 cache/ 下超过 1 GB、又没有清理器覆盖的目录发出警告。
压缩方面,context_timeout_seconds(默认 120)是智能体内部 compress_context 的不活动预算——对话循环、预检压缩、手动 /compress 都算——这样卡住的摘要模型就不会无限期拖住会话。流式输出的摘要 token 会延长等待时间,只有完全没动静的 worker 才会被掐断。这个预算有下限,不会低于辅助压缩请求自己的超时(auxiliary.compression.timeout,最少 300 秒),所以宿主不会在请求本身还没超时前就放弃一个沉默的摘要器。超时后 Hermes 会拿 auxiliary.compression.fallback_chain 的第一项重试一次摘要(如果那一项自己声明了 timeout 就用它的)——卡住的路由不会抛错,所以辅助客户端自己的 fallback 处理看不到它。如果这次也失败,或者根本没配 fallback 链,接下来怎么办取决于请求是否还塞得进模型的上下文窗口:塞得进就这一轮不压缩直接发(摘要失败的冷却期会阻止它每轮都重试);超过窗口就根本发不出去,于是 Hermes 改用确定性的兜底摘要(裁掉旧工具结果,用一段静态交接替代被摘要的中间部分),而不是直接结束这一轮——用“compression timed out”恢复结果结束这一轮(在消息网关上还会自动重置会话)是最后手段,只有连确定性兜底都缩不小对话记录时才会走到。设为 0 可以关掉。预检压缩如果一点都没回收、请求又仍然超过窗口,会立刻结束这一轮并提示你开个新会话(/new),而不是发一个模型根本接不下的请求。网关的会话卫生走自己的 hygiene_timeout_seconds 路径,不会被重复包裹。
消息网关的小细节:标题怎么起
在本地消息网关里,文本消息会拿原始请求去给会话起标题,这一步发生在绑定渠道的技能和平台上下文加进去之前。主模型和对话历史仍然保留完整的技能内容。只有附件、没有正文的那一轮,还是走原来那套“增强后消息”的标题回退逻辑。这个改动只影响新生成的标题,不会去修以前已经起好名字的会话。
好了,现在你已经掌握了配置 Hermes 的基本功。快去试试看,把它调教成你最趁手的AI助手吧!
📖 官方文档
本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/configuration