大家好,我是拭心。

上篇文章我们了解了如何在 Android 手机上实现 RAG。这篇文章我们来聊聊端上大模型应用开发的核心概念:Function Calling(函数调用能力,简写为 FC)。

Function Calling 本质上是让大模型在回答过程中,不直接给出最终答案,而是根据需求,调用外部函数/API/工具,拿到外部数据后再继续回答。

在这里插入图片描述

它把大模型从「只会聊天的模型」变成了「会用工具的智能体」。

AI Edge Function Calling 是 Google 为 Android/iOS 等终端设备提供的函数调用 SDK,它的出现让端上模型也能调用外部函数,实现一些复杂的业务功能。

一、了解 AI Edge Function Calling API

一般来说,Function Calling 主要包括这几步:

  1. 定义函数声明:声明 LLM 可以调用的函数的结构和参数。
  2. 设置提示和输出格式:将函数的数据结构转换为字符串以及将字符串转换为函数结构,以便 LLM 能够以适当的格式显示信息。
  3. 解析输出:检测生成的响应是否包含函数调用,如果有将其解析为函数结构的数据类型,以便应用能够执行函数调用。
  4. 检查响应:检测到输出有函数调用,使用适当的参数和结构化数据类型调用该函数。否则,它会返回自然语言文本。

AI Edge Function Calling SDK 提供相关的 API:

  1. 函数定义,定义工具函数的名称和参数: FunctionDeclaration
  2. 输入格式设置器: ModelFormatter,用于将函数声明转换为 LLM 所需的特定于模型的格式,并将其插入系统提示
  3. 输出解析器: 还是 ModelFormatter,用于检测模型的输出是否表示函数调用,并将其解析为数据结构
  4. 推理后端,封装 LLM Inference API 和 ModelFormatter: InferenceBackend,最终通过 LlmInferenceBackendSession 实现核心功能

二、如何使用

只看文档不容易理解,接下来我们通过 Google 的 Function Calling demo,来看看 FC API 如何使用。

2.1 demo 功能

demo 功能:在用户录音后,将录音数据转化为表格里的内容,提升信息录入效率。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在 demo 中,Function Calling 扮演着"信息提取器"的角色。

当用户通过语音输入"我叫拭心,生日是1990年5月12日"时,函数调用机制能识别出"拭心"是姓名,"1990年5月12日"是生日,并将其与预定义的 first_namelast_name等参数相对应。

2.2 通过 demo 的实现了解怎么使用

了解 demo 功能后,接下来我们通过 demo 的源码了解下 Function Calling SDK 怎么使用。

在 demo 项目中,整体流程包括这几步:
在这里插入图片描述

2.2.1 初始化

在这里插入图片描述

在初始化时,创建了 FormViewModel,在其中会创建 HammerFormatter(ModelFormatter 的一个实现):

```kotlin
// in FormViewModel.createGenerativeModel()
val formatter =HammerFormatter(ModelFormatterOptions.builder().setAddPromptTemplate(true).build())
```

ModelFormatter 是连接模型与函数调用逻辑的关键:

  1. 请求格式化: 它将用户的文本输入、系统指令(systemInstruction)以及在 Tools.kt 中定义的可用工具(函数签名)打包成一个符合 Hammer 模型预期的提示(Prompt)。
  2. 响应解析: 当模型返回结果时,格式化器会解析输出,判断它是一个普通的文本回答还是一个结构化的函数调用请求。

随后创建了 GenerativeModel,它是 Function Calling SDK 的核心入口,整合了推理后端、系统指令和工具集。

```kotlin
// in FormViewModel.createGenerativeModel()
val systemInstruction = Content.newBuilder().setRole("system").addParts(Part.newBuilder().setText("This assistant will help you fill out a medical form.")).build()val model = GenerativeModel(llmInferenceBackend,systemInstruction,listOf(Tools.medicalFormTools).toMutableList() // 关键:定义模型可用的工具
)
```

2.2.2 函数注册

然后在 com/google/sample/fcdemo/functioncalling/Tools.kt 中声明了支持模型调用的函数列表:

