
我们平时和 AI 聊天,它只能“说”。
但 Agent 不一样。它能读文件、开浏览器、查记忆,还能在终端里运行命令。
问题来了:
Hermes 的工具列表里明明只有
terminal,为什么 AI 却能运行ping?
答案其实很简单:
terminal是工具,ping是这个工具收到的一段命令。
就像“电话”是一种工具,而你通过电话说什么,是另一回事。

先认识三个角色
为了把这件事讲清楚,我们只需要认识三个角色。
1. 模型:负责做决定
用户问:
“服务器在线吗?”
模型会判断:要回答这个问题,最好先检查网络。
它看到自己拥有一个名为 terminal 的工具,于是生成一次工具调用:
{"name": "terminal","arguments": {"command": "ping -c 3 10.x.x.x","timeout": 15}}
这里的 ping 是模型填写的参数,不是另一个工具。
2. Hermes:负责校验和转发
Hermes 收到模型返回的工具调用后,会做几件事:
检查工具名是不是真的存在; 检查参数格式是否正确; 做安全和授权判断; 找到 terminal对应的执行函数;把执行结果再交给模型。
Hermes 不需要事先知道世界上所有 Shell 命令。
3. Shell:负责真正执行
terminal 最终会把命令交给 Shell,效果类似:
bash -c 'ping -c 3 10.x.x.x'Shell 再从系统的 PATH 中找到 ping 程序并运行。
因此,git、curl、docker、ls 也遵循同样的逻辑:它们不是独立的 Hermes Tools,而是 terminal.command 中的系统命令。
Tool 到底是什么?
可以把 Tool 理解为 AI 能调用的“标准接口”。
一个 Tool 通常包含三部分:
以 terminal 为例,它的定义大致是:
{"name": "terminal","parameters": {"command": "string","timeout": "integer"}}
模型看到这份定义,就知道:如果要执行命令,可以调用 terminal,并把命令放进 command。
Toolset 又是什么?
Tools 多了以后,不能每个入口都一股脑全部开放。
Hermes 用 Toolset 对工具分组:
file → 读文件、写文件、搜索文件terminal → 执行命令、管理进程browser → 打开网页、点击、输入、滚动memory → 读取和保存长期记忆skills → 查看和管理操作知识
Toolset 就像“工具箱分类”,Tool 才是里面那把具体的工具。
为什么不同入口看到的 Tools 不一样?
Hermes 可以从很多入口接收消息,例如:
CLI; Telegram; Discord; Slack; API Server; Home Assistant。
每个入口都可以配置自己的 Toolsets。
例如,Discord 入口可能需要 Discord 专属工具;CLI 更偏向文件和开发;Home Assistant 则可能需要智能家居能力。
所以,即使它们使用同一个模型,最终收到的工具列表也可能不同。
可以用一个公式概括:
最终 Tools= 当前入口启用的 Toolsets+ MCP 和插件工具− 全局禁用项− 当前环境不可用的工具
为什么“已经启用”的工具仍可能消失?
因为“允许使用”和“现在能用”不是一回事。
例如:
配置允许 Web Search,但没有搜索 API Key; 配置允许浏览器工具,但浏览器服务没有启动; 配置允许图片生成,但没有可用的图片提供商; 配置允许某个 MCP,但 MCP 服务连接失败。
Hermes 会通过 check_fn 做运行时检查。
检查不通过的工具不会发给模型,避免模型调用一个注定失败的接口。
MCP 在这里扮演什么角色?
内置 Tools 来自 Hermes 自己的代码,MCP Tools 则来自外部 MCP Server。
可以把 MCP 理解为“外接工具扩展坞”:
Hermes├── 内置 Tools├── 插件 Tools└── MCP Server 提供的 Tools
MCP 工具通常会带服务器前缀,例如:
mcp__remote_coder__run这样可以避免不同服务器之间发生重名。
Skill 和 Tool 有什么区别?
这也是最容易混淆的地方。
一句话区分:
Skill 告诉模型“应该怎么做”,Tool 让模型“真的可以做”。
例如,一个服务器巡检 Skill 可能规定:
先核对资产清单; 只能进行只读检查; 应使用指定的审计脚本; 修改配置前必须获得批准。
但 Skill 本身不会执行 ping。
模型读完 Skill 后,仍然需要调用 terminal,再由 terminal 执行具体命令。
这些 Tools 会不会每次都发给模型?
在常见的 OpenAI-compatible Chat Completions 模式下,请求大致包含:
{"model": "example-model","messages": ["系统提示", "历史消息", "当前问题"],"tools": ["完整工具定义"]}
因此,通常不只是 messages 会随请求发送,当前 Agent 的完整 Tools Schema 也会放进请求体。
需要注意两点:
Session 导出文件不会被整体上传;用户 ID、聊天 ID、成本统计等本地字段不属于模型请求。 服务端即使支持 Prompt Cache,网络请求仍可能携带稳定的 System Prompt 和 Tools Schema,只是服务端可以复用部分计算。
一条完整链路
现在把整个过程连起来:
用户从某个入口发消息↓Hermes 根据入口选择 Toolsets↓加载内置、插件和 MCP Tools↓过滤当前环境不可用的工具↓把最终 Tools 发给模型↓模型选择 terminal,并生成 ping 参数↓Hermes 调用 terminal handler↓Shell 执行 ping↓执行结果返回模型↓模型组织最终回答
最后记住这五句话
如果你只想记住重点,记住下面五句就够了:
- Tool 是模型可以调用的结构化接口。
- Toolset 是一组 Tools 的选择和配置单位。
- 不同入口可以获得不同的 Toolsets。
- Skill 提供操作知识,Tool 提供执行能力。
terminal是 Tool,ping只是模型写进参数的系统命令。
理解这几个边界之后,再看 Agent 的工具调用记录,就不会把 Tool、Skill 和 Shell命令混在一起了。
夜雨聆风