Hermes Agent 不走各家官方 API,改走 TaoToken,企业还能照抄那套三层架构吗?
2026/9/17 19:42:18 网站建设 项目流程

翻 Hermes 的代码时,run_agent.py 里 AIAgent 那段主循环我看了不止一遍:组装 system prompt 和当前消息、调模型、模型发起 tool call 就当场执行、把工具结果塞回上下文、继续下一轮,直到模型不再调用工具才输出结论。这套「走一步、看结果、再决定下一步」的闭环不难理解,难的是企业把它搬进自己系统时,第一个闹别扭的往往不是工具层,而是模型入口。同一个 Agent 要接两家供应商,Key 存在哪、Base URL 填什么、模型名怎么对齐,三份配置各写各的,三层架构还没跑通,光模型接入就先把人拖住了。我的做法是把这一层收掉:先打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 创建一把 Key,再把 Hermes 的模型 Base URL 改成 https://taotoken.net/api,原来面向各家官方 API 的配置项就收敛成一个兼容通道。三层分离不用动,run_agent.py 主循环也不用动,改的只是它下面那层 client 从哪里取地址和密钥。

1. 从 run_agent.py 的主循环说起:三层分离里最先卡住的是模型接入

1.1 AIAgent 的循环到底循环了什么

Hermes 的中枢不在 CLI,而在 run_agent.py 里的 AIAgent。它的主循环没什么玄学:把 system prompt 和当前消息组装好,调用模型;模型如果返回 tool call,就立刻执行;执行结果不吞掉,原样塞回上下文;然后带着新的上下文再调一轮。循环退出条件是模型不再发起工具调用,直接把结论说出来。

很多人第一次读会以为这跟普通 ReAct 差不多,区别在于 Hermes 每一步都拿真实执行反馈重新喂回决策,而不是开局把计划写死再照单执行。这个差异在复杂任务里会被放大:同一条命令报错,预先编排好的流程只会继续往下走,而它会把报错当成本轮输入,重新判断下一步该做什么。这就是它给企业最值钱的启发,大脑层要闭环,不是流程要好看。

1.2 企业照抄时,卡点往往在模型接入而不是编排

企业要把这套主循环搬进自己系统,通常不是卡在「怎么循环」,而是卡在「模型从哪来」。一个中台可能同时服务几个部门,A 部门用这家模型,B 部门偏好另一家,预算还要分开算。每接一家,就要多一份 Key、多一个 Base URL、多一套模型名映射,run_agent.py 里每加一个分支,测试和排障成本就翻一倍。

原文在讲企业版搭法时把「模型路由和降级」放在第三阶段,其实更靠前的痛点是接入本身没有统一:只要 provider 的数量超过两个,配置就会先乱。把模型调用收成一个兼容通道,是让三层架构能尽早跑通的前提,不是锦上添花。先把出口统一,后面才有资格谈路由和降级。

2. 大脑层换供应商,肌肉层和神经层为什么不用跟着改

2.1 肌肉层管的是能力注册,跟模型从哪来无关

Hermes 的肌肉层不是一堆散装脚本。model_tools.py 在启动时集中导入 tools/ 下的模块,每个工具再通过 tools/registry.py 注册自己的 schema、handler、toolset 和可用条件。模型看到的不是「后端有一堆函数」,而是「当前场景下哪些能力可以被调用、参数长什么样」。

这层描述的是能力边界,不关心模型是这家还是那家。所以你把 Base URL 换掉,工具注册表不需要改一行:schema 还是那些 schema,handler 还是那些 handler,按场景裁剪 toolset 的逻辑照常生效。真正要确认的是新模型对 tool call 的 schema 支持是否到位,这属于模型选型问题,不是架构问题。

2.2 神经层管的是状态与边界,也不依赖供应商

神经层里最典型的是 hermes_state.py:会话状态落在 SQLite,开 WAL 让多读单写更稳,用 FTS5 让历史会话可以全文检索,messages_fts 通过 trigger 和消息表联动。另一块是 tools/delegate_tool.py 的委托机制,每个子 Agent 拿独立上下文、独立 task_id、独立终端会话,默认禁止递归委托、禁止直接写共享 memory。

这两块依赖的是「状态怎么存、边界怎么划」,和「模型由谁提供」没有耦合。换句话说,供应商差异只影响大脑层外面那圈调用接口,影响不到记忆结构和协作边界。这也是为什么统一通道之后,企业最容易慌的那部分其实可以稳住:你换的是模型出口,不是整套系统的骨架。

