尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Function Calling 原理、API 工作流程与工具定义实践

Function Calling 原理、API 工作流程与工具定义实践 1. 学习背景与目的随着大语言模型能力的发展模型已经能够理解用户使用自然语言提出的复杂需求但大模型本身通常不能直接查询实时天气、访问数据库或执行项目中的 Java 方法。例如当用户询问“北京现在天气怎么样”时模型仅依靠自身训练数据无法保证回答的实时性和准确性。Function Calling 为大模型连接外部程序提供了一种实现方式。开发者可以提前向模型声明系统中可以使用的工具模型根据用户的自然语言判断是否需要调用工具并生成对应的函数名称和结构化参数。随后后端程序根据模型返回的信息执行真实函数并将执行结果重新返回给模型。本文主要学习 Function Calling 的基本原理、OpenAI Function Calling API 的通用工作流程、JSON Schema 在工具参数定义中的作用以及 Function Calling 与传统 API 的区别。同时本文使用 DashScope Java SDK 中的FunctionDefinition和ToolFunction完成一个天气查询工具的定义和测试。2. Function Calling 基本原理Function Calling 是一种让大模型与外部工具、程序接口和业务系统进行交互的机制。需要注意的是Function Calling 并不表示大模型能够直接执行 Java 函数。大模型主要负责以下工作理解用户的自然语言需求判断是否需要调用外部工具选择合适的工具从用户输入中提取工具参数按照规定格式生成函数调用信息。真正的函数执行仍然由后端程序负责。例如用户输入北京天气怎么样模型根据天气工具定义可能生成{ location: 北京 }随后Java 后端读取函数名称和参数并执行对应的天气查询方法。因此Function Calling 可以理解为大模型与传统程序之间的一层智能调度机制用户自然语言 ↓ 大模型理解用户意图 ↓ 选择工具并生成参数 ↓ 后端执行真实函数 ↓ 返回工具执行结果 ↓ 模型生成最终回答3. Function Calling 的完整工作流程3.1 开发者定义工具在调用模型之前开发者需要提前描述系统中有哪些工具。一个工具定义通常包括name工具名称 description工具作用 parameters工具参数要求以天气查询工具为例{ type: function, function: { name: get_current_weather, description: 查询指定城市的天气, parameters: { type: object, properties: { location: { type: string, description: 需要查询天气的城市名称 } }, required: [location], additionalProperties: false } } }这段内容并没有真正查询天气而是向模型说明系统中有一个名为 get_current_weather 的工具 该工具用于查询天气 调用时必须提供 location 参数 location 参数必须是字符串。3.2 提交用户消息和工具列表调用模型时请求中通常同时包含messages用户和模型之间的对话内容 tools当前模型可以使用的工具例如Message 中保存用户问题{ role: user, content: 北京天气怎么样 }Tools 中保存天气查询工具的定义。3.3 模型选择工具并生成参数模型接收到用户消息和工具定义后会判断当前问题是否需要调用工具。在本次测试中模型成功返回工具名称get_current_weather 工具参数{location:北京}这说明模型完成了两项工作识别出用户正在询问天气 从用户消息中提取出城市“北京”。3.4 后端执行真实函数模型返回工具名称和参数后Java 后端根据函数名称找到对应的工具方法并传入参数WeatherTool.execute(functionArguments);工具执行完成后返回结果例如{ success: true, location: 北京, weather: 晴, temperature: 30 }在本次学习实践中天气和温度采用模拟数据主要用于验证工具定义和参数提取流程并不代表真实天气查询结果。3.5 返回工具结果在完整的 Function Calling 流程中后端还需要将工具执行结果返回给模型。模型根据用户原始问题和工具结果生成更加自然的最终回答例如北京当前天气晴气温约为30℃。4. JSON 与 JSON Schema4.1 JSONJSON 是一种轻量级的结构化数据交换格式常用于不同程序、不同服务和不同编程语言之间传输数据。例如{ location: 北京 }这是一份实际的 JSON 数据表示location字段的值为“北京”。JSON 常见的数据类型包括类型示例string北京number30booleantrueobject{location:北京}array[北京,上海]nullnull4.2 JSON SchemaJSON Schema 并不是实际数据而是用于描述和约束 JSON 数据结构的一套规则。天气工具的参数 Schema 为{ type: object, properties: { location: { type: string, description: 需要查询天气的城市名称 } }, required: [location], additionalProperties: false }其中字段含义type: object参数整体是一个 JSON 对象properties定义对象中允许出现的字段location.type规定location必须是字符串description向模型解释参数的含义required规定必须提供的参数additionalProperties: false禁止模型生成未定义字段因此在 Function Calling 场景中可以将 JSON Schema 理解为工具参数的说明书和填写规则。JSON Schema 规定参数应该长什么样模型生成的arguments则是按照这些规则填写的实际数据。5. Tools 与 Messages 的区别工具定义和消息都使用 JSON 格式但二者的作用完全不同。对比项ToolsMessages主要作用描述模型可以使用哪些工具保存对话内容和上下文主要内容工具名称、描述、参数结构角色和消息内容是否包含 JSON Schemaparameters中包含普通消息一般不包含是否经常变化工具不变时相对固定每次对话都会变化核心字段name、description、parametersrole、content可以简单概括为Tools 管能力 Messages 管对话 Parameters 管工具参数格式 Arguments 是模型生成的实际参数。6. OpenAI Function Calling API 的通用工作流不同模型平台的具体类名和请求字段可能不同但 Function Calling 的核心流程基本一致。第一次模型请求第一次请求中需要提交用户消息 历史对话 可用工具定义。模型可能直接回答也可能返回工具调用请求。工具调用请求通常包含函数名称 函数参数 本次工具调用的唯一标识。后端执行函数后端根据模型返回的函数名称找到对应的 Java 方法并解析 JSON 格式的参数。返回工具结果工具执行完成后后端将结果与对应的调用标识一起返回给模型使模型能够判断该结果属于哪一次工具调用。第二次模型请求模型读取工具执行结果后生成最终自然语言回答。如果一个问题需要多个工具也可能继续发起新的工具调用。整个过程可以概括为第一次请求模型 → 模型返回工具调用 → 后端执行函数 → 返回工具结果 → 第二次请求模型 → 获得最终回答7. Function Calling 与传统 API 的区别对比项传统 APIFunction Calling输入方式固定参数或固定请求地址用户自然语言调用逻辑程序员提前写死模型根据语义选择工具参数来源前端或程序直接提供模型从用户语言中提取执行主体后端程序仍然是后端程序返回内容一般直接返回 JSON可以由模型重新组织为自然语言适用场景固定业务流程智能助手、多工具调度确定性相对较高受模型理解结果影响Function Calling 并不能替代传统 API。天气查询、数据库访问和业务操作仍然需要由传统接口或 Java 方法完成。Function Calling 的作用是Function Calling 的作用是在用户自然语言和传统 API 之间增加一层意图识别、工具选择和参数提取能力使程序可以通过更加灵活的方式调用已有的后端服务。8. DashScope Java 工具定义实践8.1 工具设计本次实践设计了一个天气查询工具工具名称get_current_weather 工具作用查询指定城市的天气 参数名称location 参数类型string 是否必填是8.2 使用 FunctionDefinition 封装工具DashScope SDK 提供了FunctionDefinition类用于封装工具名称、工具描述和参数结构。关键代码如下FunctionDefinition function FunctionDefinition.builder() .name(TOOL_NAME) .description(查询天气) .parameters( JsonUtils.parseString(parametersSchema) .getAsJsonObject() ) .build();随后使用ToolFunction将函数定义包装成模型可以识别的工具return ToolFunction.builder() .type(function) .function(function) .build();使用这些工具类可以避免开发者手动拼接完整的工具 JSON但参数部分仍然需要符合 JSON Schema 规范。8.3 工具执行方法工具执行方法接收模型生成的参数public static String execute(String argumentsJson) { JsonObject arguments JsonUtils.parseString(argumentsJson) .getAsJsonObject(); String location arguments.get(location).getAsString(); JsonObject result new JsonObject(); result.addProperty(success, true); result.addProperty(location, location); result.addProperty(weather, 晴); result.addProperty(temperature, 30); return result.toString(); }该方法首先解析模型返回的 JSON 参数获取location字段然后返回模拟天气结果。9. 运行结果与分析本地工具测试结果为工具执行结果 {success:true,location:北京,weather:晴,temperature:30}将工具定义和用户消息提交给模型后模型第一次返回工具名称get_current_weather 工具参数{location: 北京} 调用 IDcall_e377da710a22466084e3d4从运行结果可以看出模型成功识别了用户“北京天气怎么样”中的天气查询意图并正确选择了get_current_weather工具。同时模型能够从自然语言中提取城市名称“北京”并按照 JSON Schema 生成location参数。这说明工具的名称、描述和参数结构已经能够被模型正确理解。10. 面向初学者的 Function Calling 学习路径对于刚开始学习 Function Calling 的开发者不建议一开始就直接编写完整的模型调用流程。Function Calling 涉及 JSON、JSON Schema、工具定义、消息结构、模型调用以及后端函数执行等多个部分如果同时学习所有内容容易混淆不同模块之间的作用。较为合适的学习方式是从简单的数据格式开始逐步完成工具定义和最小 Demo。10.1 第一阶段掌握 JSON 基本格式首先需要了解 JSON 是一种结构化数据格式并掌握对象、数组、字符串、数字和布尔值等常见类型。例如{ location: 北京, temperature: 30, success: true }初学者应重点注意以下 JSON 语法规则JSON 对象使用大括号{}JSON 数组使用中括号[]字段名和字符串必须使用双引号不同字段之间使用逗号分隔JSON 中不能使用分号最后一个字段后不能添加多余的逗号。在学习过程中可以先手写几个简单的 JSON 对象并使用 JSON 格式校验工具检查语法是否正确。10.2 第二阶段学习 JSON Schema掌握基本 JSON 格式后再学习 JSON Schema。JSON Schema 的作用不是保存实际数据而是规定 JSON 数据应该采用什么结构。例如天气查询工具需要一个location参数对应的 JSON Schema 为{ type: object, properties: { location: { type: string, description: 需要查询天气的城市名称 } }, required: [location], additionalProperties: false }学习 JSON Schema 时可以先掌握以下字段type properties description required additionalProperties现阶段不需要学习 JSON Schema 的全部规范只需要能够根据工具需求定义简单的字符串、数字和布尔值参数。10.3 第三阶段区分工具定义和消息结构Function Calling 中容易混淆的两个概念是tools和messages。tools用于描述模型能够使用哪些工具例如天气查询、时间查询和计算工具messages用于保存系统消息、用户消息以及模型回复。可以概括为Tools 管能力 Messages 管对话 Parameters 管参数规则 Arguments 是模型生成的实际参数。初学者需要先理解二者的职责再进入 Java SDK 的使用阶段。10.4 第四阶段手写一个简单工具的 JSON Schema在使用 SDK 封装工具之前可以先根据需求手写参数 Schema。例如设计天气查询工具工具名称get_current_weather 工具作用查询指定城市的天气 参数名称location 参数类型string 是否必填是然后根据需求写出{ type: object, properties: { location: { type: string, description: 城市名称 } }, required: [location], additionalProperties: false }这一阶段的重点不是一次写对而是能够根据报错逐步检查字段拼写、逗号和大括号位置。10.5 第五阶段使用 FunctionDefinition 封装工具理解工具原始 JSON 格式后可以使用 DashScope SDK 提供的FunctionDefinition和ToolFunction进行封装。FunctionDefinition function FunctionDefinition.builder() .name(get_current_weather) .description(查询指定城市的天气) .parameters( JsonUtils.parseString(parametersSchema) .getAsJsonObject() ) .build(); ToolFunction weatherTool ToolFunction.builder() .type(function) .function(function) .build();使用 SDK 封装后开发者不需要手动拼接完整的工具 JSON但仍然需要正确编写parameters对应的 JSON Schema。10.6 第六阶段编写本地工具执行方法完成工具定义后可以先编写一个不依赖大模型的普通 Java 方法。public static String execute(String argumentsJson) { JsonObject arguments JsonUtils.parseString(argumentsJson) .getAsJsonObject(); String location arguments.get(location).getAsString(); JsonObject result new JsonObject(); result.addProperty(success, true); result.addProperty(location, location); result.addProperty(weather, 晴); result.addProperty(temperature, 30); return result.toString(); }在这一阶段可以先使用模拟数据不需要立即连接真实天气 API。这样能够把注意力集中在参数解析和工具执行流程上。10.7 第七阶段进行本地测试在连接模型之前应先测试工具定义和执行方法是否能够正常运行。public static void main(String[] args) { System.out.println(getToolDefinition()); System.out.println( execute({\location\:\北京\}) ); }如果能够正确输出工具定义和天气结果说明工具的 JSON Schema、Java 封装和执行方法已经基本正确。10.8 第八阶段完成第一次模型调用本地测试成功后再将用户消息和工具定义一起提交给模型。这一阶段只需要验证模型能否完成以下任务识别用户意图 选择正确的工具 从用户消息中提取参数 返回函数名称和 arguments。例如用户输入北京天气怎么样模型返回工具名称get_current_weather 工具参数{location:北京}如果能够得到以上结果就说明最基本的 Function Calling Demo 已经完成。10.9 第九阶段理解完整调用闭环在掌握第一次模型调用后再学习完整流程模型返回工具调用 → Java 执行工具 → 将工具结果添加到消息列表 → 再次请求模型 → 模型生成最终回答初学阶段不需要马上实现多工具并行调用、自动工具注册或复杂的调用循环应先保证单个工具的流程能够理解和运行。10.10 推荐学习顺序完整的初学者学习路径可以概括为学习 JSON 基本语法 → 学习 JSON Schema → 区分 Tools 和 Messages → 手写简单参数 Schema → 使用 FunctionDefinition 封装 → 编写本地 execute 方法 → 完成本地测试 → 完成第一次模型调用 → 学习完整工具调用闭环 → 扩展多个工具这种学习顺序能够将复杂问题拆分为多个小步骤。初学者不需要一开始就独立写出完整代码而应该先做到能够看懂工具格式、根据模板修改参数并理解模型与 Java 后端各自负责的工作。
返回列表