小白程序员必看:轻松掌握Function Calling,解锁大模型调用外部工具的秘籍!
本文介绍了Function Calling的概念和作用,它允许大模型调用外部工具实现更强大的功能。通过JSON Schema描述工具,模型可以判断何时调用哪个函数,并将请求发送给应用程序执行。文章详细解释了Function Calling的工作流程,包括工具注册、用户提问、模型判断、程序执行、结果回灌和模型最终回答。此外,还列举了新手容易犯的错误和避免这些错误的建议,以及Function Calling与Agent的关系和最小可运行示例。最后,文章讨论了Function Calling的价值和应用场景,强调了模型与程序之间的分工合作。
Function Calling—让大模型调用外部工具的机制。
你可以把大模型想象成一个只会在房间里走来走去的聪明人:它智商很高,但出不了门、碰不到东西。Function Calling 就是给他的一把把钥匙。每把钥匙对应一扇门,门后是一个真实世界的服务。模型学会判断"现在该用哪把钥匙",然后交给外面的人去开门、拿东西、再回来汇报。
从一个最朴素的例子开始
你问模型:“北京今天天气怎么样?”
如果大模型没有工具,它会怎么答?大概率是:
“我查不到实时天气,建议你打开天气 App 看看。”
这回答没错,但没用。现在给模型配一个 get_weather 工具,再问同样的问题,事情就不一样了。
模型看到问题后,会想:“用户问的是北京今天天气。我有一个 get_weather 工具可以查实时天气,需要传入城市名。我应该调用它。”
于是它不直接回答你,而是输出一段类似这样的东西:
{
"name":"get_weather",
"arguments":{"city":"北京"}
}
你的程序拿到这段请求,真的去调用天气 API,得到结果:
{"city":"北京","weather":"晴","temperature":"28°C"}
然后再把这个结果喂回给模型。模型这时才给出最终回答:
“北京今天晴天,气温 28°C,适合出门。”
整个过程分成了两步:先调用工具,再基于工具结果回答。Function Calling 就是连接这两步的协议。
Function Calling 不是模型在"执行代码"
这一点很多人会误解。看到模型输出一个函数调用,就以为模型自己跑到服务器上去执行了。
不是的。模型只负责"决定调用哪个函数、传什么参数"。真正执行函数的是你的应用程序。模型输出的那段 JSON,只是一个"调用请求",你的代码负责解析这个请求、执行真实逻辑、把结果返回。
这个设计很巧妙,因为它把"决策"和"执行"分开了:
- 模型做它擅长的事:理解意图、判断该用什么工具、组织参数
- 你的程序做它擅长的事:访问数据库、调 API、执行本地命令、保证安全
如果让模型自己执行代码,安全和可控性都是灾难。Function Calling 在"让模型更强大"和"保持系统可控"之间找了个平衡点。
JSON Schema:工具说明书
要让模型知道有哪些工具可用,你得给它一份"说明书",每个工具一份。行业里基本都用 JSON Schema 来描述。
以天气工具为例,说明书长这样:
{
"type":"function",
"function":{
"name":"get_weather",
"description":"查询指定城市的实时天气",
"parameters":{
"type":"object",
"properties":{
"city":{
"type":"string",
"description":"城市名称,例如:北京、上海"
},
"date":{
"type":"string",
"description":"日期,格式 YYYY-MM-DD,例如:2026-08-28"
}
},
"required":["city"]
}
}
}
这里面的每个字段都有用:
name
:函数名,要唯
一、好懂。
description
:自然语言描述,模型就是靠这个判断"什么时候该用这个函数"。写得越清楚,模型判断越准。
parameters
:参数列表,包括类型、含义、是否必填。
required
:哪些参数必须传。
description 是最容易被忽视的,也是最重要的。 你如果写得太模糊,模型会乱调用;写得太具体,它该调的时候又可能不敢调。
举个例子,你有两个函数:
search_company_info(company_name)
:查公司工商信息
search_news(query)
:查新闻
如果用户问"小米最近有什么新闻",模型看到 search_news 的描述,就会调用它;如果问"小米公司注册资本是多少",它应该调用 search_company_info。描述写准了,模型不会张冠李戴。

