1. 从一次技能库失控说起Hermes Curator 要解决的真实问题如果你自建过 Agent大概率遇到过这种局面一开始只写了三五个技能文件半年后目录里躺着三百多个 SKILL.md其中一半是当时调试用的临时脚本另一半功能高度重叠——fetch-url、get-webpage、read-link三个文件干的是同一件事。你不敢删因为不知道哪个还在被引用你也不想整理因为逐个打开比对太费时间。Hermes Curator 就是为这个场景设计的。它是 Hermes Agent 在 v0.12.0 引入的惰性后台任务挂载在 Gateway 既有的 cron ticker 线程上不单独起进程。核心目标只有一个在你不用 Agent 的时候自动把技能库从三百个碎片收敛成一百个带小节的伞型技能并且所有破坏性操作都可逆。它适合谁三类人值得细看一是自建 Agent 框架、想借鉴技能治理思路的工程师二是已经在用 Hermes、技能目录开始膨胀的重度用户三是想理解LLM 做语义判断 确定性代码守安全边界这套混合架构怎么落地的人。本文会拆到状态机迁移条件、LLM fork 的凭据透传、tool-call 审计的校正逻辑并给出可复制的配置片段和本地验证步骤。多模型接入部分我会用 TaoToken 的统一 Key 通道来演示因为 Curator 的 fork 机制对 base_url 和 api_key 的透传要求很严格正好是个合适的验证场景。先说结论性的设计主线后面所有细节都围绕它展开LLM 负责意图判断确定性代码负责执行安全边界。规则状态机做时间维度的无争议清理LLM 做内容相似性的语义判断tool-call 审计校正 LLM 的幻觉而删除这个动作被架构性禁止一律降级为可逆归档。理解这条主线再看代码就不会迷路。2. TaoToken 统一 Key 通道Curator fork 场景下的前置准备Curator 的第二阶段会 fork 一个独立的子 AIAgent通过load_config()resolve_runtime_provider()读取你当前配置然后显式传入 provider、model、api_key、base_url、api_mode 来实例化。这里有个历史坑早期版本用空凭据触发直接吃 HTTP 400。所以 fork 能不能跑通取决于你的凭据配置是否完整、base_url 是否可达。TaoToken 在这个环节的价值是它提供统一的 Key 和 API 通道一个 Key 可以路由到多个模型base_url 固定不需要为每个 provider 单独维护一套凭据。对 Curator 这种fork 时原样透传父级运行时的机制来说配置面越小越不容易出错。你只需要在配置里写一次 base_url 和 api_keyfork 出来的子 Agent 继承同一套OAuth-only 和 pool-backed 凭据都能正常工作。前置准备分三步。第一步拿到 Key。访问 https://taotoken.net/api-keys 创建注意这个页面是控制台里的密钥管理入口创建后立刻复制页面刷新后不再完整显示。第二步确认 base_url。API 通道地址是 https://taotoken.net/api注意不要带任何查询参数Curator 透传时会原样使用这个值。第三步确认你要用的 Model ID。在 https://taotoken.net/models 可以查看当前可用的模型列表把 Model ID 记下来后面写进配置。这里要强调一个容易踩的点Curator 的 fork 会读取api_mode参数。如果你的配置里 api_mode 和实际通道不匹配比如写成了某种需要额外鉴权头的模式fork 出来的子 Agent 会在第一次 API 调用时报 401。稳妥做法是先用模型对话页面 https://taotoken.net/chat 手动发一条消息确认 Key、base_url、Model ID 三者组合可用再写进 Curator 配置。这一步花两分钟能省掉后面半小时的排障。另外提醒一句Curator 的 LLM pass 一次完整 umbrella 合并可能需要 50 到 100 次 API 调用作者实测 346 个技能跑了 86 次调用、约 6.5 分钟。所以你的 Key 需要有足够的额度余量别在跑到一半时被限流中断那样状态机会停在中间态虽然可恢复但排查起来麻烦。3. 可复制配置状态机参数与 Curator settings 片段Curator 的配置读取集中在agent/curator.py但用户侧可调的参数通过 settings 文件暴露。下面给出一份可直接复制的配置片段路径按 Hermes 默认约定放在~/.hermes/settings.toml。如果你用的是 JSON 配置体系等价结构在下一段给出。# ~/.hermes/settings.toml [curator] enabled true interval_hours 168 # 默认 7 天两次 LLM pass 的最小间隔 min_idle_hours 2 # agent 空闲多久才允许启动双重门控的第二层 stale_after_days 30 # 上次使用超过 30 天且 active → 标记 stale archive_after_days 90 # stale 且超过 90 天未用 → 归档到 .archive/ max_iterations 9999 # fork 子 Agent 的迭代上限别调低 pin_protected true # 被 pin 的技能跳过所有自动迁移 [curator.llm] provider taotoken model your-model-id # 替换为 https://taotoken.net/models 里的 Model ID api_key sk-xxxxxxxx # 替换为 https://taotoken.net/api-keys 创建的 Key base_url https://taotoken.net/api api_mode chat_completions # 与通道匹配不匹配会 401如果你更习惯 JSON 体系比如 Codex 风格的auth.json或 Cline MCP 的 settings等价片段如下。注意三件套必须齐全Base URL、Key、Model ID缺一个 fork 就会失败。{ curator: { enabled: true, interval_hours: 168, min_idle_hours: 2, stale_after_days: 30, archive_after_days: 90, max_iterations: 9999, pin_protected: true, llm: { provider: taotoken, model: your-model-id, api_key: sk-xxxxxxxx, base_url: https://taotoken.net/api, api_mode: chat_completions } } }几个参数的解释值得展开。interval_hours和min_idle_hours构成双重空闲门控前者是时间条件后者是活跃度条件两者都满足才启动。为什么不用 cron 定时PR 描述写得很清楚用 inactivity-triggered 模式是为了避免在你活跃使用时消耗 token 配额、产生 API 调用噪音。max_iterations千万别按早期版本的 8 去设一次完整 umbrella pass 需要 50 到 100 次 API 调用设低了会在合并中途截断。stale_after_days和archive_after_days对应第一阶段纯规则状态机这一阶段完全不消耗 token。迁移逻辑是确定性的上次使用超过 30 天且状态为 active 的标记为 stalestale 且超过 90 天未用的归档到~/.hermes/skills/.archive/曾被标记 stale 但近期又被使用的重新激活为 active。这三条规则没有任何 LLM 参与是显然废弃技能的快速清理。配置写完后用 CLI 子命令确认状态。hermes curator status会输出当前是否启用、运行次数、上次运行时间、上次摘要、报告路径、间隔设置、stale 和 archive 阈值以及使用次数最多和最少的各五个技能。如果 status 显示 ENABLED 但 runs 为 0说明门控还没满足可以手动触发一次验证hermes curator run。想临时停掉用hermes curator pause恢复用resume把某个技能排除在自动迁移外用pin取消用unpin误归档了用restore skill拉回来。4. 验证请求与成功结果跑一次完整的 Curator pass配置就绪后验证分四步走每步都有明确的成功标志出问题能立刻定位到哪一层。第一步验证凭据通道。在终端直接发一条最小请求确认 Key、base_url、Model ID 三件套可用curl -s https://taotoken.net/api/chat/completions \ -H Authorization: Bearer sk-xxxxxxxx \ -H Content-Type: application/json \ -d { model: your-model-id, messages: [{role: user, content: reply with ok}] }成功标志是返回 JSON 里choices[0].message.content有内容。如果这里就报 401别往下走先回 https://taotoken.net/api-keys 确认 Key 没写错、没被删。如果报 model not found去 https://taotoken.net/models 核对 Model ID 拼写。第二步手动触发 Curator 并观察日志。执行hermes curator run然后盯住~/.hermes/logs/curator/下最新时间戳目录。每次运行会写两个文件run.json是机器可读的含完整 LLM 最终响应、所有 tool_call 记录、before/after 技能数量 diffREPORT.md是人类可读的含自动迁移摘要、LLM 合并结果、归档列表前 50 条内联、恢复命令提示。第三步检查状态机迁移是否符合预期。打开REPORT.md看自动迁移摘要里 stale 和 archive 的数量。如果你有一个明确超过 90 天没用的测试技能它应该出现在归档列表里。成功标志是归档条目存在且原文件被移动到~/.hermes/skills/.archive/而不是被删除。第四步检查 LLM pass 的合并结果。run.json里的 tool_call 记录会显示skill_manage的 patch/create/write_file 操作。成功标志是出现了新的伞型 SKILL.md或者已有伞型技能被追加了小节被合并的原始技能进入归档。作者实测的参考数据是 346 个技能经过 umbrella-first 策略后收敛到 118 个减少 66%所有内容保留在 references/ 里。验证阶段有个细节要注意Curator 的 fork 子 Agent 工具集被限制为skills_list、skill_view、skill_managepatch/create/write_file、terminal仅用于归档其他工具全部禁止。这是防止 Curator 扩权的设计。如果你在 run.json 里看到子 Agent 尝试调用被禁工具说明配置或版本有问题正常情况不应该出现。跑通一次之后hermes curator status的输出会更新。参考作者给出的示例格式curator 显示 ENABLEDruns 计数加一last run 显示时间last summary 会写类似 auto: no changes; llm: Consolidated nothing; tiny test run. 的摘要last report 给出报告路径后面跟着 interval、stale after、archive after 的当前值以及 most used 和 least used 各五个技能。看到这个输出说明整条链路通了。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth排障部分按报错原文对照每条给出触发原因和修复动作。这些是我在实际配置过程中遇到或见到的典型问题。401 Unauthorizedfork 子 Agent 首次调用即失败。最常见的原因是 fork 时凭据没透传完整。Curator 通过load_config()resolve_runtime_provider()读取配置后显式传入 provider、model、api_key、base_url、api_mode五个参数缺一不可。检查你的 settings 里这五项是否都写了。另一个原因是 api_mode 与通道不匹配比如通道期望 chat_completions 但你写了别的模式鉴权头构造方式不同就会 401。修复把 api_mode 改成chat_completions并确认 base_url 是https://taotoken.net/api不带多余路径。local proxy failed 或连接被拒。这个报错通常出现在 base_url 写错或网络不可达时。先确认 base_url 拼写注意不要带尾部斜杠导致路径拼接成双斜杠。如果 base_url 正确但仍失败用第 4 节的 curl 命令单独测通道把 Curator 和网络问题隔离开。curl 通了说明是 Curator 配置问题curl 不通说明是通道或 Key 问题。reading choices of undefined 或类似字段读取错误。这个报错说明请求发出去了、也返回了但返回体结构不符合预期代码在解析choices时拿到 undefined。常见原因是 Model ID 写错通道返回了一个错误对象而不是正常的 completion 结构。修复核对 Model ID用 https://taotoken.net/models 的列表逐字比对。另一个可能是 api_mode 设错导致解析路径不匹配。OAuth 相关报错提示凭据类型不支持。Curator 的 fork 设计上要继承父级完整运行时OAuth-only 和 pool-backed 凭据都应该能正常工作。如果你用的是 OAuth 凭据却报错检查 Hermes 版本是否包含 PR #17941 之后的修复。临时绕过方案是改用 API Key 方式配置把 provider 指向 taotoken、填 api_key 和 base_url这条路径最直接。LLM pass 跑完但合并数为 0。这不是报错但属于没达到预期。原因通常是提示策略问题。早期版本的被动审计提示会让模型倾向于在技能不完全相同时保持 keep测试中 346 个技能只归档了 3 个。修复确认你用的是 umbrella-first 提示策略PR #17277 之后它的核心要求是定性为UMBRELLA-BUILDING 合并 pass、判断标准是维护者会写成 N 个独立文件还是一个带 N 小节的 SKILL.md、并预设反驳使用次数为 0 不是拒绝合并的理由。误归档后想恢复。用hermes curator restore skill。注意 PR #17941 解决的正是这个 UX 问题用户看到技能被归档分不清是真正废弃pruning还是内容已被吸收到新伞型技能consolidation误用 restore 会产生重复。判断方法看 REPORT.md 里的分类如果归档项标注了 into 某个伞型技能说明是 consolidationrestore 前先确认那个伞型技能里是否已有对应小节。被 pin 的技能仍被迁移。不应该发生。安全不变量里明确写了被 pin 的技能跳过所有自动迁移且模型永远不会自动 pin。如果你遇到这种情况检查 pin 操作是否真的写入了状态文件用hermes curator status确认 pin 列表。另外注意内置技能和 Hub 技能有双重过滤.bundled_manifest.hub/lock.json代码层面无法绕过这类技能永远不会被 Curator 碰。6. 把 Curator 的思路用起来从统一 Key 到可观测的 Agent 调度拆完 Curator 的实现最值得带走的是它的架构取舍。它没有让 LLM 直接做删除决策而是把 LLM 限制在一个有限工具集里做提案所有破坏性操作降级为可逆归档再用 tool-call 审计校正模型幻觉。这套AI 提案、基础设施执行的分工比AI 全权决策稳得多也更适合自建 Agent 的同学借鉴。如果你想把这条链路跑起来建议的顺序是先在 https://taotoken.net/api-keys 建一个 Key用 https://taotoken.net/chat 手动验证模型可用再按第 3 节的配置片段写进 settings最后用hermes curator run跑一次小规模测试。技能库不大时可以把stale_after_days和archive_after_days调小快速看到状态机迁移效果。对于需要长期跑 Agent、频繁做技能治理的场景Coding Plan 这类按周期计费的方式比按次调用更可控尤其是 Curator 这种一次 pass 可能几十上百次调用的任务额度规划清楚能避免跑到一半被限流。接入细节和参数说明在接入文档里有完整对照遇到本文没覆盖的报错可以对着查。最后留一个实用技巧Curator 的run.json里保存了完整的 tool_call 记录这是排查为什么这个技能被合并/被归档的最佳材料。每次觉得结果不符合预期时先翻 run.json 看模型实际调用了什么、传了什么参数比猜提示词有效得多。把可观测性做足Agent 调度才不是黑盒。