第六章

工具调用机制

🎧 语音播放

理解 Hermes 如何让 AI "动手"做事

🎯 本章目标

  • 理解工具调用的原理
  • 掌握工具注册和调度机制
  • 理解 OpenAI Function Calling 格式

📚 前置知识

  • 第五章的 Agent 循环

💡 学完收获

  • 能解释工具调用的完整流程
  • 能够添加自定义工具

6.1 为什么需要工具?

LLM 本身只能"说",不能"做"。工具让 AI 有了执行力

💬 LLM 只能
生成文本 · 回答问题 · 分析推理
🔧 工具能
搜索网页 · 读写文件 · 执行命令
🤝 组合后
AI 能完成真实任务

6.2 工具系统架构

工具系统架构 Tool System Architecture

flowchart TD A["📦 registry.py"] --> B["🔧 model_tools.py"] B --> C["🧠 run_agent.py"] C --> D["📡 LLM API"] D --> E{"tool_call?"} E -->|有| F["⚡ handle_function_call()"] F --> G["📦 registry.dispatch()"] G --> H["🛠️ 具体工具"] H --> I["📝 结果"] I --> C style A fill:#ede9fe,stroke:#7c3aed style H fill:#d1fae5,stroke:#059669

6.3 工具注册表

tools/registry.py 是所有工具的中央注册表:

📦 ToolRegistry
register(name, toolset, schema, handler)
向注册表添加一个工具
get_definitions(tool_names=None)
获取工具的 OpenAI Schema 定义
dispatch(name, args)
执行指定工具

6.4 OpenAI Function Calling 格式

Hermes 使用 OpenAI 的 Function Calling 格式。工具定义看起来像:

示例:read_file 工具的 Schema
{
  "type": "function",
  "function": {
    "name": "read_file",
    "description": "读取文件内容",
    "parameters": {
      "type": "object",
      "properties": {
        "path": {
          "type": "string",
          "description": "文件路径"
        }
      },
      "required": ["path"]
    }
  }
}
💡 为什么需要 Schema?

Schema 就像是工具的"说明书"。LLM 看到 Schema 后,就知道:

  • 这个工具叫什么
  • 它能做什么
  • 需要什么参数

然后 LLM 才能决定什么时候调用、传什么参数。

6.5 工具执行流程

1
LLM 返回
tool_calls 包含 name 和 arguments
2
解析参数
JSON.parse arguments
3
分发
registry.dispatch(name, args)
4
执行
调用工具函数
5
返回结果
结果加入消息历史

6.6 核心代码

model_tools.py
async def handle_function_call(function_call) -> str:
    """执行单个函数调用"""
    name = function_call.function.name
    args = json.loads(function_call.function.arguments)
    
    # 分发到注册表
    result = await registry.dispatch(name, args)
    return result

6.7 内置工具一览

📁 file
read/write/patch
🔍 grep
文件内容搜索
🖥️ terminal
命令执行
🌐 web
search/extract
🌐 browser
浏览器自动化
📤 delegate
子代理
cronjob
定时任务
📧 email
邮件发送

6.8 工具集(Toolsets)

工具集是对工具的分组,方便按需启用:

toolsets.py
TOOLSETS = {
    "web": ["web_search", "web_extract"],
    "terminal": ["terminal", "process"],
    "file": ["read_file", "write_file", ...],
    "browser": ["browse_page", ...],
    "delegate": ["delegate_task"],
    "skills": ["skill_*"],
}

📚 本章总结

本章重点:

  • 工具 = LLM 的"手"和"脚"
  • 注册表模式:register → get_definitions → dispatch
  • OpenAI Function Calling 格式让跨模型成为可能
  • 工具集是对工具的分组管理

一句话记忆点: 工具系统就是给 AI 装上"手"——让它不仅能想,还能做

延伸思考

  1. 工具的同步和异步执行有什么区别?什么时候用哪个?
  2. 如果工具执行失败(比如网络超时),Agent 应该怎么处理?