一次真实交互长什么样
把上面讲的东西串起来,一次 Function Calling 的完整交互如下:
第 1 步:系统提示里注册工具
你把所有工具的 JSON Schema 一次性告诉模型。注意是"告诉",不是"让它记"——每次请求都要带,因为模型无状态。
第 2 步:用户提问
用户:“北京今天天气怎么样?”
第 3 步:模型判断需要调用工具
模型发现用户问的是天气,自己手里有 get_weather,于是输出:
{
"name":"get_weather",
"arguments":{"city":"北京","date":"2026-08-28"}
}
第 4 步:程序执行函数
你的代码解析这个 JSON,调用真实的天气 API,拿到结果。
第 5 步:把结果回灌给模型
你把函数执行结果包装成一条"工具返回"消息,放进新的请求里:
{
"role":"tool",
"tool_call_id":"call_001",
"content":"北京今天晴,28°C"
}
第 6 步:模型给出最终回答
模型看到结果后,用自然语言回答用户:“北京今天晴天,28°C。”

这就是标准流程。Function Calling 本质上是一个"模型请求 → 程序执行 → 结果回灌 → 模型再回答"的协议。
新手最容易栽的几个地方
Function Calling 看似简单,但实际落地时坑不少。我列几个最常见的:
坑一:description 写得太潦草
我见过有人把工具描述写成:“用于查询”。模型看了根本不知道查什么,结果该调不调、不该调乱调。描述要回答三个问题:这个工具是干什么的、什么时候用、参数是什么意思。
坑二:参数类型对不上
Schema 里写 date 是 string,模型却可能给你传 "今天" 而不是 "2026-08-28"。你不做校验直接传进 API,大概率报错。Function Calling 不是银弹,模型也会"猜错"参数值,尤其是时间、数字这种需要格式化的东西。
坑三:函数返回 unstructured 文本
工具返回的内容如果是一段乱七八糟的字符串,模型很难从中提取有效信息。建议返回结构化数据(JSON),模型处理起来稳定得多。
坑四:不处理函数调用失败
真实世界里 API 会超时、会限流、会返回 500。你不处理,模型下一轮就会基于错误信息继续瞎跑。每次执行函数后,都要给模型一个明确的成功/失败结果。失败了,可以让模型重试,或者告诉用户"查询失败"。
坑五:工具太多导致模型"选择困难"
一次性给模型注册二三十个工具,它可能选错。工具数量多的时候,要做好分类,或者在 prompt 里明确告诉它"先选哪一个类别的工具"。

