做AI应用的都知道,大模型最擅长的是"说",最不擅长的是"做"——让它写一段话很厉害,让它查个数据、调个接口就抓瞎了。Function Calling(函数调用)就是解决这个问题的关键能力:模型能"决定"调用哪个工具、传什么参数,把"对话"变成"行动"。我最近在项目里深度用了一把Function Calling,把订单查询、天气查询、库存检查都接进去了,踩了不少坑,这篇文章把实测过程和心得完整记录下来。
简单说,Function Calling让模型具备"工具使用"能力:
关键点:函数返回的是真实数据,模型只是"决定调谁",数据不再靠模型"编"——这是解决幻觉的终极方案之一,也是智能体(Agent)的基石。
我给内部客服做了一个订单查询助手,定义了两个函数:
tools = [
{
"type": "function",
"function": {
"name": "query_order",
"description": "根据订单号查询订单状态、金额、物流信息",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string", "description": "订单号"}
},
"required": ["order_id"]
}
}
},
{
"type": "function",
"function": {
"name": "get_user_orders",
"description": "根据用户ID查询该用户最近的所有订单",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string", "description": "用户ID"}
},
"required": ["user_id"]
}
}
}
]实测下来,当用户的问法规范时("帮我查订单A12345"),模型100%能正确选中query_order并填对参数。但一旦问法口语化、含糊,坑就来了。
用户说"查一下我昨天买的那个书包",模型可能把"书包"当成订单号传给query_order。解决:两个函数的description写得更细,明确"order_id必须是订单号格式(A开头+数字),不能是商品名";同时先调get_user_orders拿到订单列表,再让用户确认是哪一单。
函数多了以后,模型会选错函数——因为描述写得像。比如"query_order"和"get_order_detail"容易混淆。解决:函数数量控制住(5个以内),描述用"业务术语"写清楚差异;后来我把两个函数合并成一个,问题消失。
最坑的是:模型明明该调函数,却直接编了个答案回答用户。我排查发现是提示词里没说清楚"必须调用函数才能回答"。解决:在system prompt里加死规矩——"涉及订单信息的问题,必须先调用函数获取数据,禁止凭记忆回答"。
查询返回的订单列表有几十条,全塞回给模型,上下文爆了、回答也乱。解决:函数返回时做摘要(只返回最近5条+总数),并提示模型"如果用户需要更多,再追问"。
用户先问A订单,再问"那这个呢"——模型分不清"这个"指哪个订单。解决:在返回结果时把订单号带回给模型("已查询订单A12345:已发货"),让模型有上下文可循。
用100个真实客服问题测试:
指标 | 结果 |
|---|---|
正确触发函数 | 87% |
参数提取完全正确 | 79% |
回答基于真实数据(无编造) | 100%(调了函数就一定是真数据) |
需要人工兜底 | 13%(主要是含糊指代) |
最惊喜的是"无编造"这条:只要走通了函数调用,回答里的数据100%是真实的——这就是Function Calling对RAG的补充价值。
我的核心体会:
如果你正在做客服、查询、自动化类AI应用,Function Calling是必学的核心能力。它让模型从"只会说"变成"会做事",是AI落地从"聊天玩具"走向"生产力工具"的分水岭。