Administrator
发布于 2026-03-09 / 414 阅读
2

Spring 生态在 AI 时代的新定位

「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 天
多环境切换Profile1 天
密钥不进代码外部化配置 + 占位符1 天
超时/重试/熔断Resilience4j 集成3~5 天
指标与链路追踪Micrometer + OpenTelemetry5~8 天
健康检查Actuator2 天
并发与调度虚拟线程、@Scheduled3 天

最后一行两列加起来的差距,大概是 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

说了这么多好话,也得说清楚它的边界。有三类场景我不会用:

  1. 重度的模型实验和调优。 你要是天天在调 prompt、试不同的 RAG 策略、跑评测集,Python 生态的工具链还是舒服得多,LangChain / LlamaIndex 的社区积累不是 Spring AI 短期能追上的;
  2. 纯 AI 的独立服务。 如果一个服务只做 AI 相关的事,不碰业务系统、不需要事务、不需要企业集成,那 Spring 的很多优势用不上,反而带来启动慢、内存大的负担。这种情况我们有一个服务就用了 Python;
  3. 需要最新模型能力的场景。 Spring AI 的抽象层意味着它必然滞后于模型厂商的新特性。要用最新的结构化输出 API、最新的推理模式,往往得等一两个版本。我们有个服务要用到某个厂商的专属能力,最后是在 Spring AI 之外直接调 HTTP。

判断标准就一句话:如果你的 AI 代码需要和企业系统的其他部分共享基础设施(配置、监控、事务、安全),用 Spring;如果是独立的实验性服务,用顺手的就行。

留个问题

关于《Spring 生态在 AI 时代的新定位》里这个坑,你当时是怎么处理的?欢迎在评论区聊聊你踩过的类似情况。

参考