Function Calling 跟 Agent 是什么关系
很多人把这两个概念混在一起,其实关系很清楚:
Function Calling 是一种能力,Agent 是一种架构。
Function Calling 让大模型可以"伸出一只手"去调用外部工具。Agent 则是在这个能力之上,加上循环、记忆、规划,让模型能完成多步任务。
你可以这么理解:
- 单个 Function Calling:模型决定调用一次工具,然后回答。像问天气这种一轮就结束的场景。
- Agent:模型决定调用一次工具,看到结果,再决定第二次调用,再看到结果……直到任务完成。像订餐厅、做旅行规划这种多轮场景。
所以上一篇讲的 ReAct 循环,每一轮循环里都会发生一次或多次 Function Calling。Function Calling 是 Agent 这台机器里的"传动轴",负责把模型的决策翻译成实际动作。
一个最小可运行示例
为了让你有体感,下面给一个 Python 伪代码示例,展示 Function Calling 的主循环骨架:
import json
defget_weather(city):
# 真实项目里这里调天气 API
return {"city": city, "weather": "晴", "temperature": "28°C"}
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市实时天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
}
}]
messages = [
{"role": "system", "content": "你可以调用工具帮助用户。"},
{"role": "user", "content": "北京今天天气怎么样?"}
]
# 第一次调用模型
response = model.chat(messages, tools=tools)
# 如果模型要求调用工具
if response.tool_calls:
tool_call = response.tool_calls[0]
fn_name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
# 执行本地函数
result = globals()[fn_name](args)
# 把结果塞回 messages
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result, ensure_ascii=False)
})
# 第二次调用模型,让它基于结果回答
final = model.chat(messages, tools=tools)
print(final.content)
这个骨架抓住了 Function Calling 的核心:模型判断、程序执行、结果回灌、再生成回答。真实项目里会在这个骨架上加入错误处理、多工具管理、重试机制、日志追踪,但万变不离其宗。
一次要调多个工具,以及工具之间要"传话"
真实业务里,模型经常需要一次调用多个工具。比如用户问"帮我对比北京和上海今天谁更热,顺便看看这两个城市未来三天的机票哪个便宜",这背后至少涉及两个工具:查天气、查机票。模型可以并行决定"两个都调",你的程序拿到两个结果后一起喂回去,模型再做综合回答。
在协议层面,模型返回的 tool_calls 可以是一个数组,而不是单个对象——它一次说"我要调这两个":
{
"tool_calls":[
{"function":{"name":"get_weather","arguments":"{/"city/": /"北京/"}"}},
{"function":{"name":"get_weather","arguments":"{/"city/": /"上海/"}"}}
]
}
你的程序拿到这个数组,可以并行跑两个工具(各起一个请求),再把两个结果都塞回对话。这比"调完一个再调下一个"快得多。
更复杂的情况是工具之间要传话:工具 A 的返回结果,是工具 B 的输入。比如"查订单 → 拿到订单里的商品 ID → 用商品 ID 查库存"。这种链式调用,模型自己会处理:它先调 A,看到结果里有商品 ID,下一轮决策时就拿着这个 ID 去调 B。你的程序要做的,还是那套"执行 → 回灌 → 再决策"的循环,只不过循环里会出现一连串工具调用。这也是 Agent 能完成复杂任务的根本机制——Function Calling 是单步的,把单步串成链,就成了 Agent。
写好 Function Calling 的五个要点
讲了这么多,给你一份我自己写工具时常对照的清单,照着做能避开大部分新手坑:
一、description 写给"模型"看,不是写给人看。 模型没有你的业务背景,它只会读你写的字。把"这个工具干啥的、什么时候该用、输入是什么、输出是什么"用模型能听懂的大白话写清楚。宁可啰嗦,别含蓄。
二、参数 schema 越严越好。 能用枚举(enum)就别用自由字符串;能用数字范围约束就别开放区间;required 字段列全。约束越死,模型乱填的概率越低,你后端解析越省心。
三、永远校验参数再执行。 模型给的 arguments 可能是非法 JSON、可能是类型不对、可能是你业务里不存在的值。执行工具前必须做一层校验和兜底,别把模型的"随口一说"直接丢进你的数据库查询。
四、工具失败要返回结构化错误。 工具执行失败时,别只回一句"失败了"。返回清晰的错误信息(哪一步错、为什么错、能不能重试),模型才能据此调整参数再试一次。返回"调用失败"四个字,模型大概率会原地重试同样的错误。
五、控制工具数量和粒度。 一次性塞给模型二三十个工具,它会"选择困难",调用准确率下降。按场景分批给工具,每个工具职责单一、边界清晰,比堆一大坨杂糅工具效果好得多。
把这五条记牢,你搭出来的 Function Calling 就具备了上生产的基本素质。剩下的都是在具体业务里打磨参数、调提示词、加监控。
从"调不通"到"调得稳"
讲完设计,最后给一套我实际排错时用的套路。Function Calling 第一次接不通,八成是卡在这几个地方:
第一,模型压根不调工具。 现象是你明明给了工具,它却每次都直接回答、不动手。先查三件事:工具的 description 是不是写得太模糊,模型没意识到"这工具能解决这个问题";tools 参数有没有真的传进 API 调用(很多人代码里忘了把 tools 带上去);还有,是不是你在系统提示词里下了"不要使用任何工具"之类的反指令。
第二,调了工具但参数填错。 比如该传数字的地方传了字符串,该传城市名的地方传了"北京市"(多了个市字,你的接口只认"北京")。这种最隐蔽。对策是:把参数 schema 写严,并在执行前做一层类型转换和归一化。比如城市名统一 trim、统一去掉"市"字再查表。
第三,工具返回了,模型却"看不见"。 你明明把结果塞回了 messages,它下一轮却像没收到。常见原因是回灌的格式不对——Function Calling 要求工具结果用固定的 role(tool)和 tool_call_id 挂回去,你如果随手塞进一条普通 user 消息,模型就识别不出"这是上一步工具的执行结果"。
第四,反复调同一个工具死循环。 模型调了工具 A,拿到结果,又调 A,又拿结果,转了五六圈不出循环。这通常是提示词没给它"什么时候算完成"的明确标准。加一句"如果已经拿到足够信息就直接回答用户,不要再调用工具",能解决大部分。
调试时有个很实用的小技巧:把每次的 tools 定义、模型返回的 tool_calls、你实际执行的参数、工具的返回结果,全部打印成日志。Function Calling 是个多步协议,任何一步出错都会表现为"答非所问",光看最终输出是定位不到的。日志拉出来,哪一步歪了一目了然。
把这十节看完,你对 Function Calling 的理解,已经从"听说过"走到了"能独立接上线、调通、排错"。它是 Agent 的钥匙,也是你迈入更复杂 AI 应用的门把手。
什么时候不该用 Function Calling
前面一直在讲它多好用,这节泼点冷水——有些场景,硬上 Function Calling 反而是给自己找麻烦。
第一,流程是死的,就别让它"决策"。 如果你的业务逻辑是固定的"用户下单 → 查库存 → 扣款 → 发通知",每一步都是写死的,那直接用普通代码串起来就行,又快又稳又便宜。让模型来"决定调哪个工具",等于把确定的事交给一个概率系统,徒增不确定性和成本。
第二,工具很少且每次必用,也不用走"模型判断"这一步。 比如你就是想"每次都先查一次天气再回答",那直接在代码里固定调用天气接口、把结果拼进提示词即可,没必要让模型去"决定"要不要调——它每次都会调,这个决策是多余的。Function Calling 真正的价值在"多工具、按需选择",工具少到没得选时,它的优势体现不出来。
第三,对延迟极度敏感的场景。 每次 Function Calling 至少多一轮模型调用(模型先判断 → 你执行 → 模型再回答),比普通问答慢几百毫秒到几秒。做实时性要求高的服务(比如高频交易的即时报价),这个延迟可能不可接受,得换成预编译好的确定性逻辑。
一句话总结:Function Calling 是"把不确定交给模型、把确定留给自己"的桥梁。当你的场景里"不确定的部分"很少,这座桥反而是累赘。 用对地方它是钥匙,用错地方它是枷锁。
Function Calling 的价值,在于它让大模型从"会说话"进化到"能动手"。但动手的是你的程序,不是模型本身。模型只负责决定"拿什么钥匙开哪扇门"。
理解了这个分工,你就知道怎么设计工具、怎么写 description、怎么校验参数、怎么处理失败。Function Calling 用得好不好,关键不在模型,而在你给的说明书和外围的工程处理。
大模型的知识又多又杂,到底怎么学?
做这行久了,被问最多的问题就一个:大模型的知识又多又杂,我到底先学啥?翻了一堆资料,看啥都像重点,结果啥都没学进去。今天把我自己一路摸出来的顺序捋一遍,零基础、应届生、转行的都适用。跟着走,至少方向不乱、不瞎忙,学完拿得出手。
第一阶段(10天):初阶应用
这一阶段就一个目标:把大模型真正"玩明白",不是只会聊天那种,而是能调教它、能用代码把大模型和业务接起来。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
这阶段正式进实战,目标很实在:做出两个能拿出手的东西——一个私有知识库,一个 agent 对话机器人。
-
为什么要做 RAG
-
搭建一个简单的 ChatPDF
-
检索的基础概念
-
什么是向量表示(Embeddings)
-
向量数据库与向量检索
-
基于向量检索的 RAG
-
搭建 RAG 系统的扩展知识
-
混合检索与 RAG-Fusion 简介
-
向量模型本地部署
-
…
走完这 30 天,Python 或 JavaScript 背景的基本能独立做一套 RAG 应用,简历上也敢写"大模型应用开发"了。
第三阶段(约20天):动手微调
学到这,你已经开始 “造” 模型了 —— 通过微调,搞出垂直领域的专用小模型。
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你从 “只会用” 变成 “能造” 的 AI 小子。那么你还想往下探索吗?
想要入局AI大模型赛道、抢占行业红利的朋友,微信扫描下方CSDN官方认证二维码,即可100%免费领取全套学习资料!
第四阶段(20天):商业闭环,部署落地
技术学完,落地才算数。这阶段带你搞明白大模型怎么真正跑起来、用起来。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
想要入坑大模型的朋友,给大家准备了一份2026 年最新 AI 大模型全套学习资料:
1、大模型系统化学习路线

