百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

AI大模型+Function Calling技术方案

ztj100 2025-06-23 23:41 39 浏览 0 评论

在 AI 智能体开发的过程中,RAG(Retrieval-Augmented Generation) 和 功能调用(Function Calling) 已经成为两种至关重要的模式。RAG 通过结合检索技术和生成模型的强大能力,使智能体能够实时从外部数据源获取信息,并在生成过程中增强其知识深度和推理能力。Function Calling模式为智能体提供了调用外部工具的能力,极大地扩展了其应用范围。智能体可以通过调用外部工具(如数据库操作、业务规则执行、算法工具调用等),完成更为复杂的任务和操作。这种灵活性使得智能体在各种实际场景中都能表现得更为高效和精确。本文将介绍使用Spring AI 开源框架,验证AI大模型如何调用外部函数。

1、什么是Function Calling

功能调用(Function Calling)允许大型语言模型(LLM)在必要时调用一个或多个可用的工具,这些工具通常由开发者定义。工具可以是任何东西:网页搜索、对外部 API 的调用,或特定代码的执行等。

功能调用是AI应用与模型交互中一个非常典型的范式,它可以辅助模型更好的回答用户问题。我们在给模型输入的过程中,附带上可用的函数列表(包含函数名、函数描述等),模型在收到问题和函数列表后,根据对问题的推理在必要的时候发起对函数的调用。

SpringAI 帮我们规范了函数定义、注册等过程,并在发起模型请求之前自动将函数注入到 Prompt 中,而当模型决策在合适的时候去调用某个函数时,Spring AI 完成函数调用动作,最终将函数执行结果与原始问题再一并发送给模型,模型根据新的输入决策下一步动作。这其中涉及与大模型的多次交互过程,一次函数调用就是一次完成的交互过程。

2、开发示例前提条件

  • JDK为17以上版本,本人使用的jdk21版本;
  • SpringBoot版本为3.x以上,本项目使用的是SpringBoot 3.3.3版本;
  • 本文采用了阿里巴巴的Qwen大模型进行实验与验证。若选用阿里巴巴的AI服务,则需首先在阿里云平台上开通相应的大型模型服务,并获取所需的API密钥,以便在后续代码中调用。具体的开通与配置步骤,请参阅阿里云大模型服务平台“百炼”的相关文档和指南https://help.aliyun.com/zh/model-studio/developer-reference/get-api-key。这样可以确保您能够顺利地集成和使用这些先进的AI资源。

3、添加maven依赖

创建springboot工程后,在pom.xml文件里引入ai相关sdk包,本示例使用了spring-ai-alibaba框架和Qwen模型,而spring-ai-alibaba又是基于spring-ai开发的,所以引入spring-ai-alibaba即可。

Pom.xml完整内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.yuncheng</groupId>

<artifactId>spring-ai-demo</artifactId>

<version>1.0-SNAPSHOT</version>

<properties>

<maven.compiler.source>21</maven.compiler.source>

<maven.compiler.target>21</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<spring-ai.version>1.0.0-M5</spring-ai.version>

<spring-ai-alibaba.version>1.0.0-M5.1</spring-ai-alibaba.version>

</properties>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>3.3.3</version>

<relativePath/>

</parent>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>com.alibaba.cloud.ai</groupId>

<artifactId>spring-ai-alibaba-starter</artifactId>

<version>${spring-ai-alibaba.version}</version>

</dependency>

</dependencies>

<repositories>

<repository>

<id>spring-milestones</id>

<name>Spring Milestones</name>

<url>https://repo.spring.io/milestone</url>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

<repository>

<id>spring-snapshots</id>

<name>Spring Snapshots</name>

<url>https://repo.spring.io/snapshot</url>

<releases>

<enabled>false</enabled>

</releases>

</repository>

<repository>

<id>aliyun</id>

<name>aliyun Repository</name>

<url>http://maven.aliyun.com/nexus/content/groups/public/</url>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>

</project>

3、配置yml文件

#配置访问阿里巴巴AI服务的api-key,并指定了使用qwen-plus模型

server:

port: 8080

spring:

application:

name: spring-ai-demo

ai:

dashscope:

api-key: sk-b90ad31bb3eb4a158524928354x39dc5

chat:

options:

model: qwen-plus

4、创建自定义的FunctionTools

