【第二部分:大模型应用开发基础】7.Function Calling:让大模型调用真实程序能力

简介: Function Calling 让大模型从“生成文本”走向“调用真实程序能力”。模型根据工具名称、描述和 JSON Schema 选择工具、生成参数,应用程序再完成校验、鉴权、执行和结果回传。文章结合天气查询、销售数据与计算 Agent,说明并行调用、失败处理、前后端调用及权限控制,并梳理 Function Calling 与 ReAct、Tool、Skill、MCP 的关系:ReAct 负责执行循环,Tool 提供能力,Skill 沉淀方法,MCP 统一连接外部工具和数据

在前面的文章中,我们已经介绍了大模型应用开发所需的基础知识,以及 Prompt Engineering 和 Context Engineering 如何帮助模型理解任务、组织信息并形成判断。然而,理解问题并不等于完成任务。

模型可以识别用户想查询天气、分析销售数据或创建审批任务,但如果不能连接天气服务、业务数据库和审批系统,它最终仍然只能生成文字。Function Calling 解决的正是从“语言理解”到“程序执行”之间的连接问题:模型负责判断需要调用什么能力,应用程序负责校验请求、执行工具并返回真实结果。

这也是普通大模型应用向工具型 Agent 演进的关键一步。

一、Function Calling 到底是什么

Function Calling 也经常被称为 Tool Calling。它允许开发者将应用系统能够提供的函数、接口或工具描述给模型,模型再根据用户目标决定是否调用工具,并生成符合约定的结构化参数。

例如,用户提出:

📌 查询上海今天的天气。

模型不会直接执行天气接口,而是返回一个调用请求:

{

 "name": "get_weather",

 "arguments": {

   "city": "上海",

   "date": "2026-08-06"

 }

}

📋 模型返回的结构化调用请求

应用程序收到请求后,需要完成参数校验、权限判断和接口调用,再将天气服务返回的结果交给模型:

{

 "success": true,

 "data": {

   "city": "上海",

   "weather": "多云",

   "temperature": 32

 }

}

模型根据工具结果生成最终回答:

🌤️ 上海今天多云,气温约为 32℃。

因此,Function Calling 并不是让模型直接运行 Java、Python 或 JavaScript 函数,而是建立一种模型与应用程序之间的结构化调用协议。模型表达“希望执行什么操作”,应用程序决定该操作能否执行以及如何执行。

二、一次完整的工具调用如何完成

一个完整的 Function Calling 过程通常可以分为五个阶段。

首先,应用程序将用户请求、当前上下文和可用工具定义发送给模型。模型分析任务后,如果能够直接回答,就生成自然语言结果;如果需要实时数据、业务信息或外部操作,则返回一个或多个工具调用请求。

随后,应用程序根据工具名称找到对应执行器,并对参数格式、用户身份、租户范围和资源权限进行检查。校验通过后,应用调用本地函数、数据库、内部微服务或第三方 API,最后将执行结果作为工具消息重新加入模型上下文。

模型读取工具结果后,可以直接生成最终回答,也可以继续调用其他工具。

其核心过程可以概括为:

用户目标    模型理解任务    选择工具并生成参数    应用校验并执行工具    模型观察执行结果    继续调用或生成回答

这已经构成了一个最小的 Agent 执行循环。Function Calling 负责表达模型希望采取的行动,Agent Runtime 则负责工具注册、权限控制、调用执行、结果回传和循环终止。

function calling调用5个阶段.png

三、工具定义决定调用质量

模型能否正确选择工具,很大程度上取决于工具定义是否清晰。一个完整的工具定义通常包括工具名称、功能描述、参数结构和约束规则。

以天气查询工具为例:

{

 "type": "function",

 "name": "get_weather",

 "description": "查询指定城市在指定日期的天气,仅用于天气查询,不用于空气质量或历史气候分析。",

 "parameters": {

   "type": "object",

   "properties": {

     "city": { "type": "string", "description": "城市名称,例如上海、北京或杭州" },

     "date": { "type": "string", "format": "date", "description": "查询日期,格式为 YYYY-MM-DD" },

     "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位" }

   },

   "required": ["city", "date"],

   "additionalProperties": false

 },

 "strict": true

}

1. 工具名称应准确表达动作

工具名称最好采用明确的动词短语,例如:

get_weather

query_order

create_review_task

calculate_growth_rate

类似 processhandleexecute 等名称无法准确表达工具用途,会增加模型误选工具的概率。

模型选择工具时并不会搜索代码实现,而是根据工具名称、功能描述和参数定义进行语义判断。工具越多、名称越相似,描述质量越重要。

2. 工具描述应说明使用边界

传统函数注释主要供开发者阅读,而 Function Calling 中的工具描述会直接影响模型决策。除了说明工具能够做什么,还应明确什么时候使用、什么时候不能使用、是否修改数据以及是否需要用户确认。

例如,订单查询工具可以这样描述:

根据订单编号查询订单当前状态。本工具只读取数据,不修改订单。

用户未提供订单编号时不要调用,应先要求用户补充。

相比简单的“查询订单”,这种描述更容易帮助模型形成正确判断。

3. JSON Schema 是参数契约

JSON Schema 用于约束模型生成的调用参数,包括字段类型、必填属性、枚举值、日期格式、数字范围和嵌套结构。生产系统应尽量明确 required、限制枚举范围,并禁止模型生成未定义字段。

但 Schema 只能解决结构合法性,不能替代业务校验。例如:

{

 "orderId": "ORDER-001",

 "refundAmount": 999999

}

这段数据可能完全符合 JSON Schema,但退款金额是否超过订单实付金额,仍然需要业务系统判断。

因此,即使模型支持严格模式,应用程序也必须再次执行参数校验和业务规则检查

四、模型如何选择和组合工具

当应用向模型提供多个工具时,模型通常会先识别用户目标,再判断是否需要外部能力,随后比较各工具的名称、描述和参数要求,最终选择一个或多个工具并生成调用参数。

假设系统提供以下三个工具:

工具 作用
get_weather 查询指定城市天气
get_sales_summary 查询指定周期的销售数据
calculate_growth_rate 计算两个数值之间的增长率

当用户提出:

“查询上海今天的天气,并告诉我本月销售额比上月增长了多少。”

模型可以同时发起以下三个查询:

get_weather(上海,今天)

get_sales_summary(本月)

get_sales_summary(上月)

天气、本月销售额和上月销售额彼此没有依赖关系,可以并行执行。当两个月的销售数据返回后,模型再调用:

calculate_growth_rate(本月销售额,上月销售额)

因此,复杂任务中的工具调用通常不是简单地一次完成,而是形成“并行查询—结果汇总—依赖计算—最终生成”的执行过程。

随着工具数量增加,将所有工具定义一次性放入上下文会增加 Token 消耗和选择难度。更合理的做法是先根据用户身份、业务模块和任务类型筛选可用工具,再交给模型选择;在工具规模更大的系统中,还可以引入动态工具发现和分层工具注册机制。

五、Function Calling、ReAct、Tool、Skill 和 MCP 的关系

Function Calling 经常与 ReAct、Tool、Skill 和 MCP 同时出现,但它们并不是同一个层次的概念。

概念 解决的问题 核心定位
Tool 系统具体能够做什么 可执行程序能力
Function Calling 模型如何请求调用工具 结构化调用协议
ReAct 模型如何根据结果持续行动 推理、行动和观察循环
Skill 一类任务应该按照什么方法完成 可复用的流程与领域经验
MCP Agent 如何统一连接外部工具和数据 标准化连接协议

1. Function Calling 与 ReAct

ReAct 强调模型在推理、行动和观察之间持续循环:

Reason:判断当前需要解决什么    Act:选择并执行一个动作    Observe:读取动作执行结果    Reason:根据结果决定下一步

Function Calling 则负责将其中的“行动”表达为结构化工具请求。

因此,ReAct 是运行循环,Function Calling 是循环中的行动接口。在一个 ReAct Agent 中,每当模型决定查询天气、读取订单或创建任务时,都可以通过 Function Calling 发起调用。

ReAct 与工具调用反馈循环图.png

生产系统通常不需要保存模型完整的内部推理过程,但应记录可审计的执行轨迹,包括模型选择了哪个工具、生成了哪些参数、工具返回了什么结果以及调用在哪一步失败。

2. Tool 与 Skill

Tool 是一项具体的可执行能力,例如读取合同、查询客户、创建审批单或转换文档。

Skill 则描述完成某类任务的方法,通常包含领域说明、处理步骤、检查规则、工具使用方式、示例和模板。

例如,“合同风险审查 Skill”可以规定:

  • 提取合同主体和关键日期
  • 定位付款、违约和解除条款
  • 调用企业风险规则库
  • 输出风险结论和证据页码
  • 高风险结果进入人工复核

其中,读取合同和查询规则库属于 Tool;按照什么顺序使用工具、如何判断结果以及何时转人工,则属于 Skill。

