之前做个几个大模型的应用,都是使用Python语言,后来有一个项目使用了Java,并使用了Spring AI框架。随着Spring AI不断地完善,最近它发布了1.0正式版,意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说真是一个福音,其功能已经能满足基于大模型开发企业级应用。借着这次机会,给大家分享一下Spring AI框架。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 Spring AI-1.0.0,JDK版本使用的是19
代码参考: https://github.com/forever1986/springai-study

目录

  • 1 ChatModel 源码解析
  • 2 示例演示
    • 2.1 简单示例
    • 2.2 提示词示例
    • 2.3 手动配置示例

上一章解析了ChatClient的创建和底层原理,也知道其最终调用了ChatModel。那这一章,来了解Spring AI的ChatModel。

1 ChatModel 源码解析

聊天大模型通常的工作方式是向人工智能模型发送提示或部分对话,然后该模型根据其训练数据和对自然语言模式的理解生成对话的完成部分或延续内容。完成后的响应随后返回给应用程序,应用程序可以将其呈现给用户或用于进一步处理。
而Spring AI 秉承着这个工作方式,ChatModel API 被设计成一个简单且便携的接口,用于与各种 AI 模型进行交互,使开发人员能够在不同模型之间切换时只需进行最少的代码更改。这种设计与 Spring 的模块化和可互换性理念相一致。
下面来看看ChatModel这个接口的源码,代码如下:

public interface ChatModel extends Model<Prompt, ChatResponse>, StreamingChatModel {default String call(String message) {Prompt prompt = new Prompt(new UserMessage(message));Generation generation = call(prompt).getResult();return (generation != null) ? generation.getOutput().getText() : "";}default String call(Message... messages) {Prompt prompt = new Prompt(Arrays.asList(messages));Generation generation = call(prompt).getResult();return (generation != null) ? generation.getOutput().getText() : "";}// 大模型供应商需要实现真正call方法@OverrideChatResponse call(Prompt prompt);default ChatOptions getDefaultOptions() {return ChatOptions.builder().build();}// 大模型供应商需要实现真正stream方法,继承至StreamingChatModel。流式实现流式方式default Flux<ChatResponse> stream(Prompt prompt) {throw new UnsupportedOperationException("streaming is not supported");}}

说明:从上面代码看,如果一个大模型供应商要集成到Spring AI,就需要实现ChatModel 接口,实现call和stream方法

在Spring AI中已经实现了很多聊天大模型,如下图:

在这里插入图片描述

说明:上面对于ChatModel 的源码解析以及Spring AI聊天大模型目前集成的厂商做了一个预览,下面通过使用ChatModel 方式来调用聊天大模型,而非ChatClient。

2 示例演示

以下代码参考lesson15子模块

2.1 简单示例

代码参考lesson15子模块的simple子模块

示例说明:使用ChatModel方式访问聊天大模型

1)在lesson15子模块下,新建simple子模块,其pom引入如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-zhipuai</artifactId></dependency>
</dependencies>

2)配置application.properties文件

# 聊天模型
spring.ai.zhipuai.api-key=你的智谱模型的API KEY
spring.ai.zhipuai.chat.options.model=GLM-4-Flash-250414
spring.ai.zhipuai.chat.options.temperature=0.7

3)新建演示类ChatModelController :

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ChatModelController {private final ChatModel chatModel;@Autowiredpublic ChatModelController(ChatModel chatModel) {this.chatModel = chatModel;}@GetMapping("/chatmodel/generate")public String generate(@RequestParam(value = "message", defaultValue = "请跟我说个笑话!") String message) {return this.chatModel.call(message);}
}

4)新建启动类Lesson15SimpleApplication :

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Lesson15SimpleApplication {public static void main(String[] args) {SpringApplication.run(Lesson15SimpleApplication.class, args);}}

5)演示效果:

http://localhost:8080/chatmodel/generate

在这里插入图片描述

2.2 提示词示例

代码参考lesson15子模块的simple子模块

示例说明:使用ChatModel方式访问聊天大模型,并为大模型设定角色

1)沿用lesson15子模块的的simple子模块,新建演示类:

import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class ChatModelRoleController {private final ChatModel chatModel;@Autowiredpublic ChatModelRoleController(ChatModel chatModel) {this.chatModel = chatModel;}@GetMapping(value = "/chatmodel/systemrole", produces = "text/html;charset=UTF-8") //设定返回的字符,不然会出现乱码public String systemrole(@RequestParam(value = "message", defaultValue = "空指针一般有什么问题造成的?") String message) {Message systemMessage = new SystemMessage("你是一个精通Java的工程师,专门解决Java遇到的问题。");Message userMessage = new UserMessage(message);Prompt prompt = new Prompt(List.of(systemMessage,userMessage));return this.chatModel.call(prompt).getResult().getOutput().getText();}
}

2)演示效果

http://localhost:8080/chatmodel/systemrole

在这里插入图片描述

