手记

Hermes Agent 工具系统:解密 AI 智能体的“双手”

在 AI Agent 的世界里,大模型(LLM)是大脑,而工具系统(Tools System)则是它的双手。上一篇我们拆解了 Agent 的核心循环决策逻辑,即 LLM 决定“调用什么工具”,然后执行它。

那么,Hermes Agent 的工具系统是如何做到让 LLM “感知”到工具的存在?又是如何实现 70+ 个工具的自动注册与发现的?本文将为你揭晓答案。

🤝 核心原理:LLM 是如何“感知”工具的?

传统的聊天模型只能进行文本对话,而支持 Function Calling(函数调用)Tool Calling 的 LLM,具备了一种特殊能力:理解结构化工具定义。

Hermes Agent 的核心机制在于,它将系统内部的 Python 函数转换成 LLM 能理解的 Schema(模式) 格式。当 LLM 面对用户问题时,它会进行判断:

  1. 直接回复:如果问题不需要外部数据,模型直接生成文本回复。
  2. 调用工具:如果问题需要外部信息(如查询天气、搜索网络),模型会返回一个 tool_calls 指令,包含要调用的函数名和参数。

因此,Agent 的工具系统本质上是一个适配器,它将 Python 函数映射为 LLM 的 Schema,并负责执行 LLM 选定的函数。

🏗️ 架构设计:工具系统的“三件套”

Hermes 的工具系统设计非常精巧,主要由三个核心组件构成,实现了低耦合、高内聚的插件化架构。

组件文件 职责 核心逻辑
tools/registry.py 注册中心 全局单例,维护一个 name -> ToolDef 的字典,存储工具的元数据和处理函数。
*`tools/.py`** 工具实现 每个工具是一个独立的 .py 文件,包含具体的业务逻辑函数和注册代码。
model_tools.py 对外接口 run_agent.py 提供服务,负责筛选工具集和执行函数调用。

🔍 深度解析:三大核心技术亮点

1. 自动发现机制(Automatic Discovery)
Hermes 不需要开发者手动在配置文件中罗列所有工具。它在启动时会自动扫描 tools/ 目录下的所有 .py 文件。

  • 巧妙的静态分析:为了防止导入不必要的模块,系统使用了 Python 的 ast(抽象语法树)模块。它会先分析文件源码,检查是否存在 registry.register() 调用,只有确认有注册行为时,才会真正导入该模块。这比简单的字符串匹配更精准,避免了无效加载。

2. 工具集分组(Toolset)与条件启用
Hermes 将 70 多个工具分为了 20 多个工具集(如 webbrowserterminalcode_execution 等)。

  • 灵活配置:用户可以在配置中开启或关闭特定的工具集(例如:hermes tools enable web)。
  • 依赖检查:每个工具可以定义 check_fnrequires_env。例如,浏览器工具需要检查 PLAYWRIGHT_BROWSERS_PATH 环境变量。如果依赖不满足,该工具会自动“隐身”,不会暴露给 LLM,保证了系统在不同环境下的优雅降级。

3. Schema 驱动与标准兼容
Hermes 的工具定义直接映射为 OpenAI 的 Function Calling Schema。这种设计让它天然兼容 Anthropic、Google、Mistral 等主流模型的标准,具备极强的通用性。

🔄 关键流程:从注册到调用的完整链路

让我们跟随代码的执行流,看一遍工具是如何从注册到被调用的:

  1. 启动注册:程序启动,discover_builtin_tools() 扫描目录,执行各模块的 registry.register(),工具信息写入全局注册表。
  2. 用户提问get_tool_definitions() 根据用户配置的启用/禁用列表,从注册表中筛选出可用的工具 Schema,传给 LLM。
  3. LLM 决策:LLM 分析用户意图,如果需要调用工具,返回 tool_calls(函数名 + 参数)。
  4. 执行调用handle_function_call() 接收指令,从注册表查找对应的 handler(处理函数),执行并返回结果。

🚀 实战演练:手把手写一个计算器工具

为了验证这套架构的易用性,我们可以尝试为 Hermes 添加一个“计算器”工具。只需创建一个新文件 tools/calculator.py,代码如下:

import json
from tools.registry import registry

def calculate(expression: str, task_id: str = None) -> str:
    """安全执行数学表达式"""
    # 白名单校验,防止恶意代码执行
    allowed = set("0123456789+-*/()., ")
    if not all(c in allowed for c in expression):
        return json.dumps({"error": "表达式包含非法字符"})
    try:
        # 使用受限的 eval 环境
        result = eval(expression, {"__builtins__": {}}, {})
        return json.dumps({"result": result})
    except Exception as e:
        return json.dumps({"error": str(e)})

# 注册工具
registry.register(
    name="calculate",
    toolset="utility",  # 归类到实用工具集
    schema={
        "name": "calculate",
        "description": "计算数学表达式,支持 +-*/ 和括号",
        "parameters": {
            "type": "object",
            "properties": {
                "expression": {
                    "type": "string",
                    "description": "数学表达式,例如 '1+2*3'"
                }
            },
            "required": ["expression"]
        }
    },
    handler=lambda args, **kw: calculate(
        expression=args.get("expression", ""),
        task_id=kw.get("task_id")
    ),
)

重启 Hermes,LLM 就会立刻“感知”到这个新工具的存在,你无需修改任何核心代码或配置文件。

📌 总结

Hermes Agent 的工具系统设计堪称教科书级别的插件化架构:

  • 低耦合:每个工具独立成文件,互不影响。
  • 自动化:基于 AST 的自动发现机制,减少了人工维护成本。
  • 智能化:通过 Schema 驱动和条件启用,实现了工具的动态管理和安全调用。

这一设计使得 Hermes 具备了极强的扩展性,无论是增加新的搜索能力,还是集成内部业务系统,都能像搭积木一样轻松实现。

0人推荐
随时随地看视频
慕课网APP