自定义函数需要提供一个 name、description 和 function call signature,以便模型知道函数能做什么、期望的输入参数。Spring AI 使这一过程变得简单,只需定义一个返回 java.util.Function 的 @Bean 定义,并在调用 ChatModel 时将 bean 名称作为选项进行注册。在底层,Spring 会用适当的适配器代码包装你的 POJO(即函数),以便与 AI 模型进行交互,免去了编写繁琐的样板代码。FunctionCallback.java 接口和配套的 FunctionCallbackWrapper.java 工具类包含了底层实现代码,它们是简化 Java 回调函数的实现和注册的关键。

以下是自定义了模拟算术运算的函数,可以执行加法和乘法运算,在实际的业务中,你可以在自定义函数中执行数据库操作、调用HTTP服务、执行业务逻辑等。
import java.util.function.Function;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Description;

@Configuration

public class FunctionTools {

private static final Logger logger = LoggerFactory.getLogger(FunctionTools.class);

public record AddOperationRequest(int d1, int d2) {

}

public record MulOperationRequest(int d1, int d2) {

}

@Bean

@Description("加法运算")

public Function<AddOperationRequest, Integer> addOperation() {

return request -> {

logger.info("加法运算函数被调用了:" + request.d1 + "," + request.d2 );

return request.d1 + request.d2;

};

}

@Bean

@Description("乘法运算")

public Function<MulOperationRequest, Integer> mulOperation() {

return request -> {

logger.info("乘法运算函数被调用了:" + request.d1 + "," + request.d2 );

return request.d1 * request.d2;

};

}

}

如何定义&注册函数:

您可以在应用程序上下文中定义 @Beans,就像定义任何其他 Spring 管理对象一样。

在内部,Spring AI ChatModel 将创建一个 FunctionCallbackWrapper 包装器的实例,该包装器添加通过 AI 模型调用它的逻辑。@Bean 的名称作为 ChatOption 传递。

@Description 注释是可选的,它提供了函数描述,可帮助模型了解何时调用该函数。这是一个重要的属性,可帮助 AI 模型确定要调用哪个客户端函数。

5、创建ChatClient并启用自定义函数

以下代码创建一个简单的Controller类来测试验证。

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.ai.chat.client.ChatClient;

import org.springframework.ai.chat.model.ChatModel;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.MediaType;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("/ai")

public class FunctionCallController {

private static final Logger log = LoggerFactory.getLogger(FunctionCallController.class);

@Autowired

private ChatModel chatModel;

@GetMapping(value = "/chat", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)

public String ragJsonText(@RequestParam(value = "userMessage") String userMessage){

return ChatClient.builder(chatModel)

.build()

.prompt()

.system("""

您是算术计算器的代理。

您能够支持加法运算、乘法运算等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情。

在提供加法运算、乘法运算等操作之前,您必须从用户处获取如下信息:两个数字,运算类型。

请调用自定义函数执行加法运算、乘法运算。

请讲中文。

""")

.user(userMessage)

.functions("addOperation", "mulOperation")

.call()

.content();

}

}

为了让模型知道并调用您的自定义函数,您需要在 Prompt 请求中启用它,如上述代码,在functions("addOperation", "mulOperation")中告知ChatClient要使用这两个自定义函数。

另外指定了System Prompt:要求AI 模型被设定为一个算术计算器代理,能够执行加法和乘法运算,并且要求用户提供两个数字和运算类型。这个提示词内容很关键,如何让AI按照自己的意图去执行,要不断测试提示词内容。

6、测试验证Function Calling

以下测试通过4次提问进行验证AI大模型如何调用自定义函数Function:

第1次提问:打招呼

http://localhost:8080/ai/chat?userMessage=你好

返回信息如下:

你好!我是一个算术计算器的代理,目前我可以帮助你进行加法运算和乘法运算。请提供两个数字以及你想要进行的运算类型。

通过返回信息说明了,给ChatClient设置的system提示词生效了,按照默认角色输出了打招呼内容。

第2次提问:算加法

http://localhost:8080/ai/chat?userMessage=3加5等于几

返回信息如下:

3加5等于8。

此时查看后台日志输出,springai.functioncall.FunctionTools : 加法运算函数被调用了:3,5

通过返回信息说明了,证明确实调用了自定义加法函数

第3次提问:算乘法

http://localhost:8080/ai/chat?userMessage=2乘9等于多少

返回信息如下:

2乘9等于18。如果您还有其他数学问题,欢迎继续提问。

此时查看后台日志输出,springai.functioncall.FunctionTools : 乘法运算函数被调用了:2,9

通过返回信息说明了,证明确实调用了自定义乘法函数

第4次提问:算减法

http://localhost:8080/ai/chat?userMessage=5减3等于多少

返回信息如下:

目前我只能协助进行加法和乘法运算。减法功能将在后续版本中添加,敬请期待。如果您有其他运算需求,欢迎告诉我。

由于该示例中没有自定义减法运算函数,所以AI大模型还是按照提示词理解输出的,没有调用其它工具进行输出。

验证DeepSeek是否支持Function Calling

修改yml配置文件中的model值,改成deepseek-v3或deepseek-r1,重启springboot后再次测试。

spring:

ai:

dashscope:

api-key: sk-b90ad31bb3eb4a158524928354x39dc5

chat:

options:

model: deepseek-v3

再次请求http://localhost:8080/ai/chat?userMessage=3加5等于几

后台报错:

InternalError.Algo.InvalidParameter: The tool call is not supported

说明deepseek-v3和deepseek-r1目前不支持function calling功能。

相关推荐

Linux集群自动化监控系统Zabbix集群搭建到实战

自动化监控系统...

systemd是什么如何使用_systemd/system

systemd是什么如何使用简介Systemd是一个在现代Linux发行版中广泛使用的系统和服务管理器。它负责启动系统并管理系统中运行的服务和进程。使用管理服务systemd可以用来启动、停止、...

Linux服务器日常巡检脚本分享_linux服务器监控脚本

Linux系统日常巡检脚本,巡检内容包含了,磁盘,...

7,MySQL管理员用户管理_mysql 管理员用户

一、首次设置密码1.初始化时设置(推荐)mysqld--initialize--user=mysql--datadir=/data/3306/data--basedir=/usr/local...

Python数据库编程教程:第 1 章 数据库基础与 Python 连接入门

1.1数据库的核心概念在开始Python数据库编程之前,我们需要先理解几个核心概念。数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它就像一个电子化的文件柜,能让我们高效...

Linux自定义开机自启动服务脚本_linux添加开机自启动脚本

设置WGCloud开机自动启动服务init.d目录下新建脚本在/etc/rc.d/init.d新建启动脚本wgcloudstart.sh,内容如下...

linux系统启动流程和服务管理,带你进去系统的世界

Linux启动流程Rhel6启动过程:开机自检bios-->MBR引导-->GRUB菜单-->加载内核-->init进程初始化Rhel7启动过程:开机自检BIOS-->M...

CentOS7系统如何修改主机名_centos更改主机名称

请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习1.前言本文将讲解CentOS7系统如何修改主机名。...

前端工程师需要熟悉的Linux服务器(SSH 终端操作)指令

在Linux服务器管理中,SSH(SecureShell)是远程操作的核心工具。以下是SSH终端操作的常用命令和技巧,涵盖连接、文件操作、系统管理等场景:一、SSH连接服务器1.基本连接...

Linux开机自启服务完全指南:3步搞定系统服务管理器配置

为什么需要配置开机自启?想象一下:电商服务器重启后,MySQL和Nginx没自动启动,整个网站瘫痪!这就是为什么开机自启是Linux运维的必备技能。自启服务能确保核心程序在系统启动时自动运行,避免人工...

Kubernetes 高可用(HA)集群部署指南

Kubernetes高可用(HA)集群部署指南本指南涵盖从概念理解、架构选择,到kubeadm高可用部署、生产优化、监控备份和运维的全流程,适用于希望搭建稳定、生产级Kubernetes集群...

Linux项目开发,你必须了解Systemd服务!

1.Systemd简介...

Linux系统systemd服务管理工具使用技巧

简介:在Linux系统里,systemd就像是所有进程的“源头”,它可是系统中PID值为1的进程哟。systemd其实是一堆工具的组合,它的作用可不止是启动操作系统这么简单,像后台服务...

Red Hat Enterprise Linux 10 安装 Kubernetes (K8s) 集群及高级管理

一、前言...

Linux下NetworkManager和network的和平共处

简介我们在使用CentoOS系统时偶尔会遇到配置都正确但network启动不了的问题,这问题经常是由NetworkManager引起的,关闭NetworkManage并取消开机启动network就能正...

取消回复欢迎 发表评论: