Java+AI 无缝衔接:Spring AI 聊天模型入门到精通
开发者资源导航 ️博客主页 个人主页专栏订阅 JavaEE全栈专栏一、简介Spring AI 是 Spring 官方专为 Java 开发者做 AI 项目的框架简单、好上手和平时写 Spring Boot 一模一样。它能干嘛快速对接各种大模型ChatGPT、通义千问、文心一言、本地 Ollama 等轻松实现聊天、总结、翻译、内容生成用自己的文档、知识库做智能问答RAG统一接口换模型不用改大量代码完美兼容 Spring Boot、Spring Cloud 企业项目学完能做什么做企业内部智能客服、AI 问答机器人给现有系统加 AI 功能智能总结、自动文案、代码助手做基于私有文档的知识库 AI开发 Java 版 AI 应用、多模态小工具用 Java 栈快速进入 AI 开发不用从头学新语言本文将介绍Spring AI的聊天模型的使用。参考文档Spring Ai官方文档https://docs.spring.io/spring-ai/reference/index.htmlSpring Ai API文档https://docs.spring.io/spring-ai/docs/智谱AI开放平台https://docs.bigmodel.cn/cn/guide/start/introduction二、 前期准备Spring AI支持很多家的AI使用方法也很相似本文将使用智谱AI来当做演示。1. 创建Spring Boot项目2. 配置pom文件注意不同平台的AI要配置的包不一样dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-model/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-zhipuai/artifactId /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.1.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement3.官网申请APIKey打开官网智谱AI开放平台https://bigmodel.cn/usercenter/proj-mgmt/apikeys点击右上角添加新的apikey4.配置application.yml文件不同平台配置相似但是名字不一样在resource目录下创建application.yml文件填写以下以下配置spring: ai: zhipuai: api-key: 你的apikey chat: options: model: GLM-5 # 你要选择的模型填写你的apikey根据官方文档选择填写你需要的模型。5.写一个小测试RequestMapping(/ai) RestController public class ChatController { Autowired private ZhiPuAiChatModel chatModel; GetMapping(/zp) public String zp(String message) { return chatModel.call(message); } }6.启动访问本地链接进行测试注意调用远程api反应会比较慢三、ChatClientChatClient是基于ChatModel进行的封装相对于ChatModel来说它的使用会更加简单一些。可以使用流式的方式来调用该类。private final ChatClient chatClient; // chatClient初始化 public ChatController(ChatClient.Builder chatClientBuilder) { this.chatClient chatClientBuilder.build(); } GetMapping(/call) public String call(String message) { //也可以使用.prompt(message)省略user return chatClient //调用提示词 .prompt() //设置用户提示词 .user(message) //发起请求 .call() //以文本方式返回 .content(); }3.1 角色预设将ChatClient创建的时候我们可以设置它的系统提示词通过系统提示词可以实现模型的角色预设功能。Bean public ChatClient chatClient(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory) { return chatClientBuilder //不建议像我这样设置会气死人的 .defaultSystem(你是乐子人不管我说什么你都要冷嘲热讽我) .build(); }配置后我们再调用模型它就会带入我们提供的身份。Autowired private ChatClient chatClient; GetMapping(/call) public String call(String message) { return chatClient.prompt().user(message).call().content(); }这块的可开发程度很高哦3.2 结构化输出通过 entity() ⽅法将模型输出转为⾃定义实体, 需确保输出格式符合JSON规范。在转换的过程中AI会自动识别字段并且塞入合适的字段当中当然如果他不理解这个字段也会瞎填Data public class Book { private String bookName; private String bookAuthor; private String bookISBN; private String result; }GetMapping(/getBook) public String getBook() { return chatClient.prompt(帮我推荐一本2026年值得阅读的书籍并告诉我原因) .call() .entity(Book.class).toString(); }3.3 流式输出逐步生成而不是一步直接出结果这样可以提升响应时间进而提升用户体验。GetMapping(value /stream,produces text/html;charsetutf-8) public FluxString stream(String message) { return chatClient .prompt() .user(message) .advisors(advisorSpec - advisorSpec.param(ChatMemory.CONVERSATION_ID, 1)) .stream() .content(); }这里要设置字符类型否则会出现乱码。四、ChatModelChatModel 是Spring AI 框架中的底层接⼝, 直接与具体的⼤语⾔模型 (如通义千问、OpenAI) 交互,提供基础的 call 和 stream ⽅法, 开发者需⼿动处理提⽰词组装、参数配置和响应解析等细节,在使⽤上相对更加灵活但是也更复杂上面讲过的ChatClient是基于ChatModel进行封装的。Autowired private ZhiPuAiChatModel chatModel; RequestMapping(/chatByPrompt) public String chatByPrompt(String message){ Prompt prompt new Prompt(message); ChatResponse response chatModel.call(prompt); return response.getResult().getOutput().getText(); }功能相似因此此处简要介绍一下代码。4.1 角色预设GetMapping(value /role) public String role(String message) { SystemMessage systemMsg new SystemMessage(你是⼀名英国⼈, 只会说英语); UserMessage userMsg new UserMessage(message); Prompt prompt new Prompt(List.of(systemMsg, userMsg)); ChatResponse response chatModel.call(prompt); return response.getResult().getOutput().getText(); }4.2 流式输出GetMapping(value /callByStream, produces text/html;charsetutf-8) public FluxString callByStream(String message) { FluxChatResponse response chatModel.stream(new Prompt(message)); return response.map(x-x.getResult().getOutput().getText()); }五、ChatMemory和模型的对话是单向无状态的因此模型无法保存你之前的对话。如果要实现“记忆”功能你每次发送请求的时候需要将之前的对话记录也一并发给他他才可以实现“记忆”。而ChatMemory就是负责这个功能的根据id记录并区分对话。5.1MessageWindowChatMemoryMessageWindowChatMemory是目前ChatMemory唯一的实现类老版本还存在其他的。它会维护一个消息窗口窗口大小不超过指定上限。当消息数量超过上限时系统会删除较旧的消息但会保留系统消息。默认窗口大小为 20 条消息。Bean public ChatMemory chatMemory() { MessageWindowChatMemory memory MessageWindowChatMemory.builder() .maxMessages(10) .build(); return memory; }ChatMemory需要配置最大的消息数量这里不建议设置太大Token的花费容易爆炸。常用的方法//添加消息 void add(String conversationId, ListMessage messages); //获取该id下的所有消息 ListMessage get(String conversationId); //请求该id的消息 void clear(String conversationId);创建成功后需要配置给ChatClient才能生效Bean public ChatClient chatClient(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory) { return chatClientBuilder .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) .build(); }在ai模型调用中可以通过给 Advisor 传递参数指定当前对话ID来实现自动化存储。GetMapping(value /stream,produces text/html;charsetutf-8) public FluxString stream(String message) { return chatClient .prompt() .user(message) //这个1是id实际中不要像我这样写死 .advisors(advisorSpec - advisorSpec.param(ChatMemory.CONVERSATION_ID, 1)) .stream() .content(); }5.2 存储方式ChatMemory默认使用本地内存存储服务器重启后信息就会丢失ChatMemory可以配置到大多数主流的数据库当中本文只介绍Mysql的配置方式引入额外的包dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-chat-memory-repository-jdbc/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jdbc/artifactId /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId /dependency配置ChatMemoryBean public ChatMemory chatMemory(JdbcChatMemoryRepository jdbcChatMemoryRepository) { MessageWindowChatMemory memory MessageWindowChatMemory.builder() .maxMessages(30) .chatMemoryRepository(jdbcChatMemoryRepository) .build(); return memory; }配置数据库信息spring datasource: url: jdbc:mysql://localhost:3306/你的数据库?useSSLfalseserverTimezoneUTC username: 用户名 password: 密码 driver-class-name: com.mysql.cj.jdbc.Driver手动创建数据库表CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY ( conversation_id VARCHAR(36) NOT NULL, content TEXT NOT NULL, type ENUM(USER, ASSISTANT, SYSTEM, TOOL) NOT NULL, timestamp TIMESTAMP NOT NULL, INDEX SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_TIMESTAMP_IDX (conversation_id, timestamp) );配置成功后再次启动发送的消息就会自动存储到该表里面。Spring AI更新迭代比较快不同版本的差异也比较大如果发现本文与你实际体验不符合可以参考官方的文档。