ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Hermes Agent 中 Skills 与 Tools 的关系分析:从 TaoToken 统一 Key 通道看能力编排

Hermes Agent 中 Skills 与 Tools 的关系分析:从 TaoToken 统一 Key 通道看能力编排

1. 从一次「技能没生效」的排查说起:Hermes Agent 里 Skills 与 Tools 到底谁管谁

如果你刚开始接触 Hermes Agent,大概率会经历这样一个瞬间:明明在~/.hermes/skills/下放了一个写得很详细的SKILL.md,任务跑起来却像没看见一样,Agent 该怎么做还怎么做。反过来,有时候你只是随口提了一句「帮我做个代码审查」,它却主动去加载了一个叫dogfood的技能,然后按里面的步骤一步步执行。

这两种体验的差异,本质上是没搞清楚 Hermes Agent 里Skills 和 Tools 的职责边界。Skills 不是 Tools 的替代品,Tools 也不是 Skills 的容器。它们更像是一套「索引 + 按需取书」的协作机制:Tools 是 Agent 能调用的动作,Skills 是这些动作背后可以加载的知识包。

先把核心检索词说清楚。Hermes Agent 是一个支持工具调用与技能编排的 Agent 框架,Skills 是存放在本地目录、以SKILL.md为主体的可复用工作流文档,Tools 则是注册进 toolset、暴露给大模型的函数能力。适合谁看?适合已经在用 Hermes Agent 跑自动化任务、但发现技能加载不稳定、或者想自己写技能却不知道从哪下手的人。

我试过把 Skills 理解成「给 Agent 看的操作手册」,Tools 理解成「Agent 的手」。手册不会自动翻到某一页,得靠 Agent 先看到目录,判断相关,再主动去翻。这个「目录 + 翻页」的动作,就是skills_list和skill_view这两个 Tool 在干的事。

所以本文不打算泛泛谈概念,而是沿着一条真实链路走:Skills 怎么注册、怎么被索引、怎么在运行时被加载、Tools 怎么把这一切串起来。中间会给出可复制的配置片段,以及一次端到端的调用验证,让你能自己确认两者在真实任务里的分工。

需要提前说明的是,Skills 并不是作为一个统一的 tool 暴露给大模型的。它是由三个独立 Tool 组成的 toolset,这一点在源码里写得很明确,也是后面所有配置和排查的基础。

2. TaoToken 统一 Key 通道前置准备:让 Skills 与 Tools 走同一条 API 出口

在深入 Skills 和 Tools 的编排之前,得先把模型通道打通。Hermes Agent 本身不绑定某一家模型服务,它通过 Base URL + API Key + Model ID 这三件套去调用大模型。如果你同时跑多个 Agent、多个技能,每个都单独配一套 Key,管理成本会迅速上升。TaoToken 在这里的作用,就是提供一个统一的 Key/API 通道,让 Skills 触发的每一次模型调用都从同一个出口走。

这一步不是可选项。因为 Skills 的按需加载机制,本质上依赖模型在每一轮对话里看到 tool schema 后做出「要不要调skill_view」的判断。如果通道不稳定、模型返回格式异常,你会看到技能索引明明注入了,Agent 却始终不调用加载工具。所以先把通道配好,后面的验证才有意义。

TaoToken 的接入地址是https://taotoken.net/api,官网入口在https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=。你需要先在控制台创建一个 API Key,然后把它写进 Hermes Agent 的配置里。

具体操作路径是:进入控制台,找到 API Keys 页面,新建一个 Key 并复制。这个 Key 就是后面所有配置里api_key字段的值。控制台地址是https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite,API Keys 页面是https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite。

拿到 Key 之后,Hermes Agent 的模型配置通常落在一个 JSON 或 TOML 文件里。不同版本路径略有差异,常见的是项目根目录下的config.json或者用户目录下的~/.hermes/config.json。你要做的是把base_url指向 TaoToken 的 API 地址,把api_key填成刚创建的值,model填你要用的模型 ID。

