Spring AI快速上手:Java集成ChatGPT/文心一言,30分钟实现智能问答接口

随着大模型技术的普及,企业对智能问答、内容生成等AI能力的集成需求日益迫切。Spring AI作为Spring生态的官方AI开发框架,提供了标准化的大模型集成接口,无需关注不同厂商模型的调用差异,可快速将ChatGPT、文心一言等能力嵌入Java应用。本文以"快速落地"为核心,手把手教你在30分钟内完成Spring AI环境搭建、双模型集成、智能问答接口开发与测试,全程贴合Java开发者技术栈,确保新手也能快速上手。

补充说明:本文基于Spring Boot 3.2.x、Spring AI 0.8.1版本实战,兼容JDK 17+(推荐版本),同时覆盖ChatGPT(OpenAI API)与文心一言(百度智能云API)两种主流模型,可根据需求灵活切换。

一、前置准备(5分钟)

集成前需完成环境配置与API密钥申请,为后续开发扫清障碍,核心准备工作分为三步:

1. 环境要求确认

  • JDK:17+(Spring AI 0.8.x及以上版本不再支持JDK 11及以下);

  • 构建工具:Maven 3.8+ 或 Gradle 7.5+(本文以Maven为例);

  • 依赖管理:Spring Boot 3.2.x(确保与Spring AI版本兼容);

  • 网络环境:需能访问外网(集成ChatGPT)或百度智能云服务(集成文心一言)。

2. API密钥申请

需分别申请对应模型的API密钥,用于接口调用鉴权:

  • ChatGPT密钥 :登录OpenAI官网(https://platform.openai.com/),进入API Keys页面创建密钥,记录密钥信息(后续配置使用,切勿泄露);

  • 文心一言密钥 :登录百度智能云官网(https://cloud.baidu.com/),开通"文心一言"服务,创建应用后获取API Key与Secret Key(双密钥鉴权)。

注意:两种模型均有免费额度(OpenAI新用户有试用金额,百度智能云提供免费调用次数),适合前期开发测试;生产环境需根据并发量购买对应套餐。

3. 项目初始化

通过Spring Initializr(https://start.spring.io/)快速初始化Spring Boot项目,核心依赖选择:

  • Spring Web(用于开发RESTful接口);

  • Spring AI OpenAI(集成ChatGPT);

  • Spring AI Baidu(集成文心一言);

  • Lombok(可选,简化实体类代码)。

生成项目后下载解压,用IDEA或Eclipse打开,进入后续依赖配置环节。

二、依赖配置与环境搭建(5分钟)

Spring AI已将不同大模型的集成封装为starter依赖,只需在pom.xml中引入对应依赖,再配置API密钥即可完成环境搭建。

1. 核心依赖配置(pom.xml)

在pom.xml中添加Spring AI核心依赖与模型依赖,确保版本统一:

xml 复制代码
<!-- Spring Boot 父依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
    <relativePath/>
</parent>

<dependencies>
    <!-- Spring 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>0.8.1</version>
    </dependency>

    <!-- Spring AI OpenAI 依赖(集成ChatGPT) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        <version>0.8.1</version>
    </dependency>

    <!-- Spring AI 百度文心一言依赖 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-baidu-spring-boot-starter</artifactId>
        <version>0.8.1</version>
    </dependency>

    <!-- Lombok 简化代码(可选) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<!-- 配置Spring仓库(部分Spring AI依赖需从Spring仓库获取) -->
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

2. 模型密钥配置(application.yml)

在src/main/resources下创建application.yml文件,配置ChatGPT与文心一言的API密钥、模型参数,支持灵活切换模型:

yaml 复制代码
spring:
  application:
    name: spring-ai-quickstart
  # Spring AI 配置
  ai:
    # 默认使用的模型(可切换为baidu或openai)
    default-ai-client: openai
    # OpenAI(ChatGPT)配置
    openai:
      api-key: sk-your-openai-api-key # 替换为你的OpenAI API密钥
      model: gpt-3.5-turbo # 模型版本(gpt-3.5-turbo性价比最高,适合测试)
      temperature: 0.7 # 生成内容随机性(0-1,值越大越随机)
      max-tokens: 2048 # 单次响应最大token数
    # 百度文心一言配置
    baidu:
      api-key: your-baidu-api-key # 替换为你的百度API Key
      secret-key: your-baidu-secret-key # 替换为你的百度Secret Key
      model: ernie-3.5 # 模型版本(ernie-3.5为免费常用版本)
      temperature: 0.7
      max-tokens: 2048

# 服务器配置(可选,默认8080端口)
server:
  port: 8080

关键说明:① default-ai-client用于指定默认模型,切换时只需修改为baidu或openai即可;② temperature参数控制生成内容的创造性,0为确定性输出,1为最大随机性,测试阶段建议设为0.7;③ 若需代理访问OpenAI,可在openai配置下添加proxy-host与proxy-port参数。

三、核心功能开发(15分钟)

基于Spring AI封装的API,快速开发智能问答接口,支持单轮问答、多轮对话,同时实现模型动态切换功能,全程无需编写复杂的HTTP调用逻辑。

1. 实体类定义(用于接口请求/响应)

创建实体类封装接口请求参数与响应结果,使用Lombok简化getter/setter方法:

java 复制代码
import lombok.Data;

/**
 * 智能问答请求参数
 */
@Data
public class ChatRequest {
    // 提问内容
    private String question;
    // 模型类型(openai/baidu,可选,默认使用配置文件中的default-ai-client)
    private String modelType;
    // 对话ID(多轮对话用,用于关联上下文)
    private String conversationId;
}

/**
 * 智能问答响应结果
 */
@Data
public class ChatResponse {
    // 响应状态(success/fail)
    private String status;
    // 回答内容
    private String answer;
    // 对话ID(多轮对话返回,用于后续上下文关联)
    private String conversationId;
    // 模型类型(实际使用的模型)
    private String modelType;
    // 错误信息(失败时返回)
    private String errorMsg;
}

2. 服务层开发(封装AI调用逻辑)

创建服务类,注入Spring AI提供的ChatClient接口,封装单轮问答、多轮对话逻辑,支持模型动态切换:

java 复制代码
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.baidu.BaiduChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class AIService {

    // 注入默认ChatClient(由配置文件default-ai-client指定)
    @Autowired
    private ChatClient defaultChatClient;

    // 注入OpenAI客户端(单独调用ChatGPT时使用)
    @Autowired(required = false)
    private OpenAiChatClient openAiChatClient;

    // 注入百度文心一言客户端(单独调用时使用)
    @Autowired(required = false)
    private BaiduChatClient baiduChatClient;

    // 存储多轮对话上下文(key:conversationId,value:对话历史)
    private final ConcurrentHashMap<String, StringBuilder> conversationContext = new ConcurrentHashMap<>();

    /**
     * 智能问答核心方法(支持单轮/多轮、动态切换模型)
     */
    public ChatResponse chat(com.example.ai.dto.ChatRequest request) {
        ChatResponse response = new ChatResponse();
        try {
            // 生成/获取对话ID(多轮对话关联上下文)
            String conversationId = request.getConversationId() == null ? 
                    UUID.randomUUID().toString() : request.getConversationId();
            // 获取对话历史上下文
            StringBuilder context = conversationContext.getOrDefault(conversationId, new StringBuilder());

            // 选择要使用的模型客户端
            ChatClient chatClient = selectChatClient(request.getModelType());
            String modelType = request.getModelType() == null ? "openai" : request.getModelType();

            // 拼接上下文(多轮对话)
            String fullQuestion = context.append("用户:").append(request.getQuestion()).append("\n").toString();
            // 构建用户消息
            Message userMessage = new UserMessage(fullQuestion);
            Prompt prompt = new Prompt(userMessage);

            // 调用AI模型获取回答
            org.springframework.ai.chat.ChatResponse aiResponse = chatClient.call(prompt);
            String answer = aiResponse.getResult().getOutput().getContent();

            // 更新对话上下文
            context.append("AI:").append(answer).append("\n");
            conversationContext.put(conversationId, context);

            // 封装响应结果
            response.setStatus("success");
            response.setAnswer(answer);
            response.setConversationId(conversationId);
            response.setModelType(modelType);

        } catch (Exception e) {
            response.setStatus("fail");
            response.setErrorMsg("问答失败:" + e.getMessage());
        }
        return response;
    }

    /**
     * 选择模型客户端
     */
    private ChatClient selectChatClient(String modelType) {
        if (modelType == null || modelType.isEmpty()) {
            return defaultChatClient; // 使用默认模型
        }
        return switch (modelType.toLowerCase()) {
            case "baidu" -> baiduChatClient;
            case "openai" -> openAiChatClient;
            default -> defaultChatClient;
        };
    }

    /**
     * 清除对话上下文(多轮对话结束后调用)
     */
    public void clearConversationContext(String conversationId) {
        conversationContext.remove(conversationId);
    }
}

关键说明:① 多轮对话通过conversationId关联上下文,将历史对话存储在ConcurrentHashMap中(生产环境可替换为Redis,支持分布式部署);② selectChatClient方法实现模型动态切换,根据请求参数选择对应的客户端;③ 异常捕获确保接口稳定,避免因模型调用失败导致服务宕机。

3. 接口层开发(RESTful接口)

创建控制器,开发智能问答接口、清除上下文接口,对外提供HTTP服务:

java 复制代码
import com.example.ai.dto.ChatRequest;
import com.example.ai.dto.ChatResponse;
import com.example.ai.service.AIService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/ai")
@Slf4j
public class AIController {

    @Autowired
    private AIService aiService;

    /**
     * 智能问答接口(支持GET/POST,方便测试)
     */
    @PostMapping("/chat")
    public ChatResponse chat(@RequestBody ChatRequest request) {
        log.info("接收AI问答请求:question={}, modelType={}, conversationId={}",
                request.getQuestion(), request.getModelType(), request.getConversationId());
        return aiService.chat(request);
    }

    /**
     * GET方式接口(方便浏览器快速测试)
     */
    @GetMapping("/chat")
    public ChatResponse chatGet(
            @RequestParam String question,
            @RequestParam(required = false) String modelType,
            @RequestParam(required = false) String conversationId) {
        ChatRequest request = new ChatRequest();
        request.setQuestion(question);
        request.setModelType(modelType);
        request.setConversationId(conversationId);
        return aiService.chat(request);
    }

    /**
     * 清除对话上下文接口
     */
    @DeleteMapping("/conversation/{conversationId}")
    public String clearConversation(@PathVariable String conversationId) {
        aiService.clearConversationContext(conversationId);
        return "对话上下文已清除:" + conversationId;
    }
}

4. 启动类编写

创建Spring Boot启动类,开启Spring Web支持:

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringAiQuickstartApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringAiQuickstartApplication.class, args);
        System.out.println("Spring AI 智能问答服务启动成功!访问地址:http://localhost:8080/api/ai/chat");
    }
}