💡 Tool 提供能力,Skill 提供方法。

3. Function Calling 与 MCP

Function Calling 通常发生在模型与 Agent Runtime 之间,用于表达模型想调用哪个工具以及使用哪些参数。

MCP 则主要解决 Agent Runtime 如何以统一方式连接外部工具、数据源和业务系统。MCP Server 可以对外提供工具、资源和提示模板,Agent Host 通过 MCP Client 发现并调用这些能力。

其关系可以概括为:

大模型    

Function Calling    

Agent Host / Runtime    

MCP Client    

MCP Server    

数据库、业务 API、文件系统

执行结果再沿相反方向返回模型,模型根据新信息继续推理。

因此,Function Calling 负责表达“模型要调用什么”,MCP 负责解决“Agent 如何标准化连接并执行外部能力”。

Function Calling 与 MCP 架构连接图.png

六、前端与后端应该如何实现工具调用

Function Calling 可以连接前端界面操作,也可以连接后端业务服务,但二者的安全边界不同。

1. 前端工具调用

前端工具适合处理低风险、可撤销的界面动作,例如打开订单详情、定位到文档指定页面、切换图表或填充表单草稿。

Agent 可以向前端返回如下事件:

{

 "type": "ui_tool_call",

 "name": "open_order_detail",

 "arguments": {

   "orderId": "ORDER-20260806-001"

 }

}

前端只执行预先注册的白名单函数:

type UiToolCall = {

 name: "open_order_detail" | "show_sales_chart";

 arguments: Record<string, unknown>;

};

const uiTools = {

 open_order_detail: (args) => {

   const orderId = String(args.orderId ?? "");

   if (!/^ORDER-[A-Za-z0-9-]+$/.test(orderId)) {

     throw new Error("订单编号不合法");

   }

   window.location.assign(`/orders/${encodeURIComponent(orderId)}`);

 },

 show_sales_chart: (args) => {

   window.dispatchEvent(new CustomEvent("agent:show-sales-chart", { detail: args }));

 }

};

function executeUiTool(call: UiToolCall): void {

 const executor = uiTools[call.name];

 if (!executor) throw new Error(`不允许执行前端工具:${call.name}`);

 executor(call.arguments);

}

前端不能使用 eval 或动态脚本执行模型生成的代码,模型 API 密钥也不能放在浏览器中。涉及删除、支付、权限修改和数据发布等高风险操作时,应由后端进行鉴权并引入人工确认。

2. 后端业务工具

假设 Agent 需要查询企业销售数据,可以定义以下工具:

{

 "type": "function",

 "name": "get_sales_summary",

 "description": "查询当前用户所属企业在指定日期范围内的销售汇总,只读操作。",

 "parameters": {

   "type": "object",

   "properties": {

     "startDate": { "type": "string", "format": "date" },

     "endDate": { "type": "string", "format": "date" }

   },

   "required": ["startDate", "endDate"],

   "additionalProperties": false

 }

}

模型只负责生成查询时间范围,用户身份和租户信息必须由服务端登录态提供:

public SalesSummary executeSalesTool(

       SalesQuery query,

       UserContext userContext) {

   permissionService.check(userContext.userId(), userContext.tenantId(), "sales:read");

   if (query.endDate().isBefore(query.startDate())) {

       throw new IllegalArgumentException("结束日期不能早于开始日期");

   }

   if (ChronoUnit.DAYS.between(query.startDate(), query.endDate()) > 366) {

       throw new IllegalArgumentException("查询范围不能超过一年");

   }

   return salesService.getSummary(userContext.tenantId(), query.startDate(), query.endDate());

}

tenantIduserId、角色、访问令牌和权限代码等可信字段不能交给模型自由生成。模型可以表达用户想查询什么,但不能决定用户是谁、属于哪个租户以及拥有哪些权限。

七、失败处理与权限控制

工具调用失败并不一定意味着系统异常。参数错误、信息缺失、权限不足和业务冲突都需要采用不同的处理方式。

失败类型 示例 推荐处理方式
参数错误 日期格式不正确 修正参数后限次重试
信息缺失 用户未提供订单号 请求用户补充信息
权限不足 无权读取财务数据 停止执行并明确提示
业务冲突 已退款订单再次退款 返回业务原因,不自动重试
系统异常 网络超时或服务不可用 重试、熔断或降级

工具执行结果最好采用统一结构:

{

 "success": false,

 "error": {

   "code": "WEATHER_TIMEOUT",

   "message": "天气服务暂时不可用",

   "retryable": true

 },

 "traceId": "7d0e52f2"

}