说明:从上面可以看到如果不使用ChatClient一样能达到效果,只不过在一些场景下需要自己实现功能,比如聊天记忆、RAG、MCP等。这就说明Spring AI 为了方便用户使用大模型,遵循的简单和便利的原则。

2.3 手动配置示例

代码参考lesson15子模块的manual-demo子模块

示例说明:如果你不是SpringBoot项目或者Web项目,Spring AI一样开发了手动配置ChatModel的包,下面就演示手动配置ChatModel

1)新建lesson16子模块,其pom引入如下:

<dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-zhipuai</artifactId></dependency>
</dependencies>

2)创建演示类ManualChatModelTest:

import org.springframework.ai.zhipuai.ZhiPuAiChatModel;
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
import org.springframework.ai.zhipuai.api.ZhiPuAiApi;public class ManualChatModelTest {public static void main(String[] args) {// 设置API KEYvar zhiPuAiApi = new ZhiPuAiApi("你的智谱模型的API KEY");var chatModel = new ZhiPuAiChatModel(zhiPuAiApi, ZhiPuAiChatOptions.builder()// 设置模型.model("GLM-4-Flash-250414")// 设置温度.temperature(0.7).build());System.out.println(chatModel.call("请跟我说个笑话!"));}
}

3)演示效果

在这里插入图片描述

说明:可以看到每个厂商的大模型都提供一个通过手动方式创建的模式,这就是Spring AI框架为了用户在不同场景下使用考虑的各方各面。

结语:本章通过解析ChatModel源码,并通过几个示例演示了不通过ChatClient的方式使用ChatModel。虽然一样可以实现,但是如果遇到如RAG、MCP等复杂场景,其使用便捷度就没有ChatClient那么高。ChatModel聊天大模型是比较规范和成熟的模型,因此在Spring AI中有很多不同厂商的实现,下两章将针对聊天大模型比较常用的2种部署模式进行讲解。

Spring AI系列上一章:《Spring AI 系列之十七 - ChatClient源码解析》
Spring AI系列下一章:《Spring AI 系列之十九 - Ollama集成Deepseek》

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

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

相关文章

Linux学习之Linux系统权限

在上一篇的内容中我们学习到了Linux系统命令相关的知识及其相关的扩展内容&#xff0c;本期我们将学习Linux基础的另一个重要部分&#xff1a;Linux系统权限管理 作者的个人gitee&#xff1a;楼田莉子 (riko-lou-tian) - Gitee.com 目录 权限概念及必要性 什么是权限 为什么要…

Web3.0 能为你带来哪些实质性的 改变与突破

如今各种大厂裁员消息层出不穷&#xff0c;今年又添飞书、剪映、微软、思科... 这有一张网友整理的去年互联网大厂裁员裁员信息表&#xff1a; 目前国内很多大厂都在裁员&#xff0c;非常现实、且越来越多 35 技术人&#xff0c;正在面临这样的问题&#xff0c;那么Web3.0 确实…

doker centos7安装1

1.什么是doker Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;然后发布到任何支持 Docker 的操作系统上&#xff0c;实现 “一次构建&#xff0c;到处运行”。 容器是一种轻量级的虚拟化技术&#xff0c…

自动化面试题

1、什么是测试套件测试套件是多个测试用例的集合。2、搭建接口自动化框架中&#xff0c;你遇到最大的难点是什么&#xff0c;以及怎么解决的?测试数据动态管理难点:接口依赖动态参数(如Token、订单ID)&#xff0c;数据无法硬编码.解决方案:使用关联提取(如正则提取响应中的Tok…

【Linux】LVS(Linux virual server)环境搭建

一、LVS的运行原理1.1 LVS简介LVS:Linux Virtual Server&#xff0c;负载调度器&#xff0c;内核集成&#xff0c;章文嵩&#xff0c;阿里的四层SLB(Server LoadBalance)是基于LVSkeepalived实现LVS 官网: http://www.linuxvirtualserver.org/ LVS 相关术语 VS: Virtual Server…

算法竞赛备赛——【图论】求最短路径——Dijkstra

Dijkstra 用来计算从一个点到其他所有点的最短路径的算法&#xff0c;是一种单源最短路径算法。也就是说&#xff0c;只能计算起点只有一个的情况。Dijkstra的时间复杂度是O (|v|^2)&#xff0c;它不能处理存在负边权的情况。 邻接矩阵存图 #include<iostream> using …

影刀 RPA:批量修改 Word 文档格式,高效便捷省时省力

在日常办公和文档处理中&#xff0c;Word 文档格式的统一和规范是许多企业和个人用户的重要需求。无论是撰写报告、制作提案&#xff0c;还是整理资料&#xff0c;都需要确保文档格式的一致性。然而&#xff0c;手动修改多个 Word 文档的格式不仅耗时费力&#xff0c;还容易因疏…

GitLab 社区版 10.8.4 安装、汉化与使用教程