四、接口测试与验证(5分钟)

启动项目后,通过Postman、浏览器或curl命令测试接口,验证ChatGPT、文心一言的调用效果,同时测试多轮对话功能。

1. 启动项目

运行SpringAiQuickstartApplication的main方法,控制台输出"Spring AI 智能问答服务启动成功"即表示环境搭建正常。

2. 单轮问答测试(ChatGPT)

通过浏览器访问GET接口,测试ChatGPT回答效果:

响应结果示例:

3. 单轮问答测试(文心一言)

修改modelType参数为baidu,测试文心一言:

响应结果示例:

4. 多轮对话测试

使用上一轮返回的conversationId,关联上下文进行多轮对话:

AI会基于上一轮"Spring AI是什么"的对话上下文回答,实现连贯的多轮交互。

五、常见问题与避坑指南

1. API密钥无效或权限不足

现象:接口响应失败,errorMsg提示"Invalid API key"或"Insufficient quota"。解决方案:① 检查API密钥是否正确,有无多余空格;② 确认密钥未过期、未泄露,OpenAI密钥可在官网重置;③ 检查账号余额或免费额度是否耗尽,及时充值或更换账号。

2. 无法访问OpenAI服务

现象:调用ChatGPT时超时,提示"Connection timed out"。解决方案:① 配置代理,在application.yml的openai配置下添加proxy-host和proxy-port;② 确保代理能正常访问外网,无端口限制;③ 若无法使用代理,可优先测试文心一言(国内可直接访问)。

