spring-ai: 个人学习的springAi,一些基础调用,下载可运行
https://gitee.com/an-ape-hou/spring-ai
文章只写了关键步骤,具体可看代码,代码已上传至gitee
接入大模型
统一调用:百炼、Ollama、OpenAI 等
导入依赖
<?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.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>test-ai</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test-ai</name>
<description>test-ai</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!--阿里百炼依赖-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud.ai</groupId>-->
<!-- <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>-->
<!-- <version>1.0.0.2</version>-->
<!-- </dependency>-->
<!-- openai 可兼容阿里百炼-->
<!-- <dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
-->
<!-- Spring AI Ollama Starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 统一管理springai版本号-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<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>
</repositories>
</project>
同步/流式返回
同步
/**
* 简单的文本对话
*/
public String chat(String userInput) {
return chatClient
.prompt()
.user(userInput)
.call()
.content();
}
流式
/*
* 流式对话
* */
public Flux<String> chatStream(String userInput) {
return chatClient
.prompt()
.user(userInput)
.stream()
.content();
}
/** controller层
*1.需要加MediaType
*2.需要拿Flux封装
**/
// 流式接口
@GetMapping(value = "/chatStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> chatStream(@RequestParam String msg) {
return aiService.chatStream(msg);
}
多轮记忆
数据库记忆需要导入依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
新建数据库表,存储对话
CREATE TABLE `spring_ai_chat_memory` (
`conversation_id` varchar(36) NOT NULL,
`content` text NOT NULL,
`type` varchar(10) NOT NULL,
`timestamp` timestamp NOT NULL,
CONSTRAINT `TYPE_CHECK` CHECK ((`type` in ('USER','ASSISTANT','SYSTEM','TOOL')))
);
配置 yml 数据源
此处省略
示例代码
package org.example.testai.config;
import lombok.extern.slf4j.Slf4j;
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.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class ChatClientConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel, ChatMemory chatMemory) {
return ChatClient
.builder(chatModel)
.defaultSystem("你是一个专业的java代码开发工具,需要回答用户的代码问题")
// 配置默认切面:包含简单日志记录器和基于聊天记忆的顾问
.defaultAdvisors(
new SimpleLoggerAdvisor(), // 启用简单的日志记录功能
MessageChatMemoryAdvisor.builder(chatMemory).build() // 启用聊天记忆功能,用于保存上下文
)
.build();
}
}
package org.example.testai.config;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepositoryDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatMemoryConfig {
/*
* 记忆内存存储
* */
/* @Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(new InMemoryChatMemoryRepository()) // 默认内存存储
.maxMessages(20) // 最大存储消息数
.build();
} */
/*
* 记忆数据库存储
* */
@Bean
public ChatMemory chatMemory(JdbcChatMemoryRepository jdbcChatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(jdbcChatMemoryRepository) // 数据库存储
.maxMessages(20) // 最大存储消息数
.build();
}
}
/**
* bean配置的
* 带记忆功能的流式对话
* 从聊天记忆中获取历史消息,将当前用户输入和历史消息一起发送给模型,
* 并在接收到响应时更新聊天记忆(添加用户消息和助手回复)。
*
* @param userId 用户唯一标识,用于关联聊天记忆
* @param userInput 用户输入的文本内容
* @return 返回流式的助手回复内容
*/
public Flux<String> chatWithMemory(String userId, String userInput) {
return chatClient
.prompt()
.user(userInput)
.advisors(
advice -> advice.param(ChatMemory.CONVERSATION_ID, userId)
)
.stream()
.content();
}
Function Calling 调用工具
可以调用本地接口;
模型需要支持tool,个人本地模型用的是8b的,好像低于7b的一般没有这个工具;
模型训练量小,命中不是百分百,可加提示词提高命中;
方式 1:@Tool 版(快速写)
@Tool
作用:标记一个方法 → 让 AI 可以调用它
@ToolParam
作用:标记参数 → 告诉 AI 这个参数是什么
@Service
public class ToolService {
@Tool(description = "查天气")
public String getWeather(@ToolParam(description = "城市名") String city){
return city+"晴天";
}
}
调用:
chatClient.prompt().tools(toolService)

方式 2:@Bean + @Description 版(正式用)
@Description
作用:给 AI 看的功能说明,用于 @Bean Function 方式,代替 @Tool
@Configuration
public class FuncConfig {
@Bean
@Description("查天气")
public Function<CityReq, String> weather(){
return req->req.city()+"晴天";
}
record CityReq(String city){}
}
调用:
chatClient.prompt().toolCallbacks(ToolCallbacks.from(toolService))


spring-ai: 个人学习的springAi,一些基础调用,下载可运行
https://gitee.com/an-ape-hou/spring-ai