10-SpringAI智能助手案例
接下啦,我们利用SpringAI发起大模型的第一次对话。
接下啦,我们利用SpringAI发起大模型的第一次对话。
Java领域实现大模型开发,有两个非常重要的框架
SpringAI LangChin4j
SpringAI最低支持的jdk版本是17
L盎Chin4j最低支持的版本是8
1、快速入门
创建工程
创建一个新的SpringBoo工程,勾选Web、MySQL驱动即可:


引入依赖
SpringAI完全适配了SpringBoot的自动装配功能,而且给不同的大模型提供了不同的starter,比如:
|
模型/平台 |
starter |
|
Anthropic |
|
|
Azure OpenAI |
|
|
DeepSeek |
|
|
Hugging Face |
|
|
Ollama |
|
|
OpenAI |
|
我们可以根据自己选择的平台来选择引入不同的依赖。这里我们先以OpenAI为例。
首先,在项目pom.xml中添加spring-ai的版本信息:
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
然后,添加spring-ai的依赖管理项:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
最后,引入spring-ai-openai的依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>
为了方便后续开发,我们再手动引入一个Lombok依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
注意:千万不要用start.spring.io提供的lombok,有bug!!!
全部的完整的pom文件如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ruangong</groupId>
<artifactId>SpringAIDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringAIDemo</name>
<description>SpringAIDemo</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置模型信息
接下来,我们还要在配置文件中配置模型的参数信息。
以openai为例,我们将application.properties修改为application.yaml,然后添加下面的内容:
spring:
application:
name: ai-demo
# Spring AI配置
ai:
openai:
api-key: sk-qramtwqoiatggvuqzeihfesuxpaoeguqwprzdtgtaceajnfd
base-url: https://api.siliconflow.cn
chat:
options:
model: deepseek-ai/DeepSeek-V3
temperature: 0.7
completions-path: /v1/chat/completions
ChatClient
ChatClient中封装了与AI大模型对话的各种API,同时支持同步或响应式交互。不过,在使用之前,首先我们需要声明一个ChatClient。
在对应配置文件包下创建一个CommonConfiguration类
package com.ruangong.springai.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CommonConfiguration {
/**
* 配置 ChatClient - OpenAI兼容的聊天客户端
*
* Spring AI 会自动扫描带有 @Tool 注解的方法,无需手动注册
*
* @param openAiChatModel OpenAI Chat模型(由Spring AI自动配置)
* @param chatMemory 会话记忆存储
* @return ChatClient 实例
*/
@Bean("open-ai")
public ChatClient openAIChatClient(
OpenAiChatModel openAiChatModel,
ChatMemory chatMemory) {
return ChatClient.builder(openAiChatModel)
.build();
}
}
代码解读:
ChatClient.builder:会得到一个ChatClient.Builder工厂对象,利用它可以自由选择模型、添加各种自定义配置
OpenAiChatModel:如果你引入了openai的starter,这里就可以自动注入OpenAiChatModel对象。
同步调用
接下来,我们定义一个Controller,在其中接收用户发送的提示词,然后把提示词发送给大模型,交给大模型处理,拿到结果后返回。
package com.ruangong.springai.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {
private final ChatClient chatClient;
// 请求方式和路径不要改动,将来要与前端联调
@RequestMapping("/chat")
public String chat(@RequestParam(defaultValue = "讲个笑话") String prompt) {
return chatClient
.prompt(prompt) // 传入user提示词
.call() // 同步请求,会等待AI全部输出完才返回结果
.content(); //返回响应内容
}
}
请求地址:http://localhost:8080/ai/chat

注意,基于call()方法的调用属于同步调用,需要所有响应结果全部返回后才能返回给前端。启动项目,在浏览器中访问:http://localhost:8080/ai/chat?prompt=你好

