00-Hermes 全局架构地图

发布时间:2026/7/8 4:38:25

00-Hermes 全局架构地图 一句话导读Hermes 是一个能长期运行、可恢复、可扩展的多平台 AI Agent 运行时本文聚焦其三大核心架构对话主循环、动态工具注册与会话持久化带你从源码层面理解一个生产级 Agent 系统是如何设计的。为什么值得读适用人群正在学习 AI Agent 系统设计、想从源码层面理解 Agent 运行时的开发者阅读收获你将理解 Hermes 如何把 Agent 从「单次对话」升级为「长期运行的生产系统」技术栈Python、SQLite、Mermaid架构图、多平台适配CLI/TUI/Gateway/APIHermes 全局架构地图文章目录为什么值得读Hermes 全局架构地图这篇先解决什么问题功能 1一次对话的主流程先讲人话源码入口关键源码工程实现失败路径和 Codex / Claude Code 的差异功能 2工具为什么不是一个静态列表先讲人话源码入口关键源码工程实现失败路径和 Codex / Claude Code 的差异功能 3会话为什么要进数据库先讲人话源码入口关键源码工程实现失败路径和 Codex / Claude Code 的差异总结与延伸阅读QA读 Hermes 第一眼应该看哪个文件https://github.com/teachershuang/Hermes-learn 文章下载在github如果可以请您点一个宝贵的star这篇先解决什么问题功能 1一次对话的主流程先讲人话一次对话不是“用户输入 - 模型回答”这么短。Hermes 会先准备上下文再调用模型。模型如果要求使用工具Hermes 会执行工具把结果放回消息列表再次调用模型。这个循环会一直走到模型给出最终回答或者达到迭代预算。主流程可以先画成这样是否用户输入CLI / TUI / Gateway / API ServerAIAgentPrompt Builder身份、历史、上下文、记忆、技能、工具定义Provider TransportOpenAI / Anthropic / Responses / Bedrock / 插件LLM模型是否返回 tool call?工具分发文件、终端、浏览器、Web、MCP、记忆、委派、Kanban工具结果最终回复SessionDB / Memory / Compression / Trajectory源码入口角色文件/符号说明Agent 门面run_agent.py中的AIAgent对外主入口保留稳定 API初始化agent/agent_init.py中的init_agent给AIAgent填充模型、工具、状态、回调等运行时字段对话循环agent/conversation_loop.py中的run_conversation处理模型调用、工具调用、停止条件和最终回复工具执行agent/agent_runtime_helpers.py中的invoke_tool从 agent loop 进入具体工具调用关键源码AIAgent的构造函数本身没有把初始化逻辑全写在类里而是转发给agent.agent_init.init_agentclassAIAgent:def__init__(self,base_url:strNone,api_key:strNone,provider:strNone,api_mode:strNone,model:str,max_iterations:int90,enabled_toolsets:List[str]None,disabled_toolsets:List[str]None,# ... 还有很多运行时参数):Forwarder - see agent.agent_init.init_agent.fromagent.agent_initimportinit_agent init_agent(self,base_urlbase_url,api_keyapi_key,providerprovider,api_modeapi_mode,modelmodel,max_iterationsmax_iterations,enabled_toolsetsenabled_toolsets,disabled_toolsetsdisabled_toolsets,# ...)这个片段很重要。它说明run_agent.py现在更像兼容层和门面层外部仍然使用AIAgent内部实现已经拆进agent/包。读 Hermes 时不要误以为run_agent.py一个文件就能解释全部逻辑。工程实现一次对话大致经过这些步骤CLI、TUI 或 Gateway 收到用户消息。上层创建或恢复一个AIAgent。AIAgent.run_conversation(...)进入agent/conversation_loop.py。Prompt Builder 准备系统提示、历史消息、上下文文件、记忆、技能和工具定义。Provider 适配层把请求发给具体模型。如果模型返回普通文本Hermes 结束本轮。如果模型返回 tool callHermes 执行工具把工具结果加入 messages。带着工具结果再次调用模型。本轮结束后消息进入 SessionDB必要时触发压缩、记忆或轨迹记录。先不要纠结每个细节。第一阶段只要抓住Hermes 的主循环是“模型调用”和“工具执行”交替推进。失败路径这个主流程里最常见的失败有几类模型返回空内容。模型返回损坏的 tool call arguments。工具执行失败。工具结果太长。上下文太长。Provider 报错或限流。用户中断任务。Hermes 在agent/里放了大量修复和降级逻辑。后面讲 agent loop 时会单独拆empty response recovery、tool guardrails、context compression、provider fallback。和 Codex / Claude Code 的差异Codex 和 Claude Code 更聚焦开发者工作区里的编码任务。它们当然也有工具调用、上下文和安全边界但产品形态更贴近“本地或云端代码助手”。Hermes 的主流程更宽。它要同时服务 CLI、TUI、消息平台、API server、定时任务和多 Agent 协作。也就是说Hermes 的 agent loop 不是孤立存在的它旁边长期挂着 SessionDB、Gateway、Memory、Skills、Cron、Kanban、MCP 和插件系统。功能 2工具为什么不是一个静态列表先讲人话很多小型 Agent 项目会写一个静态工具列表这里有read_file、那里有run_shell启动时一次性塞给模型。Hermes 没这么做。它有很多工具工具还能来自插件和 MCP。不同平台、不同配置、不同运行环境下可用工具也不一样。所以 Hermes 需要一个中心 registry让工具自己注册再由 toolsets 和可用性检查决定哪些工具暴露给模型。源码入口角色文件/符号说明工具注册中心tools/registry.py中的ToolRegistry保存工具 schema、handler、toolset 和检查函数工具发现和导出model_tools.py中的get_tool_definitions给模型生成本轮可见的工具定义工具调用分发model_tools.py中的handle_function_call接收模型 tool call转交 registry dispatch工具集解析toolsets.py中的resolve_toolset把用户启用的工具集展开成具体工具名关键源码工具 registry 的文件头已经把设计说得很清楚Central registry for all hermes-agent tools. Each tool file calls registry.register() at module level to declare its schema, handler, toolset membership, and availability check. model_tools.py queries the registry instead of maintaining its own parallel data structures. 再看ToolEntry的字段可以知道 Hermes 认为一个工具至少由这些东西组成classToolEntry:Metadata for a single registered tool.__slots__(name,toolset,schema,handler,check_fn,requires_env,is_async,description,emoji,max_result_size_chars,dynamic_schema_overrides,)这比“函数名 函数体”复杂得多。Hermes 关心的不只是能不能调用函数还关心属于哪个 toolset。schema 如何暴露给模型。handler 是同步还是异步。当前环境是否满足要求。工具结果最多多长。schema 是否要根据运行时配置动态调整。工程实现工具暴露给模型之前大致经过这条链tools/*.pyregistry.register(...)ToolRegistrytoolsets.resolve_toolsetmodel_tools.get_tool_definitions模型看到的 tools schema模型真的调用工具时则走另一条链模型返回 tool callmodel_tools.handle_function_callregistry.dispatch具体工具 handler工具结果字符串或结构化结果这个拆法有一个好处工具实现不用知道模型请求怎么发模型请求层也不用知道每个工具内部怎么跑。中间靠 registry 和model_tools.py接起来。失败路径工具系统的失败不只是 handler 抛异常。更麻烦的是这些情况工具所属环境不可用比如 Docker、浏览器、MCP server 没启动。工具 schema 太宽模型误用。工具结果太长挤爆上下文。同一工具重复失败模型陷入循环。文件或终端工具触发安全策略。所以 Hermes 在工具周围加了几层保护check_fn、toolset 暴露控制、结果长度限制、工具循环守卫、安全审批、路径和 URL 检查。后面的工具章节会逐个拆。和 Codex / Claude Code 的差异Codex 的工具面更依赖宿主环境。工具能做什么、能访问哪里通常由当前运行环境和 sandbox 直接定义。Claude Code 的工具更围绕本地开发流程读写文件、执行命令、理解项目上下文。Hermes 的工具层更像一个可扩展平台。它要同时接住内置工具、插件工具、MCP 工具还要能按平台、profile、toolset 和环境状态动态暴露。功能 3会话为什么要进数据库先讲人话如果只是做一个 demo消息存在内存里就够了。但 Hermes 要支持恢复会话、跨会话搜索、Gateway 长期运行、压缩后继续、分支、子 Agent、历史回忆。这些能力都要求状态落盘。所以 Hermes 使用 SQLite 做 session store。源码入口角色文件/符号说明会话数据库hermes_state.py中的SessionDB保存 session 元数据和 messages搜索hermes_state.py中的 FTS5 相关逻辑支持跨会话全文搜索会话搜索工具tools/session_search_tool.py让 Agent 可以搜索过去会话压缩关系hermes_state.py中的 parent session 逻辑表达压缩、分支、子 Agent 等关系关键源码hermes_state.py开头的设计说明值得记住 SQLite State Store for Hermes Agent. Provides persistent session storage with FTS5 full-text search, replacing the per-session JSONL file approach. Stores session metadata, full message history, and model configuration for CLI and gateway sessions. Key design decisions: - WAL mode for concurrent readers one writer (gateway multi-platform) - FTS5 virtual table for fast text search across all session messages - Compression-triggered session splitting via parent_session_id chains - Batch runner and RL trajectories are NOT stored here (separate systems) 这段说明了 Hermes 的状态层不是简单“存聊天记录”。它直接支撑几个上层功能多平台 Gateway 同时读写。/resume和历史会话恢复。session search。context compression 之后继续对话。分支和子 Agent 关系。工程实现可以把状态分成三类类型作用Session history保存完整对话和模型配置支持恢复和审计Memory保存跨会话长期信息比如用户偏好、事实、经验Compression summary长上下文压缩后的摘要用来让当前任务继续跑这三者都可能影响模型下一轮看到什么但目标不同。不要混在一起理解。失败路径状态层主要怕这些问题SQLite WAL 在某些文件系统上不可用。长期运行的 Gateway 并发读写。压缩、分支、子 Agent 导致 session parent chain 复杂。搜索输入可能不安全或过长。会话删除时误删分支或子会话。Hermes 在hermes_state.py里有不少保护逻辑比如 WAL fallback、FTS 查询限制、branch child 和 delegate child 的区分。后面讲 SessionDB 时再细拆。和 Codex / Claude Code 的差异Codex 的会话状态更贴近当前任务和工作区。Claude Code 也更围绕本地开发会话。Hermes 的状态层要支撑更长的生命周期它可能从 Telegram 收消息在云主机跑任务隔天被 cron 唤醒又从旧 session 搜索上下文。这个产品目标决定了它需要更重的状态系统。总结与延伸阅读核心要点回顾AIAgent是门面真正的初始化和对话循环已经拆到agent/学习时不要被run_agent.py一个文件困住。Hermes 的主循环是「模型调用 → 工具调用 → 结果回填 → 再次调用」关键在交替推进和状态管理。工具系统不是静态列表而是 Registry Toolsets Runtime Checks可动态适配多平台和环境。SessionDB 支撑长期运行不仅是「存聊天记录」更是会话恢复、压缩、搜索、分支等能力的基础。Hermes 与 Codex/Claude Code 的本质差异不在工具调用本身而在于其系统级 Agent 运行时定位。下一步学习建议深入阅读agent/conversation_loop.py中的循环控制和异常恢复逻辑仔细分析tools/registry.py的插件化设计和 MCP 集成理解hermes_state.py的 WAL 模式、FTS5 搜索和 Session 分支管理参考资源Hermes 项目主页AI Agent 系统设计最佳实践SQLite WAL 模式详解QA读 Hermes 第一眼应该看哪个文件先看run_agent.py的AIAgent但不要停在那里。马上跳到agent/agent_init.py和agent/conversation_loop.py再看tools/registry.py、model_tools.py、hermes_state.py。这几处连起来才是第一张地图。

相关新闻