这里有个容易踩的坑:Base URL 末尾不要多加/v1或者斜杠。TaoToken 的 API 地址就是https://taotoken.net/api,Hermes Agent 内部会自己拼接具体路径。多写一层会导致 404,而 404 在 Agent 日志里经常被误报成「模型不可用」,让你以为是 Key 的问题。

配置完成后,建议先用一次最简单的模型对话验证通道。你可以打开模型对话页面https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite,手动发一条消息,确认返回正常。这一步能排除掉大部分「Key 无效」「额度不足」「模型名写错」的问题。

通道打通之后,Skills 和 Tools 才有稳定的运行环境。接下来进入正题:Skills 到底是怎么注册进 Tools 体系的。

3. 可复制配置:Skills 三件套 Tool 的注册与 SKILL.md 装载链路

先把结论摆出来:Skills 通过三个独立 Tool 暴露给大模型,它们都注册在skills这个 toolset 下,分别是skills_list、skill_view、skill_manage。这三个 Tool 定义在toolsets.py的_HERMES_CORE_TOOLS列表里,属于默认加载的核心工具。

这意味着你不需要额外开启什么开关,只要 Hermes Agent 正常启动,这三个 Tool 就会进入valid_tool_names。但「进入」不等于「被模型使用」,中间还有一层索引注入的逻辑。

3.1 三个 Tool 的职责划分

skills_list负责列出所有可用技能的名称和一句话描述,是一个轻量索引。它对应的 schema 里只有一个可选的category参数,用来按分类过滤。skill_view负责按需全文加载某个特定技能的SKILL.md内容,必填参数是name,可选参数是file_path,用来访问技能目录下的引用文件、模板或脚本。skill_manage负责创建、编辑、删除技能,让 Agent 能把成功经验保存下来。

这三个 Tool 的 handler 分别在tools/skills_tool.py和tools/skill_manager_tool.py里实现。skills_list和skill_view在skills_tool.py,skill_manage在skill_manager_tool.py。

3.2 技能索引如何注入 System Prompt

当skills_list、skill_view、skill_manage中任意一个出现在valid_tool_names里时,Hermes Agent 会调用build_skills_system_prompt()构建技能索引,并注入 system prompt 的 stable tier。生成的索引格式大致是这样:

## Skills (mandatory) Before replying, scan the skills below. If a skill matches or is even partially relevant to your task, you MUST load it with skill_view(name) and follow its instructions. <available_skills> qa: - dogfood: Exploratory QA of web apps: find bugs, evidence, reports. devops: - kubernetes: Deploy and manage Kubernetes clusters. - terraform: Provision infrastructure as code. </available_skills>

注意这里只包含name: description,每条描述不超过 60 字,不包含完整的SKILL.md正文。这就是「两级加载」的第一级:初始化时只给目录,不给全文。

索引构建时还会做条件过滤。如果某个技能依赖的工具或工具集没有加载,或者操作系统平台不匹配,它会被隐藏。这个过滤逻辑在_skill_should_show()里。另外索引构建有三层缓存:L1 内存 LRU、L2 磁盘快照、L3 全量扫描,用来加速。

3.3 SKILLS_GUIDANCE 行为指导

当skill_manage可用时,system prompt 的 stable tier 还会注入一段SKILLS_GUIDANCE,大意是:完成复杂任务、修复棘手错误、发现非平凡工作流之后,用skill_manage把方法保存为技能;使用技能时发现过时或不完整,立即用skill_manage(action='patch')修补。

这段指导的注入条件是skill_manage在valid_tool_names里。它不参与具体技能内容,只影响 Agent 的行为倾向。

3.4 第二级:Tool Schema 随每次 API 调用携带

三个 Tool 的 JSON Schema 描述会随每次模型 API 调用一起发送。skills_list的 schema 描述是「List available skills (name + description). Use skill_view(name) to load full content.」。skill_view的 schema 描述更长,说明了它可以加载完整内容或访问链接文件,第一次调用返回SKILL.md内容加一个linked_files字典,要访问那些文件需要再次调用并传file_path。skill_manage的 schema 描述包含所有 action 的用法指导。

