Agent 工程化系列 · 第 04 篇

Function Call 是什么?让大模型从“会说”变成“会做”的第一步

不是模型真的去执行函数,而是模型生成一份可被程序执行的工具调用请求。


开篇定位

前面三篇,我们已经把 Agent 最容易混淆的几个基础边界讲清楚了。

LLM 更像能力核心,负责理解、生成和推理。

Agent 更像执行系统,围绕目标持续推进任务。

Workflow 更像固定流程,适合确定性强的自动化。

到了这一篇,我们开始进入 Agent 工程化系列的第二阶段:工具与协议

因为一个 Agent 如果只能在聊天框里回答问题,它最多是一个聪明的助手。只有当它能连接外部系统、查询真实数据、触发业务动作时,它才开始具备“做事”的能力。

Function Call,就是让模型从“会说”走向“会做”的第一块积木。

在这里插入图片描述

图 1:Agent 工程化系列路线图


目录

  1. 为什么需要 Function Call?
  2. Function Call 一句话讲清楚
  3. 它到底怎么工作?
  4. 底层实现看哪几个关键点?
  5. 工程上怎么设计一个好工具?
  6. 它和 API、结构化输出有什么区别?
  7. 常见使用场景
  8. 最后总结

01 为什么需要 Function Call?

先看一个最简单的问题。

用户问:

“帮我查一下今天北京天气,如果下雨就提醒我带伞。”

普通 LLM 可以根据语言能力给你一个很像样的回答,但它有一个天然问题:

它不知道此刻真实的天气。

它可以推理、解释、生成文本,但不能凭空访问实时天气 API、数据库、订单系统、文件系统或者企业内部系统。

这就是 Function Call 出现的原因。

它不是为了让模型变得更会聊天,而是为了给模型接上外部能力。

在这里插入图片描述

图 2:为什么需要 Function Call

一句话定位

Function Call 是一种工具调用机制:模型根据上下文判断是否需要调用某个工具,并生成工具名和参数;真正执行工具的是应用程序。

OpenAI 文档把 Function Calling / Tool Calling 描述为让模型连接外部系统、访问训练数据之外的信息和动作能力的方式;函数工具通常通过 JSON Schema 描述输入结构。


02 Function Call 一句话讲清楚

很多人第一次听到 Function Call,会误以为:

“是不是大模型自己在执行函数?”

不是。

更准确的说法是:

模型不执行函数,模型生成调用意图。

也就是说,模型输出的不是最终自然语言答案,而是一段结构化请求:

{
  "name": "get_weather",
  "arguments": {
    "city": "北京"
  }
}

这段内容的意思是:

“我判断现在需要调用 get_weather 这个工具,参数是 city=北京。”

接下来,真正执行函数的,是你写的后端服务、Agent Runtime,或者某个工具执行器。

在这里插入图片描述

图 3:Function Call 的工程本质

可以这样理解

LLM 像一个会判断问题的调度员。

Function Call 像调度员写出的一张工单。

工具执行器像真正去办事的人。

最终结果再交回给 LLM,由它组织成用户能看懂的答案。


03 它到底怎么工作?

一个完整的 Function Call,通常不是一次请求就结束,而是一个多步骤闭环。

在这里插入图片描述

图 4:Function Call 的 5 步执行链路

第一步:应用把工具清单告诉模型

比如你告诉模型:

“你可以使用 get_weather 工具,它需要一个 city 参数,用来查询城市天气。”

这里的重点不是只写一个函数名,而是要描述清楚:

  • 这个工具叫什么;
  • 它什么时候该被使用;
  • 它需要哪些参数;
  • 参数类型和边界是什么;
  • 返回结果大概是什么格式。

第二步:模型判断是否需要工具

当用户提问时,模型会结合上下文判断:

“这个问题我能直接回答吗?还是必须调用工具?”

如果需要工具,它会返回一个 tool call。

第三步:应用侧执行真实函数

这一步非常关键。

模型并没有真的去访问天气服务,也没有真的去查数据库。

你的程序拿到 tool call 后,才会根据函数名和参数,去执行对应逻辑。

第四步:工具结果返回给模型

工具执行后,会把结果返回给模型。

例如:

{
  "city": "北京",
  "weather": "小雨",
  "temperature": "12℃"
}

第五步:模型生成最终回复

模型拿到工具结果后,再组织成人能读懂的话:

“北京今天小雨,气温 12℃,出门建议带伞。”


04 底层实现看哪几个关键点?

Function Call 看起来很简单,底层其实有几个非常重要的工程点。

在这里插入图片描述

图 5:底层到底传了什么

1. 工具定义:把能力描述给模型

工具定义通常包含:

字段 作用
name 工具名,模型用它选择调用哪个工具
description 工具说明,影响模型什么时候调用它
parameters 参数结构,通常使用 JSON Schema 描述
required 哪些参数必须提供
additionalProperties 是否允许模型传入额外字段
strict 是否要求更严格地符合 Schema

工具名要短、明确、可区分。

工具说明要写清楚“什么时候用”,而不是只写“这是一个查询工具”。

参数描述要尽量贴近业务语言,否则模型可能传错字段、漏传字段,或者在不该调用的时候调用。

2. 参数生成:模型输出结构化参数

Function Call 的关键优势之一,是让模型输出结构化参数。

