当前位置: 首页 > news >正文

Hermes Agent 核心架构分析

Hermes Agent 核心架构分析

源码路径:/home/xc/.hermes/hermes-agent/
分析版本:v0.13.0 (May 2026)


一、整体架构

┌─────────────────────────────────────────────────────────────────────┐
│                        Hermes Agent                                  │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  cli.py  (~13,540 LOC)  /  ui-tui/ (Ink React)               │  │
│  │  HermesCLI — 交互式终端,prompt_toolkit / Ink 双前端          │  │
│  └────────────────────────────┬───────────────────────────────────┘  │
│                               │                                       │
│  ┌────────────────────────────▼───────────────────────────────────┐  │
│  │  run_agent.py  (~15,700 LOC)                                    │  │
│  │  AIAgent.run_conversation() — 核心对话循环                       │  │
│  │  while not done:                                                 │  │
│  │    resp = client.chat.completions.create(messages, tools)       │  │
│  │    for tool_call in resp.tool_calls:                             │  │
│  │      result = handle_function_call(tool_call.name, args)        │  │
│  │      messages.append(tool_result_message(result))               │  │
│  └────────────────────────────┬───────────────────────────────────┘  │
│                               │                                       │
│  ┌────────────────────────────▼───────────────────────────────────┐  │
│  │  model_tools.py  (~865 LOC)  — 工具编排层                        │  │
│  │  get_tool_definitions() / handle_function_call()               │  │
│  │  持久化 asyncio 事件循环(防 Event loop is closed 错误)        │  │
│  └────────────────────────────┬───────────────────────────────────┘  │
│                               │                                       │
│  ┌────────────────────────────▼───────────────────────────────────┐  │
│  │  tools/registry.py  (~563 LOC)  — 工具注册中心                   │  │
│  │  discover_builtin_tools() — AST 扫描自动发现                    │  │
│  │  registry.register() — 工具自注册                               │  │
│  └────────────────────────────┬───────────────────────────────────┘  │
│                               │                                       │
│  ┌────────────────────────────▼───────────────────────────────────┐  │
│  │  toolsets.py  (~855 LOC)  — 工具分组与别名                       │  │
│  │  _HERMES_CORE_TOOLS — 核心工具列表                              │  │
│  │  TOOLSETS["web"] / TOOLSETS["terminal"] / ...                   │  │
│  └────────────────────────────┬───────────────────────────────────┘  │
│                               │                                       │
│  ┌────────────────────────────▼───────────────────────────────────┐  │
│  │  tools/*.py  — ~70 个工具实现(自注册)                          │  │
│  │  terminal_tool / file_tools / web_tools / delegate_tool / ...   │  │
│  │  environments/ — local / ssh / docker / modal / daytona / ...   │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐    │
│  │  agent/  — Agent 内部模块                                     │    │
│  │  prompt_builder / context_compressor / memory_manager         │    │
│  │  anthropic_adapter / bedrock_adapter / gemini_native_adapter   │    │
│  │  skill_commands / skill_utils / skill_preprocessing           │    │
│  │  token_cost / rate_limit_tracker / retry_utils               │    │
│  └──────────────────────────────────────────────────────────────┘    │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐    │
│  │  hermes_state.py  (~2,966 LOC)  — SQLite + FTS5 会话存储     │    │
│  │  SessionDB — WAL 模式 / FTS5 全文搜索 / 压缩分割              │    │
│  └──────────────────────────────────────────────────────────────┘    │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐    │
│  │  gateway/  — 消息网关(多平台适配)                             │    │
│  │  run.py / session.py / platforms/ — telegram/discord/slack/... │    │
│  └──────────────────────────────────────────────────────────────┘    │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐    │
│  │  plugins/  — 插件系统                                          │    │
│  │  kanban / memory / model-providers / observability / ...      │    │
│  └──────────────────────────────────────────────────────────────┘    │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐    │
│  │  skills/  — 内置技能(~30 个领域技能)                          │    │
│  │  github / cnblogs / jupyter-live-kernel / dogfood / ...      │    │
│  └──────────────────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────────────┘

二、核心模块详解

2.1 AIAgent 核心循环(run_agent.py)

文件:~15,700 LOC,核心类 AIAgent

两个入口接口:

def chat(self, message: str) -> str:"""简单接口 — 返回最终响应字符串"""def run_conversation(self, user_message: str, system_message: str = None,conversation_history: list = None, task_id: str = None) -> dict:"""完整接口 — 返回 dict 含 final_response + messages"""

核心循环逻辑:

while (api_call_count < self.max_iterations and self.iteration_budget.remaining > 0) \or self._budget_grace_call:if self._interrupt_requested: breakresponse = client.chat.completions.create(model=model, messages=messages, tools=tool_schemas)if response.tool_calls:for tool_call in response.tool_calls:result = handle_function_call(tool_call.name, tool_call.args, task_id)messages.append(tool_result_message(result))api_call_count += 1else:return response.content

关键设计点:

  • 完全同步的循环,含 interrupt 检查 + budget 跟踪
  • OpenAI 格式消息:{"role": "system/user/assistant/tool", ...}
  • reasoning 内容存在 assistant_msg["reasoning"]
  • max_iterations=90(默认工具调用上限)
  • OpenAI SDK 延迟导入(避免 ~240ms 的 import 开销)

AIAgent.init 参数:
约 60 个参数,包含 base_url / api_key / provider / model / max_iterations / enabled_toolsets / disabled_toolsets / platform / session_id / credential_pool / iteration_budget / fallback_model 等。

2.2 工具编排层(model_tools.py)

文件:~865 LOC

公共 API:

get_tool_definitions(enabled_toolsets, disabled_toolsets, quiet_mode) -> list
handle_function_call(function_name, function_args, task_id, user_task) -> str
TOOL_TO_TOOLSET_MAP: dict   # 批量运行时用
get_available_toolsets() -> dict

asyncio 事件循环复用设计:

# 问题:asyncio.run() 每次创建并关闭循环
#     -> cached httpx/AsyncOpenAI 客户端在 GC 时报 "Event loop is closed"# 解决:持久化循环,主线程 + 每个 worker 线程各有一个
_tool_loop = None           # 主 CLI 线程
_worker_thread_local.loop    # delegate_task 线程池各用各的循环

这解决了长期运行的 CLI 或 gateway 进程中异步客户端的生命周期问题。

2.3 工具注册中心(tools/registry.py)

文件:~563 LOC,核心 ToolEntry

工具自注册机制:
每个工具文件在模块顶层调用 registry.register(),registry 通过 AST 扫描发现所有工具:

tools/registry.py  (无任何导入依赖)^
tools/*.py         (模块顶层调用 registry.register())^
model_tools.py     (导入 registry + 所有工具模块)^
run_agent.py / cli.py / batch_runner.py / environments/

AST 自动发现:

def _module_registers_tools(module_path: Path) -> bool:tree = ast.parse(source)# 只检查模块顶层语句,函数内的 helper 调用不误判return any(is_registry_register_call(stmt) for stmt in tree.body)

ToolEntry 元数据结构:

class ToolEntry:__slots__ = ("name", "toolset", "schema", "handler", "check_fn","requires_env", "is_async", "description", "emoji","max_result_size_chars", "dynamic_schema_overrides",)

check_fn TTL 缓存(30s):
check_fn 检查外部状态(Docker daemon / Modal SDK / playwright 等),缓存 30s 避免频繁探测,同时确保环境变量切换后 1-2 轮内生效。

动态 schema override:
dynamic_schema_overrides 字段是零参 callable,在每次 get_definitions() 时调用,用于运行时动态修改 schema(如 delegate_task 的描述反映用户当前的 max_concurrent_children 配置)。

2.4 工具分组与别名(toolsets.py)

文件:~855 LOC

核心工具列表 _HERMES_CORE_TOOLS(所有平台共享):

_HERMES_CORE_TOOLS = [# Web"web_search", "web_extract",# Terminal + process management"terminal", "process",# File manipulation"read_file", "write_file", "patch", "search_files",# Vision + image generation"vision_analyze", "image_generate",# Skills"skills_list", "skill_view", "skill_manage",# Browser automation"browser_navigate", "browser_snapshot", "browser_click", ...# Delegation"execute_code", "delegate_task",# Kanban"kanban_show", "kanban_list", "kanban_complete", ...# Computer use (macOS)"computer_use",
]

工具集定义示例:

TOOLSETS = {"web": {...},"terminal": {...},"file": {...},"vision": {...},"skills": {...},"browser": {...},"full": union of all above,"minimal": web + terminal + file only,
}

2.5 会话存储(hermes_state.py)

文件:~2,966 LOC,SessionDB

核心设计:

  • SQLite + WAL 模式(WAL = Write-Ahead Logging,并发读 + 单写)
  • FTS5 虚拟表:全文本搜索跨所有会话消息
  • 压缩触发会话分割:通过 parent_session_id 链管理
  • 会话来源标签:'cli' / 'telegram' / 'discord'

WAL 降级策略:
WAL 模式在网络文件系统(NFS / SMB / CIFS / WSL1)上不兼容,遇到 SQLITE_PROTOCOL 错误时自动降级到 journal_mode=DELETE,牺牲并发换可靠性。

Schema 版本: SCHEMA_VERSION = 11

2.6 CLI(cli.py)

文件:~13,540 LOC,HermesCLI

依赖:

  • Rich — banner / panels 渲染
  • prompt_toolkit — 带自动补全的交互式输入

核心机制:

  • KawaiiSpinneragent/display.py)— API 调用时的动画表情 + 活动日志
  • Skin enginehermes_cli/skin_engine.py)— 数据驱动的 CLI 主题定制
  • Slash 命令注册表hermes_cli/commands.py)— 单一 COMMAND_REGISTRY,CLI / Gateway / Telegram / Slack / autocomplete 自动同步

Slash 命令注入方式:
agent/skill_commands.py 扫描 ~/.hermes/skills/,注入为 user message(而非 system prompt),保留 prompt 缓存效益。

2.7 网关(gateway/)

进程模型:

gateway/run.py        — 网关主进程
gateway/session.py   — 会话上下文
gateway/platforms/    — telegram / discord / slack / whatsapp / signal / matrix / ...
gateway/builtin_hooks/ — 扩展钩子

多平台适配器架构:
每个平台(telegram / discord 等)是一个 adapter,平台无关的逻辑在 run.py / session.py 中统一处理。

2.8 Agent 内部模块(agent/)

约 50+ 个文件,核心子模块:

模块 职责
anthropic_adapter.py / bedrock_adapter.py / gemini_native_adapter.py 多模型提供方适配
prompt_builder.py 系统提示词构建
context_compressor.py 上下文压缩(处理超长会话)
memory_manager.py 记忆管理
skill_commands.py Skill 命令扫描和注入
skill_utils.py / skill_preprocessing.py Skill 工具函数
token_cost.py / usage_pricing.py Token 成本计算
rate_limit_tracker.py 速率限制跟踪
retry_utils.py 重试逻辑
trajectory.py 轨迹记录
checkpoint_manager.py 检查点管理
credential_pool.py 凭据池管理

2.9 插件系统(plugins/)

插件 职责
kanban/ 多 Agent 看板协调
memory/ 记忆提供方插件(mem0 / supermemory / ...)
model-providers/ 推理后端插件(openrouter / anthropic / gmi / ...)
observability/ 指标 / 追踪 / 日志
image_gen/ 图像生成提供方
spotify/ Spotify 集成
teams_pipeline/ Teams 会议摘要流水线
hermes-achievements/ 游戏化成就追踪
disk-cleanup/ 磁盘清理

2.10 技能系统(skills/)

Skills 是 Hermes Agent 的知识模块系统:

  • 每个 Skill 有一个 SKILL.md 定义接口和行为
  • Skill 文件存储在 ~/.hermes/skills/
  • Skill 可以在 cronjob 中加载,跨会话持久运行
  • 内置约 30 个技能,涵盖 github / cnblogs / jupyter / dogfood / autonomous-ai-agents 等

三、工具执行环境(tools/environments/)

环境 说明
local.py 本地 shell 执行
ssh.py 远程 SSH 执行
docker.py Docker 容器执行
modal.py Modal 云端执行
daytona.py Daytona 云端沙箱
managed_modal.py Modal 托管环境
singularity.py Singularity 容器
vercel_sandbox.py Vercel 沙箱

四、TUI 架构(ui-tui/ + tui_gateway/)

hermes --tui└─ Node (Ink React)  ──stdio JSON-RPC──  Python (tui_gateway)│                                    └─ AIAgent + tools + sessions└─ 渲染 transcript / composer / prompts / activity

TypeScript 掌控屏幕渲染,Python 掌控会话、工具和模型调用。
传输协议:newline-delimited JSON-RPC over stdio。


五、关键设计哲学

1. 自注册工具模式

工具不需要在中心配置文件声明——每个工具文件在模块顶层调用 registry.register(),registry 通过 AST 扫描自动发现。新增工具只需创建新文件,无需修改任何中心文件。

2. 零循环导入设计

tools/registry.py  →  无从任何模块导入
tools/*.py        →  只从 registry.py 导入
model_tools.py    →  从 registry + toolsets 导入
run_agent.py      →  从 model_tools 导入

禁止反向依赖,保证工具系统完全解耦。

3. 事件循环复用

asyncio 循环不在每次调用时创建和销毁,而是在主线程和每个 worker 线程中持久化,避免异步客户端在循环关闭后报错。

4. 单一命令注册表

所有 slash 命令在一个 COMMAND_REGISTRY 中定义,CLI / Gateway / Telegram / Slack / autocomplete 自动从同一数据源派生,无需多处修改。

5. Skill 作为知识模块

Skill 不是硬编码逻辑,而是声明式的 SKILL.md,可被 cronjob 加载、跨会话持久化,支持版本管理和动态更新。


六、关键文件速查

文件 LOC 职责
run_agent.py ~15,700 AIAgent 核心对话循环
cli.py ~13,540 HermesCLI 交互式终端
model_tools.py ~865 工具编排层
tools/registry.py ~563 工具注册中心(AST 发现)
toolsets.py ~855 工具分组与别名
hermes_state.py ~2,966 SQLite + FTS5 会话存储
hermes_constants.py get_hermes_home() 路径管理
gateway/run.py 消息网关主进程
gateway/session.py 会话上下文
gateway/platforms/ ~20+ 平台适配器
agent/ ~50 文件 Agent 内部模块
plugins/ 插件系统
tools/ ~70 文件 ~70 个工具实现
tools/environments/ 8 种终端执行环境
hermes_cli/ CLI 子命令、皮肤引擎、命令注册表
ui-tui/ Ink React TUI 前端
tui_gateway/ TUI JSON-RPC 后端
AGENTS.md 开发者指南
http://www.jsqmd.com/news/810070/

相关文章:

  • 2026国内甲醛检测机构推荐及服务解析 - 品牌排行榜
  • Adobe-GenP 3.0:三步解锁Adobe全系列创意软件的终极指南
  • 3分钟快速上手:AMD Ryzen调试神器SMUDebugTool完整使用指南
  • 2026年6大主流CRM厂商深度评测:功能与性价比解析 - Blue_dou
  • 2026风口风阀厂家推荐:技术与应用场景解析 - 品牌排行榜
  • 从AstrBot到Nebula:深度定制聊天机器人框架的架构演进与实践
  • 【invt】【威纶通触摸屏】深圳英威腾CHH100高压变频器监控系统V3.12触摸屏密码
  • 一站式自动化工具OpenCLI,收获19.3k Star
  • 如何深度掌控AMD锐龙性能:Ryzen SDT调试工具终极指南
  • 解决 Claude Code 访问不稳定与 Token 不足的 Taotoken 替代方案
  • 为Claude Code配置Taotoken密钥解决封号与Token不足困扰
  • Python新闻追踪器:基于网络爬虫与关键词过滤的个性化信息聚合工具
  • 1000元加油充值卡回收价格明细,新手不担心吃亏 - 淘淘收小程序
  • 2026石英传感器十大品牌出炉,广州晶石石英传感器凭硬实力上榜 - 品牌速递
  • 2026高温高压设备集成有资质公司推荐:行业实力厂商盘点 - 品牌2025
  • Dify-WebUI:低代码构建AI应用的Web界面实战指南
  • PCIe ATS实战:从协议原理到性能优化与安全考量
  • 供应链韧性构建:从需求预测到库存策略的黑五大促实战指南
  • 390万买台“高达”开上路?王兴兴这次真的坐进去了!
  • ESP8266+STM32远程控制实战:如何通过华为云中转指令与数据
  • 2026年深圳纯直营驾培避坑指南:从C1/C2快速拿证到智驾陪驾一站式闭环 - 企业名录优选推荐
  • Python导入的‘隐形’陷阱:除了循环导入,这些`import`写法也在悄悄拖慢你的项目
  • 值得信赖的选择!广州晶石石英传感器,服务全国超千家企业 - 品牌速递
  • 多模态大语言模型(MLLM)核心架构、关键技术路径与实战指南
  • 2026七类CRM硬核横评:全链路业务协同与数据智能解析 - Blue_dou
  • 本地项目从0到1(AI协作实操指南)
  • 2026年西藏镀锌角钢、工字钢采购指南:源头直供降本秘诀 - 年度推荐企业名录
  • Cortex-R52中断控制器架构与虚拟化技术解析
  • AI时代,我们到底在焦虑什么
  • 2026年5月空气压力波治疗仪品牌TOP3榜单|供应商精选 - 品牌推荐大师1