最新SpringAI-1.1.2接入openai兼容模型

背景

测试了下SpringAI,文档繁琐,一团乱麻,搞了好久终于搞定了,因此本次文档分享一下如何快速接入。

目标

接入openai-兼容的LLM,且官方没有提供原始实现的,如:qianfan,等

版本:

  • springboot: 3.5.9
  • springai: 1.1.2

示例

本次以qianfan为例子,自行在idea创建一个java项目,包管理使用gradle(如果是maven自行把gradle转换成maven就行,用llm转很快)

1. 配置文件gradle

  1. 要引入spring-boot-starter-webflux,用于返回流式内容
  2. 引入openai包,spring-ai-starter-model-openai
gradle 复制代码
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.5.9'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'ai-learn'
version = '0.0.1-SNAPSHOT'
description = 'springai-test'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

repositories {
    mavenCentral()
}

ext {
    set('springAiVersion', "1.1.2")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.ai:spring-ai-starter-model-openai'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.ai:spring-ai-bom:${springAiVersion}"
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

2. yml配置

参考如下

yml 复制代码
server:
  port: 8080
spring:
  ai:
    openai:
      # 模型的基础地址
      base-url: https://qianfan.baidubce.com/v2
      api-key: 你的api-key
      chat:
        options:
          # 模型名
          model: ernie-4.5-turbo-32k
        completions-path: /chat/completions

注意:

  1. 模型基础地址,观察对应模型的说明文档,一般都会给出openai兼容的地址,如千帆OpenAI SDK兼容介绍
  2. 一些其他坑人情况,如:completions-path,这个具体配置成什么,可以参考说明文档,如:千帆AI应用开发者中心-API参考:模型:文本生成,其中写道:请求地址拼接出来应该是:https://qianfan.baidubce.com/v2/chat/completions
    我们观察springai官方文档说的是:

spring.ai.openai.chat.completions-path(附加到基础 URL 的路径)

默认值:/v1/chat/completions

和我们api中看到的/v2/chat/completions不一致,因此,这里要修改配置completions-path为/chat/completions,大功告成。

3. 新增测试Controller

可以测试三种情况,阻塞,转json,流式

java 复制代码
package ailearn.springaitest;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder
                .defaultSystem("你是一个友好的 AI 助手,请用中文简洁地回答问题。")
                .build();
    }

    // 1. 最简单的文本对话
    @GetMapping("/chat")
    public String chat(@RequestParam String message) {
        return chatClient.prompt()
                .user(message)
                .call()
                .content();
    }

    // 2. 结构化输出 (Structured Output) - 返回 Java Bean
    // Spring AI 会自动提示 LLM 输出 JSON 并解析
    @GetMapping("/actor")
    public ActorInfo getActorInfo(@RequestParam String name) {
        return chatClient.prompt()
                .user(u -> u
                        .text("请生成一个关于演员 '{actor}' 的简介")
                        .param("actor", name))
                .call()
                .entity(ActorInfo.class); // 自动映射到 Record
    }

    // 3. 流式响应 (Streaming)
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamChat(@RequestParam String message) {
        return chatClient.prompt()
                .user(message)
                .stream()
                .content()
                // 【关键】打印每一个 Token,观察控制台
                .doOnNext(token -> System.out.println("收到 Token: " + token))
                .doOnComplete(() -> System.out.println("流结束"));
    }

    // 用于结构化输出的 Record
    record ActorInfo(String name, String famousMovie, int age) {}
}

4. 测试

在前端页面分别调用即可,注意流式测试时,输入内容可以是:"帮我生成1个500字的故事",可以观察是否是真流式

附录

其他参数可以自行查看SpringAI官方文档:SpringAI

相关推荐
带刺的坐椅18 小时前
用 10 行 Java8 代码,开发一个自己的 ClaudeCodeCLI?你信吗?
java·ai·llm·agent·solon·mcp·claudecode·skills
学历真的很重要18 小时前
【系统架构师】第二章 操作系统知识 - 第二部分:进程管理(详解版)
学习·职场和发展·系统架构·系统架构师
Nebula_g18 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
HAPPY酷18 小时前
构造与析构:C++ 中对象的温柔生灭
java·jvm·c++
lang2015092818 小时前
Java JSR 250核心注解全解析
java·开发语言
星期五不见面18 小时前
机器人学习!(二)ROS2-节点(7)2026/02/03
学习
czhc114007566318 小时前
协议 25
java·开发语言·算法
逆光的July18 小时前
如何解决超卖问题
java
狂奔蜗牛飙车18 小时前
Python学习之路-循环语句学习详解
python·学习·python学习·#python学习笔记·循环语句详解
落花流水 丶18 小时前
Java 集合框架完全指南
java