一、GitLab 安装 GitLab 提供了集成所需软件的 RPM 包&#xff0c;简化了安装流程。我们选择安装社区版&#xff08;CE&#xff09;10.8.4&#xff0c;可通过官方网站或国内镜像源&#xff08;如清华镜像&#xff09;获取安装包。 1. 准备工作 首先创建工具目录并进入&#…

[硬件电路-64]:模拟器件 -二极管在稳压电路中的应用

二极管在稳压电路中的应用主要基于其单向导电性和特定类型二极管&#xff08;如稳压二极管&#xff09;的电压稳定特性。以下是详细解释&#xff1a;一、普通二极管的稳压作用&#xff08;有限场景&#xff09;正向导通压降的利用&#xff1a;原理&#xff1a;普通二极管在正向…

【Linux】重生之从零开始学习运维之Nginx

安装apt/yum安装apt imstall nginx yum install nginxRocky源码编译安装基础编译环境yum install gcc make gcc-c glibc glibc-devel pcre pcre-devel openssl openssldevel systemd-devel zlib-devel yum install libxml2 libxml2-devel libxslt libxslt-devel php-gd gd-deve…

主流 MQ 的关键性能指标

常用消息队列&#xff08;MQ&#xff09;的“数量级”通常围绕吞吐量&#xff08;TPS&#xff0c;每秒处理消息数&#xff09;、消息堆积能力、延迟三个核心指标展开&#xff0c;不同MQ因设计目标&#xff08;高吞吐、低延迟、高可靠等&#xff09;不同&#xff0c;数量级差异显…

[NIPST AI]对抗性机器学习攻击和缓解的分类和术语

原文link&#xff1a;https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.100-2e2025.pdf Introduction 人工智能&#xff08;AI&#xff09;系统在过去几年中持续全球扩展。这些系统正在被众多国家开发并广泛部署于各自的经济体系中&#xff0c;人们在生活的许多领域都获得了更多使…

[深度学习] 大模型学习3上-模型训练与微调

在文章大语言模型基础知识里&#xff0c;模型训练与微调作为大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;应用构建的主要方式被简要提及&#xff0c;本系列文章将从技术原理、实施流程及应用场景等维度展开深度解析。相关知识的进一步参考见&#x…

Claude Code 启动提示 Note: Claude Code might not be available in your country. 解决

如下图所示 主播参考了在别的地方看来的解决方案&#xff08;并非主播不想标注来源&#xff0c;主要是忘记是哪里看来的了&#xff0c;下班就忘记了&#xff0c;懒得找了&#x1f62d;&#xff0c;如果后续找到会补上的&#xff09;。 好了&#xff0c;开始正文&#xff0c;开始…

Unity VR多人手术系统恢复3:Agora语音通讯系统问题解决全记录

&#x1f3af; 前言 这是一个Unity多人VR手术模拟项目&#xff0c;已经搁置了近两年时间。最近重新启动了这个项目&#xff0c;然而在恢复过程中却遇到了些的技术障碍。 项目重启遇到的挑战 当我们重新部署和测试系统时&#xff0c;发现原本运行良好的Agora语音通讯功能完全…

sqli-labs靶场通关笔记:第46-53关 order by注入

目录 第46关 order by注入 第47关 闭合的order by注入 第48关 无报错回显的数字型order by注入 第49关 无报错回显的闭合型order by注入 第50关 基于order by的堆叠注入 第51关 闭合的报错注入或堆叠注入 第52关 数字型盲注或堆叠注入 第53关 闭合的盲注或堆叠注入 第…

cdh6.3.2的hive使用apache paimon格式只能创建不能写报错的问题

前言根据官网paimon安装教程&#xff0c;看上去简单&#xff0c;实则报错阻碍使用的信心。 解决方法原带的jars下的zstd开头的包旧了&#xff0c;重新下载zstd较新的包单独放到每个节点的hive/lib下;然后将hdfs yarn用户下的mr-framework.tar.gz中的zstdjar包替换成新的版本。重…

【Vue进阶学习笔记】实现图片懒加载

创建Vue项目 首先确保你已安装Vue CLI&#xff0c;然后创建一个新的Vue 3项目&#xff1a; npm init vuelatest安装依赖 安装vueuse/core库&#xff0c;它提供了useIntersectionObserver组合式API&#xff1a; cnpm install cnpm install vueuse/core创建指令文件夹和文件 在sr…

深入理解 synchronized

深入理解 synchronized 引言&#xff1a;synchronized的核心地位 在Java并发编程中&#xff0c;synchronized关键字是实现线程安全的基石。自JDK 1.0引入以来&#xff0c;它经历了从"重量级锁"到"自适应锁"的进化&#xff0c;如今已成为兼顾安全性与性能的…

C语言字符串相关函数

C语言笔记内容提要数组字符串基本操作字符串相关函数综合案例&#xff1a;学生成绩管理系统数组字符串基本操作在用格式化说明符%s进行输入输出时&#xff0c;其输入输出项均为数组名。但在输入时&#xff0c;相邻两个字符串之间要用空格分隔&#xff0c;系统将自动在字符串后加…