流式调用
同步调用需要等待很长时间页面才能看到结果,用户体验不好。为了解决这个问题,我们可以改进调用方式为流式调用。
在SpringAI中使用了WebFlux技术实现流式调用。
在chatController中添加了chat2方法
// 注意看返回值,是Flux<String>,也就是流式结果,另外需要设定响应类型和编码,不然前端会乱码
@RequestMapping(value = "/chat2", produces = "text/html;charset=UTF-8")
public Flux<String> chat2(@RequestParam(defaultValue = "讲个笑话") String prompt) {
return chatClient
.prompt(prompt)
.stream() // 流式调用
.content();
}
重启测试,再次访问,会一点点生成数据展示在页面上。
System设定
可以发现,当我们询问AI你是谁的时候,它回答自己是DeepSeek-R1,这是大模型底层的设定。如果我们希望AI按照新的设定工作,就需要给它设置System背景信息。
在SpringAI中,设置System信息非常方便,不需要在每次发送时封装到Message,而是创建ChatClient时指定即可。
我们修改CommonConfiguration中的代码,给ChatClient设定默认的System信息:
@Bean
public ChatClient chatClient(OpenAiChatModel model) {
return ChatClient.builder(model) // 创建ChatClient工厂实例
.defaultSystem("您是一家专门做非遗产品的客户聊天助手,你的名字叫小一。请以友好、乐于助人和愉快的方式解答学生的各种问题。")
.defaultAdvisors(new SimpleLoggerAdvisor())
.build(); // 构建ChatClient实例
}
我们再次询问“你是谁?”

上下文设定
假如你问它 假如你有12个苹果分给2个人,每个人分几个? 它回答完了,你再问他(分给三个人呢?)它不知道要分配苹果,并且也不知道是12个苹果,说明当前的chatAI不具备了解上下文的能力?怎么办?
CommonConfig 添加如下方法:
public static final Integer MAX_MEMORY_MESSAGE_SIZE = 30;
/**
* 配置 ChatMemory - 内存存储的会话记忆
*
* @return ChatMemory 内存存储的会话记忆实例
*/
@Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.builder()
.maxMessages(MAX_MEMORY_MESSAGE_SIZE) // 窗口最大消息数目,保留最近30条消息
.build();
}
并且调用:
@Bean("open-ai")
public ChatClient openAIChatConfig(OpenAiChatModel openAiChatModel,ChatMemory chatMemory){
return ChatClient.
builder(openAiChatModel)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory()).build())
.build();
}
然后重试,发现可行:

2、日志功能
默认情况下,应用于AI的交互时不记录日志的,我们无法得到SpringAI组织的提示词到底长什么样,有没有问题。这样不方便我们调试。
Advisor
SpringAI基于AOP机制实现与大模型对话过程的增强、拦截、修改等功能。所有的增强通知都需要实现Advisor接口。

Spring提供了一些Advisor的默认实现,来实现一些基本的增强功能。

SimpleLoggerAdvisor:日志记录的Advisor
MessageChatMemoryAdvisor:会话记忆的Advisor
QuestionAnswerAdvisor:实现RAG的Advisor
当然,我们也可以自定义Advisor,具体可以参考:
https://docs.spring.io/spring-ai/reference/1.0/api/advisors.html#_implementing_an_advisor
添加日志Advisor
首先,我们需要修改CommonConfiguration,给ChatClient添加日志Advisor:
@Bean("open-ai")
public ChatClient openAIChatConfig(OpenAiChatModel openAiChatModel,ChatMemory chatMemory){
return ChatClient.
builder(openAiChatModel)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory()).build())
.defaultAdvisors(new SimpleLoggerAdvisor())
.build();
}
修改日志级别
接下来,我们在application.yaml中添加日志配置,更新日志级别:
位置要顶格写,不要写在spring标签的下面
logging:
level:
org.springframework.ai: debug # AI对话的日志级别
com.ruangong.springai: debug # 本项目的日志级别
重启项目,再次聊天就能看到AI对话的日志信息了。
3、对接前端
在浏览器通过地址访问,非常麻烦,也不够优雅,如果能有一个优美的前端页面就好了。别着急,我提前给大家准备了一个前端页面。而且有两种不同的运行方式。、
npm运行
在材料中给大家提供了前端的源代码:

直接 npm run dev即可启动

解决CORS问题
前后端在不同域名,存在跨域问题,因此我们需要在服务器端解决cors问题。在config包中添加一个MvcConfiguration类:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("Content-Disposition");
}
}
重启服务,如果你的服务端接口正常,那么应该就可以聊天了。
注意:前端访问服务端的默认路径是:http://localhost:8080
聊天对话的接口是:POST /ai/chat
请确保你的服务端接口也是这样。

恭喜您,你的第一个AI对话机器人就完成了。
4、补充说明:
Ollama(Ollama):ollama 是一个软件,可以在ollama 下载各种大模型

硅基流动 https://www.siliconflow.cn/
硅基流动:就是大模型的商店,里面有各种正在售卖的大模型可以被调用

更多推荐


所有评论(0)