公司动态

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

📅 2026/8/8 7:18:47
【第二部分:大模型应用开发基础】7.Function Calling:让大模型调用真实程序能力
在前面的文章中我们已经介绍了大模型应用开发所需的基础知识以及 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 则负责工具注册、权限控制、调用执行、结果回传和循环终止。三、工具定义决定调用质量模型能否正确选择工具很大程度上取决于工具定义是否清晰。一个完整的工具定义通常包括工具名称、功能描述、参数结构和约束规则。以天气查询工具为例{ 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类似process、handle、execute等名称无法准确表达工具用途会增加模型误选工具的概率。模型选择工具时并不会搜索代码实现而是根据工具名称、功能描述和参数定义进行语义判断。工具越多、名称越相似描述质量越重要。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一类任务应该按照什么方法完成可复用的流程与领域经验MCPAgent 如何统一连接外部工具和数据标准化连接协议1. Function Calling 与 ReActReAct 强调模型在推理、行动和观察之间持续循环Reason判断当前需要解决什么 ↓ Act选择并执行一个动作 ↓ Observe读取动作执行结果 ↓ Reason根据结果决定下一步Function Calling 则负责将其中的“行动”表达为结构化工具请求。因此ReAct 是运行循环Function Calling 是循环中的行动接口。在一个 ReAct Agent 中每当模型决定查询天气、读取订单或创建任务时都可以通过 Function Calling 发起调用。生产系统通常不需要保存模型完整的内部推理过程但应记录可审计的执行轨迹包括模型选择了哪个工具、生成了哪些参数、工具返回了什么结果以及调用在哪一步失败。2. Tool 与 SkillTool 是一项具体的可执行能力例如读取合同、查询客户、创建审批单或转换文档。Skill 则描述完成某类任务的方法通常包含领域说明、处理步骤、检查规则、工具使用方式、示例和模板。例如“合同风险审查 Skill”可以规定提取合同主体和关键日期 定位付款、违约和解除条款 调用企业风险规则库 输出风险结论和证据页码 高风险结果进入人工复核其中读取合同和查询规则库属于 Tool按照什么顺序使用工具、如何判断结果以及何时转人工则属于 Skill。可以简单理解为Tool 提供能力Skill 提供方法。3. Function Calling 与 MCPFunction 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 可以连接前端界面操作也可以连接后端业务服务但二者的安全边界不同。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: Recordstring, unknown; }; const uiTools { open_order_detail: (args: Recordstring, unknown) { 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: Recordstring, unknown) { 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() ); }tenantId、userId、角色、访问令牌和权限代码等可信字段不能交给模型自由生成。模型可以表达用户想查询什么但不能决定用户是谁、属于哪个租户以及拥有哪些权限。七、失败处理与权限控制工具调用失败并不一定意味着系统异常。参数错误、信息缺失、权限不足和业务冲突都需要采用不同的处理方式。失败类型示例推荐处理方式参数错误日期格式不正确修正参数后限次重试信息缺失用户未提供订单号请求用户补充信息权限不足无权读取财务数据停止执行并明确提示业务冲突已退款订单再次退款返回业务原因不自动重试系统异常网络超时或服务不可用重试、熔断或降级工具执行结果最好采用统一结构{ success: false, error: { code: WEATHER_TIMEOUT, message: 天气服务暂时不可用, retryable: true }, traceId: 7d0e52f2 }模型可以根据错误类型调整下一步但最大重试次数、超时时间、指数退避、熔断策略和最大 Agent 步数应由运行时控制不能让模型在失败后无限循环。权限控制同样不能交给模型。模型只能申请调用工具真正的授权判断必须由应用系统完成。生产环境至少应建立以下控制机制根据用户、租户和业务场景动态提供工具避免模型看到无权使用的能力。在每次工具执行前重新校验用户身份、数据范围和资源权限。对删除、支付、退款、授权和对外发布等高风险操作增加人工确认。为写操作设置幂等键避免模型重试或任务恢复导致重复执行。记录用户、租户、工具名称、参数摘要、权限判断、执行结果和人工确认信息形成完整审计链路。安全的工具调用不是“模型生成参数后立即执行”而是“模型提出行动请求系统根据确定性规则决定是否执行”。八、并不是所有任务都需要 Function CallingFunction Calling 适合连接模型无法独立完成的实时数据和外部能力例如天气、库存、订单、CRM、ERP、审批、文件处理、搜索、代码执行和前端界面操作。如果任务只是文本改写、摘要、分类或内容生成并不依赖外部数据也不会产生真实业务动作则可以直接由模型完成。金额计算、状态判断、参数校验和权限检查等确定性逻辑也应优先由程序实现而不是重新交给模型推理。合理的职责边界是模型负责理解自然语言和处理不确定性程序负责执行确定性逻辑并控制真实业务。Function Calling 的价值并不是把所有代码逻辑交给模型而是让模型在合适的位置选择并组合已有程序能力。九、小结Function Calling 让大模型从“生成内容”进一步走向“调用真实程序能力”但模型并不会直接执行函数。完整的工具调用仍然需要应用程序完成工具注册、参数校验、权限判断、调用执行、结果回传、异常处理和审计记录。在整个 Agent 技术体系中Tool 提供具体能力Function Calling 表达调用请求ReAct 负责推理与行动循环Skill 沉淀可复用的方法和领域经验MCP 则为外部工具与数据提供标准化连接方式。Function Calling 解决了模型如何发起行动的问题但业务系统还需要可靠地处理模型生成的数据。例如模型可以调用工具创建任务单但任务名称、负责人、优先级、截止日期和验收标准如何稳定映射为 Java DTO、TypeScript Interface 或数据库字段仍然需要更严格的输出约束。上一篇回顾【第二部分大模型应用开发基础】6. Prompt Engineering 与 Context Engineering生产级 Agent 如何管理上下文-CSDN博客下一篇将进一步介绍Structured Output让模型输出可被程序可靠处理的数据我们将重点讨论 JSON Schema、字段校验、枚举、日期、金额、嵌套对象、输出修复和重试机制以及如何将自然语言需求稳定转换为结构化业务数据。