3. 把 Hermes 的模型接入收到 https://taotoken.net/api:两处改动

3.1 准备:在 TaoToken 上创建一把统一 Key

打开 TaoToken 注册账号,进控制台创建一把 API Key,这就是后面 Hermes 要读的 YOUR_API_KEY。模型 ID 不要凭记忆写,去 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 的模型广场看当时可用的列表,记下你要用的那个标识。这一步的意义在于:以后无论是给 Hermes 配模型,还是给别的执行端配模型,都是同一把 Key、同一个入口,换供应时只改模型 ID 和用量策略,不用重新走一遍注册和记账。

有人会问,既然要统一,为什么不直接把某家官方地址写进配置再包一层函数?可以,但包函数解决的是代码复用,解决不了 Key 和账期分散的问题。企业里真正烦的是每接一家就要新开一个账号、走一遍财务流程、单独看一份用量。统一通道把入口收在一处之后,模型 ID 变成一个可替换的值,切换成本从「接一个新供应商」降到「换一个字符串」。

3.2 .env 里只留 Base URL、Key 和模型 ID 三个变量

# Hermes Agent 运行前加载的环境变量 # Base URL 填 TaoToken 兼容通道,末尾不要加 /v1 HERMES_MODEL_BASE_URL=https://taotoken.net/api # Key 从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 创建 HERMES_MODEL_API_KEY=YOUR_API_KEY # 模型 ID 以模型广场当时列表为准,不要自己拼日期后缀 HERMES_MODEL_ID=YOUR_MODEL_ID

提示:Base URL 只需要写到 https://taotoken.net/api,末尾不要补 /v1。很多 OpenAI 兼容 SDK 会自己在后面拼路径,多写一层会直接给你 404。

这三行的排布有个讲究:Base URL 和 Key 是基础设施,模型 ID 是业务选择。前者一次配好基本不动,后者按任务换。把两类东西放在同一个文件里,是为了让「换模型」这件事看起来像一个配置改动,而不是一次代码发布。

3.3 run_agent.py 里的 client 初始化改成从环境变量取值

# run_agent.py 里 AIAgent 初始化模型 client 的部分 import os from openai import OpenAI client = OpenAI( # 统一走兼容通道,不写死任何一家官方地址 base_url=os.environ["HERMES_MODEL_BASE_URL"], # https://taotoken.net/api api_key=os.environ["HERMES_MODEL_API_KEY"], # YOUR_API_KEY ) def run_agent(messages, tools): while True: resp = client.chat.completions.create( model=os.environ["HERMES_MODEL_ID"], messages=messages, tools=tools, # schema 仍来自 tools/registry.py ) msg = resp.choices[0].message if not msg.tool_calls: return msg.content messages.append(msg) for call in msg.tool_calls: # handler 从 model_tools.py 的注册表里取,和模型来源无关 output = dispatch_registered_tool( call.function.name, call.function.arguments ) messages.append({ "role": "tool", "tool_call_id": call.id, "content": output, })

这段是示意,字段名按你仓库里实际的配置读取方式对齐即可。要改的只有两处:client 的 base_url 和 api_key 不再硬编码成某一家。主循环的五步一步没少,tool call 仍然走原来的注册表分发,唯一的变化是模型请求打到了同一个出口。

4. 切换模型时最容易顺手改坏的三处

4.1 run_agent.py 里的 prompt 组装不要因为换模型就重写

换掉模型之后总有人手痒,觉得新模型更强,顺手把 system prompt、工具说明、上下文裁剪策略一起重构。结果任务一旦跑歪,你根本分不清是模型换了还是 prompt 改了。更稳的做法是一次只动一个变量:这次只改 Base URL 和模型 ID,prompt 组装保持原样,等基线稳定后再单独做 prompt 实验。原文把 run_agent.py 的主循环称为中枢,中枢的价值就在于它足够稳定,别拿它当试验场。

4.2 hermes_state.py 的 frozen snapshot 不要改成每轮重注入

原文里长期记忆的做法是会话开始时把记忆快照注入 system prompt,中途继续写盘但不再反复改 system prompt,目的就是保住 prompt cache。换了上下文窗口更大的模型之后,很容易产生「那我每轮都重新注入一遍最新记忆」的冲动。这么改,成本会先涨,命中率反而可能掉,因为前缀一直在变,缓存全失效。

