到目前为止,我们整个系列的旅程都是在功能强大的LangChain4j框架上构建的。它就像一个装备齐全的“瑞士军刀”,为我们提供了构建RAG和Agents所需的所有底层和高层工具。
然而,在Java企业级开发的世界里,有一个名字我们永远无法忽视——Spring。当AI浪潮来袭,Spring官方团队自然不会缺席。他们推出了自己的解决方案:Spring AI。
那么,Spring AI是什么?它和我们已经熟练使用的LangChain4j是什么关系?是竞争者还是协作者?它能为我们带来什么新的价值?今天,我们将一起探索这个由Spring官方打造的AI框架,体验它所带来的“原生”开发感受。
Spring AI是一个应用框架,旨在将AI功能(特别是基于大语言模型的功能)以一种**“Spring原生”**的方式,无缝集成到企业级应用中。
它的核心设计哲学不是从零开始创造一切,而是:
ChatClient
和EmbeddingClient
。application.properties
中填写配置,相应的Bean就会被自动创建和注入。Spring AI vs. LangChain4j:是什么关系?
它们并非严格的竞争关系,而是不同层面的抽象。Spring AI更侧重于简化集成和提升Spring开发者的体验。事实上,Spring AI的某些模块底层就是由LangChain4j驱动的!你可以把Spring AI看作是一个更高层次的“门面”,它为你整合了包括LangChain4j在内的多种AI库,并用一层标准的Spring接口将其包装起来。
让我们在一个新的分支或项目中,体验一下Spring AI的配置过程。
修改pom.xml
Spring AI有自己的BOM(Bill of Materials)来管理版本。我们需要先引入BOM,再添加具体的Starter。
<properties>
<java.version>21java.version>
<spring-ai.version>1.0.0-M3spring-ai.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-bomartifactId>
<version>${spring-ai.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-openai-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-transformers-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
<repositories>
<repository>
<id>spring-milestonesid>
<name>Spring Milestonesname>
<url>https://repo.spring.io/milestoneurl>
<snapshots>
<enabled>falseenabled>
snapshots>
repository>
<repository>
<id>spring-snapshotsid>
<name>Spring Snapshotsname>
<url>https://repo.spring.io/snapshoturl>
<releases>
<enabled>falseenabled>
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
这个抽象接口。创建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开发者来说更具辨识度。ChatModel
,一个非常直接、面向任务的客户端。它的目标是让你用最少的代码完成最常见的任务。ChatLanguageModel
接口和AiServices
工厂/注解。它更侧重于将一个Java接口映射为一个AI服务,提供了更灵活的、声明式的编程模型。ChatClient
极其简单直接,学习成本几乎为零。RetrievalAugmentor
和@Tool
等组件提供了更结构化、更专门的解决方案。我应该用哪个?
好消息是,你不必二选一。你完全可以在一个Spring AI项目中使用LangChain4j的组件,它们可以和谐共存。
今天,我们探索了Spring官方的AI解决方案——Spring AI。我们了解了它以“Spring原生体验”为核心的设计思想,并通过ChatClient
体验了其简洁流畅的API。
我们现在武器库中又增添了一件利器。我们既有功能全面、灵活强大的LangChain4j,又有与Spring生态无缝集成的Spring AI。作为开发者,我们可以根据项目的具体需求,选择最合适的工具。
在我们开发之旅接近尾声时,我们已经探索了多种工具和技术。但无论技术如何,将AI应用推向生产环境,都会面临一些共通的挑战。
源码获取
本文中所有实战代码均已同步更新至Gitee仓库。建议您git pull
拉取最新代码,对照本文进行学习。
下一篇预告:
《Java大模型开发入门 (14/15):生产环境考量 - 成本、安全与性能优化》—— 我们将从编码转向工程,探讨在生产环境中部署和运维一个LLM应用时,必须考虑的成本控制、安全防护和性能优化等关键问题。