在这里插入图片描述

🍃 予枫个人主页

📚 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常

💻 Debug 这个世界,Return 更好的自己!

引言

随着AIGC技术爆发,大模型对话应用已成为企业级开发的高频需求。但原生大模型API调用繁琐、异步处理复杂、参数调优无章法,让不少Java开发者望而却步。Spring AI的出现,完美解决了这些痛点——它将大模型调用封装为简洁的Spring Bean,轻松实现同步、异步、流式输出等能力。本文就手把手教你搭建第一个可运行Demo,从最简代码到进阶优化,再到源码解读,让你快速掌握Spring AI开发大模型对话应用的核心技巧~

一、环境准备(前置必备)

✨ 工欲善其事,必先利其器。在开始编码前,我们需要准备好基础环境,确保Demo能顺利运行。

1.1 开发环境清单

  • JDK:17+(Spring AI对JDK版本有最低要求,17是最稳定的选择)
  • 构建工具:Maven 3.8+ 或 Gradle 7.5+(本文以Maven为例)
  • 开发工具:IntelliJ IDEA(推荐,自带Spring Boot支持,调试更便捷)
  • 大模型API密钥:本文以OpenAI API为例(也可替换为国内大模型,如百度文心一言、阿里通义千问,配置方式类似)
  • 测试工具:Postman 或 Swagger(用于接口调试)

1.2 Maven依赖配置

在Spring Boot项目的pom.xml中,引入核心依赖(Spring AI Starter + 大模型客户端),无需额外导入过多依赖,Spring AI已做好封装:

<!-- Spring Boot父工程 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.4</version>
    <relativePath/>
</parent>

<dependencies>
    <!-- Spring Web:用于开发接口 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
    </dependency>
<!-- Spring AI OpenAI Starter:核心依赖,封装大模型调用 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        <version>1.0.0-M1</version>
    </dependency>
    <!-- Swagger:接口文档,方便调试 -->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        <version>2.2.0</version>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
    </dependency>
</dependencies>

💡 注意:Spring AI目前处于快速迭代阶段,版本可能更新,建议使用最新稳定版;若替换为其他大模型,只需替换对应的starter依赖(如spring-ai-ernie-starter for 文心一言)。

1.3 配置文件设置

在application.yml中配置大模型API密钥、模型名称等核心参数,无需硬编码,方便后续修改:

spring:
  ai:
    openai:
      api-key: 你的OpenAI API密钥
      chat:
        model: gpt-3.5-turbo # 模型名称,可替换为gpt-4(需开通权限)
        temperature: 0.7 # 默认温度,后续会讲解调优技巧
        top-p: 0.9 # 默认top_p参数,控制输出的多样性

# Swagger配置(可选,方便接口调试)
springdoc:
  api-docs:
    path: /api-docs
  swagger-ui:
    path: /swagger-ui.html
    operationsSorter: method

二、最简Demo:同步对话接口开发(核心第一步)

这一部分我们实现最基础的同步对话功能——前端发送问题,后端调用大模型,同步返回回答。代码极简,新手也能快速跑通。

2.1 核心代码实现(Controller层)

创建ChatController,注入OpenAiChatClient(Spring AI自动配置的Bean),编写一个POST接口,接收用户提问,调用大模型并返回结果:

import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 大模型对话接口控制器
 * 关注我,获取更多Spring AI实战技巧~
 */
@RestController
public class ChatController {

    // 注入Spring AI自动配置的OpenAI对话客户端
    private final OpenAiChatClient openAiChatClient;

    // 构造方法注入(Spring Boot自动装配,无需手动new)
    public ChatController(OpenAiChatClient openAiChatClient) {
        this.openAiChatClient = openAiChatClient;
    }

    /**
     * 同步对话接口:接收用户提问,同步返回大模型回答
     * @param request 用户提问内容(封装为实体类,更规范)
     * @return 大模型回答结果
     */
    @PostMapping("/api/chat/sync")
    public String syncChat(@RequestBody ChatRequest request) {
        // 直接调用客户端的generate方法,传入提问内容,返回回答
        return openAiChatClient.generate(request.getQuestion());
    }

    // 静态内部类:接收前端请求参数
    public static class ChatRequest {
        private String question; // 用户提问内容

        // getter/setter
        public String getQuestion() {
            return question;
        }

        public void setQuestion(String question) {
            this.question = question;
        }
    }
}

2.2 启动项目,测试接口

  1. 启动Spring Boot项目,确保无报错(若提示API密钥错误,检查配置文件中的api-key是否正确);
  2. 打开Postman,发送POST请求:
    • 地址:http://localhost:8080/api/chat/sync
    • 请求体(JSON):{“question”:“请用Java代码实现一个简单的单例模式”}
  3. 查看响应结果:大模型会返回对应的Java代码,同步接口开发完成!

🌟 小技巧:此时可以点赞收藏本文,后续开发时直接复用这段代码,省去重复编码的时间~

