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

【Spring AI】Java实现类似langchain的第三方函数调用_原理与详细示例

Spring AI 介绍 :简化Java AI开发的统一接口解决方案

在过去,使用Java开发AI应用时面临的主要困境是没有统一且标准的封装库,导致开发者需要针对不同的AI服务提供商分别学习和对接各自的API,这增加了开发难度与迁移成本。而Spring AI的出现解决了这一问题,它提供了一套兼容市面上主要生成任务(如文本、图像生成)的标准接口。通过采用Spring AI,开发者只需编写一次代码,并通过修改配置即可轻松切换至不同AI供应商的服务,极大简化了AI功能集成过程,使得基于Java Spring的应用能够更加便捷地利用先进的AI能力。

Spring AI Alibaba:阿里的Spring AI最佳实践集合

Spring AI Alibaba 是基于 Spring AI 的实现,专为阿里云的百炼系列大模型提供接入服务。它继承了 Spring 生态系统的设计原则,如可移植性和模块化设计,并将其应用于人工智能领域。Spring AI 的核心优势在于其标准化了不同AI提供商(如OpenAI、Azure、阿里云等)的接口实现,使得开发者只需编写一次代码,通过修改配置即可轻松切换不同的AI后端。此外,Spring AI 直接兼容Flux流输出,简化了与市面上大多数基于流的机器人模型的集成过程。这不仅大幅减少了开发和迁移时的工作量,也提高了应用程序的灵活性和适应性。通过使用 Spring AI Alibaba,开发者可以更高效地构建并扩展利用通义千问等大模型的应用程序。

Spring AI函数调用(function calling) 机制探秘

在Spring AI中实现函数调用的原理是,用户首先定义一个实现了Function接口的Java类,该类通过特定的注解如@JsonProperty@JsonPropertyDescription来描述其输入参数、输出结果以及函数的具体作用。这些注解使得开发者能够明确指定函数的行为及其预期用途,为后续步骤打下基础。

当应用程序启动时,Spring AI会自动读取并解析这些注解信息,将它们转换成一种易于大模型理解的文字描述形式,并作为上下文的一部分传递给大模型。这样做是为了让大模型能够根据当前对话或任务的需求,判断是否需要调用某个已定义好的函数来完成更复杂的任务。如果大模型决定调用某项功能,则会在响应中明确指出希望调用哪个具体的函数及所需的参数值。

接下来,Spring AI接收到这一指示后,在本地环境中执行相应的Java方法,获取到执行结果。随后,它不仅将该结果反馈给大模型,同时还会一并将之前的对话历史或相关信息再次提交给大模型,以确保整个交互过程中的连贯性和一致性。这种方式有效地增强了AI系统的功能性与灵活性,使其能够利用外部工具或服务完成更加多样化且复杂的工作流程。

构建后端:Spring Boot集成Spring AI Alibaba实现第三方API调用优化利润分析

实现步骤

1. 环境准备与依赖添加

首先确保JDK版本为17及以上,Spring Boot版本为3.3.x以上。接着,在项目中添加必要的仓库和依赖。

仓库配置

<repositories><repository><id>sonatype-snapshots</id><url>https://oss.sonatype.org/content/repositories/snapshots</url><snapshots><enabled>true</enabled></snapshots></repository><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></repositories>

依赖配置

<dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M2</version></dependency><!-- 其他必需依赖 -->
</dependencies>
需要配置spring boot parent 
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version><relativePath/> <!-- lookup parent from repository --></parent>

2. 配置阿里云API Key

application.properties文件中设置阿里云通义大模型的API Key。

spring.ai.dashscope.api-key=YOUR_API_KEY
3. 创建函数定义