3.5 第三级:运行时按需全文加载

这是核心机制。模型看到 system prompt 里的紧凑索引,判断某个技能相关,调用skill_view(name="dogfood"),skills_tool.py读取完整的~/.hermes/skills/qa/dogfood/SKILL.md,作为 tool result 注入当前 turn 的 messages,模型这才看到完整的技能文档。

绝大多数技能的完整内容永远不进入 context window,只有被主动调用时才加载。这就是为什么 Skills 不会撑爆上下文,也是为什么技能没被调用时你感觉它「没生效」。

3.6 一个可复制的 SKILL.md 结构

技能目录结构通常是~/.hermes/skills/<category>/<skill_name>/SKILL.md。一个最小可用的SKILL.md长这样:

--- name: api-smoke-test description: 对指定 API 做一次冒烟测试,验证 Key 与 Base URL 是否可用 --- # API 冒烟测试 ## 适用场景 当你需要确认某个 API 通道是否正常时使用。 ## 步骤 1. 读取配置中的 base_url 与 api_key。 2. 发送一条最小请求。 3. 检查返回状态码与响应体。 ## 注意事项 - 不要在技能里硬编码 Key。 - 失败时先看状态码,401 通常是 Key 问题。

description会进入索引,name是skill_view的调用参数。正文只在被加载时进入上下文。

4. 端到端验证:一次请求里确认 Skills 与 Tools 的分工

配置和结构都清楚了,现在做一次端到端验证,确认两者在真实任务里的衔接。验证目标是:让 Agent 在一个任务里先看到技能索引,再主动调用skill_view加载技能,最后按技能内容执行。

4.1 准备验证环境

先确认技能目录存在,并且里面至少有一个技能。假设你已经按上一节创建了api-smoke-test,路径是~/.hermes/skills/qa/api-smoke-test/SKILL.md。然后确认 Hermes Agent 的配置里base_url指向 TaoToken,api_key已填。

启动 Agent 后,先看日志里有没有技能索引注入的记录。如果日志级别够,你会看到build_skills_system_prompt被调用,以及<available_skills>的内容。

4.2 发起一个会触发技能加载的任务

给 Agent 发一条明确指向技能场景的消息,比如「帮我做一次 API 冒烟测试」。注意不要直接说「加载 api-smoke-test 技能」,那样验证的是指令跟随,不是索引匹配。你要验证的是 Agent 能否从索引里自己判断出相关技能。

正常情况下,你会看到 Agent 先调用skills_list或者直接根据 system prompt 里的索引判断,然后调用skill_view(name="api-smoke-test")。这个调用会返回完整的SKILL.md正文,作为 tool result 进入当前轮次。

4.3 观察调用链

一次成功的调用链大致是:模型收到 system prompt(含技能索引)和 tools schema(含三个 skills tool)→ 模型输出 tool callskill_view→ Hermes Agent 执行 handler 读取文件 → 返回内容 → 模型基于内容继续执行后续步骤。

如果你在日志里看到skill_view被调用,并且返回内容里包含你写的步骤,说明 Skills 和 Tools 的衔接是通的。如果模型始终不调用skill_view,问题通常出在索引没注入、或者模型没理解索引里的指令。

4.4 用一次真实请求确认通道

为了同时验证 TaoToken 通道,可以在技能执行过程中让它发一次真实 API 请求。比如技能里写了「发送一条最小请求」,Agent 执行到这一步时会走 TaoToken 的 API 地址。如果返回正常,说明通道和技能编排都没问题。

这一步的价值在于:它把「模型调用」和「技能加载」放在同一条链路上验证。很多问题单独看通道是好的,单独看技能也是好的,但合在一起就出问题,原因往往是配置里的 Base URL 或 Key 在技能执行路径上被覆盖了。

4.5 验证成功的判断标准

判断标准有三条:第一,日志里出现技能索引注入;第二,模型主动调用了skill_view且返回了完整正文;第三,技能里定义的步骤被实际执行,且涉及模型调用的步骤走的是 TaoToken 通道。

