本文介绍了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大模型最新行业报告

img

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

img

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

img

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%免费领取全套学习资料!在这里插入图片描述

好了,就写到这。路线是死的,人是活的,卡住了随时来问我。觉得有用就点个收藏,别让它进收藏夹吃灰——动起来比啥都强。

Logo

更多推荐