Hermes Agent 扩展开发完全指南:5 分钟从自定义 Tool 到组合 Toolset
Hermes Agent 扩展开发完全指南:5 分钟从自定义 Tool 到组合 Toolset
【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent
读完这篇文章,你能给 Hermes Agent——一个支持自定义 Tool 与 Toolset 的开源 AI Agent 框架——加上自己的工具,并用 includes 把它们组合成按平台启用的工具集。适合会基础 Python、刚接触这个项目的开发者,示例代码都是最小可复制版本。
内置工具不够用时:先想清楚 Agent 要"多会的一招"
你在批量生成 PR 描述,想让 Agent 顺手统计词数、清掉文本里的多余空白,但内置工具里没有干这种细活文本处理的。与其把文本粘进聊天框让它现算,不如给它写个专用工具。它桌面端的会话与工具管理界面,就是你写完工具后验证效果的地方:
5 分钟跑通第一个自定义工具
把工具放进tools/目录即可被内置的自动发现机制导入:只要文件顶层有一次registry.register(...)调用,加载时会自动挂载,不需要维护手工 import 清单。一个字数统计 + 文本清洗工具长这样:
# tools/text_stats.py from tools.registry import registry def text_stats(text: str, mode: str = "count") -> str: """词数统计或空白清洗""" return " ".join(text.split()) if mode == "clean" else f"words={len(text.split())}" SCHEMA = { # JSON Schema:模型按它决定怎么调用工具 "type": "function", "function": { "name": "text_stats", "description": "统计文本词数或清洗多余空白", "parameters": {"type": "object", "properties": {"text": {"type": "string"}, "mode": {"type": "string", "enum": ["count", "clean"]}}, "required": ["text"]}, }, } registry.register(name="text_stats", toolset="text_utils", schema=SCHEMA, handler=lambda a, **k: text_stats(**a, **k)) # 注册到 text_utils 工具集这就是注册自定义工具的三要素:工具函数、JSON Schema 参数定义、registry.register()。注意函数返回值约定为字符串(或 JSON 字符串),方便模型直接消费。
接着在toolsets.py里声明对应的集合(写法见下一节),然后只挂载这一个工具集跑一遍就能看到效果:
hermes run --toolset text_utils -q "统计 README 词数并清洗空白" # 只启用 text_utils读懂 toolsets.py 的 description / tools / includes
Tool 是真正干活的单元(一个函数 + 一份 Schema);Toolset 是工具的分组,决定哪些平台、哪些会话看得到这些工具。toolsets.py 配置全部挂在单个TOOLSETS字典上,见 toolsets.py,每个条目就三个字段,各管一件事:
TOOLSETS = { "text_utils": { "description": "文本统计与清洗", # 用途说明,展示与检索用 "tools": ["text_stats"], # 本集合直接包含的工具名(只写名字) "includes": ["web"], # 复用其它工具集,递归展开 }, }description给人看,出现在工具集列表和搜索结果里,写清楚"什么时候该用它";tools给运行时用,名单里的名字要和注册时的工具名逐字一致;includes写的是别的工具集的名字,引用关系会递归展开。
不走 CLI、在代码里启动时,把工具集名字通过enabled_toolsets传入,效果相同。
includes 嵌套组合与运行时动态建集合
includes 组合工具集的核心是嵌套:一个工具集可以 include 别的工具集,后者自己再 include 更多。下面这个条目展开后,text_utils里直接包含的工具、以及它内部 include 的web,都会被一并带入:
"report_writer": { "description": "报告写作专用集合", "tools": ["text_stats"], "includes": ["text_utils", "image_gen"], # 嵌套展开,递归解析 },两条注意事项:includes按名字精确匹配且区分大小写,拼错不会报错,只是静默少一组工具;组合时留意每个工具都要占上下文里的 schema 空间,别把不相关的集合顺手塞进来。
不想改toolsets.py时,可以在运行时动态创建集合:
from toolsets import create_custom_toolset create_custom_toolset(name="hotfix_utils", description="临时调试用", tools=["text_stats"], includes=["web", "terminal"])依赖是否满足,交给注册表检查,缺依赖的工具会被如实列出来:
from tools.registry import registry available, missing = registry.check_tool_availability() # 不可用的工具在 missing上线前自检:validate_toolset 与树形输出
提交前先用两个校验函数过一遍:
from toolsets import validate_toolset, get_toolset_info if validate_toolset("report_writer"): info = get_toolset_info("report_writer") print(info["description"], info["resolved_tools"]) # 最终展开后的完整工具列表resolved_tools是最可靠的口径:includes 全部展开后真正会生效的工具名。想看结构全貌,用树形输出:
from toolsets import print_toolset_tree print_toolset_tree("report_writer") # 递归打印 includes 树输出是一棵嵌套树,能读两件事:每个节点的tools是它直接包含的工具,includes下面的子节点是递归展开的集合。叶子节点的工具才是模型真正能调用的——如果某个集合下没有任何叶子,大概率是那一层名字拼错了。
report_writer: 报告写作专用集合 ├─ tools: text_stats └─ includes └─ text_utils: 文本统计与清洗 ├─ tools: text_stats └─ includes └─ web: Web research and content extraction高频翻车点:工具注册了却"隐身"
- 忘了注册,或注册不在顶层:
tools/*.py里的registry.register(...)必须出现在模块顶层,写进函数体内自动发现就不会找到。 - 注册了没暴露:自动发现只负责导入;工具名没写进
toolsets.py任一工具集的tools名单,模型就永远看不到它——这是"工具像没写"的最常见原因。 - Schema 缺 required:模型会缺参调用,第一轮就报错;参数类型也要和函数签名对齐,返回值保持字符串。
- includes 名字拼错:不报错、静默少一组工具,用树形输出的叶子节点对一遍。
- 工具描述里"点名"其它工具集的工具:那个工具集被禁用时模型会幻觉出不存在的调用,描述只写自己做什么。
用 tests/ 里的参照用例给工具上保险
单测以 tests/tools/test_registry.py 为参照,覆盖注册行为与可用性检查;工具集展开逻辑的用例在tests/test_toolsets.py。最少补两条路径:参数齐全时的正常返回,以及缺 required 参数时的表现。先把参照用例跑通再动手改:
pytest tests/test_toolsets.py tests/tools/test_registry.py -q # 先跑通参照用例把你的工具集跑起来
延伸阅读三个文件:toolsets.py(全部工具集定义)、tools/registry.py(注册与自动发现实现)、CONTRIBUTING.md(贡献流程与工具规范)。把上面的最小路径完整跑一遍,今晚就能让自己的自定义工具集在 Hermes Agent 里跑起来 🚀
【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
