Spring AI 1.1:快速接入主流 LLM,实现智能问答与文本生成

在大模型(LLM)技术爆发的当下,开发者们迫切需要一套简洁、统一的方案,将不同厂商的LLM能力集成到自身应用中。Spring AI的出现,恰好填补了这一空白------它依托Spring生态的强大优势,为LLM集成提供了标准化的API、自动配置等核心能力,让开发者无需关注不同LLM的底层差异,就能快速实现智能问答、文本生成、图像理解等功能。

Spring AI 1.1作为其重要更新版本,进一步完善了对主流LLM的支持(如OpenAI、阿里云通义千问、百度文心一言等),优化了配置方式与性能表现。本文将从环境准备入手,手把手教你接入主流LLM,实现智能问答与文本生成核心功能,并拓展讲解提示词工程、多模型切换等实用技巧,助力你快速上手Spring AI 1.1开发。

一、Spring AI 1.1 核心特性速览

在正式实操前,我们先梳理下Spring AI 1.1的核心优势,明白它为何能成为LLM集成的首选方案:

  • 统一API抽象:对不同LLM厂商(OpenAI、通义千问、文心一言等)的接口进行标准化封装,开发者无需修改核心业务代码,即可切换不同LLM模型,降低接入成本与迁移风险。

  • 原生Spring生态集成:无缝兼容Spring Boot、Spring Cloud等生态组件,支持基于application.yml的配置驱动开发,符合Spring开发者的使用习惯。

  • 丰富的功能支持:除基础的文本问答、生成外,还支持流式响应、提示词模板、函数调用(Function Call)、向量数据库集成(用于RAG场景)等高级特性。

  • 简化的依赖管理:通过starter依赖即可快速引入对应LLM的集成能力,无需手动管理复杂的第三方SDK依赖。

  • 完善的异常处理:提供统一的异常封装与处理机制,便于开发者排查API调用超时、鉴权失败等问题。

二、环境准备:快速搭建Spring AI 1.1项目

本节将以Spring Boot 3.2(Spring AI 1.1最低支持Spring Boot 3.0+)为基础,搭建项目骨架,引入核心依赖。

2.1 版本选型说明

  • JDK:17+(Spring Boot 3.x最低要求,也是Spring AI推荐版本)

  • Spring Boot:3.2.x

  • Spring AI:1.1.0(最新稳定版,可通过Spring Initializr自动引入)

2.2 项目初始化(两种方式)

推荐使用Spring Initializr快速生成项目,也可手动配置pom.xml。

方式1:Spring Initializr生成(推荐)

  1. 访问Spring Initializr官网:https://start.spring.io/

  2. 配置基础信息:

    Project:Maven/Gradle(本文以Maven为例)

  3. Language:Java

  4. Spring Boot:3.2.x

  5. Group/Artifact:自定义(如com.example/spring-ai-demo)

  6. Dependencies:搜索并添加「Spring AI Starter」(会自动引入spring-ai-core核心依赖),若需接入特定LLM(如OpenAI),可直接搜索「Spring AI Starter for OpenAI」。

  7. 点击「Generate」下载项目压缩包,解压后导入IDE(如IntelliJ IDEA)。

方式2:手动配置pom.xml

若需手动配置,在Spring Boot项目的pom.xml中添加Spring AI的依赖管理与核心依赖:

xml 复制代码
<!-- Spring AI 依赖管理 -->
<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>

<!-- 核心依赖:Spring AI Core -->
<dependencies>
    <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>
    </dependency>
    
    <!-- 示例:OpenAI 集成依赖(需接入其他LLM可替换为对应starter) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>
    
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
    

三、核心实操:接入主流LLM,实现智能问答与文本生成

本节将以「OpenAI」「阿里云通义千问」为例,讲解如何通过Spring AI 1.1快速接入,分别实现智能问答(如知识库查询、问题解答)与文本生成(如文案创作、代码生成)功能。核心思路是:通过配置文件指定LLM的API密钥、模型名称等信息,Spring AI会自动创建对应的客户端实例,开发者直接注入使用即可。

3.1 接入OpenAI:基础示例(智能问答+文本生成)

OpenAI的GPT系列模型(如gpt-3.5-turbo、gpt-4)是目前最常用的LLM之一,Spring AI 1.1通过spring-ai-openai-spring-boot-starter提供了完善的支持。

步骤1:配置OpenAI相关信息

在application.yml中添加以下配置(需替换为自己的OpenAI API密钥,可从OpenAI官网获取):

yaml 复制代码
spring:
  ai:
    openai:
      api-key: sk-your-openai-api-key  # 替换为你的OpenAI API密钥
      chat:
        model: gpt-3.5-turbo  # 默认使用的聊天模型
        temperature: 0.7  # 生成文本的随机性(0-2,值越大越随机)
        max-tokens: 2048  # 生成文本的最大token数

