本节摘要:133 个工具直接摊给 LLM 既浪费 token 又稀释注意力,Hermes 的解法是
toolsets.py(1083 行)的双层分组。第一层是功能分组:TOOLSETS 字典把工具切成 web/browser/terminal/file/skills/computer_use/tts/cronjob/delegation/kanban 等约 35 个组,每组是{description, tools, includes}三元组,includes允许组间递归引用(debugging 组包含 web+file);resolve_toolset递归展开并做环检测与菱形去重,"all"别名自动并集所有组。第二层是平台预设:24 个hermes-<platform>预设(telegram/discord/slack/微信 weixin/飞书 feishu/钉钉 dingtalk/QQ bot/企微 wecom/元宝 yuanbao...)以_HERMES_CORE_TOOLS为公共底盘、按平台增删;官方架构文档按可用 toolset 计数约 28 个。本节盘点分组全景、解析机制、平台裁剪与代表工具。
内容来源:原项目源码
toolsets.py:31-102(核心工具底盘)/:107-651(TOOLSETS 字典)/:769-878(resolve_toolset)。
⚠️ 注意:
toolsets.py的 TOOLSETS 静态字典在 0.20.5 共 59 个条目——35 个功能分组 + 24 个平台预设;官方架构文档的 "~28 toolsets" 与总纲的"28"指的是实际注册进 registry 的工具集口径(tools/*.py 里出现的 toolset 名约 28 个,如 browser-cdp、browser-use 这类注册用别名)。两个口径都对,引用数字时说清口径即可,别把它们混为一谈。
阅读完本节,你应当能够:
resolve_toolset 的四个要点:别名并集/环检测/菱形去重/代数备忘录。_HERMES_CORE_TOOLS 公共底盘的构成与"刻意不在场"的两类工具。hermes tools 与 check_fn 二次裁剪。toolsets.py 的核心是一个静态字典,每个条目是三元组:
107 TOOLSETS = { 109 "web": { 110 "description": "Web research and content extraction tools", 111 "tools": ["web_search", "web_extract"], 112 "includes": [] # No other toolsets included 113 }, ... 387 "debugging": { 388 "description": "Debugging and troubleshooting toolkit", 389 "tools": ["terminal", "process"], 390 "includes": ["web", "file"] # For searching error messages ...
tools 是自有工具,includes 引用其他组(解析时递归并入)。约 35 个功能分组可粗分四类:
| 类别 | 代表分组(工具) |
|---|---|
| 感知与检索 | web(web_search/web_extract)、search(仅搜索)、vision(vision_analyze)、session_search、memory |
| 行动与执行 | terminal(terminal/process)、file(read_file/write_file/patch/search_files)、browser(13 个 browser_* + web_search)、computer_use、code_execution(execute_code) |
| 外循环接口★ | skills(skills_list/skill_view/skill_manage)、memory、session_search——外循环三注入点的工具面 |
| 编排与领域 | delegation(delegate_task)、kanban(13 个 kanban_*)、cronjob、tts、todo、clarify、homeassistant、discord/discord_admin、feishu_doc/feishu_drive、yuanbao、spotify、image_gen/video_gen/bfl、desktop_ui、project |
场景组则用 includes 组合出"姿势":debugging = terminal+web+file;safe = web+vision+image_gen(无终端);coding 是代码工作区自动选中的姿势组(带 "posture": True 标记,文件+终端+浏览器+技能+委派,刻意排除消息/TTS/智能家居)。coding 组的注释(:399-407)值得细读:它在代码工作区由 agent/coding_context.py 按会话自动选中,且永不回写进各平台的工具配置(用户手动改 hermes tools 不会被姿势组反向污染)——"姿势"是会话级判断,不是持久配置;GUI 网关还会为桌面来源的会话在 coding 之外叠加 desktop_ui 组(面归客户端,姿势归工作区,两者正交)。
平台预设全部以 _HERMES_CORE_TOOLS(:31-92)为底盘——编辑这一处,所有平台同步更新:
31 _HERMES_CORE_TOOLS = [ 32 # Web 33 "web_search", "web_extract", 35 # Terminal + process management 36 "terminal", "process", 44 # File manipulation 44 "read_file", "write_file", "patch", "search_files", ... 52 # Skills 53 "skills_list", "skill_view", "skill_manage", ... 63 "todo", "memory", 74 "execute_code", "delegate_task", ... 91 "computer_use", 92 ]
底盘刻意不含两类工具,源码注释给出理由(:36-42 与 :64-68):desktop_ui 的 GUI 面板工具(read_terminal/open_preview 等)只对"另一端有 GUI 渲染器"的会话有意义,由桌面网关按会话来源启用,不看进程环境变量(环境变量分不清桌面客户端连的是远程后端);project 三件套同理。24 个平台预设基本是"底盘+平台专属":hermes-discord 加 discord/discord_admin,hermes-feishu 加 5 个飞书文档工具,hermes-yuanbao 加 5 个元宝工具,微信/钉钉/QQ bot/企微用纯底盘。最克制的预设是 webhook:
94 # Webhook events may originate from untrusted third-party content (for example, 95 # public PR titles/comments). Keep the default webhook toolset intentionally 96 # constrained to avoid local file/system execution by prompt injection. 97 _HERMES_WEBHOOK_SAFE_TOOLS = [ 98 "web_search", 99 "web_extract", 100 "vision_analyze", 101 "clarify", 102 ]
——webhook 事件可能来自公网 PR 标题/评论这类不可信内容,默认只给 4 个只读/澄清工具,把提示注入的破坏面压到最小。hermes-gateway 则是反向的并集:includes 列出全部 19 个消息平台预设。代表性平台预设速查:
| 预设 | 底盘之外新增 | 备注 |
|---|---|---|
hermes-cli/hermes-cron |
无(纯底盘) | CLI 与 cron 共用核心面,cron 再由 hermes tools 过滤 |
hermes-telegram/hermes-slack/hermes-signal |
无(纯底盘) | 个人/工作消息平台,terminal 有安全审批 |
hermes-discord |
discord、discord_admin | 消息读取/成员搜索/建线程 + 服务器管理 |
hermes-feishu |
feishu_doc_read + 4 个 feishu_drive 工具 | 飞书文档与评论操作 |
hermes-yuanbao |
5 个 yb_* 工具 | 群信息/成员/私聊/贴纸 |
hermes-weixin/hermes-dingtalk/hermes-qqbot/hermes-wecom |
无(纯底盘) | 国内平台走核心面 |
hermes-acp |
无(纯底盘,去 clarify) | 编辑器集成,无交互 UI 工具 |
hermes-webhook |
负增量(仅 4 工具) | 不可信内容的最小面 |
hermes-gateway |
并集 includes 全部平台预设 | 网关进程的聚合视图 |
分组的运行时展开在 toolsets.py:769:
769 def resolve_toolset(name: str, visited: Set[str] = None, *, include_registry: bool = True) -> List[str]: ... 807 # Special aliases that represent all tools across every toolset 808 # This ensures future toolsets are automatically included without changes. 809 if name in {"all", "*"}: 810 all_tools: Set[str] = set() 811 for toolset_name in get_toolset_names(): 813 resolved = resolve_toolset(toolset_name, visited.copy(), ...) 814 all_tools.update(resolved) 815 return sorted(all_tools) 817 # Check for cycles / already-resolved (diamond deps). 820 if name in visited: 821 return [] 823 visited.add(name) ... 854 tools = set(toolset.get("tools", [])) 859 for included_name in toolset.get("includes", []): 860 included_tools = resolve_toolset(included_name, visited, ...) 861 tools.update(included_tools) 863 result = sorted(tools)
四个要点:其一,"all"/"*" 别名遍历全部组取并集——新增 toolset 自动进 all,无需维护清单(808 行注释原话);其二,visited 集合同时处理环(A→B→A 时安全跳过)与菱形依赖(A→B,A→C,B/C→D 时 D 只收一次),源码注释承认两者共用同一静默返回 [] 的行为;其三,外部调用带备忘录(:799 的 memo 键含 registry 代数),MCP 刷新推进代数即自动失效,备忘录超 256 条整体清空防膨胀;其四,include_registry=False 提供静态视图(不含插件注册进组的工具),供平台反向映射使用——注册表加进来的工具不能反向让整个 toolset 从推理面消失(源码引用编号 #49622)。此外还有一条动态兜底(:833-847):名字以 hermes- 开头但不在字典里的平台,自动生成"底盘+该平台名下注册工具"的预设——插件平台零清单接入。
上一节的 _compute_tool_definitions 正是这套解析的消费者:enabled_toolsets 逐个 resolve 取并集,disabled_toolsets 在最后统一做减法(即使组合组如 hermes-cli 启用了,被禁组的工具也严格剔除);kanban 派发的工人进程会被强制补上 kanban 组(:430-440,生命周期交接工具不能被档案裁掉)。
terminal 组:terminal(命令执行,6 种后端)+process(后台进程管理)——第三章末精读。browser 组:13 个工具覆盖 navigate/snapshot/click/type/scroll/back/press/get_images/vision/console/cdp/dialog/exec,五后端(Browser Use 云/Browserbase 云/本地 Chromium/Camofox 反检测/CDP)对 agent 面行为一致——工具描述走无障碍树(ariaSnapshot)文本表示,无视觉能力的模型也能用。file 组:read/write/patch(模糊匹配补丁)/search_files 四件套。computer_use 组:单工具 computer_use,cua-driver 驱动的后台桌面控制(截图/鼠标/键盘/滚动/拖拽),不抢用户焦点,任何支持工具调用的模型可用。skills 组★:skills_list/skill_view/skill_manage——外循环的会话内操作面,模型能在对话中翻阅、增补、修订自己的技能(第 4 章主角)。delegation 组:单工具 delegate_task,委派 subagent 的唯一入口(spawn/list/steer/stop 四个动作,第 8 章)。kanban 组:13 个工具(任务看板/完成/阻塞/评审/心跳/评论/附件),只在 HERMES_KANBAN_TASK 派发的工人进程里显形。cronjob 组:单工具 cronjob 管理定时任务(自然语言描述、投递到任意平台)。其他:tts(text_to_speech,Edge/ElevenLabs/OpenAI/xAI 四引擎)、vision(vision_analyze)、memory(memory)、session_search(session_search)、clarify(clarify,交互式澄清——强制串行执行的工具)、code_execution(execute_code,写 Python 批量调工具,预算可 refund)。
平台侧的二次裁剪发生在两处:hermes tools 命令按平台启用/禁用组(配置持久化);check_fn 在 schema 收集时再探一次运行环境(无 HASS_TOKEN 的 homeassistant 工具即使被启用也不进列表)。加上第一层的 toolset 解析,一个工具要"出现在模型面前"需要连过三关:组的开关(配置)→平台的预设(结构)→check_fn 探针(环境)。三层各有分工:配置管用户意愿,预设管场景边界,探针管物理现实——例如你在无桌面的服务器上启用 computer_use 组,check_fn(探测 cua-driver 是否安装)依然会把它从 schema 里剔除,而不是让模型拿到一个必败的工具。
💡 循环要点:toolsets 的本质是给 LLM 的注意力做减法、给平台差异做加法。减法:任何会话只 resolve 出所需的工具子集,133 个工具从不全量进 schema;加法:平台预设让同一颗 AIAgent 在 Telegram 是"全能个人助理"、在 webhook 是"4 工具的谨慎信息员"、在代码工作区是"coding 姿势的结对程序员"。而 skills/memory/session_search 三组是外循环的接口——分组表里藏着双循环的耦合点。
{description, tools, includes};includes 递归引用(debugging=terminal+web+file)。resolve_toolset 四要点:all/* 别名自动并集、visited 兼做环检测与菱形去重、代数键备忘录、include_registry=False 静态视图。_HERMES_CORE_TOOLS 是全部平台预设的公共底盘;desktop_ui 与 project 工具刻意不在底盘(只对 GUI 会话有意义)。下一节给这双手装上"保险丝":approval 危险命令审批(5714 行)、path_security 路径约束、threat_patterns 威胁模式三重防线,以及 terminal/browser/computer_use/delegate 四件代表工具的源码精读。