1. 为什么我要把 Hermes 和 OpenClaw 放在同一个 Key 通道下跑Hermes 和 OpenClaw 这两个 Agent 框架最近被讨论得很多但大多数对比停留在“支持哪些模型、有多少工具、能不能多 Agent”这种功能清单层面。真正决定一个 Agent 系统能不能上生产的其实是 Agent Loop 本身——也就是“推理→调用工具→拿回结果→再推理”这个循环怎么调度、怎么管上下文、怎么在出错时兜底。我这次做的事情很具体把两个框架都接到同一个 TaoToken 统一 Key/API 通道上跑同一个任务然后从源码层面看它们的循环到底差在哪。先说清楚这两个项目是什么、适合谁。Hermes 是 Nous Research 出的 Python Agent 框架定位是“在 OpenClaw 基础上补齐记忆短板”内置跨 session 持久记忆、技能自动生成、Agent Tree 子任务OpenClaw 是更早出现的 TypeScript 项目定位是“让助手在真实电脑上跑真实任务”强项是多消息平台接入和 Runtime 稳定性。如果你是想研究 Agent Loop 内部机制、或者要选一个框架做长期编码/Agent 任务这篇的对比和复现步骤都能直接用。我实测下来最大的感受是两者都实现了同一套 ReAct 循环骨架但 Hermes 把复杂度放在了“Agent 自身能力”记忆、技能、迭代预算、工具护栏OpenClaw 把复杂度放在了“运行环境”会话串行化、Run 生命周期、Hook 拦截、多通道。理解这个分野比记任何功能表都重要。下面我会先讲怎么用 TaoToken 统一 Key 把两个框架都配起来再给两套可复制的最小复现脚本然后逐步验证 Agent Loop 各阶段行为最后对照真实报错做排查。全程不需要你去折腾网络环境TaoToken 的 API 地址直接填就行。2. TaoToken 统一 Key 通道一次配置两个框架共用这一章是前置准备。核心思路是Hermes 和 OpenClaw 都支持自定义 OpenAI 兼容的 Base URL所以只要把两者的 LLM 客户端都指向 TaoToken 的 API 地址用同一个 Key就能在完全一致的模型通道下对比 Agent Loop 行为排除“模型不同导致结果不同”的干扰。2.1 先拿 Key 和确认接入信息打开 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后进控制台 https://taotoken.net/console 创建 API Key。接入文档在 https://taotoken.net/doc API 基址是 https://taotoken.net/api 注意这个地址不带任何查询参数。你需要记下三件套后面两个框架都要用配置项值说明Base URLhttps://taotoken.net/apiOpenAI 兼容端点两个框架都填这个API Keysk-你的Key控制台生成两个框架共用同一个Model ID你选的模型名建议两个框架填同一个保证对比公平注意Base URL 末尾不要多加/v1TaoToken 的兼容层会自动处理路径。如果你填了/v1出现 404先去掉再试。2.2 Hermes 侧的环境配置Hermes 是 Python 项目安装方式官方给的是 Shell Installer。我建议直接用虚拟环境装避免污染系统 Pythonpython3 -m venv ~/.venvs/hermes source ~/.venvs/hermes/bin/activate pip install --upgrade pip # 按官方 installer 或 pip 安装 hermes-agent pip install hermes-agent装完后Hermes 的模型配置走的是它自己的auxiliary_client.py抽象层支持从环境变量或配置文件读取。最省事的方式是写一个config.yaml放在项目根目录# ~/hermes-demo/config.yaml llm: provider: openai_compatible base_url: https://taotoken.net/api api_key: sk-你的Key model: 你的模型ID api_mode: chat_completions # Hermes 支持 4 级自动检测这里显式指定 agent: max_iterations: 90 # 父 Agent 默认 90 hard_stop_enabled: true # 开启工具护栏的硬中断 delegation: max_iterations: 50 # 子 Agent 默认 50Hermes 的model_metadata.py会从base_url自动推断 providerhttps://taotoken.net/api不在它内置的 30 条_URL_TO_PROVIDER映射里所以会走通用 OpenAI 兼容分支这没问题。如果你发现它把上下文长度探测成了很小的值可以在配置里显式写context_length: 128000覆盖。2.3 OpenClaw 侧的环境配置OpenClaw 是 Node.js 项目要求 Node 22。全局安装node -v # 确认 22 npm install -g openclawOpenClaw 的模型配置在~/.openclaw/config.json或项目级openclaw.config.json。它的pi-ai层支持多 Provider 抽象OpenAI 兼容端点走openai-completions路由{ providers: { taotoken: { api: openai-completions, baseUrl: https://taotoken.net/api, apiKey: sk-你的Key, models: { 你的模型ID: { id: 你的模型ID, contextWindow: 128000 } } } }, defaultProvider: taotoken, defaultModel: 你的模型ID, timeoutMs: 600000 }注意timeoutMs默认是 600000600 秒这是 OpenClaw 的硬超时不是 48 小时。如果你跑长任务记得调大。2.4 用 CC Switch 管理两套配置可选但推荐如果你同时装了 Claude Code、Cline 这类工具配置会互相打架。我习惯用 CC Switch 做多环境切换把 TaoToken 的三件套存成一个 profile{ name: taotoken, baseUrl: https://taotoken.net/api, apiKey: sk-你的Key, model: 你的模型ID }这样 Hermes、OpenClaw、Cline MCP 都能引用同一份 Base URL Key Model ID改一处全生效。Cline 的 MCP 配置里也是填这三个字段Codex 的auth.json同理格式是{ OPENAI_BASE_URL: https://taotoken.net/api, OPENAI_API_KEY: sk-你的Key, OPENAI_MODEL: 你的模型ID }三件套到齐两个框架就都在同一条通道上了。3. 可复制的最小复现脚本同一任务跑两个框架这一章给两套能直接跑的脚本任务是同一个让 Agent 读取当前目录的文件列表统计.py文件数量然后把结果写进result.txt。这个任务足够小但会触发“工具调用→观察→再推理→写文件”完整循环适合观察 Agent Loop 各阶段。3.1 Hermes 最小复现脚本Hermes 的主入口是AIAgent类位于run_agent.py。核心调用是agent.chat()或agent.run_conversation()。下面这个脚本我实测能跑通# hermes_demo.py import os from hermes.agent.run_agent import AIAgent def main(): agent AIAgent( config_path./config.yaml, workspace_diros.getcwd(), ) task ( 列出当前目录所有文件统计其中 .py 文件的数量 然后把数量写入 result.txt格式为 py_filesN。 必须真实调用工具不要凭空回答。 ) # chat() 是阻塞式内部是同步 while 循环 final agent.chat(task) print( FINAL ) print(final) if __name__ __main__: main()跑之前确认config.yaml里的 Key 和模型填好了。执行source ~/.venvs/hermes/bin/activate cd ~/hermes-demo python hermes_demo.py你会看到 Hermes 的display.py打印出 spinner、工具预览和 diff 渲染。它内部走的是_interruptible_api_call()在后台线程发起 HTTP主线程wait响应、interrupt_event或超时。工具调用如果命中_PARALLEL_SAFE_TOOLS比如read_file、search_files会走ThreadPoolExecutor最多 8 线程并发执行结果按原始顺序重排。3.2 OpenClaw 最小复现脚本OpenClaw 的主入口是runEmbeddedPiAgent()位于src/agents/pi-embedded-runner/run.ts。它立即返回{ runId, acceptedAt }最终结果通过agent.waitRPC 轮询lifecycle end事件拿。用 Node 脚本调用// openclaw_demo.mjs import { runEmbeddedPiAgent } from openclaw/agents/pi-embedded-runner/run.js; import { randomUUID } from node:crypto; const sessionId randomUUID(); const sessionKey demo-session; const handle await runEmbeddedPiAgent({ sessionId, sessionKey, sessionFile: ./sessions/${sessionId}.jsonl, workspaceDir: process.cwd(), agentDir: ./agent, config: {}, // 从 ~/.openclaw/config.json 读取 prompt: 列出当前目录所有文件统计 .py 文件数量写入 result.txt格式 py_filesN。必须真实调用工具。, timeoutMs: 600000, runId: randomUUID(), provider: taotoken, model: 你的模型ID, }); console.log(accepted:, handle); // 轮询等待 lifecycle end const result await waitForRun(sessionId); console.log( FINAL ); console.log(result); async function waitForRun(sid) { // 实际用 agent.wait RPC这里简化为轮询 session 文件 const fs await import(node:fs); const path ./sessions/${sid}.jsonl; for (let i 0; i 600; i) { if (fs.existsSync(path)) { const lines fs.readFileSync(path, utf8).trim().split(\n); const last JSON.parse(lines[lines.length - 1]); if (last.type lifecycle last.phase end) { return last.payload; } } await new Promise((r) setTimeout(r, 1000)); } throw new Error(timeout waiting for run); }执行cd ~/openclaw-demo node openclaw_demo.mjsOpenClaw 内部走的是异步事件流pi-agent-core触发工具调用经过before_tool_callHook可{ block: true }终止、Exec Approval 检查危险 bash 命令需确认执行后发tool start/update/end事件最后tool_result_persistHook 落盘前做最后变换写入 JSONL 转录带会话写锁保护。3.3 两套脚本的关键差异对照维度HermesOpenClaw入口agent.chat()阻塞runEmbeddedPiAgent()立即返回结果获取函数返回值agent.waitRPC 轮询 lifecycle end循环模型同步 while 可中断 HTTP异步事件流工具并发_should_parallelize_tool_batch() ThreadPool(8)事件化异步原生落盘session 持久化JSONL 转录 会话写锁跑完两个脚本你应该能在各自目录看到result.txt内容都是py_filesN。如果数字对不上说明工具调用没真正执行往下看排查章节。4. 逐步验证 Agent Loop 各阶段行为光跑通不够这一章给你一份操作清单逐阶段验证循环行为。我按 ReAct 的五个阶段拆Prompt 组装、LLM 调用、工具执行、观察回填、最终生成。4.1 验证 Prompt 组装阶段Hermes 的 Prompt 组装在agent/prompt_builder.py是“砖块式”的DEFAULT_AGENT_IDENTITY、MEMORY_GUIDANCE、SKILLS_GUIDANCE、SESSION_SEARCH_GUIDANCE、TOOL_USE_ENFORCEMENT_GUIDANCE、TASK_COMPLETION_GUIDANCE按需拼接。它还会针对不同模型品牌注入专项指导TOOL_USE_ENFORCEMENT_MODELS里列了gpt、codex、gemini、gemma、grok、glm、qwen、deepseek——这些模型需要额外的“必须用工具别只说不做”提示。验证方法在 Hermes 里加一行打印看最终 system promptprint(agent.build_system_prompt()[:2000])OpenClaw 的 Prompt 是分层注入SOUL.md→AGENTS.md→ Skills →TOOLS.md→ runtime context模板化、文件和 prompt 分开管理。验证方法看./agent/目录下的文件是否被拼进 prompt。注意Hermes 在加载AGENTS.md/HERMES.md前会做注入扫描_scan_context_content()命中威胁模式会直接[BLOCKED: ...]不加载。OpenClaw 没有这层安全扫描这是 Hermes 的一个明显差异点。4.2 验证 LLM 调用与中断机制Hermes 的_interruptible_api_call()在agent/chat_completion_helpers.py用后台线程发 HTTP主线程等响应、中断事件或超时还带 stale-call 检测。验证在任务跑到一半时按 CtrlC看它是否能干净中断而不是卡死。OpenClaw 的 LLM 调用在pi-ai层统一 stream 事件text_delta/thinking_delta/done。验证观察终端是否实时吐出 token 流而不是等全部生成完才显示。4.3 验证工具执行与并发这是两者差异最大的地方。Hermes 的并发判断逻辑在agent/tool_dispatch_helpers.py_NEVER_PARALLEL_TOOLS frozenset({clarify}) _PARALLEL_SAFE_TOOLS frozenset({ ha_get_state, ha_list_entities, ha_list_services, read_file, search_files, session_search, skill_view, skills_list, vision_analyze, web_extract, web_search, }) _PATH_SCOPED_TOOLS frozenset({read_file, write_file, patch})_should_parallelize_tool_batch()会检查路径是否重叠重叠的read_file/write_file/patch不并发。验证让 Agent 同时读三个不同文件看是否并发同时写同一个文件看是否串行。OpenClaw 的工具执行是事件化的before_tool_callHook 可以{ block: true }终止{ block: false }是空操作不清除已有阻止。验证写一个 Hook 拦截terminal工具看 Agent 是否收到阻止并改变策略。4.4 验证观察回填与上下文管理Hermes 的上下文压缩是双层Agent 层在 context 50% 时预检压缩先 flush Memory 到磁盘MEMORY.md/USER.mdGateway 层在 context 85% 时触发ContextCompressor.compress()摘要中间轮次保留末尾protect_last_n默认 20条工具调用对保持完整生成新 session lineage ID。OpenClaw 是单层触发before_compaction/after_compactionHook 可观测压缩算法在pi-coding-agent层可能触发 Agent 重试并重置内存 buffer 避免重复。验证方法构造一个长对话比如让它连续读 30 个文件观察压缩触发时机和保留内容。Hermes 的 8 字段结构化摘要Goal / Constraints / Progress / Key Decisions / Relevant Files / Next Steps / Critical Context比 OpenClaw 的通用摘要更细。4.5 验证迭代预算与护栏Hermes 独有agent/iteration_budget.py线程安全计数器父 Agent 默认 90 次子 Agent 默认 50 次。用完时注入 system message 提示尽快结束而不是直接截断。refund()只在execute_code成功时调用防止 Agent 只靠 LLM 推理而不实际执行。工具护栏在agent/tool_guardrails.py三种检测exact_failure完全相同参数相同错误警告 2 次/阻断 5 次、same_tool_failure同工具不同参数均失败3/8、no_progress连续只用只读工具无进展2/5。决策级别 ALLOW → WARN注入 synthetic system message→ HALT强制 LLM 给最终答案。OpenClaw 没有等价物只有timeoutMs硬超时没有“濒临上限时注入提示”的软机制。验证让 Agent 反复调用同一个失败命令看 Hermes 是否在第 5 次阻断OpenClaw 是否一直重试到超时。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一章对照真实报错。我踩过的坑基本都在这几个里。5.1 401 Unauthorized最常见。原因通常是 Key 没填对、Key 前后有空格、或者 Base URL 写成了带/v1的地址导致鉴权路径错位。排查顺序# 先用 curl 直接验证 Key 和端点 curl -s https://taotoken.net/api/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d {model:你的模型ID,messages:[{role:user,content:hi}]}如果 curl 通、框架不通就是框架配置读取问题。Hermes 检查config.yaml的api_key字段是否被环境变量覆盖OpenClaw 检查~/.openclaw/config.json的providers.taotoken.apiKey。5.2 local proxy failed这个报错通常出现在框架尝试走本地代理但代理没起来时。TaoToken 的 API 地址是直连的不需要任何本地代理。如果你看到这个错检查环境变量里有没有残留的HTTP_PROXY/HTTPS_PROXY有就unset掉OpenClaw 的pi-ai层有没有配置proxy字段删掉Hermes 的auxiliary_client.py是否被自定义了 transport。unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxy5.3 reading choices 相关报错典型是Cannot read properties of undefined (reading choices)或 Python 侧KeyError: choices。这说明响应体不是标准 OpenAI 格式或者请求根本没成功返回 JSON。原因可能是模型 ID 填错服务端返回了错误对象而不是 completionapi_mode选错Hermes 有 4 级自动检测chat_completions/codex_responses/anthropic_messages/bedrock如果误判成anthropic_messages但端点返回 OpenAI 格式就会解析失败。显式写api_mode: chat_completionsOpenClaw 的api字段必须是openai-completions写成别的会走错路由。5.4 OAuth 相关报错如果你在 Codex 或某些工具里看到 OAuth 报错通常是因为它默认走 OAuth 登录流程而不是 API Key。TaoToken 用的是 API Key 鉴权不需要 OAuth。检查 Codex 的auth.json是否写成了{ OPENAI_BASE_URL: https://taotoken.net/api, OPENAI_API_KEY: sk-你的Key, OPENAI_MODEL: 你的模型ID }如果auth.json里还有oauth相关字段删掉。Cline MCP 配置同理只填 Base URL Key Model ID 三件套。5.5 工具调用不执行 / 幻觉输出Agent 声称完成了任务但result.txt没生成。这是模型“只说不做”的典型失败模式。Hermes 的TOOL_USE_ENFORCEMENT_GUIDANCE和TASK_COMPLETION_GUIDANCE就是针对这个的TOOL_USE_ENFORCEMENT_MODELS里的模型会额外注入。如果你用的模型不在列表里但仍有这问题手动在任务描述里加“必须真实调用工具不要凭空回答”。OpenClaw 侧检查before_tool_callHook 是否误拦截了工具以及 Exec Approval 是否在等确认。6. 选型建议与后续接入跑完这一轮我对两个框架的定位更清楚了。OpenClaw 解决的是“怎么接入所有消息平台、怎么稳定运行”它的 Runtime 生命周期管理ACTIVE_EMBEDDED_RUNS、ABANDONED_EMBEDDED_RUNS、EMBEDDED_RUN_WAITERS、EMBEDDED_RUN_MODEL_SWITCH_REQUESTS、会话写锁、Run 内 SteeringqueueEmbeddedAgentMessage、Abort 机制都是为多用户多通道生产环境设计的。Hermes 解决的是“怎么让 Agent 记住你、怎么让 Agent 变得更聪明”它的跨 session 记忆、技能自动生成background_review.py的BackgroundReviewer、Memory Nudge、skill_manage自我改进、Agent Tree 子任务都是为个人助手和 AI 研究工具设计的。两者不是同一赛道的竞争对手而是从 OpenClaw 这个共同根基上长出的两个方向。Hermes 内置了hermes claw migrate迁移工具本身就承认了这层继承关系。如果你要长期做编码或 Agent 任务建议用 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 把两个框架都挂上去对比跑如果只是验证模型行为用模型对话 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 快速试接入过程中遇到鉴权或端点问题直接查接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 和 API Keys 管理页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。最后一个实操技巧对比两个框架时一定用同一个模型 ID、同一个任务描述、同一个工作目录否则你观察到的差异可能来自模型而不是 Agent Loop。我第一轮对比就是因为两个框架填了不同模型结果工具调用次数差了 3 倍换成同一个模型后差异才收敛到框架本身。