步骤2:核心业务代码实现

Spring AI 1.1提供了ChatClient接口,用于与LLM进行聊天交互(支持问答、文本生成等场景)。我们只需通过@Autowired注入ChatClient实例,调用其generate方法即可完成请求。

(1)创建服务层(Service)

封装智能问答与文本生成的核心逻辑:

java 复制代码
package com.example.springaidemo.service;

import org.springframework.ai.chat.ChatClient;
import org.springframework.stereotype.Service;

/**
 * LLM核心服务:封装智能问答与文本生成功能
 */
@Service
public class LlmService {

    // 注入Spring AI自动配置的ChatClient(OpenAI实现)
    private final ChatClient chatClient;

    // 构造器注入(Spring 4.3+支持,无需@Autowired)
    public LlmService(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    /**
     * 智能问答:回答用户的问题
     * @param question 用户问题(如"Spring AI是什么?")
     * @return LLM的回答结果
     */
    public String smartQa(String question) {
        // 构建提示词(可根据需求优化提示词)
        String prompt = String.format("请用通俗易懂的语言回答以下问题:%s", question);
        // 调用ChatClient生成回答
        return chatClient.generate(prompt);
    }

    /**
     * 文本生成:根据需求生成指定类型的文本
     * @param requirement 生成需求(如"写一篇关于Spring Boot的技术博客引言")
     * @return 生成的文本内容
     */
    public String textGeneration(String requirement) {
        String prompt = String.format("请严格按照以下需求生成文本:%s。要求语言流畅、逻辑清晰,符合技术文章风格。", requirement);
        return chatClient.generate(prompt);
    }

    /**
     * 高级用法:带提示词模板的文本生成(更灵活的需求控制)
     * @param topic 博客主题
     * @param audience 目标读者(如"初学者"、"资深开发者")
     * @return 生成的博客引言
     */
    public String generateBlogIntro(String topic, String audience) {
        // 提示词模板:通过占位符动态填充参数,提升复用性
        String promptTemplate = "请为主题《%s》写一篇技术博客的引言,目标读者是%s。要求:1. 开篇点题,说明主题的重要性;2. 语言简洁,避免冗余;3. 引导读者继续阅读下文。";
        String prompt = String.format(promptTemplate, topic, audience);
        return chatClient.generate(prompt);
    }
}
(2)创建控制层(Controller)

提供HTTP接口,供前端或其他服务调用:

java 复制代码
package com.example.springaidemo.controller;

import com.example.springaidemo.service.LlmService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * LLM接口控制器:提供智能问答与文本生成的HTTP接口
 */
@RestController
@RequestMapping("/llm")
public class LlmController {

    private final LlmService llmService;

    public LlmController(LlmService llmService) {
        this.llmService = llmService;
    }

    /**
     * 智能问答接口
     * @param question 用户问题
     * @return 回答结果
     */
    @GetMapping("/qa")
    public String qa(@RequestParam String question) {
        return llmService.smartQa(question);
    }

    /**
     * 文本生成接口
     * @param requirement 生成需求
     * @return 生成的文本
     */
    @GetMapping("/generate/text")
    public String generateText(@RequestParam String requirement) {
        return llmService.textGeneration(requirement);
    }

    /**
     * 博客引言生成接口(带多参数)
     * @param topic 博客主题
     * @param audience 目标读者
     * @return 博客引言
     */
    @GetMapping("/generate/blog/intro")
    public String generateBlogIntro(@RequestParam String topic, @RequestParam String audience) {
        return llmService.generateBlogIntro(topic, audience);
    }
}

步骤3:测试接口功能

启动Spring Boot应用,通过Postman或浏览器调用接口,测试功能是否正常:

  1. 智能问答测试:访问 http://localhost:8080/llm/qa?question=Spring AI是什么?,预期返回:"Spring AI是Spring生态下的一个AI集成框架,它为开发者提供了统一的API,用于快速接入各种大语言模型(如OpenAI、通义千问等),实现智能问答、文本生成等AI功能。它简化了LLM集成的复杂度,让开发者无需关注不同模型的底层差异,只需专注于业务逻辑开发..."

  2. 文本生成测试:访问 http://localhost:8080/llm/generate/text?requirement=写一篇关于Spring Boot的技术博客引言,预期返回符合需求的博客引言内容。

  3. 博客引言生成测试:访问 http://localhost:8080/llm/generate/blog/intro?topic=Spring AI 1.1实战&audience=初学者,预期返回针对初学者的Spring AI 1.1实战博客引言。

3.2 切换到阿里云通义千问:无需修改核心代码

Spring AI 1.1的核心优势之一是「统一API抽象」,当我们需要从OpenAI切换到其他LLM(如阿里云通义千问)时,只需修改依赖与配置,核心业务代码(Service、Controller)完全无需改动。

步骤1:替换依赖(pom.xml)

移除OpenAI的starter依赖,添加通义千问的starter依赖:

xml 复制代码
<!-- 移除OpenAI依赖(若之前添加) -->
<!--<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>-->

<!-- 添加通义千问依赖 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-tongyi-spring-boot-starter</artifactId>
</dependency>

步骤2:配置通义千问信息

在application.yml中替换为通义千问的配置(需替换为自己的Access Key ID和Access Key Secret,可从阿里云控制台获取):

yaml 复制代码
spring:
  ai:
    tongyi:
      access-key-id: your-aliyun-access-key-id  # 你的阿里云Access Key ID
      access-key-secret: your-aliyun-access-key-secret  # 你的阿里云Access Key Secret
      chat:
        model: qwen-turbo  # 通义千问的聊天模型(qwen-turbo为基础版,qwen-plus为增强版)
        temperature: 0.7
        max-tokens: 2048

步骤3:直接测试接口

启动应用后,再次调用3.1中的所有接口(如/llm/qa、/llm/generate/text),会发现功能完全正常,只是底层调用的LLM从OpenAI切换到了通义千问。这就是Spring AI统一API的魅力------极大降低了多LLM接入与切换的成本。

四、实用拓展:提升LLM集成效果的关键技巧

除了基础的问答与文本生成,Spring AI 1.1还支持多种高级特性,掌握这些技巧能让你的AI应用更实用、更灵活。

4.1 提示词工程:优化生成结果的核心

LLM的生成效果很大程度上依赖于提示词(Prompt)的质量。Spring AI 1.1支持提示词模板(Prompt Template),可通过占位符动态填充参数,同时支持设置系统提示词(System Prompt)来定义LLM的角色。

示例:优化智能问答的提示词,让LLM以"技术顾问"的身份回答,且只回答与Java相关的问题:

java 复制代码
/**
 * 优化后的智能问答:限定LLM角色与回答范围
 */
public String optimizedSmartQa(String question) {
    // 系统提示词:定义LLM的角色与规则
    String systemPrompt = "你是一名资深Java技术顾问,只回答与Java相关的技术问题。若问题不涉及Java,直接回复'抱歉,我仅专注于Java相关技术问题的解答,请更换问题。'";
    // 用户提示词:结合系统提示词与用户问题
    String userPrompt = String.format("用户问题:%s", question);
    // 构建完整提示词(系统提示词 + 用户提示词)
    String fullPrompt = String.format("System: %s\nUser: %s", systemPrompt, userPrompt);
    return chatClient.generate(fullPrompt);
}

测试:调用该方法时,若用户问题为"Java中如何实现线程安全?",LLM会以技术顾问的身份详细解答;若问题为"Python的列表推导式怎么用?",会返回预设的拒绝回答内容。

4.2 流式响应:提升用户体验

在生成较长文本(如万字博客、详细报告)时,若等待完整结果返回,用户体验会很差。Spring AI 1.1支持流式响应(Streaming Response),即LLM生成内容时逐句返回,前端可实时展示。

示例:实现流式文本生成(以OpenAI为例):

java 复制代码
import org.springframework.ai.chat.ChatResponse;
import reactor.core.publisher.Flux;

/**
 * 流式文本生成:逐句返回生成结果
 * @param requirement 生成需求
 * @return 流式响应(Flux)
 */
public Flux<String> streamingTextGeneration(String requirement) {
    String prompt = String.format("请按照以下需求生成详细文本:%s", requirement);
    // 调用stream方法获取流式响应(返回Flux<ChatResponse>)
    Flux<ChatResponse> responseFlux = chatClient.stream(prompt);
    // 提取每个响应中的生成文本,返回Flux<String>
    return responseFlux.map(chatResponse -> chatResponse.getResult().getOutput().getContent());
}

控制器层接口调整(返回Flux):

java 复制代码
/**
 * 流式文本生成接口
 */
@GetMapping(value = "/generate/text/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamingGenerateText(@RequestParam String requirement) {
    return llmService.streamingTextGeneration(requirement);
}

测试:调用该接口时,前端会实时接收LLM生成的内容并逐句展示,避免了长时间等待。

4.3 多模型动态切换:应对不同场景需求

实际开发中,可能需要根据不同场景(如成本、性能、功能)动态切换LLM模型。Spring AI 1.1支持通过ChatClientBuilder手动构建不同LLM的ChatClient实例,实现动态切换。

示例:手动构建OpenAI和通义千问的ChatClient,根据场景切换:

java 复制代码
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiChatClientBuilder;
import org.springframework.ai.tongyi.TongYiChatClient;
import org.springframework.ai.tongyi.TongYiChatClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class DynamicLlmService {

    // 从配置文件中读取各LLM的密钥
    @Value("${spring.ai.openai.api-key:}")
    private String openAiApiKey;

    @Value("${spring.ai.tongyi.access-key-id:}")
    private String tongYiAccessKeyId;

    @Value("${spring.ai.tongyi.access-key-secret:}")
    private String tongYiAccessKeySecret;

    /**
     * 动态获取ChatClient
     * @param llmType LLM类型("openai"或"tongyi")
     * @return 对应的ChatClient实例
     */
    private ChatClient getChatClient(String llmType) {
        return switch (llmType) {
            case "openai" -> new OpenAiChatClientBuilder()
                    .apiKey(openAiApiKey)
                    .model("gpt-3.5-turbo")
                    .temperature(0.7)
                    .build();
            case "tongyi" -> new TongYiChatClientBuilder()
                    .accessKeyId(tongYiAccessKeyId)
                    .accessKeySecret(tongYiAccessKeySecret)
                    .model("qwen-turbo")
                    .temperature(0.7)
                    .build();
            default -> throw new IllegalArgumentException("不支持的LLM类型:" + llmType);
        };
    }

    /**
     * 动态切换LLM进行文本生成
     * @param llmType LLM类型
     * @param requirement 生成需求
     * @return 生成结果
     */
    public String dynamicTextGeneration(String llmType, String requirement) {
        ChatClient chatClient = getChatClient(llmType);
        return chatClient.generate(requirement);
    }
}

测试:调用dynamicTextGeneration方法时,传入llmType="openai"则使用OpenAI,传入"tongyi"则使用通义千问,灵活应对不同场景。

五、常见问题排查