3. 模型客户端注入失败

现象:启动项目时报错"Could not autowire field: OpenAiChatClient"。解决方案:① 检查pom.xml中对应模型的依赖是否引入,版本是否与Spring AI一致;② 确认配置文件中模型密钥是否填写,无密钥会导致客户端无法初始化。

4. 多轮对话上下文丢失

现象:多轮对话时AI无法关联历史内容。解决方案:① 确保每次请求都携带正确的conversationId;② 生产环境建议将上下文存储在Redis中,而非本地Map(避免服务重启后丢失)。

六、进阶优化建议(可选)

若需将接口用于生产环境,可从以下维度优化,提升稳定性与性能:

  • 上下文存储优化:将对话历史从ConcurrentHashMap迁移至Redis,支持分布式部署,同时设置过期时间(如30分钟),避免内存溢出;

  • 限流与熔断:通过Sentinel或Resilience4j对接口限流,避免因高频调用触发模型API的限流机制;添加熔断逻辑,模型调用失败时降级返回预设内容;

  • 日志与监控:记录每一次问答请求与响应,集成Spring Boot Actuator+Prometheus监控接口调用量、响应时间;

  • 模型参数优化:根据业务场景调整temperature、max-tokens参数,如知识问答场景temperature设为0.2(更精准),内容生成场景设为0.8(更多样);

  • 多模型负载均衡:实现模型轮询调用,当一个模型不可用时自动切换至另一个模型,提升服务可用性。

七、总结

本文通过"前置准备-环境搭建-功能开发-接口测试"四步流程,30分钟内完成了Spring AI集成ChatGPT与文心一言的智能问答接口开发。Spring AI的核心价值在于提供了标准化的AI调用接口,屏蔽了不同厂商模型的调用差异,让Java开发者无需掌握复杂的HTTP请求、鉴权逻辑,即可快速集成AI能力。

后续可基于本文基础,扩展更多功能:如内容生成、代码辅助、智能客服等,适配不同业务场景。对于Java开发者而言,Spring AI降低了AI应用的开发门槛,让传统Java应用快速具备智能化能力,是云原生时代AI与业务融合的优选工具。

相关推荐
C系语言2 小时前
Anaconda虚拟环境,完全使用conda install命令安装所有包,使用conda install pytorch
人工智能·pytorch·conda
jkyy20142 小时前
AI赋能健康新生态:HealthAgent开放平台重构B端服务价值
大数据·人工智能·健康医疗
GIOTTO情2 小时前
2026 舆情监测技术选型指南:Infoseek 基于 AI 大模型的全链路技术落地解析
人工智能
愚公搬代码2 小时前
【愚公系列】《AI+直播营销》036-直播间装修和布置(直播间装修和布置的5个场景)
人工智能
VertGrow AI销冠2 小时前
AI在吸引客户和引流方面的实际效果和应用研究
人工智能
smj2302_796826522 小时前
解决leetcode第3816题.删除重复字符后的字典序最小字符串
python·算法·leetcode
七夜zippoe2 小时前
Python多线程性能优化实战:突破GIL限制的高性能并发编程指南
python·macos·多线程·读写锁·gil·rcu
快乐非自愿2 小时前
AI低代码与智改数转:破除伪命题,重构技术落地逻辑
人工智能·低代码·重构
chao_7892 小时前
链表题解——相交链表【Leetcode】(最新版,核心思路)
数据结构·python·leetcode·链表