一、面试题目
请你说明如何提升大模型 Function Call(工具调用) 准确率?常见的失败场景有哪些?分别怎么解决?
二、知识储备
1. 核心结论(面试必背)
提升 Function Call 准确率,本质是三件事:描述清晰、参数约束强、上下文干净、召回策略合理 。失败 90% 来自:意图识别错、参数填错、格式错、上下文乱、工具太多。
2. 提升 Function Call 准确率的 8 个工程方法
① 函数描述(description)必须精准、简短、明确
- 告诉模型什么时候调用 、不什么时候调用
- 描述越模糊,越容易误触发
② 参数定义要严格:类型 + 枚举 + 必填 + 示例
- 用
enum限制取值(城市、状态、类型) - 给
example - 必填参数严格标记
③ 控制工具数量:不要一次性塞太多工具
- 工具越多,模型越容易选错
- 按场景动态加载工具(分场景注册)
④ 清理上下文,不要带无关历史
- 冗余对话会干扰意图判断
- 用滑动窗口 / 摘要保持上下文干净
⑤ 缺失参数必须让模型主动追问
- 不要让模型瞎猜参数
- 配置模型:缺失参数时反问用户,不自行填充
⑥ 增加参数校验层(二次校验)
- 前端做规则校验
- 后端做参数格式 / 范围校验
- 错误直接返回让模型重推
⑦ 使用专用 Function Call 模型
- 专用微调模型 > 通用模型
- GPT / 通义 / 文心 都有 FC 优化版
⑧ 加入反思(Reflection)机制
- 调用失败 → 反思原因 → 修正参数 → 重试
- 大幅提升复杂任务成功率
3. 常见失败场景 + 根因 + 解决方案(面试高频)
场景 1:不该调用时乱调用(误触发)
① 原因:函数描述太泛、上下文干扰、工具太多
② 解决:
- 精简 description
- 明确写 "不需要时不调用"
- 分场景加载工具
- 清理上下文
场景 2:应该调用却不调用(漏调用)
① 原因:描述不清晰、用户问题太间接
② 解决:
- 增强描述
- 加示例
- 使用更强 FC 模型
场景 3:参数缺失、参数错误、类型不匹配
① 原因:模型瞎猜、用户信息不全、无枚举
② 解决:
- 枚举约束
- 开启自动追问
- 加参数校验
- 给示例
场景 4:选错函数(A 功能调用成 B)
① 原因:函数功能重叠、描述相似、工具太多
② 解决:
- 合并相似功能
- 明确区分功能边界
- 动态加载工具
场景 5:格式错误(模型不按 JSON 返回)
① 原因:模型版本不对、上下文混乱
② 解决:
- 使用官方 FC 接口,不要手动解析
- 保持上下文干净
场景 6:多轮调用失败(链式工具调用)
① 原因:中间结果丢失、上下文溢出
② 解决:
- 精简上下文
- 摘要历史
- 反思重试
4. 工程级最佳实践(高分回答)
- 函数描述精准化
- 参数严格枚举化
- 工具动态加载
- 上下文干净化
- 缺失参数追问
- 参数校验前置
- 失败反思重试
这套体系能把 FC 成功率从 60%~70% 提升到 95%+。
三、破局之道
在面试中用这段话展示深度:
Function Call 准确率低,本质不是模型能力问题,而是工程设计问题。函数描述不清、参数不约束、工具不分类、上下文不干净、缺乏校验与反思,必然导致调用失败。
提升准确率的核心思路是:让模型 "容易选对、容易填对、不能瞎猜、错了能改" 。真正生产级的工具调用,一定是严格定义 + 动态路由 + 参数校验 + 反思重试的闭环系统,而不只是简单丢给模型去调用。
四、代码实现
Python 版本(高质量 Function Call 工程模板)
python
# 高质量工具定义:描述清晰 + 枚举 + 必填 + 示例
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市的天气。仅当用户明确询问天气时调用。",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名,如北京、上海",
"enum": ["北京", "上海", "广州", "深圳"],
"example": "北京"
}
},
"required": ["city"]
}
}
}
]
# 工具执行 + 参数校验
def execute_function(func_name, parameters):
# 1. 参数校验层
if func_name == "get_weather":
city = parameters.get("city")
if not city or city not in ["北京", "上海", "广州", "深圳"]:
return {"error": "城市参数错误,请重新提供"}
# 2. 正常执行
return {"result": f"{city} 天气晴,25℃"}
return {"error": "函数不存在"}
# 带反思的完整调用流程
def function_call_with_reflect(query, history):
# 清理上下文
clean_history = history[-5:] # 滑动窗口
# 1. 模型原生FC
response = llm.chat(
messages=[{"role": "user", "content": query}],
tools=tools
)
# 2. 执行并校验
result = execute_function(response.name, response.parameters)
# 3. 失败反思重试
if "error" in result:
fix_prompt = f"调用失败:{result},请修正参数重新调用"
response = llm.chat([{"role": "user", "content": fix_prompt}], tools)
result = execute_function(response.name, response.parameters)
return result
JavaScript 版本
javascript
// 高质量工具定义
const tools = [{
name: "getWeather",
description: "查询城市天气,用户明确问天气才调用",
parameters: {
city: {
type: "string",
enum: ["北京", "上海", "广州", "深圳"],
required: true
}
}
}];
// 执行 + 校验
function executeFunction(name, params) {
if (name === "getWeather") {
const { city } = params;
if (!city || !["北京", "上海", "广州", "深圳"].includes(city)) {
return { error: "参数错误" };
}
return { result: `${city} 晴天` };
}
return { error: "不支持的函数" };
}
// 带反思的调用
async function fcWithReflection(query) {
const res = await llm.invoke(query, tools);
let result = executeFunction(res.functionName, res.arguments);
if (result.error) {
const fixRes = await llm.invoke(`失败:${result.error},请修正`, tools);
result = executeFunction(fixRes.functionName, fixRes.arguments);
}
return result;
}