val medicalFormTools: Tool = Tool.newBuilder().addFunctionDeclarations(// 1. 姓名函数FunctionDeclaration.newBuilder().setName("provide_name").setDescription("Records the user's first and last name.").setParameters(/* 参数定义 */)).addFunctionDeclarations(// 2. 生日函数FunctionDeclaration.newBuilder().setName("provide_dob").setDescription("Records the user's date of birth.").setParameters(/* 参数定义 */)).addFunctionDeclarations(// 3. 人口统计函数FunctionDeclaration.newBuilder().setName("provide_demographics").setDescription("Records the user's sex and marital status.").setParameters(/* 参数定义 */)).addFunctionDeclarations(// 4. 职业函数FunctionDeclaration.newBuilder().setName("provide_occupation").setDescription("Records the user's occupation or job.").setParameters(/* 参数定义 */)).addFunctionDeclarations(// 5. 医疗历史函数FunctionDeclaration.newBuilder().setName("update_medical_history").setDescription("Updates the user's medical history based on the conditions provided.").setParameters(/* 参数定义 */)).build()

函数声明通过 FC SDK 的 FunctionDeclaration。
在这里插入图片描述

2.2.3 用户输入

当用户输入"我叫拭心,生日是1990年5月12日"时,HammerFormatter 会构建一个包含以下元素的完整提示:

在这里插入图片描述

LlmInferenceBackendSession#addSystemMessage:

public void addSystemMessage(Content systemInstruction, List<Tool> tools) {this.systemInstruction = systemInstruction;this.tools = new ArrayList(tools);String systemMessage = this.formatter.formatSystemMessage(systemInstruction, tools);this.llmInferenceSession.addQueryChunk(systemMessage);
}

2.2.4 模型推理

模型接收到格式化后的提示后,会:

  1. 理解用户意图:识别出用户想要填写表单
  2. 匹配可用函数:从预定义的函数列表中找到最匹配的函数
  3. 提取结构化数据:从自然语言中提取出具体的参数值
  4. 生成函数调用:输出结构化的函数调用指令

当要调用函数时,模型返回的不是自然语言,而是结构化的函数调用对象:

{"functionCall": {"name": "provide_name","args": {"fieldsMap": {"first_name": {"stringValue": "拭心"},"last_name": {"stringValue": "<unknown>"}}}}
}

2.2.5 函数调用

在这里插入图片描述

模型返回的响应包含在 Part 对象中,每个 Part 可能包含一个 functionCall


// 1.模型处理
val response = chatSession!!.sendMessage(spokenText)// 2.从响应里找是否有函数调用
response.getCandidates(0).content.partsList?.forEach { part ->// extract the function from all the parts in the responseparts.forEach { part ->part?.functionCall?.args?.fieldsMap?.forEach { (key, value) ->value.stringValue?.let { stringValue ->if (stringValue != "<unknown>") {//3.有函数调用,更新对应的 valuewhen (key) {"first_name" -> _firstName.value = value.stringValue"last_name" -> _lastName.value = value.stringValue"occupation" -> _occupation.value = value.stringValue"sex" -> _sex.value = value.stringValue"marital_status" -> _maritalStatus.value = value.stringValue"date_of_birth" -> _dob.value = value.stringValue"conditions" -> {val currentMap = _medicalConditionsMap.value.toMutableMap()value.listValue.valuesList.forEach { condition ->currentMap[condition.stringValue] = true}_medicalConditionsMap.value = currentMap}else -> {throw Exception("Unknown function: $key value: $value")}}}}}}}

三、总结

好了,这就是 Google AI Edge Function Calling SDK 的相关介绍,它极大地简化 FC 与端侧大语言模型交互的复杂性,开发者无需手动进行复杂的提示工程和响应解析,只需定义好自己的"工具",即可让 AI 理解并执行任务,专注于应用的核心业务逻辑。

更多详细信息,请参阅 官方 Android 函数调用指南。

PS:记录一个容易混淆的问题,MCP 和 Function Calling 的关系?目前我的理解:

  • MCP 包含 Function Calling,但远不止于 Function Calling
  • MCP 试图统一所有上下文交互和外部工具接口,把 Function Calling 纳入整个智能体协议体系里

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87305.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87305.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/87305.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模型调试实用技巧 (Pytorch Lightning)

【PL 基础】模型调试实用技巧 摘要1. 设置断点2. 快速运行所有模型代码一次3. 缩短 epoch 长度4. 运行健全性检查5. 打印 LightningModule 权重摘要6. 打印输入输出层尺寸 摘要 本文总结了6种实用的模型调试技巧&#xff1a;1&#xff09;通过设置断点逐行检查代码&#xff1b;…

计算机网络(四)网际层IP

目录 一、概念 ​编辑 二、网际层和数据链路层的关系​ 三、IP地址的基础认识 四、IP地址的分类 五、无分类地址CIDR 六、子网掩码 七、为什么要分离网络号和主机号 八、公有IP和私有IP ​编辑 九、IP地址与路由控制 十、IP分片和重组 十一、IPv6 十二、IP协议…

Java--多态--向上转型--动态绑定机制--断点调试--向下转型

目录 1. 向上转型 2. 向下转型 3. java的动态绑定机制&#xff1a; 4. Object类讲解 5. 断点调试 1. 向上转型 提前&#xff1a;俩个对象&#xff08;类&#xff09;存在继承关系 本质&#xff1a;父类的引用指向了子类的对象 语法&#xff1a;父类 类型 引用名 new…

Python爬虫实战:研究urllib 库相关技术

1. 引言 1.1 研究背景与意义 互联网每天产生海量数据,如何高效获取和利用这些数据成为重要研究方向。网页爬虫作为自动获取网络信息的核心技术,在市场调研、舆情分析、学术研究等领域具有广泛应用。Python 凭借其简洁语法和丰富库支持,成为爬虫开发的首选语言。 1.2 相关…

【机器学习赋能的智能光子学器件系统研究与应用】

目前在Nature和Science杂志上发表的机器学习与光子学结合的研究主要集中在以下几个方面&#xff1a; 1.光子器件的逆向设计&#xff1a;通过机器学习&#xff0c;特别是深度学习&#xff0c;可以高效地进行光子器件的逆向设计&#xff0c;这在传统的多参数优化问题中尤为重要。…

Codeforces Round 1034 (Div. 3)

比赛链接如下&#xff1a;https://codeforces.com/contest/2123 A. Blackboard Game Initially, the integers from 00 to n−1 are written on a blackboard. In one round, Alice chooses an integer a on the blackboard and erases it;then Bob chooses an integer b on …

微电网系列之微电网的孤岛运行

个人主页&#xff1a;云纳星辰怀自在 座右铭&#xff1a;“所谓坚持&#xff0c;就是觉得还有希望&#xff01;” 微电网的孤岛运行 微电网具有并网和孤岛两种运行模式&#xff0c;由于孤岛运行模式下&#xff0c;分布式电源为微电网内部负荷提供频率和电压支撑&#xff0c;由…

JsonCpp的核心类及核心函数使用汇总

文章目录 JsonCpp的核心类及核心函数使用汇总一、前言二、JsonCpp 核心类介绍三、Value 类函数解析1. 值获取函数&#xff08;asxxx 系列 &#xff09;2. 值类型判断函数&#xff08;isxxx 系列 &#xff09;3. 数组操作函数4. 对象操作函数5. 运算符重载6. 迭代器7. JSON 转化…

Qt写入excel

1.tableView导出到excel 点击导出函数按钮、发送sendMessage信号&#xff08;信号名称&#xff0c;对象&#xff0c;数据&#xff09; void HydroelectricPowerPluginImpl::exportTableViewSelectedRows(QTableView* tableView, QWidget* parent) {if (!tableView || !tableVie…

OSCP - Proving Grounds - DC - 1

主要知识点 drupal 7 RCEfind SUID提权 具体步骤 nmap起手,80端口比较有意思&#xff0c;安装了 Drupal 7 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-17 14:23 UTC Nmap scan report for 192.168.57.193 Host is up (0.00087s latency). Not shown: 65531 cl…

仿小红书交流社区(微服务架构)

文章目录 framework - 平台基础设施starter - jacksoncommonexceptionresponseutil starter - content 全局上下文distributed - id - generate - 分布式 IdSnowflake - 基于雪花算法生成 IdSegment - 基于分段式生成 Id OSS - 对象存储KV - 短文本存储笔记评论 user - 用户服务…

大模型开源技术解析 4.5 的系列开源技术解析:从模型矩阵到产业赋能的全栈突破

提示&#xff1a;本篇文章 1300 字&#xff0c;阅读时间&#xff1a;5分钟。 前言 6 月 30 日&#xff0c;百度正式开源文心大模型 4.5 系列&#xff0c;这一动作不仅兑现了 2 月发布会上的技术承诺&#xff0c;更以 10 款全维度模型矩阵刷新了国内开源模型的技术边界。从学术…

[6-02-01].第05节:配置文件 - YAML配置文件语法

SpringBoot学习大纲 一、YAML语法 1.1.概述&#xff1a; 1.YAML是一种数据序列化格式&#xff1b;2.它是以数据为中心3.容易阅读&#xff0c;容易与脚本语言交互,如下图所示&#xff1a; 1.2.基本语法 1.key: value&#xff1a;kv之间有空格2.使用缩进表示层级关系3.缩进时…

FPGA学习

一、module : 定义&#xff1a; 是构建数字系统的基本单元&#xff0c;用于封装电路的结构和行为。它可以表示从简单的逻辑门到复杂的处理器等任何硬件组件。 1. module 的基本定义 module 模块名 (端口列表);// 端口声明input [位宽] 输入端口1;output [位宽] 输出端口1;ino…

26-计组-存储器与Cache机制

一、存储器与局部性原理 1. 局部性原理 基础概念&#xff1a; 时间局部性&#xff1a;一个存储单元被访问后&#xff0c;短时间内可能再次被访问&#xff08;例如循环变量&#xff09;。空间局部性&#xff1a;一个存储单元被访问后&#xff0c;其附近单元可能在短时间内被访…

I/O 线程 7.3

前言 以下&#xff1a; 概述 1.基础 2.代码演示 3.练习 4.分析题 1.基础 一、线程基础概念 并发执行原理 通过时间片轮转实现多任务"并行"效果 实际为CPU快速切换执行不同线程 线程 vs 进程 线程共享进程地址空间&#xff0c;切换开销更小 进程拥有独立资源&am…

MySQL JSON数据类型完全指南:从版本演进到企业实践的深度对话

&#x1f4ca; MySQL JSON数据类型完全指南&#xff1a;从版本演进到企业实践的深度对话 在当今数据驱动的时代&#xff0c;MySQL作为最受欢迎的关系型数据库之一&#xff0c;不断演进以满足现代应用的需求。JSON数据类型的引入&#xff0c;让MySQL在保持关系型数据库优势的同时…

BI × 餐饮行业 | 以数据应用重塑全链路业务增长路径

在竞争激烈的餐饮行业中&#xff0c;数据已成为企业保持竞争力的关键资产。通过深入分析顾客数据&#xff0c;餐饮企业能够洞察消费者的需求和偏好&#xff0c;从而提供更加精准和个性化的服务。此外&#xff0c;利用数据优化业务管理&#xff0c;降低成本&#xff0c;并提高运…

【学习线路】机器学习线路概述与内容关键点说明

文章目录 零、机器学习的企业价值一、基础概念1. 机器学习定义2. 学习类型3. 学习范式 二、核心算法与技术1. 监督学习2. 无监督学习3. 模型评估与优化 三、深度学习与神经网络1. 神经网络基础2. 深度学习框架3. 应用场景 四、工具与实践1. 数据处理2. 模型部署3. 机器学习的生…

Linux 命令:cp

Linux cp 命令详细教程 cp 是 Linux 系统中最常用的命令之一&#xff0c;用于复制文件或目录。它可以将源文件/目录复制到指定的目标位置&#xff0c;支持批量复制、强制覆盖、保留文件属性等功能。下面详细介绍其用法。资料已经分类整理好&#xff1a;https://pan.quark.cn/s…