Technical Guide

08. Tools 原理:工具是怎么注册、筛选和执行的

从工具注册、toolset 分组、schema 暴露和 handler 执行理解 Hermes 的工具系统。

这篇解决什么问题

Hermes 能干活,主要靠工具。

模型本身不能真的读文件、跑命令、发请求、生成 PDF。它只能提出 tool call。真正动作由 Hermes 的工具系统执行。

所以读 Hermes 源码,Tools 是必须看的一块。

工具系统解决什么问题

一个工具系统至少要解决四件事:

1. 有哪些工具
2. 当前会话允许哪些工具
3. 每个工具的 schema 怎么告诉模型
4. 模型发起调用后,怎么找到真实 handler 执行

Hermes 也是围绕这四件事设计。

三个核心概念

1. Tool

一个具体能力,例如:

web_search
read_file
terminal
patch
skill_view
cronjob
vision_analyze

2. Toolset

一组工具,例如:

web       → web_search, web_extract
file      → read_file, write_file, patch, search_files
terminal  → terminal, process
skills    → skills_list, skill_view, skill_manage

Toolset 让不同场景可以暴露不同工具。

3. Handler

工具真正执行的函数。

模型只知道 schema,不会直接执行 Python。Hermes 根据工具名找到 handler,再把参数传进去。

为什么要有 toolset

不是所有会话都应该有所有工具。

例如:

  • 普通聊天不一定需要 terminal;
  • webhook 来源可能不可信,不应该默认有本地文件和 shell;
  • 子 Agent 可以只给 webfile
  • cron job 可以限制为 web,减少风险和上下文开销。

所以 toolset 是能力边界,也是安全边界。

工具调用的基本链路

简化看是:

tools/*.py 通过 registry.register 注册工具
→ model_tools.discover_builtin_tools 导入工具模块
→ model_tools.get_tool_definitions 生成 schema
→ AIAgent 把 schema 发给模型
→ 模型返回 tool_calls
→ tool_executor 执行 tool_calls
→ model_tools.handle_function_call 找到工具 handler
→ 工具结果返回 messages

这个链路就是 Tools 源码阅读的主线。

schema 很重要

模型调用工具时,看的不是 Python 函数签名,而是 JSON schema。

schema 里包含:

工具名
描述
参数
必填字段
枚举值

描述写得不好,模型就容易误用工具。

所以新增工具时,不只是写 handler,也要写好 schema。

check_fn 做什么

很多工具不是永远可用。

比如:

  • 浏览器工具需要浏览器后端;
  • TTS 需要 provider 或依赖;
  • Home Assistant 需要 token;
  • 某些外部服务需要环境变量。

check_fn 用来判断当前环境是否满足要求。不满足时,工具不应该出现在 schema 里。

工具结果为什么要控制大小

工具结果会回到模型上下文。

如果 read_file 一次读出几十万字符,或者 web_extract 抓回一大篇网页,下一次模型调用就可能爆上下文。

所以 Hermes 有工具结果预算、持久化和截断逻辑。工具系统不只是执行,还要控制结果进入上下文的方式。

下一篇看什么

下一篇看源码:tools/registry.pytoolsets.pymodel_tools.pyagent/tool_executor.py 是怎么配合的。