「Spring 是不是被 AI 时代落下了」
上个月团队里一个工作两年的同学问我:现在大家都在聊 LangChain、LlamaIndex、各种 Agent 框架,Spring 在这些话题里几乎不出现,是不是已经过时了?
这个问题我这两年听过很多次。我当时没直接回答,让他去看看 spring-ai 仓库的提交记录和 Spring 官方 2026 年的路线图。一周后他自己来找我,说「好像不是一回事」。
这篇把我这几年对这件事的想法整理一下。不吹不黑,尽量说清楚 Spring 在 AI 时代到底占据什么位置。
先厘清一个误解:Spring 从来不是做「AI 能力」的
很多人拿 Spring AI 和 LangChain4j、LlamaIndex 比,比完觉得 Spring AI 功能少、更新慢、抽象笨重。这个比较本身就有问题。
看一眼 2026 年 Spring 官方对自己 AI 相关能力的定位,大致是三层:
| 层次 | Spring 提供什么 | 不提供什么 |
|---|---|---|
| 接入层 | 统一的 ChatClient / EmbeddingModel 抽象,多供应商可切换 | 模型本身、模型训练 |
| 集成层 | 把 AI 能力接进 Spring 的 DI、配置、事务、观测体系 | 复杂的 Agent 编排 DSL、预训练 pipeline |
| 工程层 | Advisor 拦截链、向量存储抽象、结构化输出、可观测性 | 向量检索算法、Rerank 模型、文档解析算法 |
换句话说:Spring 做的是「让 AI 能力能像一个普通的企业级组件一样被使用」,而不是「提供最强的 AI 能力」。
这个定位其实和它在 Web 时代的位置一样。Spring MVC 从来不是最快的 Web 框架,但它让「写一个 HTTP 接口」这件事变得可以标准化、可以被 AOP 拦截、可以被配置中心管理、可以被 Actuator 监控。AI 时代它想做的是同一件事。
传统企业应用和 AI 能力的三个结合点
说了定位,说说实际。我们这两年在传统业务系统里接 AI 能力,真正有价值的结合点其实只有三个。其他大部分「AI 赋能」的尝试,最后都停在演示阶段。
结合点一:把非结构化输入转成业务系统的结构化入参
这是最成熟、最有价值的一类。传统企业系统的接口都要求严格的结构化入参,而现实世界里用户的输入是自然语言、图片、PDF。
我们做的一个真实场景:供应商对账单。以前是财务同事拿到供应商发来的 PDF 对账单(每家格式都不一样),手工录入到系统里,一家平均 40 分钟,月底要处理 180 家。
接入 AI 之后的做法:
@Service
public class StatementExtractor {
private final ChatClient chatClient;
public StatementRecord extract(MultipartFile pdf) {
String text = pdfParser.parse(pdf); // 表格解析,保留行列结构
return chatClient.prompt()
.system("""
从对账单文本中提取结构化信息。
金额一律转成 BigDecimal 字符串,日期转成 yyyy-MM-dd。
如果某个字段在文本中不存在,填 null,不要猜测。
""")
.user(u -> u.text("{statement}").param("statement", text))
.call()
.entity(StatementRecord.class); // 结构化输出,直接映射成 Java 对象
}
}
关键点在最后一行 .entity(StatementRecord.class)。Spring AI 的结构化输出会把 JSON Schema 传给模型,并且做校验和重试。这让我们可以直接拿 Java 对象往下走业务逻辑,不用写一堆解析和兜底代码。
效果:单家处理时间从 40 分钟降到 3 分钟(其中 2 分半是人工复核),准确率 96.3%,剩下 3.7% 由人工修正。这个数字很重要——我们从来不敢让 AI 全自动做财务相关的事,人工复核这一环保留着。
这类场景的共同特征:AI 只负责「理解」,不负责「决策」。它把非结构化变成结构化,后面的业务逻辑还是老代码在跑,事务、校验、审计都不变。
结合点二:把业务系统的数据变成可检索的知识
第二类是把已有的结构化数据变成能被语义检索的东西。这里 Spring 的价值在于它把「向量化」这件事变成了一个普通的持久化操作。
@Service
public class ProductIndexer {
private final VectorStore vectorStore;
private final EmbeddingModel embeddingModel;
private final JdbcClient jdbc;
@Scheduled(cron = "0 */10 * * * ?")
@Transactional(readOnly = true)
public void sync() {
List<Product> changed = jdbc.sql(
"SELECT * FROM product WHERE updated_at > :since")
.param("since", lastSyncTime)
.query(Product.class)
.list();
List<Document> docs = changed.stream()
.map(p -> new Document(
p.getId().toString(),
toText(p), // 结构化字段拼成自然语言
Map.of("category", p.getCategory(),
"tenant", p.getTenantId(),
"updatedAt", p.getUpdatedAt().toString())))
.toList();
vectorStore.add(docs);
}
}
检索的时候,Spring AI 的 VectorStore 抽象支持带过滤条件的相似性搜索:
SearchRequest request = SearchRequest.builder()
.query(userQuery)
.topK(20)
.similarityThreshold(0.72) // 低于阈值不召回
.filterExpression("tenant == 'T001' && category in ['A','B']")
.build();
List<Document> docs = vectorStore.similaritySearch(request);
filterExpression 这一行是我在别的框架里很少见到的便利。它把「元数据过滤」和「向量检索」合成了一个操作,这对企业应用太重要了——我们的搜索从来不可能是纯语义的,必须叠加权限、租户、状态这些硬约束。
这类场景的价值是:让原本只能通过精确字段查询的数据,支持了模糊的自然语言查询。我们的客服系统接入之后,「帮我找去年买过的那个蓝色的东西」这种查询终于能答了。
结合点三:让确定性流程里嵌入非确定性步骤
第三类最难,也最容易被做砸。它是把一个 AI 步骤插进一个有明确业务语义的流程里。
我们的退款审核流程是个例子。原来的流程是纯规则:金额 < 200 且七天无理由 → 自动通过。现在想在中间加一步「理解用户的退款理由,判断是否有异常」。
关键设计是:AI 的输出必须收敛成枚举,且必须有兜底。
public enum RefundRisk { NORMAL, SUSPICIOUS, NEED_HUMAN }
@Service
public class RefundRiskAssessor {
public RefundRisk assess(RefundApplication app) {
try {
return chatClient.prompt()
.system(SYSTEM_PROMPT)
.user(buildDescription(app))
.call()
.entity(RefundRisk.class);
} catch (Exception e) {
// 兜底:AI 挂了不影响主流程,走人工
log.warn("refund risk assess failed, fallback to human", e);
return RefundRisk.NEED_HUMAN;
}
}
}
// 流程编排:AI 只是其中一个节点
public RefundResult handle(RefundApplication app) {
if (app.getAmount().compareAtMost(200) && app.isSevenDays()) {
return autoApprove(app); // 规则优先,不经过 AI
}
return switch (riskAssessor.assess(app)) {
case NORMAL -> autoApprove(app);
case SUSPICIOUS -> rejectWithReason(app);
case NEED_HUMAN -> transferToHuman(app); // 含 AI 失败的情况
};
}
这段代码里两个设计要点:一是 AI 失败时的兜底是「转人工」而不是「放行」;二是 AI 不覆盖确定性规则,金额小、条件明确的直接走规则,不花那份钱也不冒那份险。
上线三个月的数据:AI 处理了 2.4 万单,其中判定 NORMAL 1.6 万单(自动通过)、SUSPICIOUS 0.3 万单、NEED_HUMAN 0.5 万单(含 412 次 AI 调用失败兜底)。人工复核抽样 800 单,AI 判定错误 23 单,错误率 2.9%,全部是「把 SUSPICIOUS 判成 NORMAL」的方向,没有误拒。
Spring 真正的优势不在 AI,在「周围」
上面三个例子里,AI 相关的代码都很短。真正让这套东西能在生产跑起来的,是那些看起来和 AI 无关的部分。这也是我认为 Spring 在 AI 时代不会被替代的原因。
| 能力 | Spring 里的现成方案 | 自己搭要多久 |
|---|---|---|
| 配置管理 | @ConfigurationProperties + 配置中心 | 2~3 天 |
| 多环境切换 | Profile | 1 天 |
| 密钥不进代码 | 外部化配置 + 占位符 | 1 天 |
| 超时/重试/熔断 | Resilience4j 集成 | 3~5 天 |
| 指标与链路追踪 | Micrometer + OpenTelemetry | 5~8 天 |
| 健康检查 | Actuator | 2 天 |
| 并发与调度 | 虚拟线程、@Scheduled | 3 天 |
最后一行两列加起来的差距,大概是 20~25 人日。这不是说别的框架做不到,而是说在一个已经有 Spring 技术栈的公司里,用 Spring AI 的边际成本几乎为零。
举个例子,我们给所有 AI 调用加了 token 计量和链路追踪,代码量是这样的:
@Configuration
public class AiObservabilityConfig {
@Bean
ChatClient chatClient(ChatClient.Builder builder,
ObservationRegistry registry) {
return builder
.observationRegistry(registry) // 一行接入 Micrometer
.build();
}
}
# 自动产出这些指标
gen_ai_client_operation_seconds_bucket
gen_ai_client_token_usage_total{model="qwen-max",type="input"}
gen_ai_client_token_usage_total{model="qwen-max",type="output"}
一行代码,然后 Grafana 上就有每个模型、每个接口的调用量、延迟分布、token 消耗。因为我们整体的可观测体系本来就是 Micrometer + OTel,这块直接复用。
我见过用 Python 栈做的团队,为了实现同样的东西,自己写了一套埋点 SDK,维护了三个月还在改。这就是生态的价值——它不体现在功能列表上,体现在「你不需要做的事」上。
演进方向:我看到的三个趋势
说说我认为 Spring 在 AI 时代会往哪走。这部分是我的判断,不一定对。
一是从「接入抽象」走向「编排抽象」。 现在的 Advisor 链已经有点这个意思了,但还比较薄。Spring AI 2.0 对 Advisor 链做了重构,看得出是想把它做成类似 Filter 链那样的基础设施。以后大概会出现「AI 流程的 Spring MVC」——你定义节点,框架管调度、状态、观测。
二是和 MCP 的深度整合。 这几乎是必然的。Spring 已经在 spring-ai-mcp 里提供了 Server 和 Client 两侧的支持。我判断一年之内,「用 Spring 注解把一个 Bean 暴露成 MCP 工具」会变得和现在「用 @RestController 暴露 HTTP 接口」一样自然。
@McpTool(name = "queryOrder", description = "查询用户订单")
public OrderView queryOrder(@McpToolParam String orderNo) { ... }
// 和这个一样自然
@GetMapping("/order/{no}")
public OrderView queryOrder(@PathVariable String no) { ... }
三是企业级能力的补齐。 多租户隔离、成本归因、审计日志、内容安全过滤。这些是企业在生产上用 AI 真正缺的东西,也是 Spring 最擅长的领域(它历史上就是把企业级 Java 的脏活累活标准化)。我们现在这些内容都是自己写的,我猜两三年内会有一部分被官方吸收。
那什么时候不该用 Spring AI
说了这么多好话,也得说清楚它的边界。有三类场景我不会用:
- 重度的模型实验和调优。 你要是天天在调 prompt、试不同的 RAG 策略、跑评测集,Python 生态的工具链还是舒服得多,LangChain / LlamaIndex 的社区积累不是 Spring AI 短期能追上的;
- 纯 AI 的独立服务。 如果一个服务只做 AI 相关的事,不碰业务系统、不需要事务、不需要企业集成,那 Spring 的很多优势用不上,反而带来启动慢、内存大的负担。这种情况我们有一个服务就用了 Python;
- 需要最新模型能力的场景。 Spring AI 的抽象层意味着它必然滞后于模型厂商的新特性。要用最新的结构化输出 API、最新的推理模式,往往得等一两个版本。我们有个服务要用到某个厂商的专属能力,最后是在 Spring AI 之外直接调 HTTP。
判断标准就一句话:如果你的 AI 代码需要和企业系统的其他部分共享基础设施(配置、监控、事务、安全),用 Spring;如果是独立的实验性服务,用顺手的就行。
留个问题
关于《Spring 生态在 AI 时代的新定位》里这个坑,你当时是怎么处理的?欢迎在评论区聊聊你踩过的类似情况。