4.3 delegate_tool.py 的隔离别在「新模型更强」的错觉下放开

子 Agent 的独立上下文、独立 task_id、独立终端会话,以及默认禁止递归委托、禁止直接写共享 memory,这些限制和模型强弱无关,是协作不失控的前提。模型一换就把限制放开,短期看像是让系统更灵活,长期看是把上下文串味、权限串味、预算串味的老问题重新请回来。切供应商的时候,神经层的边界一动都别动。

5. 企业自建版 Hermes 五层里,模型治理放在哪

5.1 接入层统一入口,模型调用统一出口

原文给企业版排的五层是接入层、Agent 编排层、记忆层、技能层、知识库与治理层。接入层原本解决的是「人怎么进来」:企业微信、门户、OpenAPI、内部工单。照这个思路再往前推一步,模型调用也需要一个统一出口,解决的是「请求怎么出去」。

入口和出口都统一之后,编排层就不需要认识任何一家的 SDK 细节,只需要知道模型 ID 和这个兼容通道。这才是三层分离在企业里能落地的完整形态:大脑层负责想,肌肉层负责做,神经层负责记,模型出口负责把所有对外的调用收成一条线。

5.2 记忆层和技能层照原方案走,治理层补 Key 与用量

记忆还是那三层:偏好和执行元数据放关系型库,会话与操作日志放检索库,语义知识放向量库;技能还是用 Git 管版本、用元数据中心管权限和适用部门。这两层不需要因为换了模型出口而重新设计。

治理层要补的是和模型调用直接相关的部分:Key 的归属、调用量的统计、按部门或项目拆分的用量视图。因为调用出口从 N 个变成 1 个之后,审计日志里的模型调用记录可以和工具调用、委托记录挂在同一条时间线上,出了问题能顺着一次 run 把「谁发起、调了哪个模型、执行了哪些工具、花了多少」串起来。这些在多个官方入口并存时是很难对齐的。

6. 切完通道先验证这几件事

配置保存之后别急着跑长任务,先用同一把 Key 做两件小事。第一,去 TaoToken 模型对话 发一条普通消息,确认模型 ID 是列表里真实存在的,Base URL 也没填错。这一步排掉的是纯配置错误,成本最低。

第二,回到 Hermes 跑一个带工具调用的最小任务,比如让它读取一个本地文件再总结,重点看 tool call 能不能正常回灌、能不能触发第二轮。多轮工具调用是大脑层闭环的关键,如果第一轮就断,问题多半不在模型本身。

最后去 控制台 API Keys 看一下这次的调用有没有记上账,模型 ID 对不对。如果后面打算长期跑 Agent 任务,先看一眼 Coding Plan 的额度是否够用,别等跑到一半才发现配额见底。

7. 排障:401、来自 /v1 的 404,以及 tool schema 报错

最常见的第一个错是 401。它一般不是 Key 本身失效,而是环境变量没被读到:.env 放在项目根目录但启动脚本用了别的工作目录,或者用了 source 加载却没 export。排查时先打印一下 os.environ.get("HERMES_MODEL_API_KEY") 是否存在,再确认值没有多余空格和引号。

第二个是 404,而且报错里往往能看到路径被拼成了 /v1/chat/completions。原因就是 Base URL 多写了一段,把 https://taotoken.net/api 写成了带 /v1 的版本。改回来,只留 https://taotoken.net/api。

第三个是 tool call 相关的 schema 报错,典型信息是模型声称要调用的工具不在提供的列表里,或者参数结构对不上。这通常不是通道的问题,而是模型对工具 schema 的支持程度不同,或者工具名和 tools/registry.py 里注册的名字没对齐。换模型之后如果只在这类任务上出问题,优先对照注册表的 schema 检查,而不是怀疑 Key。

把这三类错分开看,排障就不会一上来就乱改配置:401 查环境变量,404 查 Base URL 末尾,schema 错查工具注册表。三个位置互不重叠,改动也互不牵连。

模型出口统一之后,Hermes 的三层分离才算真正可搬运。你要接着做的是把这次跑通的配置固化下来:Key 放在统一的地方管理,模型 ID 写进配置而不是散在代码里,调用记录挂在同一条审计线上。想先试模型就打开 TaoToken 模型对话 发一条消息,要长期跑就去看 Coding Plan,Key 在 控制台 API Keys 创建。后面如果你还要把 Claude Code 这类执行端接到同一把 Key 上,环境变量对照可以参考 接入文档。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询