Hermes Agent 深度解读

一、项目概述

Hermes Agent 是由 Nous Research 开发的一个全功能 AI Agent 框架,支持 CLI、Telegram、Discord、Slack、WhatsApp、Signal、Home Assistant 等多个平台。它不仅仅是一个聊天机器人,而是一个能实际执行任务的智能代理——可以写代码、操作文件、运行命令、浏览网页、管理定时任务、调用外部服务等。

项目核心代码约 5 万行 Python,包含约 3000 个测试,工具数量超过 40 个。


二、核心架构分层

┌─────────────────────────────────────────────────────┐
│                   用户交互层                          │
│  cli.py (CLI TUI)  │  gateway/run.py (多平台网关)     │
│  acp_adapter/ (VSCode/Zed 插件)    │  cron/ (定时)    │
├─────────────────────────────────────────────────────┤
│                   Agent 核心层                        │
│  run_agent.py → AIAgent 类(对话循环 + 工具调度)      │
│  agent/ 子包(prompt构建、上下文压缩、缓存、显示等)     │
├─────────────────────────────────────────────────────┤
│                   工具编排层                          │
│  model_tools.py(薄编排层)│ toolsets.py(工具集定义)  │
│  tools/registry.py(中央注册表)                      │
├─────────────────────────────────────────────────────┤
│                   工具实现层                          │
│  tools/*.py  每个文件一个工具,自动注册                  │
│  tools/environments/  终端后端(local/docker/ssh/modal)│
├─────────────────────────────────────────────────────┤
│                   持久化层                            │
│  hermes_state.py(SQLite + FTS5 全文搜索)             │
│  memory_tool / skills / config.yaml                   │
└─────────────────────────────────────────────────────┘

三、每个文件/模块的详细作用

3.1 核心文件

run_agent.py(~11600 行,项目最大的文件)

AIAgent 类的完整实现,是整个项目的引擎。关键职责:

  • 初始化阶段:解析配置、建立 LLM 客户端(支持 OpenRouter、Anthropic、OpenAI、AWS Bedrock 等多种 provider)、加载工具集、初始化上下文压缩器、内存系统、checkpoint 管理器
  • 对话循环:核心 loop——发送消息给 LLM → 如果有 tool_calls 则执行工具 → 把结果返回给 LLM → 重复直到 LLM 给出纯文本回复或达到最大迭代次数
  • 多 API 模式:自动检测并适配 chat_completions(OpenAI 兼容)、anthropic_messages(原生 Anthropic SDK)、codex_responses(OpenAI Responses API)、bedrock_converse(AWS Bedrock)
  • Provider 回退链:主 provider 遇到限流/过载时自动切换到备用 provider
  • Prompt 缓存:对 Claude 模型自动启用 Anthropic 的 prompt caching(system_and_3 策略),多轮对话输入成本降低约 75%
  • 上下文压缩:当接近模型上下文窗口限制时,自动压缩中间对话
  • 安全包装:SafeWriter 包装 stdout/stderr 防止管道断裂导致崩溃
  • 预算控制:IterationBudget 控制最大工具调用次数(默认 90)
toolsets.py(~700 行)

工具集定义系统。核心是 _HERMES_CORE_TOOLS 列表(定义所有核心工具)和 TOOLSETS 字典(将工具分组为 web、terminal、file、browser、skills 等类别)。支持工具集的嵌套组合。

model_tools.py(~560 行)

薄编排层,位于 registry 和 run_agent 之间。负责:

  • 导入所有工具模块触发自动注册(discover_builtin_tools()
  • 发现 MCP 工具和插件工具
  • 提供 get_tool_definitions() 按 toolset 过滤
  • 提供 handle_function_call() 分派工具调用
  • 管理异步桥接(_run_async)——解决 asyncio 事件生命周期问题
cli.py(~10200 行)

CLI 交互式终端界面。使用 Rich + prompt_toolkit 构建精美的 TUI:

  • 动态输入补全(slash 命令)
  • KawaiiSpinner 动画(API 调用时显示)
  • Skin 引擎(主题定制)
  • 管理所有 slash 命令(/model、/skills、/tools、/usage 等)
  • TUI 布局:固定输入区 + 滚动输出区
hermes_state.py(~1200 行)

SQLite 会话存储,替代了旧的 JSONL 文件方案:

  • WAL 模式支持并发读写
  • FTS5 虚拟表实现全文搜索
  • 压缩触发会话分裂(parent_session_id 链)
  • 随机抖动重试解决写竞争问题

3.2 agent/ 子包(Agent 内部组件)

文件 作用
prompt_builder.py 系统提示词组装——Agent 身份、平台提示、技能索引、上下文文件注入、提示词注入检测
context_compressor.py 自动上下文压缩——当对话接近窗口限制时,用便宜的辅助模型总结中间轮次,保护头部和尾部
prompt_caching.py Anthropic prompt caching 实现——system_and_3 策略(系统提示词 + 最近 3 条消息),4 个 cache_control 断点
auxiliary_client.py 辅助 LLM 客户端——用于视觉分析、网页提取、审批判断等辅助任务,独立于主模型
model_metadata.py 模型元数据管理——上下文长度、token 估算、价格信息,带 1 小时缓存
display.py KawaiiSpinner 动画、工具预览格式化、工具 emoji
skill_commands.py 技能斜杠命令(CLI/gateway 共享)
trajectory.py 对话轨迹保存(JSONL 格式)
memory_manager.py 内存提供者插件系统(支持 Honcho 等外部内存后端)
anthropic_adapter.py Anthropic 原生 SDK 适配层
usage_pricing.py 用量和费用估算
model_normalize.py 模型名称归一化
retry_utils.py 带抖动的退避重试
error_classifier.py API 错误分类(限流、过载、连接失败等)
redact.py 敏感信息脱敏
checkpoint_manager.py 文件系统 checkpoint(快照/回滚)

3.3 tools/ 目录(工具实现)

每个工具文件通过调用 registry.register() 在模块导入时自动注册:

文件 工具名 作用
registry.py - 中央注册表——ToolEntry + ToolRegistry,线程安全的工具元数据存储,支持 AST 扫描自动发现
file_tools.py read_file, write_file, patch, search_files 文件读写、模糊匹配替换、内容搜索。包含敏感路径保护、设备路径黑名单、重复读取检测
terminal_tool.py terminal 命令执行,支持多种后端(local/docker/ssh/modal/daytona/singularity)
process.py process 后台进程管理(启动/轮询/写入/关闭)
web_tools.py web_search, web_extract 网页搜索和内容提取(Parallel + Firecrawl)
browser_tool.py browser_*(12 个工具) 浏览器自动化(Browserbase/Firecrawl/browser-use 多 provider)
code_execution_tool.py execute_code 程序化工具调用(PTC)——让 LLM 写 Python 脚本批量调用工具,多步操作合并为一轮推理
delegate_tool.py delegate_task 子代理委派——创建隔离上下文的子 Agent,支持最多 3 个并行子代理
mcp_tool.py MCP 工具(动态) MCP(Model Context Protocol)客户端——连接外部 MCP 服务器,发现其工具并注册
mcp_oauth.py - MCP OAuth 认证
memory_tool.py memory 持久化内存(MEMORY.md + USER.md)
todo_tool.py todo 任务列表管理
session_search_tool.py session_search 历史会话搜索(基于 FTS5)
clarify_tool.py clarify 向用户提问(多选/开放)
cronjob_tools.py cronjob 定时任务管理
skills_hub.py skills_list, skill_view, skill_manage 技能系统——创建/查看/管理技能文档
tts_tool.py text_to_speech 文本转语音(Edge TTS / ElevenLabs / OpenAI / xAI)
vision_tools.py vision_analyze, image_generate 图像分析和生成
skills_sync.py - 技能同步
budget_config.py - 预算配置
fuzzy_match.py - 模糊匹配(用于 patch 工具的字符串匹配)
path_security.py - 路径安全检查
url_safety.py - URL 安全检查
tirith_security.py - 安全策略检查
osv_check.py - 开源漏洞检查
interrupt.py - 中断机制
approval.py - 危险命令检测
credential_files.py - 凭证文件管理
debug_helpers.py - 调试工具
ansi_strip.py - ANSI 转义码剥离
openrouter_client.py - OpenRouter 客户端封装
transcription_tools.py - 语音转录
tools/voice_mode.py - 语音模式
tools/mixture_of_agents_tool.py mixture_of_agents 多模型集成推理

3.4 tools/environments/ 目录(终端后端)

文件 作用
base.py 环境基类(抽象接口)
local.py 本地终端环境
docker.py Docker 容器后端
ssh.py SSH 远程后端
modal.py Modal 云 GPU 后端
managed_modal.py 托管 Modal 环境
daytona.py Daytona 沙箱后端
singularity.py Singularity 容器后端
file_sync.py 文件同步(本地与远程之间)
modal_utils.py Modal 工具函数

3.5 gateway/ 目录(消息平台网关)

文件 作用
run.py 网关主循环、斜杠命令处理、消息分发
session.py 会话存储——对话持久化
platforms/ 各平台适配器(Telegram、Discord、Slack、WhatsApp、Home Assistant、Signal、QQBot)

3.6 其他重要目录

目录/文件 作用
hermes_cli/ CLI 子命令和设置向导(main.py, config.py, commands.py, setup.py, skin_engine.py 等)
acp_adapter/ ACP 服务器(VS Code / Zed / JetBrains 编辑器集成)
cron/ 调度器(jobs.py, scheduler.py)
environments/ RL 训练环境(Atropos)
plugins/ 插件系统(内存提供者、上下文引擎等)
packaging/homebrew/ Homebrew 打包
batch_runner.py 并行批处理
hermes_constants.py 全局常量(路径、URL、版本等)

四、为什么速度这么快

Hermes Agent 的速度优势来自多个层面的优化,不是单一技巧的结果:

4.1 程序化工具调用(PTC)—— execute_code 工具

这是最大的速度优化。传统的 AI Agent 每执行一步操作都需要:

LLM 推理 → 工具调用 → 等待结果 → LLM 推理 → 下一个工具调用 → ...

每一步都是一次完整的 API 往返,延迟通常在 1-5 秒之间。

Hermes Agent 的 execute_code 工具让 LLM 写一个 Python 脚本,脚本中直接调用工具(通过 Unix Domain Socket RPC 或文件 RPC):

# LLM 一次性写出:
results = search_files("def handle_")
for match in results['matches']:
    content = read_file(match['path'])
    patch(match['path'], "old", "new")

这个脚本在子进程中运行,7 个工具(web_search, web_extract, read_file, write_file, search_files, patch, terminal)可以顺序执行而不需要回到 LLM。中间结果不进入上下文窗口。

效果:原本需要 6-10 轮 API 调用的任务,现在只需 1-2 轮。

4.2 并行工具调用

当 LLM 返回多个独立的工具调用时(如同时读取 3 个不同文件),Hermes Agent 会并行执行它们:

  • _PARALLEL_SAFE_TOOLS 定义了可安全并发的只读工具(read_file, search_files, web_search, web_extract 等)
  • _PATH_SCOPED_TOOLS 对文件工具做路径级冲突检测——不同路径可以并行
  • _NEVER_PARALLEL_TOOLS 定义绝对不能并发的工具(如 clarify)
  • 最多 8 个工作线程并发执行

4.3 Anthropic Prompt Caching

对 Claude 模型启用 system_and_3 缓存策略:

  • 系统提示词(不变的部分)被缓存
  • 最近 3 条非系统消息被缓存
  • 多轮对话中,大部分输入 token 命中缓存
  • 输入成本降低约 75%,同时缓存命中的 token 处理速度远快于全新 token

4.4 自动上下文压缩(Context Compressor)

当对话接近模型上下文窗口限制时:

  1. 先做廉价修剪:用规则替换旧的工具输出为简短摘要(无需 LLM 调用)
  2. 保护头部:系统提示词和前几条对话保留
  3. 保护尾部:最近的 ~20K token 保留(预算驱动)
  4. 用辅助模型总结中间部分:用便宜的快速模型做摘要
  5. 迭代更新:后续压缩时保留之前摘要中的待解决问题

这避免了频繁遇到上下文溢出,也避免了每次都重传大量历史。

4.5 子代理委派(Delegate Task)

对于独立子任务,可以创建隔离的子 Agent

  • 子 Agent 有独立的对话上下文(不携带父 Agent 的历史)
  • 独立的终端会话和工具集
  • 最多 3 个子代理并行执行
  • 父 Agent 的上下文只看到委派调用和最终摘要

这避免了长上下文的 token 浪费,也实现了真正的并行工作。

4.6 辅助模型分离

视觉分析、网页提取、审批判断等辅助任务使用独立的辅助模型(通常是更便宜的模型),不占用主模型的 token 预算和推理时间。

4.7 高效的异步桥接

model_tools.py 中的 _run_async 解决了 Python 异步事件循环的生命周期问题:

  • 主线程使用持久的事件循环(而非每次都 asyncio.run() 创建-销毁)
  • 工作线程使用线程本地的持久循环
  • 避免 “Event loop is closed” 错误和缓存客户端的重复初始化

4.8 智能的 Provider 路由

通过 OpenRouter 或直接连接多个 provider:

  • 自动选择最快/最便宜的 provider
  • 限流时自动回退到备用 provider
  • 不同任务使用不同模型(主任务用强模型,辅助任务用快模型)

4.9 SQLite 状态存储 + FTS5

会话数据存储在 SQLite 中而非 JSONL 文件:

  • WAL 模式支持并发
  • FTS5 全文索引实现毫秒级搜索
  • 随机抖动重试避免写竞争

五、为什么效果好

5.1 精心设计的系统提示词

  • Agent 身份:明确的角色定义和行为准则
  • 工具使用强制执行:对特定模型家族(GPT、Gemini、Gemma、Grok)注入额外的工具使用纪律指导
  • 平台适配提示:根据运行平台(CLI/Telegram/Discord)注入不同的格式化指导
  • 上下文文件注入:自动发现并注入 .hermes.mdAGENTS.mdSOUL.md.cursorrules 等项目级配置
  • 提示词注入防护:扫描上下文文件中的注入模式(“ignore previous instructions” 等)

5.2 工具设计哲学

  • 一个工具一个文件:职责清晰,易于维护
  • 自动注册:工具通过 registry.register() 自注册,不需要手动维护列表
  • 丰富的描述:每个工具的 schema 包含详细的描述和参数说明,帮助 LLM 正确使用
  • 错误恢复:工具调用失败时有清晰的错误信息反馈给 LLM
  • 安全保护:敏感路径保护、设备路径黑名单、危险命令检测

5.3 技能系统(Skills)

Skills 是可重用的专业知识和工作流文档:

  • 每个 skill 是一个包含 YAML frontmatter + Markdown 的目录
  • 支持引用文件、模板、脚本
  • Agent 被指导在完成复杂任务后自动创建 skill
  • 使用 skill 时发现过时或不完整,立即 patch 更新
  • 目前有 50+ 预置技能(GitHub、MCP、ML 模型、创意工具等)

5.4 持久化记忆

  • MEMORY.md 存储项目级记忆(环境事实、工具怪癖、工作流约定)
  • USER.md 存储用户级记忆(偏好、角色、沟通风格)
  • 每次对话自动注入相关记忆
  • 支持外部内存提供者插件(如 Honcho)

5.5 多平台一致性

CLI、Telegram、Discord、Slack、WhatsApp、Signal、Home Assistant 等平台共享同一套 Agent 核心,确保跨平台体验一致。

5.6 MCP 集成

通过 MCP(Model Context Protocol)可以连接任意外部 MCP 服务器,发现并使用其工具。这使得 Hermes Agent 的能力可以无限扩展。


六、数据流示例:用户输入 “帮我重构这个项目”

1. cli.py 接收用户输入 → 创建 AIAgent 实例
2. AIAgent.__init__():
   - 解析 config.yaml,确定模型/provider
   - 初始化 OpenAI/Anthropic 客户端
   - 加载工具定义(过滤启用的 toolset)
   - 构建系统提示词(身份 + 记忆 + 技能 + 上下文文件)
   - 初始化上下文压缩器、SQLite 存储、todo 存储
3. run_conversation() 主循环:
   a. 发送 [系统提示词 + 用户消息] 给 LLM
   b. LLM 返回 tool_calls: [search_files("TODO"), read_file("src/main.py")]
   c. 并行执行两个工具(因为都是只读文件操作)
   d. 把结果附加到消息列表
   e. 再次发送给 LLM
   f. LLM 返回 tool_calls: [execute_code(...)] — 一个 Python 脚本
   g. 在子进程中运行脚本,脚本内部调用 read_file/patch/terminal
   h. 脚本输出作为工具结果返回
   i. LLM 继续推理...
   j. 直到 LLM 返回纯文本(最终回复)
4. 回复展示给用户,会话保存到 SQLite

七、关键设计理念总结

  1. 模块化:每个关注点独立模块,通过注册表解耦
  2. 自动发现:工具自注册、MCP 动态发现、插件系统
  3. 多层优化:PTC 减少 API 往返、并行执行、prompt 缓存、上下文压缩
  4. 安全第一:路径保护、注入检测、凭证脱敏、危险命令识别
  5. 可扩展:plugin 系统、MCP 集成、memory provider、context engine 插件
  6. 生产就绪:~3000 测试、WAL 并发、随机抖动重试、SafeWriter 防崩溃
  7. 多模型支持:OpenRouter、Anthropic、OpenAI、Bedrock、Ollama、Copilot 等
  8. 多平台:CLI + 7 个消息平台 + ACP 编辑器集成
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