定义一个用于查询雪球股票利润表的Java函数。此函数将被注册给LLM使用。

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import org.springframework.web.client.RestTemplate;public class XueQiuStockService implements Function<XueQiuStockService.StockRequest, String> {private final RestTemplate restTemplate = new RestTemplate();@Overridepublic String apply(StockRequest request) {String url = "https://stock.xueqiu.com/v5/stock/finance/cn/income.json?symbol=" + request.getSymbol() + "&type=all&is_detail=true&count=1";String response = restTemplate.getForObject(url, String.class);// 对返回的数据进行简单处理或直接返回return response;}public static class StockRequest {@JsonProperty(required = true, value = "股票代码")@JsonPropertyDescription("股票代码, 如SH600900")private String symbol;public StockRequest() {}public StockRequest(String symbol) { this.symbol = symbol; }public String getSymbol() { return symbol; }public void setSymbol(String symbol) { this.symbol = symbol; }}
}
4. 注册函数

通过Spring配置类将上述定义的函数注册为一个Bean。

@Configuration
public class AppConfig {@Bean@Description("查询指定股票代码的利润表")public Function<XueQiuStockService.StockRequest, String> xueQiuStockFunction() {return new XueQiuStockService();}
}
5. 使用Prompt Template结合函数提供服务

创建Controller来接收请求并结合Prompt和已注册的函数执行操作。

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*")
public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient.Builder builder) {this.chatClient = builder.build();}@GetMapping("/chatSteam")public Flux<String> chatSteam(@RequestParam String input) {PromptTemplate promptTemplate = new PromptTemplate("{input} 的利润率是多少?请给出详细分析。");DashScopeChatOptionsBuilder opsBuilder = DashScopeChatOptions.builder().withFunction("xueQiuStockFunction");DashScopeChatOptions ops = opsBuilder.build();Map<String, Object> map = Map.of("input", input);Prompt prompt = promptTemplate.create(map, ops);return chatClient.prompt(prompt).stream().content();}
}

步骤解释

  1. 环境准备:确保开发环境满足基本要求(JDK、Spring Boot版本)。
  1. 依赖添加:添加了Spring AI Alibaba和其他必要依赖。
  1. 配置API Key:设置了阿里云API Key以启用大模型服务。
  1. 函数定义与注册:创建了一个简单的HTTP客户端函数来获取股票财务数据,并将其作为Spring Bean注册。
  1. 服务实现:编写了一个控制器方法,该方法接受用户输入(股票代码),构建带有特定提示的Prompt,并指示大模型调用之前注册的功能来获取所需数据。最终,返回模型生成的内容流。

这样就完成了基于Spring Boot集成Spring AI Alibaba以及使用其Function Calling能力完成对话和分析模型的任务。

构建前端:一个简单的对话基于React

为了构建一个基于React的简单前端项目,支持从后端接收流数据(flux<String>),可以按照以下步骤进行操作。此示例假设你的后端接口地址为 http://.../ai/chatStream?input=... 并且返回的是一个字符串流。

创建并初始化项目

首先,你需要创建一个新的 React 应用,并安装所有必要的依赖项。打开终端并运行以下命令:

npx create-react-app frontend
cd frontend
npm install

这将生成一个新的 React 项目结构,并自动安装基本的开发环境。

配置基础文件

确保你有如下几个基础文件设置好。这些文件通常不需要做过多修改,但确认它们的存在是重要的一步。

  • public/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Chat App</title></head><body><div id="root"></div></body></html>
  • src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);
  • src/App.js
import React from 'react';
import ChatComponent from './components/ChatComponent';function App() {return (<div className="App"><ChatComponent /></div>);
}export default App;
实现聊天组件

关键部分在于实现一个能够发送请求到后端并处理响应流的组件。这里我们定义了 ChatComponent 来完成这个任务。

  • src/components/ChatComponent.js
