ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Hermes Agent 内存优化完整指南:缓存策略与资源释放实操

Hermes Agent 内存优化完整指南:缓存策略与资源释放实操

Hermes Agent 内存优化完整指南:缓存策略与资源释放实操

【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent

跑一个长会话两小时,RSS 从 800 MB 爬到 4 GB,新回复越转越慢,直到报 context full——Hermes Agent 内存优化的问题通常就出在这类长跑场景。这篇指南按可执行步骤拆解:先定位瓶颈在哪一层,再决定缓存 TTL 怎么设、上下文压缩怎么开,最后给容器任务兜底限额。每个参数都给默认值和取舍建议,改完有验证方法。

Hermes Agent 的缓存分三层:提示词缓存(Anthropic cache_control 标记,5m/1h 两档)、模型元数据缓存(进程内 1 小时,上下文长度落盘到 context_length_cache.yaml)、技能索引缓存(1 小时,写在磁盘上)。资源释放靠两块:上下文压缩和容器资源限额。

先诊断:Hermes Agent 内存瓶颈在哪一层

内存占用大致分三类:进程 RSS、上下文 token 数、磁盘缓存文件。别急着改参数,先判断属于哪类。

# 找到主进程,每分钟采样一次 RSS(单位 KB) ps aux | grep -E "hermes" | grep -v grep watch -n 60 'ps -o rss= -p <PID>'

RSS 随轮次持续上涨:上下文没在压缩,看压缩配置;RSS 平稳但响应变慢:多半是提示词缓存命中率掉了,看 TTL;磁盘目录变大:索引缓存堆积。

# 定位 HERMES_HOME,检查技能索引缓存大小与文件新鲜度 echo "$HERMES_HOME" du -sh "$HERMES_HOME/skills/.hub/index-cache" ls -lt "$HERMES_HOME/skills/.hub/index-cache" | head

另一个容易漏的点:上下文压缩默认是静默的,后台执行、只在服务端日志留痕。想看它有没有在工作,临时把compression.progress_notices设为 true,聊天平台会开始推送 compaction 进度。确认完记得改回。

长会话场景:Hermes Agent 上下文压缩怎么开、缓存 TTL 设多少

现象:会话超过 1 小时后 RSS 单调上涨,prompt tokens 逼近模型上下文上限,回复延迟明显升高。

改哪里:配置文件里的compression段和prompt_caching段,标记注入逻辑在 agent/prompt_caching.py。

prompt_caching: cache_ttl: "1h" # 默认 "5m",只有人在交互时才值得 1h compression: threshold: 0.50 protect_first_n: 0 # 长跑会话建议 0,默认 3 max_attempts: 6 # 工具调用密集时 3 轮压不下去

改多少有讲究。压缩默认在 prompt tokens 达到模型上下文窗口 50% 时触发,protect_last_n默认保留最近 20 条消息,这个不用动。protect_first_n默认保留开头 3 条非系统消息且永不被摘要,长会话里它们早就和当前语境脱节,设 0 只保系统提示词最干净。

TTL 这一档要算账:1h 档的缓存写入成本是基础输入价的 2 倍,5m 档是 1.25 倍,只有轮次间隔超过 5 分钟的人机交互才回本。代码里对 subagent、cron、webhook 这类机器节奏的来源会自动按 5m 处理,你手动设 1h 也救不回来;Qwen 等阿里系路由不支持 1h,会被自动钳回 5m。所以这个场景下不建议无脑拉满,人跑 1h、机器跑 5m。

怎么验证:改完跑一个 30 分钟以上的会话,观察两点——RSS 在压缩触发后回落或走平,聊天里偶尔出现 compaction 通知;再看 API 用量的缓存写入 token 占比,比改之前低才说明选对了档位。

技能批量加载场景:1 小时索引缓存怎么用

现象:批量安装或升级技能时请求 hub 频繁,首次列表加载慢,怀疑缓存失效。

改哪里:技能中心 tools/skills_hub.py 把各源索引写到HERMES_HOME/skills/.hub/index-cache/,TTL 固定 1 小时(INDEX_CACHE_TTL = 3600),过期自动重取。

改多少:默认值就是权衡过的,一般不动。想省请求就别去手动刷新缓存;想省磁盘就清理老文件,代价是清理后首次访问该源要重新拉一次索引:

# 删除超过 1 天的过期索引缓存,下次读取自动重建 find "$HERMES_HOME/skills/.hub/index-cache" -name '*.json' -mtime +1 -delete

怎么验证:ls -lt该目录,文件修改时间应全部在近 1 小时内;对同一批技能再跑一次列表操作,明显变快且不产生新的索引文件,说明命中了缓存。

容器隔离场景:给单任务内存封顶

现象:agent 跑构建或测试命令时把宿主内存吃满,整机变卡甚至触发 OOM killer 误伤别的服务。

改哪里:terminal配置段的container_memory,对 docker、singularity、modal、daytona 四个容器后端生效,local/ssh 忽略。Singularity 后端把它翻译成--memory <MB>参数拼进命令,见 tools/environments/singularity.py。

terminal: container_memory: 8192 # 默认 5120;按任务峰值上浮 30% 左右

改多少:先跑一次目标命令记下容器内峰值,再按峰值的 1.3 倍设。命令本身吃不到 2 GB 就设 2048,封顶的意义就是留安全垫,设成默认 5120 而实际只用 1 GB,等于没设。

怎么验证:跑一个故意吃内存的命令(比如 Python 里循环分配大列表),预期容器内进程被杀、宿主 RSS 曲线不受影响;再跑正常任务确认没被限额误杀。

参数速查表

参数默认值建议值适用场景
prompt_caching.cache_ttl"5m"人在交互设"1h",机器节奏保持"5m"长跑会话、定时任务
compression.threshold0.501M 窗口设0.30,128K 窗口设0.60上下文压缩触发点
compression.protect_last_n20保持默认压缩时保留的尾部消息数
compression.protect_first_n3长会话设0永不被摘要的头部消息数
compression.max_attempts3工具密集会话设6压缩重试轮数上限 10
compression.idle_compact_after_seconds0长期线程设1800闲置 30 分钟后回来先压一轮
memory.memory_char_limit2200保持默认(约 800 token)MEMORY.md 字符限额
memory.user_char_limit1375保持默认(约 500 token)USER.md 字符限额
技能索引缓存 TTL3600秒保持默认skills/.hub/index-cache/
模型元数据缓存3600秒保持默认进程内,免重复请求
container_memory5120MB任务峰值 × 1.3,最小 2048容器后端内存封顶

落地顺序

先改compression段并跑一个长会话确认 RSS 走平,这是收益最大的一步;再把交互场景的cache_ttl调到 1h 观察缓存写入成本是否回落;容器限额最后加,它只影响隔离任务,和前面两项互不干扰,任何一条出问题单独回滚即可。

【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进