第六章
工具调用机制
🎧 语音播放
理解 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 装上"手"——让它不仅能想,还能做
延伸思考
- 工具的同步和异步执行有什么区别?什么时候用哪个?
- 如果工具执行失败(比如网络超时),Agent 应该怎么处理?