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要配置的包不一样)

XML 复制代码
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-model</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-zhipuai</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.1.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

3.官网申请APIKey

打开官网:智谱AI开放平台https://bigmodel.cn/usercenter/proj-mgmt/apikeys

点击右上角添加新的apikey:

4.配置application.yml文件(不同平台配置相似,但是名字不一样)

在resource目录下创建application.yml文件,填写以下以下配置:

XML 复制代码
spring:
  ai:
    zhipuai:
      api-key: 你的apikey
      chat:
        options:
          model: GLM-5 # 你要选择的模型

填写你的apikey,根据官方文档选择填写你需要的模型。

5.写一个小测试

java 复制代码
@RequestMapping("/ai")
@RestController
public class ChatController {
    @Autowired
    private ZhiPuAiChatModel chatModel;

    @GetMapping("/zp")
    public String zp(String message) {
        return chatModel.call(message);
    }
}

6.启动!访问本地链接进行测试

(注意!调用远程api反应会比较慢)

三、ChatClient

ChatClient是基于ChatModel进行的封装,相对于ChatModel来说它的使用会更加简单一些。

可以使用流式的方式来调用该类。

java 复制代码
    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创建的时候我们可以设置它的系统提示词,通过系统提示词可以实现模型的角色预设功能。

java 复制代码
    @Bean
    public ChatClient chatClient(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory) {
        return chatClientBuilder
//不建议像我这样设置,会气死人的
                .defaultSystem("你是乐子人,不管我说什么,你都要冷嘲热讽我")
                .build();
    }

配置后我们再调用模型它就会带入我们提供的身份。

java 复制代码
    @Autowired
    private ChatClient chatClient;

    @GetMapping("/call")
    public String call(String message) {
        return chatClient.prompt().user(message).call().content();
    }

这块的可开发程度很高哦!!

3.2 结构化输出

通过 entity() ⽅法将模型输出转为⾃定义实体, 需确保输出格式符合JSON规范。

在转换的过程中AI会自动识别字段,并且塞入合适的字段当中(当然如果他不理解这个字段也会瞎填)

java 复制代码
@Data
public class Book {
    private String bookName;
    private String bookAuthor;
    private String bookISBN;
    private String result;
}
java 复制代码
    @GetMapping("/getBook")
    public String getBook() {
        return chatClient.prompt("帮我推荐一本2026年值得阅读的书籍,并告诉我原因")
                .call()
                .entity(Book.class).toString();
    }

3.3 流式输出

逐步生成,而不是一步直接出结果,这样可以提升响应时间,进而提升用户体验。

java 复制代码
    @GetMapping(value = "/stream",produces = "text/html;charset=utf-8")
    public Flux<String> stream(String message) {
        return chatClient
                .prompt()
                .user(message)
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, 1))
                .stream()
                .content();
    }

这里要设置字符类型,否则会出现乱码。

四、ChatModel

ChatModel 是Spring AI 框架中的底层接⼝, 直接与具体的⼤语⾔模型 (如通义千问、OpenAI) 交互,提供基础的 call 和 stream ⽅法, 开发者需⼿动处理提⽰词组装、参数配置和响应解析等细节,

在使⽤上相对更加灵活,但是也更复杂,上面讲过的ChatClient是基于ChatModel进行封装的。

java 复制代码
    @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 角色预设

java 复制代码
    @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 流式输出

java 复制代码
    @GetMapping(value = "/callByStream", produces = "text/html;charset=utf-8")
    public Flux<String> callByStream(String message) {
        Flux<ChatResponse> response = chatModel.stream(new Prompt(message));
        return response.map(x->x.getResult().getOutput().getText());
    }

五、ChatMemory

和模型的对话是单向无状态的,因此模型无法保存你之前的对话。

如果要实现"记忆"功能,你每次发送请求的时候需要将之前的对话记录也一并发给他,他才可以实现"记忆"。

而ChatMemory就是负责这个功能的,根据id记录并区分对话。

5.1 MessageWindowChatMemory

MessageWindowChatMemory是目前ChatMemory唯一的实现类(老版本还存在其他的)。

它会维护一个消息窗口,窗口大小不超过指定上限。当消息数量超过上限时,系统会删除较旧的消息,但会保留系统消息。默认窗口大小为 20 条消息。

java 复制代码
@Bean
public ChatMemory chatMemory() {
    MessageWindowChatMemory memory = MessageWindowChatMemory.builder()
            .maxMessages(10)
            .build();
    return memory;
}

ChatMemory需要配置最大的消息数量,这里不建议设置太大,Token的花费容易爆炸。

常用的方法:

java 复制代码
    //添加消息
    void add(String conversationId, List<Message> messages);

    //获取该id下的所有消息
    List<Message> get(String conversationId);

    //请求该id的消息
    void clear(String conversationId);

创建成功后需要配置给ChatClient才能生效:

java 复制代码
    @Bean
    public ChatClient chatClient(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory) {
        return chatClientBuilder
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
                .build();
    }

在ai模型调用中,可以通过给 Advisor 传递参数,指定当前对话ID,来实现自动化存储。

java 复制代码
    @GetMapping(value = "/stream",produces = "text/html;charset=utf-8")
    public Flux<String> 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的配置方式:

引入额外的包

XML 复制代码
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

配置ChatMemory

java 复制代码
    @Bean
    public ChatMemory chatMemory(JdbcChatMemoryRepository jdbcChatMemoryRepository) {
        MessageWindowChatMemory memory = MessageWindowChatMemory.builder()
                .maxMessages(30)
                .chatMemoryRepository(jdbcChatMemoryRepository)
                .build();
        return memory;
    }

配置数据库信息

XML 复制代码
spring
  datasource:
    url: jdbc:mysql://localhost:3306/你的数据库?useSSL=false&serverTimezone=UTC
    username: 用户名
    password: 密码
    driver-class-name: com.mysql.cj.jdbc.Driver

手动创建数据库表

sql 复制代码
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更新迭代比较快,不同版本的差异也比较大,如果发现本文与你实际体验不符合可以参考官方的文档。

相关推荐
Memory_荒年2 小时前
Dubbo面试通关秘籍:从“小白”到“源码大神”的终极指南
java·后端·dubbo
Codebee2 小时前
OoderAgent Apex OS:基于Skills化架构的热插拔启动机制
人工智能
苏打水前端客2 小时前
【OpenClaw 保姆级教程】第二篇:多渠道接入 + 核心技能上手(附实操案例)
人工智能
何政@2 小时前
Agent Skills 完全指南:从概念到自定义实践
人工智能·python·大模型·claw·404 not found 罗
wechatbot8882 小时前
【企业通信】基于IPAD协议的企业微信群聊管理API:群操作功能接口设计与实现
java·ios·微信·企业微信·ipad
码农三叔2 小时前
(1-2)控制系统基础与人形机器人特点:人形机器人控制的特殊挑战
人工智能·机器学习·机器人·人形机器人
ai产品老杨2 小时前
源码交付与全协议兼容:企业级 AI 视频中台的二次开发实战
人工智能·音视频
野生技术架构师2 小时前
Spring Boot 4 与 Spring Framework 7 全面解析:新特性、升级要点与实战指南
spring boot·后端·spring