2.3 关键说明

  • OpenAiChatClient是Spring AI封装的核心客户端,无需我们手动处理HTTP请求、签名验证等繁琐操作;
  • 同步调用适合简单场景,但如果大模型回答较长,会导致接口响应时间过长,用户体验不佳,这就需要用到下一部分的异步和流式输出。

三、进阶实现:异步+流式SSE+参数调优

这一部分是重点,我们优化接口性能,实现异步调用(不阻塞主线程)、流式SSE输出(实时返回回答,类似ChatGPT的打字效果),并讲解temperature、top_p等核心参数的调优技巧。

3.1 异步对话接口开发

异步调用通过Spring的@Async注解实现,结合CompletableFuture返回结果,避免接口阻塞。

3.1.1 新增异步服务层

创建ChatService,编写异步调用方法(记得添加@Async注解):

import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

/**
 * 大模型对话服务层(封装业务逻辑,便于复用)
 */
@Service
public class ChatService {

    private final OpenAiChatClient openAiChatClient;

    public ChatService(OpenAiChatClient openAiChatClient) {
        this.openAiChatClient = openAiChatClient;
    }

    /**
     * 异步对话调用
     * @param question 用户提问
     * @return 异步结果(CompletableFuture)
     */
    @Async
    public CompletableFuture<String> asyncChat(String question) {
        // 调用大模型,返回CompletableFuture
        return CompletableFuture.supplyAsync(() -> openAiChatClient.generate(question));
    }
}

3.1.2 新增异步接口(Controller层)

在ChatController中注入ChatService,新增异步接口:

// 注入对话服务
private final ChatService chatService;

// 构造方法添加ChatService注入
public ChatController(OpenAiChatClient openAiChatClient, ChatService chatService) {
    this.openAiChatClient = openAiChatClient;
    this.chatService = chatService;
}

/**
 * 异步对话接口:不阻塞主线程,提高接口吞吐量
 * @param request 用户提问
 * @return 异步结果
 */
@PostMapping("/api/chat/async")
public CompletableFuture<String> asyncChat(@RequestBody ChatRequest request) {
    return chatService.asyncChat(request.getQuestion());
}

3.1.3 开启异步支持

在Spring Boot启动类上添加@EnableAsync注解,开启异步功能:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync // 开启异步支持
public class SpringAiChatDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringAiChatDemoApplication.class, args);
    }
}

3.2 流式SSE输出(实时响应)

流式输出通过SSE(Server-Sent Events)实现,大模型的回答会分批次返回,前端可以实时展示,极大提升用户体验。Spring AI已封装好流式调用方法,直接使用即可。

3.2.1 流式接口开发(Controller层)

新增流式接口,返回SseEmitter(Spring提供的SSE工具类):

import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

/**
 * 流式SSE对话接口:实时返回大模型回答(类似ChatGPT打字效果)
 * @param request 用户提问
 * @return SseEmitter 流式响应
 */
@PostMapping(value = "/api/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamChat(@RequestBody ChatRequest request) {
    // 创建SseEmitter,设置超时时间(30秒,避免连接断开)
    SseEmitter emitter = new SseEmitter(30000L);

    // 调用Spring AI的流式生成方法,分批次接收结果
    openAiChatClient.stream(request.getQuestion())
            .doOnNext(chunk -> {
                try {
                    // 每收到一个分片,发送到前端
                    emitter.send(chunk.getContent());
                } catch (Exception e) {
                    emitter.completeWithError(e);
                }
            })
            .doOnComplete(() -> {
                // 生成完成,关闭连接
                emitter.complete();
            })
            .doOnError(error -> {
                // 出现错误,返回错误信息并关闭连接
                emitter.completeWithError(error);
            })
            .subscribe();

    return emitter;
}

3.2.2 流式接口测试

用Postman测试流式接口:

  1. 发送POST请求,地址:http://localhost:8080/api/chat/stream
  2. 请求体:{“question”:“请详细讲解Spring AI的核心原理”}
  3. 观察响应:会分批次返回内容,类似ChatGPT的实时打字效果,体验拉满!

3.3 对话参数调优(temperature/top_p)

大模型的输出效果,主要通过temperature和top_p两个参数控制,合理调优能让回答更贴合需求。

3.3.1 核心参数解读

  • temperature(温度):取值范围0~2,控制回答的随机性。

    • 取值越低(如0.1~0.3):回答越严谨、确定,适合事实查询、代码生成等场景;
    • 取值越高(如1.5~2.0):回答越有创意、发散,适合文案创作、 brainstorming 等场景;
    • 默认值0.7:平衡严谨性和创意性,适合大多数场景。
  • top_p(核采样):取值范围0~1,控制回答的多样性(与temperature二选一即可,不建议同时调整)。

    • 取值越低(如0.5):只选择概率最高的少数 tokens,回答更集中;
    • 取值越高(如0.9):选择更多概率较低的 tokens,回答更多样;
    • 默认值0.9:兼顾多样性和准确性。