三条都满足,说明 Skills 负责「知识按需加载」,Tools 负责「动作执行与内容读取」,两者分工清晰、衔接正常。

5. 常见报错排查:401、local proxy failed、reading choices 与 OAuth 问题

验证过程中最容易遇到的几类报错,这里逐个对照。

5.1 401 Unauthorized

这是最常见的。出现 401 基本可以锁定在 Key 上。检查三处:TaoToken 控制台里 Key 是否被删除或过期;Hermes Agent 配置里api_key是否有多余空格或换行;Key 是否被写进了错误的配置文件(比如项目里有一份、用户目录里有一份,实际加载的是另一份)。

排查方法是在模型对话页面手动发一条消息,如果那里也 401,就是 Key 本身的问题;如果那里正常,就是 Hermes Agent 配置读取路径的问题。

5.2 local proxy failed

这个报错通常出现在 Agent 尝试通过本地代理转发请求时。如果你没有配置任何本地代理,却看到这个错误,检查配置里是否有残留的proxy字段,或者环境变量里是否有指向本地端口的代理设置。把它清掉,让请求直连 TaoToken 的 API 地址。

5.3 reading choices 相关报错

这类报错一般出现在解析模型返回时,提示读取choices字段失败。原因通常是返回体不是预期的 JSON 结构,可能是通道返回了错误页、或者模型名写错导致返回了非标准响应。先确认model字段填的是 TaoToken 支持的模型 ID,再用模型对话页面确认该模型能正常返回。

5.4 OAuth 相关报错

如果你用的是需要 OAuth 的接入方式,报错可能出现在 token 刷新环节。检查 OAuth 配置里的回调地址、client id、client secret 是否与 TaoToken 控制台里登记的一致。OAuth 问题排查起来比较绕,建议先用 API Key 方式跑通,再切 OAuth。

5.5 技能不加载的排查

如果通道正常但技能不加载,按这个顺序查:技能目录路径是否正确;SKILL.md的 front matter 里name和description是否齐全;技能依赖的工具是否在valid_tool_names里;操作系统平台是否匹配。这几点对应_skill_should_show()的过滤条件。

5.6 配置三件套对照表

配置项正确值常见错误
Base URLhttps://taotoken.net/api多加/v1或末尾斜杠
API Key控制台创建的 Key带空格、用错配置文件
Model IDTaoToken 支持的模型 ID拼写错误、用了不存在的模型

如果你用的是 Claude Code 类接入,配置片段通常长这样:

{ "base_url": "https://taotoken.net/api", "api_key": "你的_TaoToken_Key", "model": "你的模型ID" }

把这三件套对齐,大部分报错都能定位。

6. 把 Skills 当知识层、Tools 当执行层:后续编排的实用建议

走到这里,你应该已经能自己确认 Skills 和 Tools 的分工了。最后给几条实操建议,都是我在实际编排里踩过坑之后总结的。

第一,技能描述要写得像「索引条目」,不要写成「正文摘要」。因为description会进入 system prompt,太长会挤占上下文,太模糊模型判断不出相关性。控制在 60 字以内,说清楚「这个技能解决什么问题」。

第二,不要把大段配置或密钥写进SKILL.md。技能正文会被加载进上下文,敏感信息应该放在环境变量或独立配置文件里,技能里只写读取方式。

第三,善用skill_manage的 patch 能力。技能不是一次写完就固定的,Agent 在执行中发现步骤过时,应该让它自己修补。这比每次手动改文件更符合 Agent 的工作方式。

第四,验证技能是否生效,不要只看最终结果,要看调用链。日志里有没有skill_view调用,比任务成功与否更能说明技能机制是否正常工作。

如果你需要长期跑编码类或 Agent 类任务,可以考虑用 Coding Plan 来统一管理调用额度,入口在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite。接入文档在https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite,API Keys 在https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite。需要确认模型行为时,用模型对话页面https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite手动发一条最快。

Skills 和 Tools 的关系,说到底就是「知识按需加载」和「动作随时可调」的配合。把索引写清楚,把通道配稳定,剩下的交给 Agent 自己判断。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进