Hermes Agent 自定义工具集实战:一个工具从注册到被 Agent 调用的全链路
【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent
你想让 Agent 批量改写文档大小写,翻遍内置工具没现成的。Hermes Agent 的扩展开发里,需求分两层:工具(Tool)是真正干活的函数;自定义工具集(Toolset)决定 Agent 能看见哪些工具。两层分清,注册和调试才不乱。
心智模型:Tool 干活,Toolset 发工牌
打开toolsets.py,所有工具集都挂在同一个TOOLSETS字典上。每个集合就三个字段:description写给人和文档看,tools列出这个集合直接包含的工具名,includes声明它还要把哪些别的工具集合并进来。
"web": { "description": "Web research and content extraction", "tools": ["web_search", "web_extract"], "includes": [] }可以把工具集想成文件夹:tools是放进去的文件,includes是软链接,指向另一个文件夹,展开时一起算进来。另外还有一个_HERMES_CORE_TOOLS,它是所有平台都默认继承的公共基础包,各平台工具集在它之上做加减。
一条主线:从写函数到 Agent 真正调起它
先写处理函数。新建tools/text_transform.py,实现真正干活的逻辑。Hermes 的硬性约定是:所有 handler 必须返回 JSON 字符串,注册层负责 schema 收集、分发、可用性检查和错误包装。
import json def text_transform(text: str, transform_type: str = "uppercase") -> str: if transform_type == "uppercase": return json.dumps({"success": True, "data": text.upper()}) return json.dumps({"success": True, "data": text.lower()})这段代码里最值得记住的是:返回值必须是 JSON 字符串,注册系统只替你兜错误包装,不兜数据格式。
把参数描述成 JSON Schema,然后注册。Schema 就是模型看到的函数说明书,name / description / parameters一样都不能少。
from tools.registry import registry registry.register( name="text_transform", toolset="text_processing", schema={"name": "text_transform", "description": "转换文本大小写", "parameters": {"type": "object", "properties": {"text": {"type": "string"}, "transform_type": {"type": "string", "enum": ["uppercase", "lowercase"]}}, "required": ["text"]}}, handler=lambda args, **kw: text_transform(args.get("text", ""), args.get("transform_type", "uppercase")), )这段代码里最值得记住的是:tools/下任何带顶层registry.register()调用的 .py 文件都会被自动发现并导入,但自动发现只注册 schema,不代表工具已经暴露给 Agent。
把工具挂进工具集。打开toolsets.py,把工具名写进某个集合的tools里——这是唯一必须手动做的装配步骤。
TOOLSETS = { "text_processing": { "description": "文本处理工具集", "tools": ["text_transform"], "includes": ["web"] }, }这段代码里最值得记住的是:工具名没出现在任何 toolset 里,Agent 就永远看不见它,挂集合不是可选项。
验证并启动。先跑校验函数确认名字和依赖都没拼错,再用命令行指定工具集起会话:
from toolsets import validate_toolset validate_toolset("text_processing")hermes run --toolset text_processing这段代码里最值得记住的是:validate 失败十有八九是工具名拼错,或者includes指向了一个不存在的集合名。
进阶玩法与排坑清单
运行时创建工具集:不改文件也能加
不想为了一个临时组合去改toolsets.py再重启?create_custom_toolset可以在运行时直接挂一个动态工具集,tools和includes的写法与静态定义完全一致,会话结束即失效,适合做实验性组合。
from toolsets import create_custom_toolset create_custom_toolset( name="my_dynamic_toolset", description="运行时创建的动态工具集", tools=["text_transform"], includes=["web"], )先问一句"工具到底在不在"
症状是 Agent 报"工具不存在"。原因多半不是没注册,而是check_fn或requires_env没满足——比如工具依赖的 API key 没配。解法:调一次registry.check_tool_availability(),它会分开返回可用和不可用的工具两组名字,缺什么一目了然。
用依赖树排查 toolset includes 指向问题
症状是工具明明注册了,某个平台下却用不了。原因通常是 includes 链条上有一环指错了集合名,或者被平台配置关掉了。解法:print_toolset_tree("text_processing")会把依赖树递归打出来,includes 断在哪一层、哪些工具没被展开,看一眼树就清楚。
💡 工具注册了,为什么 Agent 看不见
症状:registry.register()执行成功、validate 也过了,Agent 就是不调用。原因:注册只把 schema 放进注册表,暴露给 Agent 的开关在工具集那一层。解法:确认工具名出现在某个 toolset 的tools里;如果工具只给自己用,更干净的路是走插件——在~/.hermes/plugins/<name>/__init__.py里用ctx.register_tool(...)注册,插件工具集会被自动发现,完全不用动核心文件。
收尾:速查表与延伸入口
📋 不知道往哪下手时,先查这张表:
| 我想做什么 | 该改哪个文件 | 调哪个函数 |
|---|---|---|
| 写一个新核心工具 | tools/your_tool.py | registry.register(...) |
| 把工具暴露给 Agent | toolsets.py | 写进TOOLSETS的tools |
| 校验工具集定义 | toolsets.py | validate_toolset(name) |
| 运行时动态建工具集 | 无需改文件 | create_custom_toolset(...) |
| 按平台开关工具 | config.yaml或 CLI | hermes tools |
延伸入口从toolsets.py和tools/registry.py读起,回归用例在tests/test_toolsets.py。工具是肌肉,工具集是神经系统——挂对位置,Agent 才会真的伸手去用。
【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考