
做AI Agent开发的人大概率会在某个阶段突然发现自己看不懂自家项目了。模块多了、调用链长了、每个子任务都能跑但组合起来就是不对这时候最缺的不是代码是一张执行路径地图。Hermes Agent 就是让我在这件事上花了不少时间的项目它的子系统划分和任务执行路径在同类开源的 AI 助手项目里很有代表性。这篇文章不聊具体某一个函数的写法而是把 Hermes Agent 的架构总览拆开揉碎讲清楚它由哪些子系统组成、一条用户请求进来之后到底走了哪条执行路径以及你在部署配置桌面版、接入外部工具时最容易踩的坑。适合正在做 Agent 框架选型、想理解多子系统协作机制的开发者也适合刚接触 Hermes Agent 想快速建立整体认知的新手。1. 为什么需要一张执行路径地图1.1 单体脚本到子系统演进的必然性早期 AI Agent 大多是一个脚本从头写到尾读取用户输入、拼 Prompt、调模型接口、把结果打印出来。好处是逻辑清晰坏处是一旦要加记忆、加工具调用、加多轮对话管理代码就开始膨胀。你会在一个文件里看到网络请求、状态管理、工具分发、上下文裁剪全部混在一起改一个地方崩三个地方。Hermes Agent 这类项目走向子系统化本质上是被需求逼出来的。当 Agent 需要同时处理 CLI 交互、Bot 消息、桌面自动化操作还可能要挂载 Obsidian 这类外部知识库的时候所有逻辑塞在一个进程里已经不可能了。必须把决策和执行分开把记忆和对话分开把工具调用和工具注册分开。这就是架构总览存在的意义不是画一张漂亮的分层图自嗨而是让每个子系统有明确的边界、明确的职责和明确的通信方式。1.2 架构总览的观察视角我给 Hermes Agent 画执行路径地图时选了三个观察视角这三个视角也推荐给你看其他 Agent 项目时使用静态视角有哪些子系统、各自管什么。对应本文第 2 章。动态视角一个请求从进入到返回穿越了哪些子系统、谁先谁后。对应本文第 3 章。部署视角这些子系统在物理上怎么跑需要哪些外部依赖配置项在哪里生效。对应本文第 4 章。这三个视角缺一不可。只看静态结构你会发现子系统确实分了但不知道数据怎么流动只看动态流程你会知道先调 A 再调 B但不明白为什么 B 必须独立成一个服务只看部署配置你可能连 Agent 循环都不会转只会在 yaml 里改参数。真正的架构认知是三张图叠在一起看。2. 核心子系统逐个拆解2.1 Orchestrator决策中枢Orchestrator 是整个 Hermes Agent 的大脑它不做具体的事只做决定接下来做什么。所有用户输入首先抵达的就是这里。它手里捏着三样东西当前对话上下文、可用工具列表、Agent 循环状态机。很多人容易误解觉得 Orchestrator 就是调一次大模型然后把返回结果抛出去。实际上它干的事情精细得多。以一次工具调用为例Orchestrator 要决定的是当前这一步到底是回复用户还是去调用工具。如果调用工具用哪个工具、传什么参数。工具执行完返回结果之后Orchestrator 还要决定要不要根据这个结果继续调用下一个工具还是把综合结果整理成自然语言回给用户。这就涉及一个关键机制——工具调用协议。Hermes Agent 里Orchestrator 不与具体工具直接耦合它面向的是一个标准化的工具描述接口。每个工具被注册成一个 JSON Schema 描述名字、用途描述、参数结构。大模型根据这些描述自行决定要不要调用、怎么传参。Orchestrator 只负责把这个结构化请求从模型响应里解析出来然后路由给对应的工具执行器。这样设计的好处是新增一个工具不需要改 Orchestrator 的任何逻辑只需要在 Tool Registry 里注册一份 Schema。2.2 Memory 子系统短期与长期的层次划分Memory 子系统在 Hermes Agent 的架构里地位很高但也是很多人理解最容易出错的地方。它不是一个单一的存储组件而是分层的。短期上下文住在 Orchestrator 里本质就是拼进 Prompt 的那段对话记录。它的问题在于有长度上限模型上下文窗口是稀缺资源所以必须有人负责裁剪、摘要、丢弃。Hermes Agent 会维护一个滑动窗口窗口外的早期对话要么被丢弃要么被压缩成摘要。长期记忆才是 Memory 子系统的重头戏。它负责把历史对话里的重要信息沉淀下来在后续对话中按需检索回填。这部分在较新版本的 Hermes Agent 里可以对接向量数据库把每条记忆切块、做 embedding、存索引。检索的时候根据当前问题做相似度匹配把最相关的几条记忆注入 Prompt。我见过不少 Agent 项目把记忆做成全局变量所有对话历史一股脑存着然后全量塞进 Prompt。这种做法一旦对话轮数上去必然爆上下文窗口。Hermes Agent 的层次化设计实际是在提醒你记忆的价值在于对当前决策有用不在于全。无关的旧记忆不只是浪费 token还会干扰模型对当前任务的判断。2.3 Tool Registry工具注册中心Tool Registry 是连接 Agent 决策与外部能力的中枢。在 Hermes Agent 架构里工具不是写死在代码里的 if-else 分支而是以注册制的方式挂载到系统上。每个工具在注册时需要提供四类元信息名称、描述、参数 Schema、执行入口。名称和描述决定了模型能不能正确识别这个工具适合什么场景参数 Schema 决定了模型能不能生成合法调用执行入口才是真正跑逻辑的代码。这里有一个人工智能领域的经典问题模型返回的工具调用参数可能是错的。它不是数据库查询不会严格遵循 Schema可能多传一个没定义的字段、漏掉必填字段、甚至把布尔值传成字符串。所以 Tool Registry 还需要承担一层参数校验与容错的职责。我实际见过的情况是模型把一个用camelCase定义的参数名写成了snake_caseSchema 校验直接报错。后来在注册描述里强行加了注意参数名使用驼峰写法这类错误才明显减少。这类给模型写提示词的经验通常是文档里不会教你的。工具注册中心的另一个设计点是权限与范围。不是所有工具都该对模型无条件开放。文件系统操作、命令执行这类高风险工具在 Hermes Agent 里通常会有额外的确认机制或白名单控制。这个我后面讲到安全配置的时候再展开。2.4 上下文管理子系统上下文管理是 Agent 项目里真正决定能不能跑长久的子系统。Hermes Agent 对上下文的管理可以拆成两个动作组装与压缩。组装发生在每次请求发出之前。Orchestrator 把当前用户消息、短期对话窗口、检索到的长期记忆、工具定义、系统 Prompt 拼装成一个完整的大模型输入。这个过程要处理很多细节哪些内容优先保留、哪些工具定义太长了要精简描述、历史消息里的工具执行结果要不要保留。压缩发生在上下文即将溢出或者对话结束的时候。Hermes Agent 会启动一个压缩流程把当前对话的内容交给模型做摘要形成一条压缩记录存进长期记忆。下次再聊到这个话题检索系统可以把这条摘要捞出来作为背景信息重新注入。这里有一个常见的架构误区很多人觉得上下文管理就是把历史消息截断只留最近 N 条。直接截断会导致重要信息丢失而且模型完全感知不到更早发生的事情回答会变得失忆。Hermes Agent 这套摘要代替截断的思路本质上是把信息从原始形式转换成压缩形式保留的是语义而不是原文。两种做法在简单场景下差别不大但在长时间多轮协作场景里差距会非常明显。3. 执行路径主链路一条请求的完整旅程3.1 请求进入从消息到任务现在我们把视角从静态结构切到动态流程看一条用户请求在 Hermes Agent 里到底怎么走。起点是接入层。Hermes Agent 支持多种入口命令行直接输入、Bot 模式接收消息、桌面版图形界面以及较新版本里的 CUAComputer Use Agent模式——核心特征是能把指令转化为对桌面界面的自动化操作。不同的入口有不同的输入格式和消息预处理逻辑但它们最终都会统一成一个内部消息对象送进 Orchestrator。这个阶段有一个容易被忽略的操作指令清洗与意图预判。接入层会先做一些轻量处理比如去掉多余空白、识别明显是命令的还是普通对话的、判断是否携带了需要特殊处理的附件或文件路径。它不会做深度理解但能把明显异常或不完整的输入拦下来省得后续白白消耗一次模型调用。3.2 Agent 主循环决策与执行的反复迭代Hermes Agent 的核心执行引擎是一个循环不是一条直线。很多人以为流程是输入 - 调模型 - 输出实际在这里是输入 - 调模型 - 判断是最终答复还是工具调用 - 如果是工具调用执行工具把结果放回上下文 - 再调模型 - 再判断。这个循环会反复进行直到模型判定无需调用任何工具直接给出最终答复循环才终止。这个循环结构是所有 Agent 系统的灵魂也是最长出错的地方。我调试过的最难缠的问题基本都出在循环出口条件上——模型对要不要继续调用工具这件事给出了不符合预期的判断。比如一个简单的查天气请求模型明明已经拿到天气数据了还继续调了一个获取当前时间的工具因为工具结果里的时间戳让它觉得我应该把准确时间告诉用户。这正是架构设计的博弈点Agent 循环必须给模型足够的自由度让它能处理复杂的多步骤任务又必须用系统 Prompt、工具描述、最大迭代次数这些手段约束它避免无限循环。Hermes Agent 在参数层面对最大迭代步数做了硬限制防止模型陷入死循环。这个配置项不是摆设真实运行时确实会触发。3.3 工具调用与结果回填工具调用是 Agent 循环里信息密度最高的一环。当模型返回一个工具调用请求时Hermes Agent 的执行链路是这样的Orchestrator 从模型响应中解析出结构化调用参数。根据工具名在 Tool Registry 里查找对应的执行器。执行器校验参数、执行真实逻辑比如读写文件、查询数据库、调用外部 API。执行结果被包装成一个工具消息回填到上下文。带着这个新的上下文再次进入模型调用。这个流程里有一个值得注意的点工具执行结果不是原样塞回去的。Hermes Agent 会对结果做截断或摘要处理避免工具返回几万行日志直接撑爆上下文。像文件内容读取这种工具可能只回填前几百行像搜索结果的网页内容可能先剥离 HTML 标签再抽取正文。我踩过的一个真实场景是用一个读取文件工具读取了一份大型配置文件工具把整份文件内容都返回了直接占掉了大半上下文窗口。接下来模型面对用户的后续问题几乎处于没有余量思考的状态回答质量急剧下降。后来养成了习惯任何可能返回大块数据的工具都要在描述里明确只返回文件头部摘要或返回指定行范围。3.4 交互模式的分流路径Hermes Agent 的几种交互模式——CLI、Bot Mode、桌面版、CUA——本质上共享同一个 Agent 循环核心区别在于任务的输入形态和输出动作。CLI 模式最纯粹输入是文本输出是文本。Bot Mode 也是文本走天下区别在于它运行在消息平台上需要考虑异步消息处理、消息到达顺序、以及回复超时等问题。桌面版和 CUA 模式就复杂了Agent 的输出不再只是文本而可能是点击坐标输入文本到指定控件截取屏幕区域这类具体操作指令。CUA 模式的架构差异尤其明显。它需要一个额外的环境感知模块来理解当前桌面状态——比如读取屏幕内容、识别控件树、判断哪些按钮可用。这个模块的输出和普通对话上下文不同它表现的是界面结构而不是语言。所以 CUA 模式下上下文组装逻辑要同时处理语言信息和视觉/界面结构信息对 Prompt 的设计要求更高。这意味着你在选择交互模式时实际上是在选择不同的执行路径分支。同一个 Hermes Agent 内核在 CLI 下走的路径短、依赖少在 CUA 下走的路径长、需要额外的服务支撑。看架构图时不能只盯着主链路分支路径上的组件缺了特定模式就跑不起来。4. 部署与配置从源码到可用4.1 运行环境与安装选择Hermes Agent 的部署按使用场景大致可以分成三类每一类的复杂程度完全不同场景复杂度典型依赖纯 CLI 使用低Python 运行时、模型 API KeyBot Mode 接入消息平台中消息平台 Bot Token、异步任务队列桌面版 / CUA 模式高桌面环境权限、屏幕交互驱动、额外的服务组件如果你只是在本地跑一个命令行助手那基本只需要把项目克隆下来、安装依赖、配置好模型接口就能用。我建议新手从这里开始先把 Agent 循环跑通理解工具注册和调用的手感再往复杂的交互模式迁移。一上来就折腾桌面版很容易被环境问题淹没反而感受不到架构本身的设计思路。4.2 几个必须理解的配置项Hermes Agent 的配置文件有几个关键项它们直接影响执行路径属于不理解就在乱调的配置模型配置不只是选择模型型号还包括推理参数温度、最大 Token 数、上下文窗口上限、以及是否启用结构化输出用于保证工具调用能被正确解析。其中上下文窗口上限直接决定上下文管理子系统的压缩策略触发时机。记忆开关与存储后端是否启用长期记忆、用哪种存储基于文件还是向量数据库、检索时取回几条记忆。很多性能问题出在这里——检索回来的记忆不相关白白占用上下文或者关掉了记忆Agent 每次对话都像失忆患者。工具白名单默认启用哪些工具、哪些工具需要二次确认。这个配置是安全性的核心防线。我见到过有人在公网服务器上部署了 Agent工具列表里挂着 Shell 执行且没有开启任何确认机制。这在联网场景下是非常危险的状态相当于给任何能触达 Agent 的人开了一个命令执行入口。Agent 循环参数最大迭代步数、工具调用失败后的重试策略。这个参数我会建议保持一个偏保守的值宁可让复杂任务因步数不足拆成多轮人工引导也不要让 Agent 在循环里空转。4.3 接入 Obsidian 等外部知识库热搜词里 Obsidian 出现频率很高说明很多人想用 Hermes Agent 对接本地知识库。Obsidian 的本质是一个本地 Markdown 文件库所以接入 Hermes Agent 的路径是通过文件读取类工具直接读写 vault 目录或者通过检索类工具对 vault 生成索引后做语义搜索。文件读取方案思路最直接不需要额外服务。但要注意文件数量一大每次临时搜索文件成本很高。语义检索方案则需要一个向量化模块对 vault 里的所有 Markdown 文件做切块和 embedding存入向量库检索时再结合关键字过滤。两种方案各有取舍但我见过更多人最终选择了混合方案先按文件名和目录做一次粗过滤再对候选文件做语义检索。理由很简单——如果 vault 有几千个文件全量语义检索的延迟和资源消耗都不小先用路径规则缩小范围再在局部做深度匹配性价比高得多。这个接入过程也是理解 Hermes Agent 工具订阅制的好机会。你会发现你不需要改动 Agent 核心代码只需要注册一个指向 vault 目录的新工具或者配置一个检索工具的索引路径Agent 就学会了访问你的知识库。这就是工具注册中心设计的红利能力扩展与核心逻辑解耦。5. 实操中的架构问题排查与避坑记录5.1 从现象反推卡在哪一个子系统聊完架构最后集中说一下我在实际使用 Hermes Agent 过程中反复遇到的几类问题以及它们和架构的对应关系。排查的时候有一个很实用的原则先判断问题属于哪个子系统再动手修。比如症状是对话到一半突然感觉 Agent 失忆了完全不记得前面说过什么。这大概率不是模型问题而是上下文管理或记忆检索出了问题。优先检查短期上下文窗口是不是因为某次工具结果过大而被严重挤占或者长期记忆检索的相似度阈值设得太高什么东西都没捞回来。再比如症状是Agent 明明描述里有这个能力但就是不调用某个工具。这种情况往往出在 Tool Registry 的工具描述上。描述写得不清晰或者工具的参数 Schema 过于复杂模型宁愿自己硬答也不愿意调用。解决方式是简化工具描述把触发场景写明确必要时在描述里给一个当你需要 X 时请调用此工具的指令式语境。还有一类是工具调用了但执行结果明显不对。这种情况要往执行器那一层查看是不是参数在解析和校验阶段被篡改或拒绝了。很多时候模型生成的是一个合法但语义错误的参数比如把文件路径写成了相对路径而工具期望绝对路径。这种问题在开发时容易被忽略因为你自己调用工具时永远传的是正确参数一旦变成模型来传参边界情况就全暴露了。5.2 日志与可观测性给执行路径装上仪表盘最后一条建议也来自实战教训给 Hermes Agent 每一轮 Agent 循环加上清晰的日志输出。你不需要立刻搞一套完整的可观测性平台但至少要让每一次循环中下面几类信息能够看到模型输入大体由哪些片段组成用户消息、历史摘要、检索记忆、工具结果各自的大致长度。模型返回的类型是普通文本还是工具调用请求。如果是工具调用哪个工具、什么参数、执行耗时、返回结果截断后的样子。上下文压缩事件什么时候触发了压缩压缩前后的 Token 数变化。这些日志就是执行路径地图的实时仪表盘。我在调 Hermes Agent 类项目时很大一部分疑难问题最终都是靠翻这种循环日志定位的。没有日志时你面对的是一个黑盒——只知道输入和输出中间的一切全靠猜有了日志整个执行路径在每一跳的决策都被记录下来问题出在哪一环一目了然。这类日志可能是你配置 Hermes Agent 时最值得花时间的地方。配置文件里的其他性能参数可以慢慢试日志系统搭建好了后续所有问题排查的效率都会显著提升。从架构总览的角度来说Hermes Agent 并没有使用什么颠覆性的新技术它强在把各子系统的边界划得清楚让执行路径可以被理解、被追踪、被控制。一张地图在手改配置、加工具、换模型、排故障都有了方向感。这是我在这个项目里最大的收获也希望能帮你少走一些弯路。