函数调用:智能体的核心能力
函数调用(Function Calling)是LLM从"聊天机器人"进化为"智能体"的关键能力。Hermes 4在这一维度上做了深度优化,将函数调用的准确率从78%提升到了94%以上。本文剖析其背后的技术细节。
函数调用的三个层次
层次一:格式约束(Format-Level)
最基础的层次——确保模型输出符合可解析的函数调用格式:
// 期望格式
{
"tool": "search_web",
"parameters": {
"query": "2026年AI最新进展",
"num_results": 5
}
}
早期模型依赖严格的格式提示词和后处理来保证格式正确性:
# 传统格式约束方法
FORMAT_PROMPT = """
你必须以严格的JSON格式回复,不要添加任何其他文本。
格式示例:
{"tool": "<函数名>", "parameters": {<参数键值对>}}
可用函数:
- search_web(query: str, num_results: int): 搜索网页
- send_email(to: str, subject: str, body: str): 发送邮件
"""
def parse_tool_call(response):
"""脆弱的JSON解析,需要大量容错处理"""
try:
# 尝试从回复中提取JSON
json_str = extract_json(response)
call = json.loads(json_str)
return validate_call(call)
except:
# 格式错误时的降级处理
return fallback_parse(response)
这种方法的问题在于:模型并不"理解"函数的用途,只是在模仿格式。
层次二:语义理解(Semantic-Level)
Hermes 4的核心突破在于让模型真正理解函数的语义——什么情况下该调用哪个函数、参数应该如何填充:
# Hermes 4 的语义级函数调用
class HermesFunctionCaller:
def __init__(self, model, tool_registry):
self.model = model
self.tools = tool_registry
async def call(self, user_request, context=None):
# 1. 语义路由:理解用户意图,匹配最合适的函数
intent = await self.model.understand_intent(user_request)
candidate_tools = self.tools.match(intent)
# 2. 参数推理:从对话中推理参数值
for tool in candidate_tools:
args = await self.model.infer_arguments(
tool_schema=tool.schema,
user_request=user_request,
context=context
)
# 3. 完整性验证:检查必填参数
missing = tool.check_required(args)
if missing:
# 主动追问缺失信息
return {"status": "need_info", "missing": missing}
# 4. 类型验证:确保参数类型正确
if tool.validate_types(args):
return {"status": "ready", "tool": tool.name, "args": args}
return {"status": "no_match"}
层次三:链式编排(Orchestration-Level)
最复杂的层次——根据用户目标自动编排多步函数调用:
# 用户请求:"帮我查一下明天北京的天气,然后发邮件告诉张三"
# 需要链式调用:get_weather → compose_email → send_email
class HermesOrchestrator:
async def plan_and_execute(self, user_goal, available_tools):
# 1. 任务分解
steps = await self.model.plan(
goal=user_goal,
tools=available_tools
)
# steps = [
# {"action": "get_weather", "args": {"city": "北京", "date": "明天"}},
# {"action": "compose_email", "depends_on": 0, "template": "weather_report"},
# {"action": "send_email", "depends_on": 1, "to": "张三"}
# ]
# 2. 逐步执行
results = {}
for i, step in enumerate(steps):
# 注入前序结果
if "depends_on" in step:
step = self.inject_dependency(step, results[step["depends_on"]])
# 执行函数
result = await self.execute(step)
results[i] = result
# 3. 异常处理:如果某步失败,尝试替代方案
if not result.success:
alternative = await self.model.find_alternative(step, available_tools)
if alternative:
results[i] = await self.execute(alternative)
return results
Hermes 4的优化细节
1. 工具描述的结构化编码
Hermes 4不依赖自然语言描述工具,而是使用结构化编码:
# 传统方式:自然语言描述
tool_description = """
Search the web for information.
Args:
query (str): The search query
num_results (int): Number of results to return, default 5
"""
# Hermes 4:结构化语义编码
tool_schema = {
"name": "search_web",
"semantic_id": "information_retrieval.web_search",
"description": {
"purpose": "retrieve_current_information",
"when_to_use": [
"user_asks_about_recent_events",
"model_knowledge_may_be_outdated",
"user_requests_specific_facts"
],
"when_not_to_use": [
"user_asks_for_opinion",
"information_is_in_provided_context"
]
},
"parameters": {
"query": {
"type": "string",
"semantic_role": "search_topic",
"extraction_hint": "rephrase user question as search query"
},
"num_results": {
"type": "integer",
"default": 5,
"semantic_role": "result_count",
"extraction_hint": "if user specifies number, use it; otherwise default"
}
}
}
2. 函数选择矩阵
Hermes 4在训练中构建了函数选择的决策矩阵,显著降低了误调用率:
| 用户意图 | 正确函数 | 常见误调用 | 误调用原因 |
|---|---|---|---|
| “帮我查天气” | get_weather | search_web | 语义重叠 |
| “发邮件给张三” | send_email | send_message | 通道混淆 |
| “把这个文件翻译成英文” | translate_text | summarize_text | 操作混淆 |
| “设置每天9点提醒” | create_reminder | update_schedule | 时序混淆 |
通过在训练数据中大量包含这些"易混淆"场景,Hermes 4将误调用率从12%降至3.5%。
3. 参数消歧机制
# 参数消歧示例
user_request = "帮我订一张明天去上海的机票"
# "明天"是日期参数,但今天是几号?需要从上下文推断
# "上海"是目的地,但出发地是哪里?需要追问或从用户历史推断
class ArgumentDisambiguator:
async def disambiguate(self, tool, raw_args, context):
disambiguated = {}
for param_name, param_value in raw_args.items():
if self.is_ambiguous(param_value):
# 策略1:从上下文推断
inferred = self.infer_from_context(param_value, context)
if inferred:
disambiguated[param_name] = inferred
elif tool.parameters[param_name].required:
# 策略2:追问用户
return {"status": "ambiguous",
"param": param_name,
"hint": tool.parameters[param_name].extraction_hint}
else:
# 策略3:使用默认值
disambiguated[param_name] = tool.parameters[param_name].default
else:
disambiguated[param_name] = param_value
return {"status": "ok", "args": disambiguated}
4. 错误恢复与重试
Hermes 4在函数调用失败时具备智能恢复能力:
class ErrorRecovery:
async def handle_failure(self, tool_call, error):
error_type = self.classify_error(error)
strategies = {
"timeout": self.retry_with_backoff,
"invalid_param": self.fix_and_retry,
"permission_denied": self.request_permission,
"not_found": self.find_alternative_tool,
"rate_limit": self.queue_and_wait,
}
strategy = strategies.get(error_type, self.ask_user)
return await strategy(tool_call, error)
async def fix_and_retry(self, tool_call, error):
"""根据错误信息自动修复参数"""
fix_prompt = f"""
函数 {tool_call.tool} 调用失败。
错误信息:{error.message}
当前参数:{tool_call.args}
请分析错误原因并修正参数。
"""
fixed_args = await self.model.complete(fix_prompt)
return await self.execute(tool_call.tool, fixed_args)
性能基准
函数调用准确率对比
| 任务复杂度 | Hermes 4 | Llama 4 Instruct | Qwen 3 | GPT-5 |
|---|---|---|---|---|
| 单函数单参数 | 98.1% | 94.2% | 95.0% | 98.8% |
| 单函数多参数 | 95.7% | 86.3% | 89.1% | 96.5% |
| 函数选择(易混淆) | 93.2% | 78.5% | 82.1% | 95.3% |
| 并行函数调用 | 91.5% | 72.3% | 76.8% | 94.2% |
| 链式调用(3步) | 87.3% | 65.8% | 70.2% | 91.5% |
| 链式调用(5步+) | 78.6% | 48.1% | 55.3% | 84.7% |
| 错误恢复 | 82.1% | 54.2% | 61.5% | 88.6% |
实践建议
针对Hermes 4的函数定义最佳实践
# ✅ 好的函数定义
{
"name": "search_products",
"description": {
"purpose": "在商品数据库中搜索商品",
"when_to_use": "用户想要查找、比较或购买商品时",
"when_not_to_use": "用户只是询问购物建议而无具体商品需求时"
},
"parameters": {
"query": {
"type": "string",
"description": "搜索关键词,应提取用户提到的商品名称或类型",
"required": true
},
"max_price": {
"type": "number",
"description": "最高价格限制,用户提到预算时填入",
"required": false,
"default": null
},
"category": {
"type": "string",
"enum": ["electronics", "clothing", "food", "books", "other"],
"description": "商品类别,根据用户描述判断",
"required": false
}
}
}
# ❌ 不好的函数定义(过于简略)
{
"name": "search",
"description": "Search products",
"parameters": {
"q": {"type": "string"},
"price": {"type": "number"},
"cat": {"type": "string"}
}
}
结语
函数调用是智能体从"能说话"到"能做事"的桥梁。Hermes 4的优化思路——从格式约束到语义理解再到智能编排——为开源智能体生态提供了一条清晰的发展路径。当模型不仅能正确填写参数,还能理解何时调用、如何恢复、怎样编排时,真正实用的AI智能体才算成型。