前言
到目前为止,我们整个系列的旅程都是在功能强大的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。<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
。# ========================================== # 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
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调用是链式的,非常清晰:定义提示 -> 发起调用 -> 获取内容。
- 我们没有看到任何
-
创建
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:核心是
- 易用性:
- 对于简单的聊天或嵌入任务,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应用时,必须考虑的成本控制、安全防护和性能优化等关键问题。