当前位置: 首页 > news >正文

通义千问( 四 ) Function Call 函数调用

4.2.function call 函数调用

大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。

您可以使用function call功能,通过调用外部工具来提升模型的输出效果。您可以在调用大模型时,通过tools参数传入工具的名称、描述、入参等信息。

4.2.1.Function Call 流程

Function Call的工作流程示意图如下所示:

在这里插入图片描述

4.2.2.工具类

这里的一些工具类是一些测试工具类, 只是模拟对应的功能

获取天气

public class GetWhetherTool {private String location;public GetWhetherTool(String location) {this.location = location;}public String call() {return location + "今天是晴天";}
}

获取时间

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;public class GetTimeTool {public GetTimeTool() {}public String call() {LocalDateTime now = LocalDateTime.now();DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String currentTime = "当前时间:" + now.format(formatter) + "。";return currentTime;}
}

获取好友姓名

public class GetNamesTool {public GetNamesTool() {}public String call() {return "[\"王小二\",\"李小三\",\"赵小四\"]";}
}

4.2.3.调用处理

通过 通义大模型 进行函数调用

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.tools.FunctionDefinition;
import com.alibaba.dashscope.tools.ToolCallBase;
import com.alibaba.dashscope.tools.ToolCallFunction;
import com.alibaba.dashscope.tools.ToolFunction;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.victools.jsonschema.generator.*;
import com.yuan.tongyibase.tools.GetNamesTool;
import com.yuan.tongyibase.tools.GetTimeTool;
import com.yuan.tongyibase.tools.GetWhetherTool;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;import com.alibaba.dashscope.aigc.generation.GenerationOutput.Choice;@RestController
@RequestMapping("/tongyi")
public class CallFuncController {@Value("${tongyi.api-key}")private String apiKey;@RequestMapping("/call/func")public String callFunc(@RequestParam(value = "message", required = false, defaultValue = "中国的首都是哪里?") String message) throws NoApiKeyException, InputRequiredException {String selectTool = selectTool(message);return selectTool;}public String selectTool(String message) throws NoApiKeyException, ApiException, InputRequiredException {// 设置API密钥Constants.apiKey = apiKey;// 创建SchemaGeneratorConfigBuilder实例,指定使用JSON格式的模式版本SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON);// 构建SchemaGeneratorConfig配置,包含额外的OpenAPI格式值,但不使用枚举的toString方法进行展平SchemaGeneratorConfig config = configBuilder.with(Option.EXTRA_OPEN_API_FORMAT_VALUES).without(Option.FLATTENED_ENUMS_FROM_TOSTRING).build();// 根据配置创建SchemaGenerator实例,用于生成模式SchemaGenerator generator = new SchemaGenerator(config);// 生成GetWhetherTool类的JSON SchemaObjectNode jsonSchema_whether = generator.generateSchema(GetWhetherTool.class);// 生成GetTimeTool类的JSON SchemaObjectNode jsonSchema_time = generator.generateSchema(GetTimeTool.class);// 生成GetNamesTool类的JSON SchemaObjectNode jsonSchema_names = generator.generateSchema(GetNamesTool.class);// 构建获取指定地区天气的函数定义FunctionDefinition fd_whether = FunctionDefinition.builder().name("get_current_whether") // 设置函数名称.description("获取指定地区的天气") // 设置函数描述.parameters(JsonUtils.parseString(jsonSchema_whether.toString()).getAsJsonObject()) // 设置函数参数.build();// 构建获取当前时刻时间的函数定义FunctionDefinition fd_time = FunctionDefinition.builder().name("get_current_time") // 设置函数名称.description("获取当前时刻的时间") // 设置函数描述.parameters(JsonUtils.parseString(jsonSchema_time.toString()).getAsJsonObject()) // 设置函数参数.build();// 构建获取当前names的函数定义FunctionDefinition fd_names = FunctionDefinition.builder().name("get_current_names") // 设置函数名称.description("获取好友") // 设置函数描述.parameters(JsonUtils.parseString(jsonSchema_names.toString()).getAsJsonObject()) // 设置函数参数.build();// 构建系统消息,用于提示助手使用工具回答问题Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()) // 设置消息角色为系统.content("你是一个乐于助人的AI助手。当被问到问题时,尽可能使用工具。") // 设置消息内容.build();Message userMsg =Message.builder().role(Role.USER.getValue()).content(message).build();List<Message> messages = new ArrayList<>();messages.addAll(Arrays.asList(systemMsg, userMsg));// 构建生成参数对象,用于配置文本生成的相关参数GenerationParam param = GenerationParam.builder()// 设置所使用的模型为“qwen-max”.model("qwen-turbo") //qwen-max// 设置对话历史,用于模型生成时参考.messages(messages)// 设置生成结果的格式为消息格式.resultFormat(GenerationParam.ResultFormat.MESSAGE)// 设置可用的工具函数列表,包括天气查询和时间查询功能.tools(Arrays.asList(ToolFunction.builder().function(fd_whether).build(),ToolFunction.builder().function(fd_time).build(),ToolFunction.builder().function(fd_names).build())).build();// 大模型的第一轮调用Generation gen = new Generation();GenerationResult result = gen.call(param);System.out.println("\n大模型第一轮输出信息:" + JsonUtils.toJson(result));for (Choice choice : result.getOutput().getChoices()) {messages.add(choice.getMessage());// 如果需要调用工具if (result.getOutput().getChoices().get(0).getMessage().getToolCalls() != null) {for (ToolCallBase toolCall : result.getOutput().getChoices().get(0).getMessage().getToolCalls()) {if (toolCall.getType().equals("function")) {// 获取工具函数名称和入参String functionName = ((ToolCallFunction) toolCall).getFunction().getName();String functionArgument = ((ToolCallFunction) toolCall).getFunction().getArguments();// 大模型判断调用天气查询工具的情况if (functionName.equals("get_current_whether")) {GetWhetherTool GetWhetherFunction = JsonUtils.fromJson(functionArgument, GetWhetherTool.class);String whether = GetWhetherFunction.call();Message toolResultMessage = Message.builder().role("tool").content(String.valueOf(whether)).toolCallId(toolCall.getId()).build();messages.add(toolResultMessage);System.out.println("\n工具输出信息:" + whether);}// 大模型判断调用时间查询工具的情况else if (functionName.equals("get_current_time")) {GetTimeTool GetTimeFunction =JsonUtils.fromJson(functionArgument, GetTimeTool.class);String time = GetTimeFunction.call();Message toolResultMessage = Message.builder().role("tool").content(String.valueOf(time)).toolCallId(toolCall.getId()).build();messages.add(toolResultMessage);System.out.println("\n工具输出信息:" + time);}// 大模型判断调用[ names ]的情况else if (functionName.equals("get_current_names")) {GetNamesTool GetNamesFunction =JsonUtils.fromJson(functionArgument, GetNamesTool.class);String names = GetNamesFunction.call();Message toolResultMessage = Message.builder().role("tool").content(String.valueOf(names)).toolCallId(toolCall.getId()).build();messages.add(toolResultMessage);System.out.println("\n工具输出信息:" + names);}}}}// 如果无需调用工具,直接输出大模型的回复else {System.out.println("\n最终答案:" + result.getOutput().getChoices().get(0).getMessage().getContent());return "\n最终答案:" + result.getOutput().getChoices().get(0).getMessage().getContent();}}// 大模型的第二轮调用 包含工具输出信息param.setMessages(messages);result = gen.call(param);System.out.println("\n大模型第二轮输出信息:" + JsonUtils.toJson(result));System.out.println(("\n最终答案:" + result.getOutput().getChoices().get(0).getMessage().getContent()));return "\n最终答案:" + result.getOutput().getChoices().get(0).getMessage().getContent();}
}

4.2.4.测试

###
GET http://localhost:8081/tongyi/call/func?message=好友的名字是什么?

相关文章:

通义千问( 四 ) Function Call 函数调用

4.2.function call 函数调用 大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。 您可以使用function call功能&#xff0c;通过调用外部工具来提升模型的输出效果。您可以在调用大模型时&#xff0c;通过tools参数传入工具的名称、描述、入参等信息。…...

设置idea中放缩字体大小

由于idea没默认支持ctrl滚轴对字体调节大小&#xff0c;下面一起设置一下吧&#xff01; 点击 文件 -> 设置 按键映射 -> 编辑器操作 -> 搜索栏输入f 点击减小字体大小 -> 选择增加鼠标快捷键 按着ctrl键&#xff0c;鼠标向下滚动后&#xff0c;点击确定即可 然后…...

frameworks 之getEvent指令

frameworks 之getEvent指令 指令解析源码追溯源码解析1.解析参数2.初始化ufds数组3.添加到poll 并做对应处理 通过 getEvent 可以识别按键基本命令和里面的关键信息 涉及到的类如下 system/core/toolbox/toolbox.csystem/core/toolbox/tools.hsystem/core/toolbox/getevent.c …...

tensorboard显示一片空白解决方案

OK艾瑞巴蒂 不知道看这个视频几个小土堆过来的&#xff0c;今天已经发了一篇博文探讨快速下载tensorboard了 下面用的时候叒出现问题了 from torch.utils.tensorboard import SummaryWriter writer SummaryWriter("logs")# writer.add_image() # Yx for i in range…...

C#编程中,如何实现一个高效的数据排序算法?

在C#编程中&#xff0c;可以使用内置的排序方法来实现高效的数据排序。最常用的方法是使用Array.Sort()和List<T>.Sort()。这些方法内部使用了快速排序算法&#xff08;Quick Sort&#xff09;&#xff0c;它是一种非常高效的排序算法&#xff0c;平均时间复杂度为O(n lo…...

LookupError: Resource averaged_perceptron_tagger not found.解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

Leetcode JAVA刷刷站(39)组合总和

一、题目概述 二、思路方向 为了解决这个问题&#xff0c;我们可以使用回溯算法来找到所有可能的组合&#xff0c;使得组合中的数字之和等于目标数 target。因为数组中的元素可以无限制地重复选择&#xff0c;所以在回溯过程中&#xff0c;我们不需要跳过已经选择的元素&#x…...

Spring中AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory 是 Spring 框架中的一个抽象类&#xff0c;位于 org.springframework.beans.factory.support 包中。它实现了 AutowireCapableBeanFactory 接口&#xff0c;提供了一些通用的方法和逻辑&#xff0c;以支持 Spring 中的自动装配功能。 主要…...

PostgreSQL的walwriter和archiver进程区别

PostgreSQL的walwriter和archiver进程区别 在PostgreSQL中&#xff0c;walwriter和archiver进程是两个重要的后台进程&#xff0c;它们负责管理WAL&#xff08;Write-Ahead Logging&#xff0c;预写日志&#xff09;文件&#xff0c;但它们的职责和功能有所区别。理解这两个进…...

前端字体没有授权,字体版权检测(是否为方正字体)

1.截图系统中的首页和登录页面&#xff0c;主要是有字体的地方 2.在线字体版权检测地址&#xff1a;字体版权自动检测-求字体网 3.上传照片&#xff0c;开始对图片进行检测&#xff0c;每个账号有三次免费次数 4.检测完&#xff0c;直接查看检测报告即可&#xff0c; 报告中…...

在 SOCKS 和 HTTP 代理之间如何选择?

在 SOCKS 和 HTTP 代理之间进行选择需要彻底了解每种代理的工作原理以及它们传达的配置。只有这样&#xff0c;您才能轻松地在不同类型的代理之间进行选择。 本文概述了 HTTP 和 SOCKS 代理是什么、它们如何运作以及它们各自带来的好处。此外&#xff0c;我们将比较这两种代理类…...

C++适配windows和linux下网络编程TCP简单案例

C网络编程 网络协议是计算机网络中通信双方必须遵循的一套规则和约定&#xff0c;用于实现数据的传输、处理和控制。这些规则包括了数据格式、数据交换顺序、数据处理方式、错误检测和纠正等。网络协议是使不同类型的计算机和网络设备能够相互通信的基础&#xff0c;是网络通信…...

OpenDDS的GUID是如何构造的?

1、GUID、RepoID、GUID_t概念和关系 GUID(Global Unique IDentifiers)是RTPS规范约定的DDS对象的唯一性ID;RepoId(Repository IDentifiers)是Repo服务约定的DDS对象的唯一性ID;GUID和RepoId,都是基于GUID_t结构体定义,名称不同,但实质上是一样的。题外话: 无论是GUID还…...

初识MySQL(安装与配置环境)

嗨&#xff01;今天我们进入一个新的领域---数据库。 首先来个小小铺垫。 我们平时存储东西的时候&#xff0c;一般用到文件。为什么有文件了&#xff0c;还继续要这个数据库呢&#xff1f; 很明显&#xff0c;文件有一些不好的地方&#xff0c;需要数据库来进行补充。 文件…...

druid+logback打印sql执行日志

druid 的LogFilter 为我们准备了四种logger类型&#xff0c;对应打印 datasource相关、connection相关、statement相关、resultset相关的日志。 druid.sql.Datasource&#xff1a;打印数据源相关的字段。 druid.sql.Connection&#xff1a;打印应用程序获得数据库连接的过程。…...

C++编程:无锁环形队列 (LockFreeRingQueue)的简单实现、测试和分析

文章目录 0. 概述1. 无锁环形队列概述1.1 无锁环形队列的特点1.2 无锁环形队列的优势与局限 2. LockFreeRingQueue 实现2.1 Enqueue 操作流程图2.2 Dequeue 操作流程图 3. 核心实现细节3.1 环形队列的大小调整3.2 索引计算3.3 原子操作与CAS3.4 线程让步 4. 测试示例程序4.1 实…...

植物生长时为什么会扭动?科学家解开令查尔斯·达尔文困惑的千古之谜

在一项新的研究中&#xff0c;来自美国和以色列的物理学家可能已经弄清了植物生长过程中的一种古怪行为–也是查尔斯-达尔文本人在其生命的最后几十年里所好奇的一个谜&#xff1a;对于许多人类来说&#xff0c;植物可能看起来静止不动&#xff0c;甚至有点无趣。但实际上&…...

SAP LE学习笔记02 - WM和库存管理(IM)之间的关系,保管Lot(Quant)

上一章学习了LE的基础知识。 1&#xff0c;LE的概述&#xff0c;LE里面包含下面3个大的模块 - LE-WM 仓库管理 / - LE-SHP 发货/ - LE-TRA 运输 2&#xff0c;仓库的结构 - 仓库番号 / -保管域Type(存储区域)/ - 保管区画(存储区)/ - 棚番&#xff08;Storage Bin 仓位&…...

Span<T> 是 C# 7.2 引入的重要类型

Span<T> 是 C# 7.2 引入的一个非常重要的类型&#xff0c;它提供了一种低开销、类型安全的方式来操作连续的内存区域。Span<T> 本质上是一个结构体&#xff0c;它封装了一个内存段的引用&#xff08;通过指针&#xff09;以及该内存段的长度。由于它直接操作内存&a…...

Python办公自动化:初识 `openpyxl`

1.1 什么是 openpyxl&#xff1f; openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的 Python 库。它允许我们通过 Python 脚本自动化处理 Excel 文件&#xff0c;包括创建新的工作簿、修改现有的工作簿、格式化单元格、处理公式和图表等功能。这对于办公自动化、…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...