  1. API密钥错误:表现为启动后调用接口报「401 Unauthorized」错误。解决方案:检查配置文件中的API密钥是否正确,确保密钥未过期,且具有对应模型的调用权限。

  2. 模型名称错误:表现为报「模型不存在」或「不支持该模型」错误。解决方案:确认使用的模型名称是否符合LLM厂商的规范(如OpenAI的gpt-3.5-turbo、通义千问的qwen-turbo)。

  3. 网络问题:调用OpenAI时若报超时错误,可能是国内网络无法访问。解决方案:配置代理,或切换为国内LLM(如通义千问、文心一言)。

  4. 依赖冲突:若项目中存在多个LLM的starter依赖,可能导致ChatClient自动配置失败。解决方案:根据当前使用的LLM,只保留对应的starter依赖。

六、总结

Spring AI 1.1通过统一的API抽象、原生的Spring生态集成,极大简化了主流LLM的接入流程。本文从环境搭建入手,通过完整的示例代码实现了OpenAI与通义千问的接入,讲解了智能问答与文本生成的核心功能,并拓展了提示词工程、流式响应、多模型动态切换等实用技巧,希望能帮助你快速上手Spring AI 1.1开发。

未来,Spring AI还将支持更多LLM厂商与高级特性(如多模态生成、RAG场景深度集成等)。如果你需要实现更复杂的AI功能(如基于知识库的问答、AI绘画等),可以进一步探索Spring AI的官方文档与示例项目。动手实践起来,让LLM能力快速赋能你的应用吧!

相关推荐
tap.AI7 小时前
图片转文字技术(二)AI翻译的核心技术解析-从神经网络到多模态融合
人工智能·深度学习·神经网络
计算机学姐7 小时前
基于SSM的宠物领养管理系统【2026最新】
java·vue.js·后端·java-ee·tomcat·mybatis·宠物
东坡肘子7 小时前
周日小插曲 -- 肘子的 Swift 周报 #115
人工智能·swiftui·swift
后端小张7 小时前
【JAVA进阶】鸿蒙开发与SpringBoot深度融合:从接口设计到服务部署全解析
java·spring boot·spring·spring cloud·华为·harmonyos·鸿蒙
Qiuner7 小时前
Spring Boot AOP(一) 入门与核心概念
java·spring boot·后端·spring·aop
carry杰7 小时前
Springboot3 + shardingsphere-jdbc5.5.2 按年月分表(动态创建表)
java·spring cloud
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ7 小时前
throw new Exception 如何指定返回code
java·开发语言
C雨后彩虹7 小时前
虚拟理财游戏
java·数据结构·算法·华为·面试
jifengzhiling7 小时前
卡尔曼增益:动态权重,最优估计
人工智能·算法·机器学习