相比让模型直接在文本里说:

“你可以查询北京天气。”

Function Call 更希望模型输出:

{
  "city": "北京",
  "date": "today"
}

这样应用程序才能稳定解析。

结构化输出技术也在强化这个方向:通过 Schema 约束模型输出,减少漏字段、乱字段和格式漂移的问题。

3. 应用执行:真正的动作发生在代码里

这是 Function Call 最容易被误解的地方。

模型负责的是:

“我认为应该调用这个工具,并且参数应该是这些。”

应用程序负责的是:

“这个调用是否允许?参数是否合法?该不该真的执行?执行后结果怎么返回?”

所以,Function Call 的安全边界不在模型里,而在你的工具执行层里。

4. 多轮调用:一次任务可能需要多个工具

实际 Agent 任务里,模型可能连续调用多个工具。

例如用户说:

“帮我查一下订单状态,如果已经发货,就把物流信息整理成一句话发给我。”

可能链路是:

  1. 调用订单查询工具;
  2. 根据订单状态判断是否发货;
  3. 调用物流查询工具;
  4. 整理成最终回复。

这时 Function Call 就变成 Agent 执行循环里的一个关键环节。


05 工程上怎么设计一个好工具?

Function Call 能不能好用,不只取决于模型能力,还取决于工具设计。

一个坏工具,会让模型不知道什么时候调用,也不知道怎么传参。

一个好工具,应该做到下面几点。

工具职责要单一

不要设计一个万能工具:

handle_user_request(anything)

这种工具对模型来说太模糊。

更好的方式是拆成明确工具:

query_order_status(order_id)
query_logistics(order_id)
create_refund_request(order_id, reason)

模型更容易判断该用哪个工具。

参数边界要清楚

不要让参数变成自由文本大杂烩。

比如退款原因可以是字符串,但退款类型最好用枚举:

{
  "refund_type": "only_refund | return_and_refund"
}

参数越清楚,系统越容易校验,也越容易做权限控制。

返回结果要适合模型阅读

工具返回结果不是越多越好。

如果返回一大段无结构日志,模型可能抓不住重点。

更好的返回方式是:

{
  "status": "shipped",
  "carrier": "顺丰",
  "tracking_no": "SF123456",
  "latest_event": "已到达深圳转运中心"
}

简洁、结构化、包含决策所需的信息。

高风险工具必须加确认

查询天气、查订单,风险比较低。

但如果工具会触发真实动作,比如删除文件、退款、发邮件、提交工单、修改数据库、远程执行命令,就不能只依赖模型判断。

这类工具必须加入权限校验、人工确认、审计日志和回滚策略。

在这里插入图片描述

图 6:Function Call 的执行网关设计


06 它和 API、结构化输出有什么区别?

Function Call 很容易和两个概念混在一起:普通 API 调用、结构化输出。

普通 API 调用

普通 API 调用,是代码主动决定调用哪个接口。

比如你写死流程:

用户输入城市 → 调天气 API → 返回结果

这属于传统程序逻辑。

结构化输出

结构化输出,是让模型最终答案符合某个格式。

比如从一段文本里抽取姓名、时间、地点,输出 JSON。

它解决的是“模型怎么稳定输出格式”的问题。

Function Call

Function Call 的核心是:

模型根据上下文决定是否调用工具,以及调用哪个工具。

它解决的是“模型如何接入外部动作能力”的问题。

在这里插入图片描述

图 7:Function Call、普通 API、Prompt 规则的边界


07 常见使用场景

Function Call 的场景很多,但最常见的是这几类。

实时信息查询

比如天气、汇率、股票、新闻、物流、库存。

这些信息不是模型训练时就能固定知道的,必须查外部系统。

企业内部系统接入

比如 CRM、ERP、工单系统、知识库、数据库。

用户用自然语言提问,模型负责理解意图,Function Call 负责把意图转换成系统动作。

自动化任务执行

比如创建日程、发送邮件、生成报告、触发审批、提交表单。

这类场景要特别注意权限和确认。

Agent 多步骤任务

在 Agent 系统里,Function Call 往往不是单独存在,而是出现在执行循环中。

Agent 先判断下一步要做什么,再调用工具拿到环境反馈,然后继续判断下一步。

这就是 Agent 从“回答问题”走向“完成任务”的关键。


08 最后总结

Function Call 不是一个花哨概念。

它解决的是大模型应用里非常核心的问题:

模型怎么把自然语言理解,转换成外部系统可以执行的动作入口。

这篇只需要记住三句话:

第一,模型不会真的执行函数,它只是生成工具调用请求。

第二,真正执行函数的是应用程序,所以权限、校验、日志和错误处理必须放在执行层。

第三,Function Call 是 Agent 能力体系里的关键基础设施,没有它,Agent 很难真正连接真实世界。

下一篇,我们会继续往下拆:

Function Call 底层到底怎么实现?

也就是从模型输出、JSON Schema、工具路由、运行时执行、错误处理这些角度,进一步讲清楚它背后的工程机制。


技术参考

  • OpenAI API Documentation:Function Calling / Tool Calling
  • OpenAI API Documentation:Structured Outputs / Tools
  • OpenAI Agents SDK:Tools
  • Anthropic Claude Docs:Tool Use
  • LangChain Documentation:Tools / Tool Calling
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