模型可以根据错误类型调整下一步,但最大重试次数、超时时间、指数退避、熔断策略和最大 Agent 步数应由运行时控制,不能让模型在失败后无限循环。

权限控制同样不能交给模型。模型只能申请调用工具,真正的授权判断必须由应用系统完成。生产环境至少应建立以下控制机制:

  • 根据用户、租户和业务场景动态提供工具,避免模型看到无权使用的能力。
  • 在每次工具执行前重新校验用户身份、数据范围和资源权限。
  • 对删除、支付、退款、授权和对外发布等高风险操作增加人工确认。
  • 为写操作设置幂等键,避免模型重试或任务恢复导致重复执行。
  • 记录用户、租户、工具名称、参数摘要、权限判断、执行结果和人工确认信息,形成完整审计链路。

安全的工具调用不是“模型生成参数后立即执行”,而是“模型提出行动请求,系统根据确定性规则决定是否执行”。

八、并不是所有任务都需要 Function Calling

Function Calling 适合连接模型无法独立完成的实时数据和外部能力,例如天气、库存、订单、CRM、ERP、审批、文件处理、搜索、代码执行和前端界面操作。

如果任务只是文本改写、摘要、分类或内容生成,并不依赖外部数据,也不会产生真实业务动作,则可以直接由模型完成。金额计算、状态判断、参数校验和权限检查等确定性逻辑,也应优先由程序实现,而不是重新交给模型推理。

合理的职责边界是:

模型负责理解自然语言和处理不确定性,程序负责执行确定性逻辑并控制真实业务。

Function Calling 的价值并不是把所有代码逻辑交给模型,而是让模型在合适的位置选择并组合已有程序能力。

九、小结

Function Calling 让大模型从“生成内容”进一步走向“调用真实程序能力”,但模型并不会直接执行函数。完整的工具调用仍然需要应用程序完成工具注册、参数校验、权限判断、调用执行、结果回传、异常处理和审计记录。

在整个 Agent 技术体系中,Tool 提供具体能力,Function Calling 表达调用请求,ReAct 负责推理与行动循环,Skill 沉淀可复用的方法和领域经验,MCP 则为外部工具与数据提供标准化连接方式。

Function Calling 解决了模型如何发起行动的问题,但业务系统还需要可靠地处理模型生成的数据。例如,模型可以调用工具创建任务单,但任务名称、负责人、优先级、截止日期和验收标准如何稳定映射为 Java DTO、TypeScript Interface 或数据库字段,仍然需要更严格的输出约束。


下一篇将进一步介绍:

Structured Output:让模型输出可被程序可靠处理的数据

我们将重点讨论 JSON Schema、字段校验、枚举、日期、金额、嵌套对象、输出修复和重试机制,以及如何将自然语言需求稳定转换为结构化业务数据。

— 持续更新 · 欢迎关注 —

相关文章
|
8天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1929 8
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
2天前
|
编解码 人工智能 安全
2核4G/4核8G/8核16G阿里云服务器如何选择实例?经济型e、通用算力型u2i与计算型c9i选哪个?
本文介绍了阿里云2核4G、4核8G、8核16G三档主流配置下经济型e、通用算力型u2i和计算型c9i三种实例的最新活动价格与适用场景。同配置下三者价差显著,以2核4G为例,经济型e低至599.93元/年,计算型c9i则高达1742.08元/年。文章详细解析了各实例的性能定位:经济型e适合轻负载入门场景,u2i兼顾稳定算力与性价比,c9i凭借第9代至强处理器与芯片级安全能力支撑高性能业务。同时提示用户可叠加满减优惠券享受折上折,建议根据业务负载与预算综合决策。
500 111
|
6天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
678 111
|
16天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2600 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
14天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1864 2
|
2天前
|
人工智能 程序员 API
Codex 接入 DeepSeek-V4-Flash:还能补上识图,提供两套方案
Codex 接入 DeepSeek-V4-Flash 怎么配?本文覆盖 CLI 与桌面端,再用 qwen3-vl-flash 补识图,两套方案可直接照做
|
16天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1453 2
|
3天前
Qoder 一周年 × Qwen3.8-Max 正式上线,多重好礼限时领
8月3日,Qwen3.8-Max 正式上线Qoder,迎来Qoder一周年。新老用户可领800次免费调用,下单再赠2000次;夜间(22:00–08:00)调用5折;邀请好友双方得积分与调用额度。
292 0