SpringAI入门指南:从零搭建本地AI助手
·
1.什么是Spring AI
Spring AI 是一个用于 AI 工程的应用程序框架。支持例如OpenAI,Google ,Ollama等AI模型供应商
支持跨 AI 提供商对同步和流式处理 API 选项的可移植 API 支持
2.构建支持AI的项目



3.Ollama常用命令
-
ollama list:列出所有已下载的模型,显示模型名称、ID、大小和修改时间。
-
ollama ps:列出当前正在运行的模型实例,显示模型 ID 和状态。
-
ollama pull <model>:从 Ollama 模型库拉取指定模型到本地,未拉取的模型无法使用。
-
ollama run <model>:运行指定模型并进入交互式命令行模式,可直接与模型对话,按
Ctrl+D或输入/exit退出。也可在命令后直接跟提示词,如ollama run llama3 "用中文写一首关于秋天的诗"。 -
ollama rm <model>:删除指定模型,移除本地已下载的模型以释放磁盘空间。
-
ollama push <model>:将本地模型推送到 Ollama 模型库,适合分享自定义模型,需登录并确保已配置模型库的访问权限。
-
ollama help:显示所有可用命令和帮助信息,可快速查看命令列表和用法。
-
ollama show <model>:显示模型的详细信息,包括模型的 Modelfile、参数、系统提示等。
-
ollama --version:显示 Ollama 的版本号,用于检查是否需要更新。
4.选用模型



测试路径 :http://localhost:11434/api/chat
测试参数:
{
"model":"deepseek-r1:7b",
"messages":[
{
"role":"system",
"content":"你是一个非常热心且热情的ai小助手,你叫的名字叫小明,请以小明的身份回答用户的问题"
},
{
"role":"user",
"content":"你是谁"
}
],
"stream":false
}
model:指定要使用的模型名称及版本
messages:对话历史数组,按时间顺序排列,包含角色和内容。
stream:是否启用流式响应
5.简单的项目搭建
所需依赖
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI 核心依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<version>1.0.0-M6</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-client-chat</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-model</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
配置文件
spring: application: name: ZhenGe-ai ai: ollama: base-url: http://localhost:11434 chat: model: deepseek-r1:7b
配置类
@Configuration
public class SpringAiConfig {
@Bean
public ChatClient chatClient(OllamaChatModel model) {
return ChatClient.builder(model)
.defaultSystem("你现在叫小明,请以小明的身份跟我聊天")//设置默认系统提示
.defaultAdvisors( //用于拦截和处理对话流程
new SimpleLoggerAdvisor() //日志记录器,会打印对话的输入和输出
)
.build();
}
}
控制层
@RequestMapping(value = "chat", produces = "text/html;charset=utf-8")
public Flux<String> chat(@RequestParam String message) {
return chatClient.prompt()//创建一个 AI 对话请求构建器
.user(message)//将用户输入的消息作为用户角色(User Role)添加到对话中。
.stream()//启用流式处理模式
.content();
// .generate() // 同步生成完整结果
//.getContent();
}
6.支持会话记录
配置类
@Configuration
public class SpringAiConfig {
@Bean
public ChatMemory chatMemory() {//返回类型是 Spring AI 框架中的聊天记忆接口,用于存储和管理对话历史。
return new InMemoryChatMemory();
}
@Bean
public ChatClient chatClient(OllamaChatModel model,ChatMemory chatMemory) {
return ChatClient.builder(model)
.defaultSystem("你现在叫小明,请以小明的身份跟我聊天")
.defaultAdvisors(
new SimpleLoggerAdvisor(),
new MessageChatMemoryAdvisor(chatMemory)
)
.build();
}
}
7.支持历史记录及查询角色对话历史记录
在repository包下创建
public interface ChatHistoryRepository {
void save(String type,String chatId);
List<String> getChatById(String type);
}
@Component
public class InMemoryChatHistoryRepository implements ChatHistoryRepository{
private static final int MAX_HISTORY_SIZE = 5;
private final Map<String , List<String>> list = new HashMap<>();
@Override
public void save(String type, String chatId) {
if(!list.containsKey(type)){
list.put(type, new ArrayList<>());
}
List<String> chatIds = list.get(type);
if (chatIds.contains(chatId)){
return;
}
// 如果历史记录达到上限,删除最早的一条
if (chatIds.size() >= MAX_HISTORY_SIZE) {
chatIds.remove(0); // 删除列表中第一个元素(最早添加的)
}
chatIds.add(chatId);
}
@Override
public List<String> getChatById(String type) {
return list.getOrDefault(type,new ArrayList<>());
}
}
返回类
package cn.zhentao.vo;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
/**
* @autho:周明震
* @date 2025/7/14
*/
@NoArgsConstructor
@Data
public class MessageVo {
private String role;
private String content;
public MessageVo(Message message) {
MessageType messageType = message.getMessageType();
switch(message.getMessageType()) {
case USER:
role = "user";
break;
case ASSISTANT:
role = "assistant";
break;
default:
role = "unknown";
break;
}
this.content = message.getText();
}
}
控制层
package cn.zhentao.controller;
import cn.zhentao.repository.ChatHistoryRepository;
import cn.zhentao.vo.MessageVo;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import java.util.List;
@RestController
@RequiredArgsConstructor
@RequestMapping("ai")
@CrossOrigin(origins = "*")
public class SpringAiController {
private final ChatClient chatClient;
private final ChatHistoryRepository chatHistoryRepository;
private final ChatMemory chatMemory;
@RequestMapping(value = "chat", produces = "text/html;charset=utf-8")//响应内容类型为 HTML,编码为 UTF-8。
public Flux<String> chat(@RequestParam String message, @RequestParam String chatId) {//表示异步流式响应
chatHistoryRepository.save("chat", chatId);
return chatClient.prompt()//创建一个 AI 对话请求构建器
.user(message)//将用户输入的消息作为用户角色(User Role)添加到对话中。
.advisors(a->a.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
.stream()
.content();
}
@RequestMapping("{type}")
public List<String> getChatId(@PathVariable("type")String type){
return chatHistoryRepository.getChatById(type);
}
@RequestMapping("/{type}/{chatId}")
public List<MessageVo> getChatHistory(@PathVariable("type")String type,@PathVariable("chatId")String chatId){
List<Message> messages = chatMemory.get(chatId, 10);
if(messages==null){
return List.of();
}
return messages.stream().map(MessageVo::new).toList();
}
}
更多推荐

所有评论(0)