Java大模型开发入门 (13/15):拥抱官方标准 - Spring AI框架入门与实践

发布于:2025-06-20 ⋅ 阅读:(18) ⋅ 点赞:(0)

在这里插入图片描述

前言

到目前为止,我们整个系列的旅程都是在功能强大的LangChain4j框架上构建的。它就像一个装备齐全的“瑞士军刀”,为我们提供了构建RAG和Agents所需的所有底层和高层工具。

然而,在Java企业级开发的世界里,有一个名字我们永远无法忽视——Spring。当AI浪潮来袭,Spring官方团队自然不会缺席。他们推出了自己的解决方案:Spring AI

那么,Spring AI是什么?它和我们已经熟练使用的LangChain4j是什么关系?是竞争者还是协作者?它能为我们带来什么新的价值?今天,我们将一起探索这个由Spring官方打造的AI框架,体验它所带来的“原生”开发感受。

第一部分:什么是Spring AI?

Spring AI是一个应用框架,旨在将AI功能(特别是基于大语言模型的功能)以一种**“Spring原生”**的方式,无缝集成到企业级应用中。

它的核心设计哲学不是从零开始创造一切,而是:

  1. 提供统一的顶层抽象:无论底层模型是来自OpenAI、Google、Azure还是HuggingFace,Spring AI都力求提供一套统一的、面向接口的API,如ChatClientEmbeddingClient
  2. 拥抱Spring生态:充分利用Spring Boot的自动配置、依赖注入和外部化配置等核心特性。你不需要手动创建客户端,只需要在application.properties中填写配置,相应的Bean就会被自动创建和注入。
  3. 可移植性:它的目标是让你的业务代码与具体的AI模型提供商解耦。理论上,你只需要修改配置文件,就能从OpenAI切换到Azure OpenAI,而无需改动Java代码。

Spring AI vs. LangChain4j:是什么关系?
它们并非严格的竞争关系,而是不同层面的抽象。Spring AI更侧重于简化集成和提升Spring开发者的体验。事实上,Spring AI的某些模块底层就是由LangChain4j驱动的!你可以把Spring AI看作是一个更高层次的“门面”,它为你整合了包括LangChain4j在内的多种AI库,并用一层标准的Spring接口将其包装起来。

第二部分:在Spring Boot中集成Spring AI

让我们在一个新的分支或项目中,体验一下Spring AI的配置过程。

  1. 修改pom.xml
    Spring AI有自己的BOM(Bill of Materials)来管理版本。我们需要先引入BOM,再添加具体的Starter。

      <properties>
           <java.version>21</java.version>
           <!-- 定义Spring AI的版本 -->
           <spring-ai.version>1.0.0-M3</spring-ai.version>
       </properties>
    
       <dependencyManagement>
           <dependencies>
               <dependency>
                   <groupId>org.springframework.ai</groupId>
                   <artifactId>spring-ai-bom</artifactId>
                   <version>${spring-ai.version}</version>
                   <type>pom</type>
                   <scope>import</scope>
               </dependency>
           </dependencies>
       </dependencyManagement>
    
       <dependencies>
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-web</artifactId>
           </dependency>
    
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-test</artifactId>
               <scope>test</scope>
           </dependency>
    
           <!-- Spring AI OpenAI Starter -->
           <dependency>
               <groupId>org.springframework.ai</groupId>
               <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
           </dependency>
    
           <!-- Spring AI Vector Store - Simple (内存向量存储) -->
           <dependency>
               <groupId>org.springframework.ai</groupId>
               <artifactId>spring-ai-transformers-spring-boot-starter</artifactId>
           </dependency>
    
           <!-- JSON处理 -->
           <dependency>
               <groupId>com.fasterxml.jackson.core</groupId>
               <artifactId>jackson-databind</artifactId>
           </dependency>
    
           <!-- Lombok -->
           <dependency>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok</artifactId>
               <optional>true</optional>
           </dependency>
       </dependencies>
    
    
       <build>
           <plugins>
               <plugin>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-maven-plugin</artifactId>
               </plugin>
           </plugins>
       </build>
       <repositories>
           <repository>
               <id>spring-milestones</id>
               <name>Spring Milestones</name>
               <url>https://repo.spring.io/milestone</url>
               <snapshots>
                   <enabled>false</enabled>
               </snapshots>
           </repository>
           <repository>
               <id>spring-snapshots</id>
               <name>Spring Snapshots</name>
               <url>https://repo.spring.io/snapshot</url>
               <releases>
                   <enabled>false</enabled>
               </releases>
           </repository>
       </repositories>
    

    注意:请根据Spring AI的最新发布情况调整版本和仓库配置。

  2. 修改application.properties
    Spring AI有自己的一套配置属性,命名空间是spring.ai

    
    # ==========================================
    # Spring AI Demo 配置文件
    # ==========================================
    
    # 服务器端口配置
    server.port=8080
    
    # ==========================================
    # Spring AI OpenAI 配置
    # ==========================================
    
    # OpenAI API密钥 (请设置环境变量 OPENAI_API_KEY)
    spring.ai.openai.api-key=${OPENAI_API_KEY:your-api-key-here}
    
    # OpenAI API基础URL (支持代理服务)
    spring.ai.openai.base-url=${OPENAI_BASE_URL:https://yibuapi.com/}
    
    # 聊天模型配置
    spring.ai.openai.chat.options.model=${OPENAI_MODEL:gpt-4o-mini}
    spring.ai.openai.chat.options.temperature=${OPENAI_TEMPERATURE:0.7}
    spring.ai.openai.chat.options.max-tokens=${OPENAI_MAX_TOKENS:2000}
    
    # ==========================================
    # 应用程序配置
    # ==========================================
    
    # 应用名称
    spring.application.name=springboot-langchain4j-demo
    
    # 日志配置
    logging.level.org.springframework.ai=DEBUG
    logging.level.org.example.demo=DEBUG
    
    # ==========================================
    # Web配置
    # ==========================================
    
    # 静态资源配置
    spring.web.resources.static-locations=classpath:/static/
    spring.web.resources.cache.period=3600
    
    # 编码配置
    server.servlet.encoding.charset=UTF-8
    server.servlet.encoding.enabled=true
    server.servlet.encoding.force=true
    
    

    仅仅这样配置,Spring AI的Starter就会为我们自动创建一个配置好的ChatClient Bean。

第三部分:实战 - 使用ChatModel 进行聊天

现在,我们将创建一个新的Service和Controller,体验一下ChatModel 的流畅API。

  1. 创建SpringAiService.java

    package com.example.aidemoapp.service;
    
    import lombok.RequiredArgsConstructor;
    import org.springframework.ai.chat.model.ChatModel;
    import org.springframework.ai.chat.prompt.Prompt;
    import org.springframework.ai.chat.prompt.PromptTemplate;
    import org.springframework.stereotype.Service;
    
    @Service
    @RequiredArgsConstructor
    public class SpringAiService {
    
    
       private final ChatModel chatModel;
    
           /**
     * 简单聊天对话
     */
    public String getSimpleChatResponse(String userPrompt) {
        return chatModel.call(userPrompt);
    }
    
    /**
     * 使用模板的聊天对话
     */
    public String getChatResponseWithTemplate(String topic, String style) {
        String template = "请用{style}的风格来介绍{topic},内容要详细且有趣。";
        PromptTemplate promptTemplate = new PromptTemplate(template);
        Prompt prompt = promptTemplate.create(Map.of(
            "topic", topic,
            "style", style
        ));
        return chatModel.call(prompt).getResult().getOutput().getContent();
    }
    }
    

    代码解析

    • 我们没有看到任何OpenAi...相关的类,代码完全面向ChatModel 这个抽象接口。
    • API调用是链式的,非常清晰:定义提示 -> 发起调用 -> 获取内容。
  2. 创建SpringAiController.java

    package com.example.aidemoapp.controller;
    
    import com.example.aidemoapp.service.SpringAiService;
    import lombok.RequiredArgsConstructor;
    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;
    
    @RestController
    @RequestMapping("/api/spring-ai")
    @RequiredArgsConstructor
    public class SpringAiController {
    
        private final SpringAiService springAiService;
    
        /**
         * 简单聊天接口
         */
        @GetMapping("/chat")
        public Map<String, Object> chat(@RequestParam("query") String query) {
            try {
                String response = springAiService.getSimpleChatResponse(query);
                return Map.of(
                    "success", true,
                    "data", response,
                    "message", "聊天成功"
                );
            } catch (Exception e) {
                return Map.of(
                    "success", false,
                    "data", "",
                    "message", "聊天失败: " + e.getMessage()
                );
            }
        }
    
        /**
         * 模板聊天接口
         */
        @PostMapping("/chat/template")
        public Map<String, Object> chatWithTemplate(@RequestBody Map<String, String> request) {
            try {
                String topic = request.get("topic");
                String style = request.get("style");
                String response = springAiService.getChatResponseWithTemplate(topic, style);
                return Map.of(
                    "success", true,
                    "data", response,
                    "message", "模板聊天成功"
                );
            } catch (Exception e) {
                return Map.of(
                    "success", false,
                    "data", "",
                    "message", "模板聊天失败: " + e.getMessage()
                );
            }
        }
    }
    
第四步:对比与思考

现在我们可以清楚地看到Spring AI和LangChain4j在设计哲学上的异同:

  • 配置方式:两者都支持外部化配置,但命名空间不同。Spring AI的spring.ai.*对于Spring开发者来说更具辨识度。
  • 核心抽象
    • Spring AI:核心是ChatModel ,一个非常直接、面向任务的客户端。它的目标是让你用最少的代码完成最常见的任务。
    • LangChain4j:核心是ChatLanguageModel接口和AiServices工厂/注解。它更侧重于将一个Java接口映射为一个AI服务,提供了更灵活的、声明式的编程模型。
  • 易用性
    • 对于简单的聊天或嵌入任务,Spring AI的ChatClient极其简单直接,学习成本几乎为零。
    • 对于构建复杂的RAG或Agent流,LangChain4j通过RetrievalAugmentor@Tool等组件提供了更结构化、更专门的解决方案。

我应该用哪个?

  • 如果你是Spring重度用户,且需求是快速将聊天、RAG等标准功能集成到应用中,Spring AI是你的不二之选。它的无缝集成和极低的上手门槛会让你事半功倍。
  • 如果你需要构建高度定制化的AI工作流,或者需要使用一些LangChain4j独有的高级功能,直接使用LangChain4j会给你更大的灵活性和控制力。

好消息是,你不必二选一。你完全可以在一个Spring AI项目中使用LangChain4j的组件,它们可以和谐共存。

总结

今天,我们探索了Spring官方的AI解决方案——Spring AI。我们了解了它以“Spring原生体验”为核心的设计思想,并通过ChatClient体验了其简洁流畅的API。

我们现在武器库中又增添了一件利器。我们既有功能全面、灵活强大的LangChain4j,又有与Spring生态无缝集成的Spring AI。作为开发者,我们可以根据项目的具体需求,选择最合适的工具。

在我们开发之旅接近尾声时,我们已经探索了多种工具和技术。但无论技术如何,将AI应用推向生产环境,都会面临一些共通的挑战。


源码获取

本文中所有实战代码均已同步更新至Gitee仓库。建议您git pull拉取最新代码,对照本文进行学习。


下一篇预告:
Java大模型开发入门 (14/15):生产环境考量 - 成本、安全与性能优化》—— 我们将从编码转向工程,探讨在生产环境中部署和运维一个LLM应用时,必须考虑的成本控制、安全防护和性能优化等关键问题。


网站公告

今日签到

点亮在社区的每一天
去签到