深入理解 Hermes Agent —— 开源 Agent 模型的标杆
聊 Agent 绕不开 Function Calling,聊开源 Function Calling 模型绕不开 Nous Research 的 Hermes 系列。这篇文章帮你吃透 Hermes。
一、Hermes 是什么?
Hermes 是 AI 研究组织 Nous Research 推出的一系列开源 LLM,核心定位就是 Agent 能力——特别是函数调用(Function Calling)、工具使用(Tool Use)和指令遵循(Instruction Following)。
一句话概括:
Hermes = 开源社区最早系统性地做 Function Calling 微调的模型系列。
它的命名灵感来自希腊神话中的赫尔墨斯——众神的信使,桥梁与边界的穿越者。这也暗合了 Hermes 模型的使命:连接 LLM 与外部工具/API。
二、Hermes 系列演进
| 版本 | 基座模型 | 核心改进 | 发布时间 |
|---|---|---|---|
| Hermes 1 | Llama 2 7B/13B | 首次引入函数调用微调数据 | 2023 Q3 |
| Hermes 2 | Llama 2 + Mistral | 改进函数调用格式,增强推理 | 2023 Q4 |
| Hermes 2 Pro | Mistral 8x7B 等 | 引入结构化 JSON 输出 | 2024 Q1 |
| Hermes 3 | Llama 3.1 8B/70B/405B | 长上下文 + 复杂多步工具调用 + 角色扮演 | 2024 Q3 |
Hermes 3 的关键能力升级
-
复杂多步 Function Calling:能在一个对话轮次中合理编排多个工具调用
-
长上下文(128K+):适合处理长文档和长时间 Agent 任务
-
System Prompt 遵循度极高:比同规模通用模型更能按指令约束行为
-
多语言支持:在中文、日文、法文等语言上的函数调用能力也明显优于同期的开源模型
三、Hermes 的 Function Calling 格式
这是 Hermes 最核心的技术贡献,也是面试中能拉开差距的知识点。
3.1 工具定义(Tool Definition)
使用 OpenAI 兼容的 JSON Schema 描述工具:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 '北京'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}
}
这些工具定义通过 system prompt 注入模型,模型被训练为理解工具描述语义并生成符合参数约束的调用 JSON。
3.2 调用输出格式
当模型决定调用工具时,它会输出一个严格的 JSON 块:
<tool_call>
{
"name": "get_weather",
"arguments": {
"city": "北京",
"unit": "celsius"
}
}
</tool_call>
解析器从 <tool_call> 标签中提取 JSON,执行工具,然后将结果以特定格式回传:
<tool_response>
{
"temperature": 22,
"condition": "晴",
"humidity": 45
}
</tool_response>
3.3 核心设计思想
用户输入 │ ▼ ┌──────────────┐ │ System │── 工具定义(JSON Schema) │ Prompt │── 行为约束(角色、规则) └──────┬───────┘ │ ▼ ┌──────────────┐ │ Hermes │── 推理:是否需要调工具? │ Model │── 不需要 → 直接回答 │ │── 需要 → 输出 <tool_call> JSON └──────┬───────┘ │ ▼ ┌──────────────┐ │ 解析 & │── 提取 JSON + 执行工具 │ 执行工具 │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ <tool_ │── 把结果格式化后回传给模型 │ response> │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ Hermes │── 基于工具结果生成最终回复 │ Model │ └──────────────┘
四、Hermes 与其他方案对比
| 维度 | Hermes (Nous) | GPT-4 Function Calling | Claude Tool Use | Llama 3.x 原生 |
|---|---|---|---|---|
| 开源 | ✅ 完全开源 | ❌ 闭源 API | ❌ 闭源 API | ✅ 开源 |
| FC 成熟度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 多步调用 | ✅ 支持 | ✅ 支持 | ✅ 支持 | 部分支持 |
| 结构化输出 | 通过 JSON Schema | strict mode | structured output | 有限 |
| 部署方式 | 本地 / 私有化 | 仅 API | 仅 API | 本地 |
| 中文 FC | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
选 Hermes 的理由
-
数据隐私要求高:不能把数据发到 OpenAI 等第三方 API
-
需要深度定制:要针对自己的业务场景做微调
-
成本控制:高频调用时,自部署比 API 便宜得多
-
离线/边缘部署:在无网络环境下跑 Agent
不选 Hermes 的理由
-
极致效果优先:GPT-4 和 Claude 在复杂推理上仍有优势
-
不想管运维:自托管模型有 GPU 成本和维护负担
-
任务不敏感:调 API 更快更省事
五、实战:用 Hermes 搭建一个 Agent
from openai import OpenAI
import json, re
class HermesAgent:
"""基于 Hermes 模型的简易 Agent"""
def __init__(self, model_endpoint: str, tools: list[dict]):
self.client = OpenAI(
base_url=model_endpoint, # 如 vLLM/Ollama 暴露的地址
api_key="not-needed"
)
self.model = "hermes" # 你的模型名
self.tools = {t["function"]["name"]: t for t in tools}
self.tool_handlers = {} # 工具名 → 实际执行函数
self.messages = []
def register_tool(self, name: str, tool_def: dict, handler: callable):
"""注册工具:定义 + 执行函数"""
self.tools[name] = tool_def
self.tool_handlers[name] = handler
def run(self, user_input: str) -> str:
self.messages.append({"role": "user", "content": user_input})
for _ in range(10): # 最多 10 轮工具调用
response = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
tools=[{"type": "function", "function": t} for t in self.tools.values()],
temperature=0.1, # 低温度提高格式稳定性
)
msg = response.choices[0].message
# 情况1: 模型直接回复了
if msg.content and not msg.tool_calls:
return msg.content
# 情况2: 模型要调工具
if msg.tool_calls:
self.messages.append({
"role": "assistant",
"content": msg.content,
"tool_calls": [
{
"id": tc.id,
"type": "function",
"function": {
"name": tc.function.name,
"arguments": tc.function.arguments
}
}
for tc in msg.tool_calls
]
})
for tc in msg.tool_calls:
fn_name = tc.function.name
fn_args = json.loads(tc.function.arguments)
handler = self.tool_handlers.get(fn_name)
if handler:
result = handler(**fn_args)
result_str = json.dumps(result, ensure_ascii=False)
else:
result_str = json.dumps({"error": f"工具 {fn_name} 未实现"})
self.messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": result_str
})
else:
# 无 tool_calls 也无 content 的异常情况
return "Agent 未能生成有效响应"
return "超出最大工具调用轮次"
# ========== 使用示例 ==========
def search_database(query: str, limit: int = 5) -> dict:
"""模拟数据库查询"""
return {
"query": query,
"results": [
{"id": 1, "name": "项目 Alpha", "status": "进行中"},
{"id": 2, "name": "项目 Beta", "status": "已完成"},
],
"total": 2
}
def send_notification(to: str, message: str) -> dict:
"""模拟发送通知"""
return {"status": "sent", "to": to, "message": message}
agent = HermesAgent(
model_endpoint="http://localhost:8000/v1",
tools=[
{
"type": "function",
"function": {
"name": "search_database",
"description": "搜索数据库中的项目信息",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"},
"limit": {"type": "integer", "description": "最大返回数"}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "send_notification",
"description": "向指定用户发送通知",
"parameters": {
"type": "object",
"properties": {
"to": {"type": "string", "description": "接收人"},
"message": {"type": "string", "description": "通知内容"}
},
"required": ["to", "message"]
}
}
}
]
)
agent.register_tool("search_database", {}, search_database)
agent.register_tool("send_notification", {}, send_notification)
# 运行
result = agent.run("帮我查一下有哪些项目还在进行中,然后通知张三")
print(result)
六、Hermes 的微调哲学:为什么开源模型也能做好 Function Calling
这是面试中能体现深度的加分项。Hermes 系列证明了:
6.1 数据质量 > 数据量
Hermes 的核心训练数据来自 Glaive——一个合成数据生成平台。关键技术点:
-
多样化的函数签名:覆盖数万种不同参数的函数,训练模型泛化到未见过的工具
-
多轮交互数据:不是单次调用,而是包含多步工具编排的完整对话
-
拒绝采样:多次生成选最优,提升数据质量
6.2 格式一致性训练
模型被训练为严格遵循 JSON Schema 约束输出。这需要:
-
在训练数据中加入大量格式错误的反例,让模型学会避免
-
引入 parallel function calling 数据,让模型学会一次输出多个工具调用
-
处理缺失参数、多余参数、类型错误等各种边缘情况
6.3 角色与指令的对齐
Hermes 3 特别强调 system prompt 遵循度。举例:
System: 你是一个不擅长数学的助手。遇到计算问题必须使用 calculate 工具,不要自己心算。 User: 123 * 456 = ? Hermes 3 行为: ✅ 调用 calculate 工具 普通模型行为: ❌ 直接说"123 × 456 = 56088"
这种对齐是微调中刻意强化的,对 Agent 可靠性至关重要。
七、面试高频问题
Q1: Hermes 模型和 GPT-4 的 Function Calling 本质区别是什么?
Hermes 是开源可自部署的方案,核心技术是微调数据驱动。GPT-4 FC 是闭源 API,内部机制不完全公开。Hermes 的优势在于隐私和可定制,GPT-4 的优势在于综合推理能力更强。本质上两者做的是同一件事——让 LLM 输出结构化的工具调用指令。
Q2: 为什么 Hermes 用 JSON Schema 定义工具?
JSON Schema 是描述结构化数据的工业标准,人和模型都能理解。它有丰富的约束语法(type、enum、required、properties),能精确描述参数规范。同时与 OpenAI 生态兼容。
Q3: Hermes 如何进行多步工具编排?
不是一次规划好的,而是逐步推理。每收到一个工具结果后,模型基于新信息决定下一步。这个过程内化在模型的多轮对话能力中,训练时用多轮工具调用数据进行了强化。
Q4: 什么是 tool_call 标签的作用?
<tool_call>是一个结构化标记,让解析器能精确地从模型输出中提取函数调用 JSON。它解决了自由文本中嵌入结构化数据的边界识别问题。类似于"结构化输出的哨兵值"。
Q5: Hermes 模型部署有哪些注意事项?
GPU 显存(7B 需要 ~14GB,70B 需要 ~140GB FP16)、推理框架选择(vLLM 追求吞吐,Ollama 追求易用)、温度参数(FC 场景建议 0.1 以下)、上下文长度管理(长会话需截断或总结)。
八、总结
理解 Hermes,记住三条线:
1. 定位:开源社区中 Function Calling / Agent 能力的标杆模型系列。
2. 核心贡献:证明了高质量合成数据 + 格式一致性训练就能让开源模型在 Agent 能力上逼近闭源水平。
3. 实战价值:需要私有化部署、数据合规、或深度定制 Agent 行为时,Hermes 是最值得考虑的基座选择之一。
本文写于 2026 年 6 月,Hermes 系列仍在持续迭代。建议关注 Nous Research 的官方博客和 HuggingFace 主页获取最新模型。
参考资源:
更多推荐



所有评论(0)