import React, { useState } from 'react';function ChatComponent() {const [input, setInput] = useState('');const [messages, setMessages] = useState('');const handleInputChange = (event) => {setInput(event.target.value);};const handleSendMessage = async () => {try {// 注意这里的URL应该替换为你实际使用的后端服务地址const response = await fetch(`http://.../ai/chatStream?input=${input}`, {method: 'GET', // 或者POST根据实际情况调整headers: {'Content-Type': 'application/json',// 如果需要认证信息或其他头信息,请在此添加},});if (!response.ok) throw new Error('Network response was not ok');const reader = response.body.getReader();const decoder = new TextDecoder('utf-8');let done = false;while (!done) {const { value, done: readerDone } = await reader.read();done = readerDone;const chunk = decoder.decode(value, { stream: true });setMessages((prevMessages) => prevMessages + chunk);  // 将接收到的数据拼接到现有消息中}} catch (error) {console.error('Failed to fetch:', error);}};const handleClearMessages = () => {setMessages('');};return (<div><inputtype="text"value={input}onChange={handleInputChange}placeholder="Enter your message"/><button onClick={handleSendMessage}>Send</button><button onClick={handleClearMessages}>Clear</button><div><h3>Messages:</h3><pre>{messages}</pre>  {/* 显示接收到的消息 */}</div></div>);
}export default ChatComponent;

这段代码实现了向指定URL发送请求,并通过流式读取响应内容逐步更新状态中的消息列表的功能。注意,如果您的后端API要求特定的HTTP方法或头部信息,则需相应地调整 fetch 请求的配置。

运行项目

最后,启动你的前端应用以查看效果:

npm start

以上步骤详细描述了如何基于React构建一个简单的支持流输出的前端项目。其中涉及到的主要技术包括使用React Hooks管理状态、利用Fetch API与后端通信以及处理服务器返回的流数据。确保在开发过程中保持前后端之间的良好协作,特别是关于CORS策略的设置,以便前端能够顺利访问到后端提供的资源。

相关文章:

【Spring AI】Java实现类似langchain的第三方函数调用_原理与详细示例

Spring AI 介绍 &#xff1a;简化Java AI开发的统一接口解决方案 在过去&#xff0c;使用Java开发AI应用时面临的主要困境是没有统一且标准的封装库&#xff0c;导致开发者需要针对不同的AI服务提供商分别学习和对接各自的API&#xff0c;这增加了开发难度与迁移成本。而Sprin…...

CIM系统:智慧城市的数字基石

计算机集成制造系统&#xff08;CIM&#xff09;是智慧城市建设中的关键技术&#xff0c;它通过集成多种信息技术&#xff0c;为城市提供一个全面的数字化镜像。CIM系统不仅涉及建筑信息模型&#xff08;BIM&#xff09;、地理信息系统&#xff08;GIS&#xff09;、物联网&…...

Android中Fragment的使用场景与生命周期

Android中Fragment的使用场景和生命周期 在Android应用开发中&#xff0c;Fragment是一个非常重要的概念&#xff0c;它允许开发者将Activity拆分成多个可重用的UI组件&#xff0c;从而提供灵活的UI设计&#xff0c;简化Activity的复杂性&#xff0c;并适应不同的屏幕尺寸和方…...

输入网址后,浏览器是如何高效渲染出网页的?

当你打开浏览器,输入一个网址并按下回车,接下来发生的一切仿佛都在瞬间完成——网页很快加载出来,内容、图片、动画一应俱全,像魔法一样。然而,这背后却是一个复杂而高效的协作过程,涉及到浏览器内核的多个组件共同工作,特别是渲染线程的协调作用。那么,浏览器究竟是如…...

springboot单文件,多文件下载方式

简单大文件下载&#xff1a; /*** 下载大文件* param path 路径* param fileName 文件名* return* throws IOException*/ public static ResponseEntity<InputStreamResource> downloadFile(String path, String fileName) throws IOException {Path filePath Paths.ge…...

JIT详解

文章目录 JIT为什么说 Java 语言“编译与解释并存”&#xff1f; JIT原理JVM 架构简览JIT 编译流程JIT 编译器的实现优化策略方法内联逃逸分析 JIT 在Java中&#xff0c;JIT&#xff08;Just-In-Time&#xff09;编译器是Java虚拟机&#xff08;JVM&#xff09;的一个重要组成…...

线下陪玩导游系统软件源码,家政预约服务源码(h5+小程序+app)

游戏陪玩系统源码陪玩小程序源码搭建基于PHP&#xff0b;MySQL陪玩系统app源码陪玩系统定制开发服务、成品陪玩系统源码 系统基于Nginx或者Apache PHP7.3 数据库mysql5.6 前端为uniapp-vue2.0 后端为thinkphp6 有域名授权加密&#xff0c;其他开源可二开 演示源码下载 开…...

模拟退火算法最常见知识点详解与原理简介控制策略

章节目录 模拟退火算法简介与原理 算法的基本流程与步骤 关键参数与控制策略 模拟退火算法的应用领域 如何学习模拟退火算法 资源简介与总结 一、模拟退火算法简介与原理 重点详细内容知识点总结 1. 模拟退火算法简介 模拟退火算法&#xff08;Simulated Annealing, SA&#x…...

C语言高效内存管理:对齐、缓存与位域

C语言高效内存管理&#xff1a;对齐、缓存与位域 一、内存对齐 1. 内存对齐的概念 内存对齐&#xff08;Memory Alignment&#xff09;是指数据在内存中存储时&#xff0c;其起始地址遵循特定的规则&#xff0c;使得数据能够被高效地访问。CPU通常以固定的字节数&#xff08…...

ES操作指南

# Creating a text file with the described Elasticsearch operations. es_operations """ Elasticsearch 基本操作语法&#xff1a; 1. 索引文档 (Index Documents): 自动生成 ID: POST /index_name/_doc { "field1": "value1", "…...

【黑苹果】记录MacOS升级Sonoma的过程

【黑苹果】记录MacOS升级Sonoma的过程 一、硬件二、提前说明三、准备OC四、选择驱动五、选择ACPI六、下载内核扩展七、其他问题 一、硬件 设备是神舟zx6-ct5da 具体参照下图 二、提前说明 本机器已经安装过 macOS Monterey 12.6&#xff0c;这次是升级到 macOS Sonoma 14。 …...

向“新”发力,朝“质”攀峰 | 资福医疗携手大圣胃肠一体内窥镜系统亮相江苏省医学会第八次健康管理学学术会议

伴随“健康中国”战略的深入实施&#xff0c;为进一步加强健康管理学科内涵建设&#xff0c;提升健康管理服务能力&#xff0c;促进健康管理学科创新及多部门、多产业交叉融合&#xff0c;2024年10月12&#xff5e;14日“江苏省医学会第八次健康管理学学术会议”在南京顺利召开…...

springboot项目多个数据源配置 dblink

当项目中涉及到多个数据库连接的时候该如何处理&#xff1f; 在对应的配置文件&#xff0c;配置对应的数据库情况&#xff0c;不过我确实没咋测试对于事务的处理我可以后续在多做测试 配置文件中配置对应的数据源 然后再使用的时候使用这个 DS(“pd_ob”)注解。 然后又长知识…...

leetcode中哈希的python解法:Counter()介绍

Counter 是 Python 的 collections 模块中的一个类&#xff0c;用于统计可迭代对象中元素的出现次数。Counter 是一种专门为计数设计的哈希表&#xff08;字典&#xff09;&#xff0c;它的键是元素&#xff0c;值是元素出现的次数。 Counter 的特点&#xff1a; 继承自 dict…...

VAS1800Q奇力科技线性芯片电荷泵热处理AEC-Q1000

VAS1800Q是一款专为汽车应用设计的高效恒流LED驱动器。它具备多个显著特点&#xff0c;不仅提升了LED驱动效率&#xff0c;还大大减少了热量的产生&#xff0c;使其在汽车照明领域中具有极高的应用价值。本文将详细介绍VAS1800Q的技术参数、功能及其在实际应用中的优势。 主要…...

Java 枚举的 valueOf() 方法与 Stream API 查找枚举对象

文章目录 一、枚举类型概述二、valueOf() 方法详解1. 什么是 valueOf() 方法&#xff1f;2. 使用示例 三、使用 Stream API 查找枚举对象1. 使用 Stream 查找枚举对象2. 使用 Stream 统计枚举对象 四、总结推荐阅读文章 在 Java 中&#xff0c;枚举&#xff08;enum&#xff09…...

Git的认识及基本操作

目录 一:Git的基本认识 二:Git的安装 三:Git的基本操作 1.创建本地仓库 2.配置Git 3.⼯作区、暂存区、版本库 4. 修改文件 5.版本回退 6.撤销修改 7.删除文件 一:Git的基本认识 1.实例引入 在日常当中我们常常会遇到这样的事&#xff0c;就是在做实验报告或者课设…...

python 日志库loguru

python 日志库loguru 安装 pip install loguru最简单的基本使用 from loguru import loggerlogger.success("Hello from success!") logger.info("Hello from info!") logger.debug("Hello from debug!") logger.warning("Hello from wa…...

基于SpringBoot+Vue+uniapp的在线招聘平台的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…...

Chrome谷歌浏览器加载ActiveX控件之JT2Go控件

背景 JT2Go是一款西门子公司出品的三维图形轻量化预览解决工具&#xff0c;包含精确3D测量、基本3D剖面、PMI显示和改进的选项过滤器等强大的功能。JT2Go控件是一个标准的ActiveX控件&#xff0c;曾经主要在IE浏览器使用&#xff0c;由于微软禁用IE浏览器&#xff0c;导致JT2Go…...

Java基础概览和常用知识(七)

什么是自动装箱和自动拆箱&#xff0c;原理是什么&#xff1f; 自动装箱和自动拆箱是Java编程语言中的两个重要概念&#xff0c;它们涉及到基本数据类型与其对应包装类之间的自动转换。 一、定义 自动装箱&#xff1a;是指Java编译器在需要将基本数据类型转换为对应的包装类…...

STL-string

STL的六大组件&#xff1a; string // string constructor #include <iostream> #include <string> using namespace std; int main() {// 构造std::string s0("Initial string");std::string s1; //nullptrstd::string s2("A character sequenc…...

数据库基础-学习版

目录 数据库巡检清理表空间高水位处理重建索引扩展字段异常恢复处置常见命令汇总 数据库巡检 数据库巡检的主要目的是确保数据库的健康状态、性能和安全,及时发现潜在的问题。 一 数据库状态检查 查看数据库列表:SHOW DATABASES; 检查当前数据库SELECT DATABASE(); 检查数据…...

【Gin】Gin框架介绍和使用

一、简单使用Gin框架搭建一个服务器 package mainimport ("github.com/gin-gonic/gin" )func main() {// 创建一个默认的路由引擎r : gin.Default()// GET 请求方法r.GET("/hello", func(c *gin.Context) {// c.JSON 返回的是JSON格式的数据c.JSON(200, g…...

AI大模型带来哪些创业机遇?

AI 大模型的快速发展带来了许多创新和创业机遇&#xff0c;涵盖了从行业应用到基础设施优化的方方面面。以下是一些具体的创业机会&#xff1a; 1、垂直行业应用 大模型可以根据不同行业的需求进行定制和优化&#xff0c;提供高度专业化的 AI 解决方案。 医疗领域&#xff1a;…...

[Linux] 层层深入理解文件系统——(3)磁盘组织存储的文件

标题&#xff1a;[Linux] 层层深入理解文件系统——&#xff08;3&#xff09;磁盘组织组织存储的文件 个人主页水墨不写bug 目录 一、磁盘中的文件 1&#xff09;磁盘的物理结构 2&#xff09;磁盘的CHS寻址法 3&#xff09;磁盘的空间管理 二、磁盘如何组织存储文件 三…...

Apache Cordova学习计划

Apache Cordova&#xff08;之前称为 PhoneGap&#xff09;&#xff1a; 1. PhoneGap的起源&#xff1a;2008年8月&#xff0c;PhoneGap在旧金山的iPhoneDevCamp上首次亮相&#xff0c;由Nitobe公司开发&#xff0c;目的是“为跨越Web技术和iPhone之间的鸿沟牵线搭桥”。 2. Ph…...

Unity学习日志-API

Untiy基本API 角度旋转自转相对于某一个轴 转多少度相对于某一个点转练习 角度 this.transform.rotation(四元数)界面上的xyz(相对于世界坐标) this.transform.eulerAngles;相对于父对象 this.transform.localEulerAngles;设置角度和设置位置一样&#xff0c;不能单独设置xz…...

Java基础常见面试题总结(上)

基础概念与常识 Java 语言有哪些特点? 简单易学&#xff08;语法简单&#xff0c;上手容易&#xff09;&#xff1b;面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&…...

4 -《本地部署开源大模型》在Ubuntu 22.04系统下部署运行ChatGLM3-6B模型

在Ubuntu 22.04系统下部署运行ChatGLM3-6B模型 大模型部署整体来看并不复杂&#xff0c;且官方一般都会提供标准的模型部署流程&#xff0c;但很多人在部署过程中会遇到各种各样的问题&#xff0c;很难成功部署&#xff0c;主要是因为这个过程会涉及非常多依赖库的安装和更新及…...