1. 从一次技术选型的纠结说起
去年年底,团队接了一个企业知识库问答的项目,需求很明确:把公司内部散落在各个系统里的文档、工单、会议纪要整合起来,做一个能对话检索的入口。技术栈是 Spring Boot 那一套,团队里没人想引入 Python 服务,于是很自然地盯上了 Spring AI。
真正上手之后才发现,Spring AI 本身提供的是相当底层的抽象——ChatClient、EmbeddingModel、VectorStore 这些接口确实把各家模型的能力统一了,但当你真要把一个企业级应用搭起来,会发现大量"胶水代码"需要自己写:多轮对话的记忆怎么管理?工具调用(Function Calling)的注册和编排怎么做?RAG 的检索增强流程怎么串?可观测性怎么接?这些问题 Spring AI 给了零件,但没给整车。
后来接触到 Spring AI Alibaba,第一反应是"这是不是又一个套壳"。花了两天时间把它的源码结构和模块划分过了一遍,结论是:它确实在 Spring AI 之上做了不少实事,而且做的位置很讲究。这篇就先从整体概览和分层架构入手,把"它到底加了什么"这件事讲清楚。如果你正在评估要不要在项目里引入它,或者单纯想理解一个 AI 应用框架该怎么分层,这篇应该能帮你省下不少翻源码的时间。
需要先说明的是,下面涉及的具体类名、模块名基于我实际阅读的版本,不同版本之间可能有调整,但分层思路是稳定的。另外,我补充的一些"为什么这样设计"的推断,是基于常见工程实践的合理演绎,不代表官方设计文档的原话。
2. Spring AI 已经给了什么,又缺了什么
在讲 Spring AI Alibaba 之前,必须先把 Spring AI 的定位说清楚,否则很容易把两者的职责搞混。很多人一上来就问"Spring AI Alibaba 是不是替代 Spring AI 的",这个问题的答案是否定的——它是构建在 Spring AI 之上的,理解这一点是理解整个分层架构的前提。
2.1 Spring AI 的核心抽象层
Spring AI 做的事情,本质上是"标准化"。它定义了一套模型无关的接口:
- ChatModel / ChatClient:统一对话模型的调用方式,屏蔽 OpenAI、通义千问、Ollama 等不同厂商的 API 差异
- EmbeddingModel:统一文本向量化接口
- VectorStore:统一向量数据库的读写抽象,支持多种向量库实现
- ToolCallback:工具调用的注册机制
- Advisor:一个拦截器链式的扩展点,可以在请求前后插入逻辑
这套抽象的价值在于"可替换"。你今天用某家云厂商的模型,明天想换成本地部署的开源模型,理论上只需要换依赖和配置,业务代码不用动。这是 Spring 生态一贯的依赖倒置思路。
但问题也恰恰出在这里。抽象层为了保持通用,必然要做减法。它不会替你决定对话历史存哪里、不会替你实现复杂的检索策略、不会替你编排多个 Agent 的协作。这些"决策"和"编排"恰恰是企业应用里最耗时的部分。
2.2 企业落地时真正卡住的地方
我把团队当时遇到的坑列一下,这些也是 Spring AI Alibaba 重点要解决的问题:
| 卡点 | 具体表现 | 自己实现的成本 |
|---|---|---|
| 对话记忆 | 多轮对话历史需要持久化,还要控制 token 上限 | 需要自己接 Redis/数据库,处理截断策略 |
| RAG 流程 | 文档解析、分块、向量化、检索、重排、拼 prompt | 每个环节都要选型,串起来容易乱 |
| 工具调用编排 | 多个工具如何注册、如何让模型正确选择 | 需要理解 Function Calling 协议细节 |
| 可观测性 | 一次对话调了哪些模型、耗时多少、token 消耗 | 需要自己埋点,对接监控系统 |
| 多 Agent 协作 | 复杂任务需要多个角色分工 | 几乎没有现成方案,全靠手写状态机 |
你看,这些都不是"调不通模型"的问题,而是"调通了模型之后怎么把它变成一个能上线的系统"的问题。Spring AI 解决的是前者,Spring AI Alibaba 瞄准的是后者。
2.3 一个关键的判断:它不是重复造轮子
我一开始担心的是,Spring AI Alibaba 会不会把 Spring AI 的接口又包一层,导致学习成本翻倍。实际看下来,它的做法是"扩展而非替换"——核心的 ChatClient、ChatModel 这些还是用 Spring AI 的,它主要是在上层补充了应用级的组件,以及在下层补充了国内模型的适配。
这个判断很重要,因为它决定了你的迁移成本。如果你已经用 Spring AI 写了一些代码,引入 Spring AI Alibaba 之后这些代码大概率不用重写,只是多了一些可以选用的高级能力。这一点比某些"全盘另起炉灶"的框架要友好得多。
3. 分层架构拆解:五个层次各管什么
Spring AI Alibaba 的模块划分,我倾向于用"五层"来理解。这个分层不是官方文档里画的那种严格框图,而是我按依赖关系和职责边界梳理出来的,方便记忆和定位问题。
3.1 模型适配层:把国内模型接进来
最底层是模型适配。Spring AI 官方对 OpenAI 系的支持很完善,但国内开发者常用的通义千问、百炼平台上的各类模型,需要额外的适配。这一层做的事情就是提供符合 Spring AI 接口规范的 Model 实现。
这里有个细节值得说:适配层不只是"转发 HTTP 请求"这么简单。不同厂商的 API 在参数命名、流式返回格式、工具调用协议上都有差异。比如同样是流式输出,有的用 SSE 的data:字段,有的用自定义事件类型;同样是工具调用,返回的 JSON 结构也不完全一致。适配层的价值就是把这些差异消化掉,对上暴露统一的接口。
提示:如果你只是用官方已经支持的模型,这一层你几乎感知不到。但一旦要接入自建模型服务或者小众厂商,这一层就是你必须打交道的地方。
3.2 核心能力层:Graph、Memory、RAG 三件套
往上一层是框架的核心能力,我认为这是 Spring AI Alibaba 最有价值的部分,主要包含三块:
Graph(图编排)是这里面最"重"的设计。它把 AI 应用的执行流程抽象成一张有向图,节点是执行单元(比如一次模型调用、一次工具执行、一次条件判断),边是流转关系。这个思路和 LangGraph 很像,好处是复杂流程可以被显式地画出来、调试、复用。为什么需要它?因为真实业务里的 AI 流程很少是"一问一答",更多是"判断意图 → 检索 → 生成 → 校验 → 必要时重试"这样的多步流程,用 if-else 写会迅速失控。
Memory(记忆)解决对话历史的存储和检索。它不只是把历史消息存起来,还涉及短期记忆(当前会话)和长期记忆(跨会话的用户偏好)的区分,以及 token 超限时的截断或摘要策略。
RAG(检索增强)把文档处理的完整链路封装起来:读取、分块、向量化、存储、检索、重排、拼装。这一层通常会对接具体的向量库和 Embedding 模型。
3.3 编排与运行时层:让流程真正跑起来
有了 Graph 的定义,还需要一个运行时来执行它。这一层负责节点调度、状态传递、异常处理、中断恢复。我理解它和 Graph 的关系,有点像 Spring 容器和 Bean 定义的关系——定义是静态的,运行时是动态的。
这一层还涉及流式输出的处理。AI 应用的响应往往是流式的,token 一个一个吐出来,运行时需要把图执行过程中的中间结果也以流的方式推给前端,这对状态管理提出了更高要求。
3.4 可观测与治理层:上线之后才知重要
这一层在 demo 阶段完全用不上,但一上生产就变成刚需。它包含调用链追踪、token 消耗统计、模型调用耗时监控、异常告警等。Spring 生态本身有 Micrometer、Actuator 这些可观测性基础设施,这一层要做的是把 AI 调用的指标接进去。
我踩过的一个坑是:早期没做 token 统计,上线一个月后发现某几个用户的调用量异常高,排查时完全没有数据支撑,只能临时加日志。所以这一层建议在项目早期就预留接口,哪怕先只记录最基础的调用次数和耗时。
3.5 应用集成层:和 Spring 生态打通
最上层是和 Spring Boot 生态的集成,包括自动配置、Starter 依赖、配置属性绑定等。这一层决定了"用起来顺不顺"。好的集成应该做到:加一个依赖、写几行配置,核心能力就能用起来,而不是让你手动 new 一堆对象。
这五层的关系可以这样理解:下面两层是"能力",中间一层是"执行",上面两层是"落地"。你评估一个 AI 框架值不值得用,其实就是在看这五层里哪几层它替你做了。
4. 和裸用 Spring AI 的对比:多出来的到底是什么
光讲分层还是有点抽象,我用一个具体场景来对比:做一个带知识库检索的问答机器人。分别看裸用 Spring AI 和用 Spring AI Alibaba 的差异。
4.1 裸用 Spring AI 的典型代码量
假设你要实现"用户提问 → 检索相关文档 → 拼进 prompt → 调用模型 → 返回答案"这个流程,用 Spring AI 你需要:
- 自己写文档加载和分块逻辑(或者引入额外的文档处理库)
- 手动调用 EmbeddingModel 把分块向量化
- 手动写入 VectorStore
- 查询时手动做相似度检索
- 手动拼接检索结果和用户问题
- 调用 ChatClient
- 如果要支持多轮,还要自己管理历史消息
这里面每一步都不难,但加起来是几百行代码,而且每一步的选型和参数都需要你自己决策。更麻烦的是,当你想调整检索策略(比如加个重排)时,改动会散落在多处。
4.2 用 Spring AI Alibaba 的差异
用 Spring AI Alibaba 的 RAG 能力,上面这些步骤大部分被封装成了配置和声明式的调用。你更多是在"配置一个流程"而不是"编写一个流程"。Graph 的引入让流程可视化,调整策略时改的是图的结构,而不是散落各处的代码。
这个差异的本质是:裸用 Spring AI 你是在写代码,用 Spring AI Alibaba 你是在编排流程。前者灵活但重复劳动多,后者有约束但开发效率高。对于大多数企业应用,后者的性价比更高。
4.3 什么时候反而不该用它
也不是所有场景都适合。如果你的需求就是"调一下模型拿个结果",没有任何检索、记忆、编排的需求,那引入 Spring AI Alibaba 就是杀鸡用牛刀,直接用 Spring AI 的 ChatClient 就够了。框架的价值和你的流程复杂度成正比,流程越复杂,它替你省的事越多。
我的经验判断是:当你的 AI 流程超过三步,或者需要多轮对话记忆,或者需要接知识库,就值得考虑引入。低于这个复杂度,先裸用 Spring AI 跑起来,等复杂度上来了再迁移也不迟。
5. 上手前必须想清楚的几个问题
在真正动手之前,有几个问题我建议你先想清楚,这些是我在实际项目中踩过或者见别人踩过的。
5.1 版本兼容性是个隐形雷区
Spring AI 本身还在快速迭代,API 时有变动。Spring AI Alibaba 作为上层框架,对 Spring AI 的版本有依赖要求。我遇到过一次因为 Spring AI 小版本升级导致上层行为变化的情况,排查了大半天。
建议的做法是:在pom.xml或build.gradle里把 Spring AI 和 Spring AI Alibaba 的版本都显式锁定,不要用动态版本号。升级时先在小范围验证,别直接上生产。
5.2 向量库选型要提前定
RAG 能力依赖向量库。开发阶段用内存向量库很方便,但生产环境必须换成持久化的方案。这个切换如果做得晚,可能会发现检索行为有差异(不同向量库的相似度算法、索引方式不同,返回结果会有细微差别)。
我的建议是:开发阶段就用和生产一致的向量库,哪怕数据量小。这样能避免"开发环境好好的,上线就翻车"的经典问题。
5.3 别指望框架替你解决 prompt 工程
框架能帮你把流程串起来,但 prompt 怎么写、检索结果怎么组织、模型怎么选,这些还是得你自己调。我见过有人以为换个框架问答质量就能提升,结果发现该不准还是不准。框架解决的是工程问题,不是效果问题,这两件事要分开看。
5.4 可观测性从第一天就要有
前面提过,这个真的重要。哪怕你只是加一个拦截器记录每次调用的模型名、耗时、token 数,也比什么都没有强。等到出问题再补,你会后悔的。
注意:以上这些"注意事项"是基于常见工程实践的总结,具体到你的项目,还需要结合团队的技术栈和运维能力来判断。
6. 我对这套架构设计的几点理解
最后聊点偏"设计哲学"的东西,这些是我读完源码之后的一些体会,不一定对,但可能对理解框架有帮助。
第一,它选择了"扩展 Spring AI"而不是"重写"这条路。这个选择很聪明,因为 Spring AI 的抽象层是经过社区验证的,重写既费力又容易和上游脱节。扩展的代价是要跟着上游的节奏走,但收益是生态兼容性好。
第二,Graph 的引入是这套框架的分水岭。在 Graph 之前,AI 应用的编排基本靠代码堆;Graph 之后,编排变成了可描述、可复用的东西。这个思路和当年工作流引擎的演进很像,从硬编码到流程定义,是复杂系统必经的一步。
第三,分层清晰带来的好处是"按需取用"。你不需要一次性把所有能力都用上,可以先用模型适配层,再加 RAG,再加 Graph,逐步演进。这种渐进式的采用路径,对团队来说学习成本是可控的。
第四,它明显是面向企业场景设计的。从可观测性、多 Agent 协作、记忆管理这些能力就能看出来,它假设的使用场景不是"做个 demo",而是"做个能上线的系统"。这个定位决定了它的复杂度,也决定了它的价值。
我在实际使用中的一个体会是:不要试图一次性理解所有模块。先抓住"模型适配 + RAG + Graph"这条主线,把最简单的问答流程跑通,然后再按需深入其他模块。框架的文档和示例代码是很好的起点,但真正理解它还是得自己动手改一改、跑一跑。踩过几次坑之后,你会对"哪一层该负责什么"有更清晰的感觉,这种体感是看文档看不来的。