3.3.2 参数调优实现(动态调整)

我们可以在接口中动态接收参数,实现不同场景下的参数自定义:

  1. 修改ChatRequest实体类,添加temperature和top_p字段:
public static class ChatRequest {
    private String question;
    private Float temperature; // 可选,不传递则使用配置文件默认值
    private Float topP; // 可选,不传递则使用配置文件默认值

    // getter/setter 省略
}
  1. 优化同步对话接口,支持动态参数:
@PostMapping("/api/chat/sync")
public String syncChat(@RequestBody ChatRequest request) {
    // 构建对话参数,优先使用请求中的参数,无则使用默认值
    OpenAiChatOptions options = OpenAiChatOptions.builder()
            .temperature(request.getTemperature() != null ? request.getTemperature() : 0.7f)
            .topP(request.getTopP() != null ? request.getTopP() : 0.9f)
            .build();

    // 调用大模型,传入参数
    return openAiChatClient.generate(request.getQuestion(), options);
}

📌 提示:异步和流式接口也可以用同样的方式,添加动态参数调优功能,需要的同学可以自己动手实现(评论区可以交流实现思路哦~)

四、接口封装与测试(Postman/Swagger)

接口开发完成后,必须进行调试和测试,确保功能正常。下面分别介绍Postman和Swagger的测试方法。

4.1 Postman测试(推荐,功能更全)

4.1.1 同步接口测试

  • 方法:POST
  • 地址:http://localhost:8080/api/chat/sync
  • 请求体:
{
  "question": "请用Java代码实现冒泡排序",
  "temperature": 0.2,
  "topP": 0.8
}
  • 预期结果:返回正确的冒泡排序代码,格式规范。

4.1.2 异步接口测试

  • 方法:POST
  • 地址:http://localhost:8080/api/chat/async
  • 请求体:同上
  • 预期结果:返回CompletableFuture格式的响应,包含大模型回答。

4.1.3 流式接口测试

  • 方法:POST
  • 地址:http://localhost:8080/api/chat/stream
  • 请求体:同上
  • 预期结果:分批次返回内容,实时展示。

4.2 Swagger测试(快速调试)

启动项目后,访问:http://localhost:8080/swagger-ui.html,即可看到所有接口的文档,直接在页面上输入参数,点击“Try it out”即可测试,无需额外工具,适合快速调试。

💡 小技巧:可以将测试通过的接口保存为Postman集合,后续迭代开发时,直接复用测试用例,提高效率。

五、核心源码极简解读(Spring AI对话调用流程)

很多同学可能好奇:Spring AI到底是如何封装大模型调用的?底层执行流程是什么?这里用极简的方式拆解核心源码,不用深入复杂逻辑,快速理解核心原理。

5.1 核心执行流程(3步)

  1. 自动装配:Spring Boot启动时,Spring AI的AutoConfiguration类(如OpenAiAutoConfiguration)会自动配置OpenAiChatClient、OpenAiChatOptions等Bean,我们直接注入即可使用,无需手动创建。

  2. 请求封装:当我们调用openAiChatClient.generate()方法时,Spring AI会将用户的提问、参数(temperature/top_p)封装为大模型API要求的请求格式(如OpenAI的ChatCompletionRequest)。

  3. 请求发送与结果解析:Spring AI通过RestTemplate或WebClient发送HTTP请求到大模型API,接收响应后,解析返回的JSON数据,提取回答内容,封装为我们需要的格式(String或流式分片),返回给上层。

5.2 核心源码片段(关键类)

  • OpenAiChatClient:核心客户端,提供generate(同步)、stream(流式)等方法,是我们调用的入口。
  • OpenAiChatOptions:参数配置类,封装temperature、top_p、model等参数。
  • OpenAiChatCompletionClient:底层请求发送类,负责与大模型API交互,处理请求和响应。

📚 拓展:如果想深入学习,可以查看Spring AI的源码(GitHub地址:https://github.com/spring-projects/spring-ai),重点看openai模块下的相关类,难度不大,适合Java开发者阅读。

六、总结

本文从环境准备、最简Demo开发,到进阶的异步调用、流式SSE输出、参数调优,再到接口测试和源码解读,完整覆盖了用Spring AI实现Java版大模型对话应用的核心流程。

核心亮点:Spring AI极大简化了大模型调用的复杂度,让Java开发者无需关注底层HTTP请求、签名等细节,专注于业务逻辑;同步、异步、流式三种调用方式,满足不同场景的需求;参数调优能让大模型的回答更贴合实际业务。


✨ 最后,如果你觉得本文对你有帮助,欢迎点赞、收藏、评论,关注我(予枫),后续会分享更多Spring AI、Java、AIGC相关的实战技巧~
如果在开发过程中遇到问题,可以在评论区留言,我会第一时间回复~

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