2、大模型学习视频教程

3、大模型学习书籍&电子文档

4、AI大模型最新行业报告

5、大模型项目实战&配套源码

6、2026大模型大厂面试真题

7、为什么要学习大模型?
我国在A大模型领域面临人才短缺,数量与质量均落后于发达国家。2023年,人才缺口已超百万,凸显培养不足。随着AI技术飞速发展,预计到2025年,这一缺口将急剧扩大至400万,严重制约我国AI产业的创新步伐。加强人才培养,优化教育体系,国际合作并进是破解困局、推动AI发展的关键。


8、适合谁学?
- 传统后端 / Java / 前端开发,想转型 AI 应用
- 大学生、应届生,想拿更好的 offer
- 产品经理、运营,想武装职业竞争力
- 技术负责人,想给团队落地提效
学习是反人性的,但回报是真金白银。技术会更新,赛道会切换,但只要你先动手,机会就永远站在你这边。
9、这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。
想要入局AI大模型赛道、抢占行业红利的朋友,微信扫描下方CSDN官方认证二维码,即可100%免费领取全套学习资料!
好了,就写到这。路线是死的,人是活的,卡住了随时来问我。觉得有用就点个收藏,别让它进收藏夹吃灰——动起来比啥都强。
更多推荐




所有评论(0)