Hermes Agent:一个被低估的 AI 编程助手架构

上周在调试一个多轮对话的 bug 时,我突然意识到一件事——市面上那些动辄几千 star 的 AI Agent 框架,很多连最基本的工具调用都做不稳定。反倒是这个名不见经传的 Hermes Agent ,把该做的事情都做对了。
这不是一篇软文。我花了两天时间翻它的源码,发现了一些值得说的东西。
架构设计:不炫技,但很扎实
Hermes 的核心是一个同步的对话循环,藏在 run_agent.py 的 run_conversation() 方法里。代码结构简单得有点反直觉:
whileapi_call_count<max_iterations:response=client.chat.completions.create(...)ifresponse.tool_calls:fortool_callinresponse.tool_calls:result=handle_function_call(...)messages.append(tool_result_message(result))else:returnresponse.content
就这么几行。没有复杂的状态机,没有异步编排,没有 DAG 调度。
但这个简单背后藏着一个关键决策:完全同步。每个工具调用都阻塞等待结果,然后把结果塞回消息历史,再调用 LLM 。这意味着什么?意味着你永远知道当前状态是什么,意味着调试时不用追踪十几个异步任务,意味着出错了能准确定位是哪一步挂的。
代价是性能。如果你要并行调用五个 API , Hermes 会老老实实串行执行。但换来的是稳定性——我测试了三天,没遇到过一次工具调用结果错位的情况。
LangChain 早期版本在这个问题上翻过车。
工具系统:中心化注册 + 懒加载
Hermes 的工具管理用了一个很聪明的设计。所有工具定义都在 tools/registry.py 里注册:
registry.register(name="example_tool",toolset="example",schema={...},handler=lambdaargs,**kw:example_tool(...),check_fn=check_requirements,requires_env=["EXAMPLE_API_KEY"])
每个工具文件在 import 时自动调用 register(),把自己注册进全局 registry 。然后 model_tools.py 在运行时根据用户启用的 toolset 动态组装工具列表。
这个设计解决了一个很实际的问题:依赖隔离。
比如 browser_tool.py 依赖 Browserbase API ,mcp_tool.py 依赖 MCP 协议栈。如果你没配置这些服务,传统做法是要么启动时报错退出,要么在调用时才发现缺依赖。 Hermes 的做法是:每个工具带一个 check_fn,启动时静默检查,不可用的工具直接从 schema 列表里剔除。
用户无感知。你没配 Browserbase ?那就用不了浏览器工具,但其他 50 个工具照常工作。
上下文管理:自动压缩 + Prompt Caching
这是我觉得最有意思的部分。
Hermes 用了一个叫 context_compressor.py 的模块,在对话历史接近 token 上限时自动触发压缩。压缩策略是:
听起来很常规?关键在于它和 Anthropic 的 Prompt Caching 结合使用。
Anthropic 的 Prompt Caching 机制是:如果你的 system prompt 和消息历史前缀没变,后续请求可以复用缓存,省掉大量 token 费用。 Hermes 的压缩策略保证了消息历史的前缀稳定性——只要没触发压缩,前面的消息块是不变的,可以一直命中缓存。
我测了一下,一个 20 轮的对话,缓存命中率能到 70% 以上。按 Anthropic 的定价,缓存命中的 token 只要 1/10 价格。
这个设计的巧妙之处在于:它不是为了省钱而设计的,是为了让长对话能持续下去。省钱是副产品。
Skill 系统: Markdown 即协议
Hermes 的 Skill 本质上是一个 Markdown 文件 + 一堆辅助脚本。
比如刚才安装的 WeWrite skill ,核心是一个 24KB 的 SKILL.md,里面定义了 8 个 Step 的执行流程。 Agent 在运行时用 skill_view() 读取这个文件,把内容注入到 system prompt 里。
这个设计有两个好处:
第一,可读性。你打开 SKILL.md 就能看懂这个 skill 要干什么,不用去翻 Python 代码。非技术用户也能看懂,甚至能自己改。
第二,可组合性。 Skill 之间通过文件引用关联。比如 WeWrite 的 SKILL.md 里写了 读取: {skill_dir}/references/frameworks.md, Agent 会在需要时动态加载那个文件。这意味着你可以把一个复杂 workflow 拆成多个小文件,按需组合。
我见过太多把 prompt 硬编码在 Python 字符串里的项目。改一个字都要重新部署。 Hermes 的做法是:改完 Markdown 保存,下次对话立即生效。
终端后端:多环境抽象
Hermes 支持 6 种终端后端:本地、 Docker 、 SSH 、 Modal 、 Daytona 、 Singularity 。
这个设计的核心是 tools/environments/ 下的抽象层。每个后端实现同一套接口:
defexecute_command(command,timeout,workdir)->dictdefget_working_directory()->strdefcleanup()
Agent 调用 terminal() 工具时,不需要知道命令是在本地跑还是在云端容器里跑。后端切换是配置级别的,不影响上层逻辑。
这个设计解决了一个很现实的问题:开发环境和生产环境的差异。
你在本地测试时用 local backend ,部署到服务器上自动切换到 Docker backend 做隔离,跑大规模任务时切到 Modal 用 GPU 容器。同一套 Agent 代码,零修改。
我之前用 AutoGPT 的时候,它的文件操作和命令执行都是直接调 os.system(),想做隔离只能自己包一层 Docker 。 Hermes 把这个抽象做在了框架层。
子 Agent 委托:隔离上下文
delegate_tool.py 实现了一个子 Agent 机制。你可以在主对话里调用 delegate_task(),启动一个独立的子 Agent 去完成某个任务。
子 Agent 有自己的对话历史、自己的终端会话、自己的工具集。它跑完后只把最终结果返回给父 Agent ,中间过程不会污染父 Agent 的上下文。
这个设计的价值在于:上下文隔离。
假设你在写代码,突然需要调研一个技术方案。如果在主对话里搜索、阅读文档、总结,会产生几十轮对话,把主对话的上下文撑爆。用子 Agent 的话,调研过程在子 Agent 里完成,主对话只收到一个总结。
我测试了一个场景:主 Agent 在实现一个功能,中途委托子 Agent 去调研三个开源库的 API 差异。子 Agent 跑了 15 轮对话,最后返回一个对比表格。主 Agent 的上下文只增加了 2 条消息。
配置系统: Profile 隔离
Hermes 支持多 Profile 。每个 Profile 有独立的配置文件、独立的对话历史、独立的 skill 目录。
这个设计的实际用途是:多身份切换。
比如你有一个 Profile 用于工作项目,配置了公司的 API key 和内部工具;另一个 Profile 用于个人项目,配置了自己的服务。两个 Profile 的对话历史完全隔离,不会串。
实现上很简单:通过 HERMES_HOME 环境变量切换根目录。hermes -p work chat 会把 HERMES_HOME 设为 ~/.hermes/profiles/work,所有文件操作都在这个目录下进行。
我见过有人用多个 Git 分支来管理不同项目的配置。 Hermes 的 Profile 机制更干净——不同 Profile 之间完全独立,不需要 Git 切换,不会有合并冲突。
一些不足
说完优点,也得说说问题。
第一,同步执行的性能瓶颈。如果你的任务需要并行调用多个 API , Hermes 的串行执行会很慢。虽然稳定,但慢是真的慢。
第二,缺少流式输出。 LLM 生成内容时, Hermes 是等全部生成完才返回。如果你在 CLI 里用,会有明显的等待感。虽然有 spinner 动画,但体验还是不如流式输出。
第三,错误恢复机制比较弱。如果某个工具调用失败, Hermes 会把错误信息返回给 LLM ,让 LLM 决定怎么办。但 LLM 经常会重试同样的调用,陷入循环。缺少一个框架层的重试策略。
第四,文档和社区还很薄弱。虽然代码质量不错,但缺少系统的文档。我翻源码翻了两天才搞清楚整体架构。如果有一份架构文档,上手会快很多。
适合谁用
Hermes 不是一个面向大众的产品。它更像是一个给开发者用的工具箱。
适合的场景: – 需要稳定的工具调用,不能容忍结果错位 – 需要长对话支持,对话轮次经常超过 50 轮 – 需要在多种环境下运行(本地、容器、云端) – 需要自定义复杂的 workflow
不适合的场景: – 需要高并发、低延迟的生产服务 – 需要开箱即用的 GUI 界面 – 团队里没有人能看懂 Python 代码
如果你只是想要一个”能用”的 AI 助手, ChatGPT 或 Claude 的官方客户端就够了。 Hermes 的价值在于:当你需要定制、需要稳定、需要控制的时候,它给了你足够的灵活性。
我现在用它做什么?写代码、调研技术方案、批量处理数据。那些需要 AI 和工具深度结合的任务。
它不完美,但在它擅长的领域,做得比大多数框架都扎实。
夜雨聆风