
前言
到目前为止,我们整个系列的旅程都是在功能强大的LangChain4j框架上构建的。它就像一个装备齐全的"瑞士军刀",为我们提供了构建RAG和Agents所需的所有底层和高层工具。
然而,在Java企业级开发的世界里,有一个名字我们永远无法忽视------Spring 。当AI浪潮来袭,Spring官方团队自然不会缺席。他们推出了自己的解决方案:Spring AI。
那么,Spring AI是什么?它和我们已经熟练使用的LangChain4j是什么关系?是竞争者还是协作者?它能为我们带来什么新的价值?今天,我们将一起探索这个由Spring官方打造的AI框架,体验它所带来的"原生"开发感受。
第一部分:什么是Spring AI?
Spring AI是一个应用框架,旨在将AI功能(特别是基于大语言模型的功能)以一种**"Spring原生"**的方式,无缝集成到企业级应用中。
它的核心设计哲学不是从零开始创造一切,而是:
- 提供统一的顶层抽象 :无论底层模型是来自OpenAI、Google、Azure还是HuggingFace,Spring AI都力求提供一套统一的、面向接口的API,如
ChatClient
和EmbeddingClient
。 - 拥抱Spring生态 :充分利用Spring Boot的自动配置、依赖注入和外部化配置等核心特性。你不需要手动创建客户端,只需要在
application.properties
中填写配置,相应的Bean就会被自动创建和注入。 - 可移植性:它的目标是让你的业务代码与具体的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的配置过程。
-
修改
pom.xml
Spring AI有自己的BOM(Bill of Materials)来管理版本。我们需要先引入BOM,再添加具体的Starter。
xml<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的最新发布情况调整版本和仓库配置。
-
修改
application.properties
Spring AI有自己的一套配置属性,命名空间是
spring.ai
。properties# ========================================== # 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。
-
创建
SpringAiService.java
javapackage 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调用是链式的,非常清晰:定义提示 -> 发起调用 -> 获取内容。
- 我们没有看到任何
-
创建
SpringAiController.java
javapackage 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 :核心是
- 易用性 :
- 对于简单的聊天或嵌入任务 ,Spring AI的
ChatClient
极其简单直接,学习成本几乎为零。 - 对于构建复杂的RAG或Agent流 ,LangChain4j通过
RetrievalAugmentor
和@Tool
等组件提供了更结构化、更专门的解决方案。
- 对于简单的聊天或嵌入任务 ,Spring AI的
我应该用哪个?
- 如果你是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
拉取最新代码,对照本文进行学习。
- Gitee仓库地址 : https://gitee.com/chaocloud/spring-ai-demo
下一篇预告:
《Java大模型开发入门 (14/15):生产环境考量 - 成本、安全与性能优化》------ 我们将从编码转向工程,探讨在生产环境中部署和运维一个LLM应用时,必须考虑的成本控制、安全防护和性能优化等关键问题。