Skip to content

Spring AI 从零到生产级掌握

Spring AI 不能只学成“用 ChatClient 调一下模型”。真正的 Java 商业 AI 应用要能解释:Spring Boot 如何自动装配模型客户端,ChatClient 一次调用包含哪些步骤,Prompt 为什么要模板化,结构化输出为什么必须校验,Embedding 和 VectorStore 如何支撑 RAG,Advisor 链如何把记忆、RAG、工具调用、观测串起来,Tool Calling 为什么必须由后端执行和审计。

一句话建立主线:

Spring AI 是 Spring 生态里的 AI 应用工程化层,用 Spring Bean、自动配置、客户端、Advisor、VectorStore 和 Tool Calling 把大模型能力接入业务系统。

如果你想检查自己是否真的从零基础学懂到能面试、能落地、能排查,按 Spring AI 从零到精通验收清单 逐项验收。

学习目标

学完这一页,你要能做到:

  1. 解释 Spring AI 和 Spring Boot、AI 基础能力的关系。
  2. 解释 ChatModelChatClientPromptChatResponse 的职责。
  3. 解释同步调用、流式调用、结构化输出各适合什么场景。
  4. 解释 Advisor 链为什么重要,Advisor 顺序为什么会影响结果。
  5. 解释 Chat Memory、RAG Advisor、Tool Calling Advisor 如何组合。
  6. 解释 EmbeddingModel、VectorStore、Document、SearchRequest 的关系。
  7. 解释 Spring AI RAG 从文档入库到问题回答的完整过程。
  8. 解释 Tool Calling 为什么不是让模型直接访问业务 API。
  9. 解释生产环境里的权限、限流、审计、成本、评估、观测和回滚。
  10. 设计一个企业知识库、采集异常助手、资产问答助手或业务工具 Agent。

学习路线

mermaid
flowchart TD
    A["Spring Boot 基础"] --> B["AI 基础<br/>Token/Prompt/RAG"]
    B --> C["ChatClient<br/>模型调用入口"]
    C --> D["Prompt 和结构化输出"]
    D --> E["Embedding 和 VectorStore"]
    E --> F["RAG Advisor"]
    F --> G["Tool Calling"]
    G --> H["Memory 和 Advisor 链"]
    H --> I["安全、观测、成本和评估"]

Spring AI 是工程框架,不是模型训练框架。它解决的是“Java 后端如何稳定、可治理地调用模型和 AI 能力”。

第一步:Spring AI 在系统里的位置

不用 Spring AI,也可以直接用 HTTP 调模型:

java
// 伪代码:手写 HTTP 调模型
HttpRequest request = buildModelRequest(prompt);
HttpResponse response = httpClient.send(request);

小 Demo 可以这样写,但项目变复杂会遇到:

问题后果
模型调用到处散落难切换模型、难统一超时和日志
Prompt 写在代码里版本不可控,难灰度和回滚
RAG 链路手写文档切分、检索、重排、引用难维护
工具调用无规范权限、参数、审计风险大
没有观测不知道 Token、耗时、失败率、成本

Spring AI 的作用是把这些能力抽象成 Spring 风格组件:

mermaid
flowchart TD
    A["Controller"] --> B["Service"]
    B --> C["ChatClient"]
    C --> D["Advisor 链"]
    D --> E["ChatModel"]
    D --> F["VectorStore"]
    D --> G["ToolCallback"]
    E --> H["模型服务"]
    F --> I["向量数据库"]
    G --> J["业务系统"]

第二步:核心对象关系

对象作用类比理解
ChatModel底层聊天模型能力模型驱动
ChatClient面向应用的流式 API推荐业务入口
Prompt模型输入,包含消息和参数请求体
Messagesystem/user/assistant/tool 消息对话上下文
ChatResponse模型响应和元数据响应对象
Advisor调用前后增强AI 版拦截器
EmbeddingModel文本转向量语义编码器
VectorStore向量存储和检索RAG 检索层
ToolCallback可被模型请求的工具后端能力描述

一次最小调用:

java
@Service
public class AiChatService {
    private final ChatClient chatClient;

    public AiChatService(ChatClient.Builder builder) {
        this.chatClient = builder
                .defaultSystem("你是一个耐心的 Java 技术文档助手。")
                .build();
    }

    public String chat(String question) {
        return chatClient.prompt()
                .user(question)
                .call()
                .content();
    }
}

这个 Demo 只解决“能问答”。生产还要补权限、限流、RAG、结构化输出、日志和评估。

第三步:ChatClient 调用全过程

mermaid
flowchart TD
    A["业务代码调用 ChatClient"] --> B["组装 system/user 消息"]
    B --> C["合并默认参数和本次参数"]
    C --> D["执行 Advisor 链前置逻辑"]
    D --> E["调用 ChatModel"]
    E --> F["模型返回响应"]
    F --> G["执行 Advisor 链后置逻辑"]
    G --> H["解析 content/entity/ChatResponse"]

ChatClient 比直接调用 ChatModel 更适合业务代码,因为它提供:

  • 流式 fluent API。
  • 默认 system prompt。
  • 默认 Advisor。
  • 运行时 Advisor。
  • 工具调用自动链路。
  • 结构化输出。
  • 更好的扩展点。

同步调用

适合分类、抽取、短问答:

java
String answer = chatClient.prompt()
        .user("用一句话解释 RAG")
        .call()
        .content();

流式调用

适合聊天、长答案、前端打字机效果:

java
Flux<String> stream = chatClient.prompt()
        .user("详细解释 Spring AI 的 RAG 流程")
        .stream()
        .content();

流式不是模型更快完成,而是边生成边返回,降低用户等待感。

第四步:Prompt 和结构化输出

Prompt 在商业系统里必须模板化。

错误做法:

java
String prompt = "帮我分析:" + userInput;

问题:

  • 没有角色。
  • 没有边界。
  • 没有输出格式。
  • 不确定时可能编造。
  • 难做版本管理。

更好的 Prompt:

java
String result = chatClient.prompt()
        .system("""
                你是医疗数据采集平台的异常分析助手。
                只能根据给定上下文回答。
                如果无法判断,请回答:需要人工排查。
                输出必须是 JSON。
                """)
        .user("""
                异常日志:
                {log}

                请输出:
                {
                  "reason": "原因",
                  "suggestion": "处理建议",
                  "riskLevel": "LOW/MEDIUM/HIGH"
                }
                """)
        .call()
        .content();

结构化输出要映射成对象:

java
public record ErrorAnalysis(
        String reason,
        String suggestion,
        String riskLevel
) {
}
java
ErrorAnalysis analysis = chatClient.prompt()
        .user(promptText)
        .call()
        .entity(ErrorAnalysis.class);

为什么还要校验:

风险例子
字段缺失没有 riskLevel
类型错误数字输出成文字
枚举越界输出 VERY_HIGH
内容不可信编造原因

生产上应继续用 Bean Validation 或业务规则校验。

第五步:Advisor 链

Advisor 可以理解成 AI 调用链上的拦截器。它可以在模型调用前后修改请求、补充上下文、加入记忆、做 RAG、处理工具调用、记录观测数据。

mermaid
flowchart TD
    A["ChatClient 请求"] --> B["Memory Advisor"]
    B --> C["RAG Advisor"]
    C --> D["Tool Calling Advisor"]
    D --> E["ChatModel"]
    E --> F["响应返回 Advisor 链"]

Advisor 顺序很重要。先加记忆还是先 RAG,会影响 Prompt 里上下文如何组织;工具调用 Advisor 在循环中也会影响多轮工具结果。

常见 Advisor:

Advisor作用
MessageChatMemoryAdvisor把历史对话加入上下文
VectorStoreChatMemoryAdvisor从向量库取长期记忆
QuestionAnswerAdvisor简单 RAG,向量检索后补资料
RetrievalAugmentationAdvisor模块化 RAG 流程
ToolCallingAdvisor处理工具调用循环
SafeGuardAdvisor内容安全防护

示例:记忆 + RAG。

java
ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(
                MessageChatMemoryAdvisor.builder(chatMemory).build(),
                QuestionAnswerAdvisor.builder(vectorStore).build()
        )
        .build();

调用时带会话 ID:

java
String answer = chatClient.prompt()
        .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId))
        .user(question)
        .call()
        .content();

第六步:Memory 不是万能上下文

Memory 用来保存对话上下文,但不能无限保存。

常见策略:

策略说明
窗口记忆只保留最近 N 轮
摘要记忆把历史压缩成摘要
向量记忆按语义检索相关历史
外部存储Redis、数据库等

为什么不能所有历史都塞进 Prompt:

  • Token 成本高。
  • 延迟高。
  • 超过上下文窗口。
  • 历史噪声影响回答。
  • 可能带入过期或敏感信息。

生产建议:

  • 会话型助手保留最近窗口。
  • 客服场景按工单 ID 隔离。
  • 多租户场景 Memory 必须带租户和用户过滤。
  • 高风险工具调用不要只依赖历史记忆,必须查业务系统当前状态。

第七步:Embedding 和 VectorStore

RAG 的基础是 Embedding 和 VectorStore。

文档入库:

mermaid
flowchart TD
    A["读取文档"] --> B["清洗文本"]
    B --> C["切分 chunk"]
    C --> D["补 metadata<br/>租户、部门、来源、版本"]
    D --> E["EmbeddingModel 生成向量"]
    E --> F["VectorStore 写入"]

问答检索:

mermaid
flowchart TD
    A["用户问题"] --> B["EmbeddingModel 问题向量化"]
    B --> C["VectorStore similaritySearch"]
    C --> D["返回相关 Document"]
    D --> E["拼接到 Prompt"]
    E --> F["模型基于资料回答"]

Document 示例:

java
Document doc = new Document(
        "热点 key 过期可能导致缓存击穿,应使用互斥锁或逻辑过期。",
        Map.of(
                "tenantId", "t1",
                "department", "backend",
                "source", "redis-guide.md"
        )
);
vectorStore.add(List.of(doc));

检索时要过滤权限:

java
SearchRequest request = SearchRequest.builder()
        .query(question)
        .topK(5)
        .filterExpression("tenantId == 't1' && department == 'backend'")
        .build();

List<Document> docs = vectorStore.similaritySearch(request);

不做 metadata 权限过滤,企业知识库很容易越权泄露资料。

第八步:Spring AI RAG

最简单 RAG 可以用 QuestionAnswerAdvisor

java
String answer = ChatClient.builder(chatModel)
        .build()
        .prompt()
        .advisors(QuestionAnswerAdvisor.builder(vectorStore).build())
        .user(question)
        .call()
        .content();

完整 RAG 不只是检索:

mermaid
flowchart TD
    A["用户问题"] --> B["问题改写"]
    B --> C["权限过滤"]
    C --> D["向量检索"]
    D --> E["关键词检索"]
    E --> F["合并召回"]
    F --> G["重排 rerank"]
    G --> H["引用片段拼接"]
    H --> I["模型生成答案"]
    I --> J["引用校验和拒答"]

RetrievalAugmentationAdvisor 更适合模块化 RAG:你可以控制查询转换、检索、过滤、文档拼接等步骤。

RAG 常见问题:

问题原因处理
找不到答案切片差、Embedding 不适配优化切分、混合检索
答非所问召回错、重排差rerank、评估集
泄露资料没有 metadata 过滤检索前带权限条件
编造引用Prompt 和校验不足引用 ID 校验
成本高塞太多 chunk限制 topK、摘要、重排

第九步:Tool Calling

Tool Calling 不是让模型直接访问数据库或业务 API。

正确理解:

  1. 应用把工具定义告诉模型。
  2. 模型决定是否请求调用工具,并给出参数。
  3. Spring AI / 应用侧执行工具。
  4. 工具结果返回给模型。
  5. 模型继续生成最终回答。
mermaid
flowchart TD
    A["用户问题"] --> B["ChatClient 发送工具定义"]
    B --> C["模型请求调用工具"]
    C --> D["ToolCallingAdvisor 接收请求"]
    D --> E["应用执行 Java 工具"]
    E --> F["工具结果返回模型"]
    F --> G["模型生成最终回答"]

工具 Demo:

java
public class AssetTools {
    private final AssetService assetService;

    public AssetTools(AssetService assetService) {
        this.assetService = assetService;
    }

    @Tool(description = "根据资产编号查询资产状态")
    public AssetStatus getAssetStatus(AssetStatusRequest request) {
        return assetService.getStatus(request.assetCode());
    }
}

调用:

java
String answer = chatClient.prompt()
        .user("帮我查询资产 A-1001 当前状态")
        .tools(new AssetTools(assetService))
        .call()
        .content();

安全重点:

必做为什么
后端校验用户权限模型不能决定用户能看什么
参数校验防止错误调用和注入
幂等号防止重复创建、重复发送
高风险二次确认防止误删、误改、误发
审计日志追踪模型请求了什么工具

高风险工具不要直接开放:

  • 删除数据。
  • 修改价格。
  • 改权限。
  • 发外部通知。
  • 执行 SQL。
  • 触发支付或退款。

第十步:模型适配和配置

Spring AI 支持多种模型提供方和 OpenAI 兼容接口。工程上要把模型当成可替换资源。

配置通常包括:

配置作用
base-url模型服务地址
api-key访问密钥
model模型名称
temperature随机性
max-tokens输出上限
timeout超时时间

建议:

  • 密钥放环境变量或配置中心,不放代码。
  • 不同场景使用不同模型。
  • 简单分类用小模型,复杂问答用强模型。
  • 统一封装模型路由,避免业务代码写死模型名。

第十一步:生产化治理

AI 接口上线要有这些能力:

能力说明
鉴权用户是否能使用 AI 功能
数据权限RAG 检索只查有权资料
限流按用户、租户、场景限制调用
成本统计Token、模型、请求次数
超时和重试防止模型接口拖垮业务
缓存FAQ 和相似问题缓存
评估集改 Prompt/模型/RAG 后回归测试
审计记录输入、召回资料、工具调用、输出
脱敏敏感数据不进模型或日志
回滚Prompt、模型、知识库版本可回退

观测指标:

mermaid
flowchart TD
    A["AI 请求"] --> B["记录模型名"]
    A --> C["记录 Token"]
    A --> D["记录耗时"]
    A --> E["记录 RAG 命中"]
    A --> F["记录工具调用"]
    A --> G["记录错误码"]

Spring AI 建立在 Spring 观测体系上,可以对 ChatClientChatModelEmbeddingModelVectorStore 等组件做指标和链路追踪。

第十二步:商业场景

企业知识库

text
文档上传 -> 切分 -> Embedding -> VectorStore -> QuestionAnswerAdvisor -> 带引用回答

关键:

  • 文档 metadata 必须包含租户、部门、密级、版本。
  • 检索必须带权限过滤。
  • 回答必须带引用来源。
  • 无资料时拒答。

医疗数据采集异常助手

text
采集异常日志 -> Prompt 模板 -> RAG 查排查手册 -> 模型生成原因和建议 -> 人工确认

关键:

  • 模型只给建议,不直接修改采集任务。
  • 高风险操作需要人工确认。
  • 日志脱敏。

资产平台业务 Agent

text
用户问题 -> Tool Calling 查询资产/采集批次/字典 -> 汇总回答

关键:

  • 查询工具可开放。
  • 写操作要二次确认。
  • 工具调用带审计和幂等。

生产排查流程

模型没按预期回答

mermaid
flowchart TD
    A["回答异常"] --> B["检查 Prompt"]
    B --> C["检查模型参数"]
    C --> D["检查 Advisor 顺序"]
    D --> E["检查 RAG 召回资料"]
    E --> F["检查结构化输出校验"]
    F --> G["补评估用例"]

RAG 找不到资料

mermaid
flowchart TD
    A["RAG 无答案"] --> B["文档是否入库"]
    B --> C["chunk 是否合理"]
    C --> D["Embedding 是否成功"]
    D --> E["metadata 过滤是否过严"]
    E --> F["topK 是否太小"]
    F --> G["是否需要混合检索和重排"]

工具调用出错

mermaid
flowchart TD
    A["工具调用出错"] --> B["模型是否请求正确工具"]
    B --> C["参数 schema 是否清楚"]
    C --> D["后端参数校验是否通过"]
    D --> E["用户权限是否足够"]
    E --> F["业务接口是否成功"]
    F --> G["审计日志是否完整"]

常见坑

后果正确做法
只用 ChatClient 不做权限AI 越权回答Controller 和 RAG 检索都做权限
Prompt 到处硬编码无法灰度和回滚模板化、版本化
RAG 不做引用错了无法追踪返回引用来源
VectorStore 不存 metadata无法按租户/部门过滤入库时写完整元数据
Tool 直接改业务状态误操作真实系统二次确认、幂等、审计
所有场景同一个大模型成本高模型分层路由
不记录 Token成本失控指标和账单监控
不做评估改动后不知道效果建评估集和回归流程

最小完整 Demo:知识库问答

java
@Service
public class KnowledgeQaService {
    private final ChatClient chatClient;

    public KnowledgeQaService(ChatClient.Builder builder, VectorStore vectorStore) {
        this.chatClient = builder
                .defaultSystem("""
                        你是企业知识库助手。
                        只能基于检索到的资料回答。
                        如果资料中没有依据,请回答:资料中未找到依据。
                        """)
                .defaultAdvisors(QuestionAnswerAdvisor.builder(vectorStore).build())
                .build();
    }

    public String answer(String question, String tenantId) {
        return chatClient.prompt()
                .advisors(a -> a.param("tenantId", tenantId))
                .user(question)
                .call()
                .content();
    }
}

真实项目还要把 tenantId 转成 VectorStore 的过滤条件,确保只能检索当前用户有权访问的文档。

面试标准回答

Spring AI 是什么

Spring AI 是 Spring 生态的 AI 应用工程化框架,用 Spring Boot 自动配置、Bean、ChatClientEmbeddingModelVectorStore、Advisor 和 Tool Calling,把大模型、RAG、工具调用和观测能力接入 Java 后端业务系统。它不是训练大模型的框架,而是让模型能力在业务系统里可维护、可治理、可替换。

ChatClient 调用链怎么说

业务代码通过 ChatClient 组装 system/user 消息、模型参数和 Advisor。请求先经过 Advisor 链,例如记忆、RAG、工具调用、安全和观测,再调用底层 ChatModel。模型返回后,Advisor 可以继续处理响应,最后业务代码拿到文本、结构化对象或完整 ChatResponse

Spring AI 怎么做 RAG

文档先解析、清洗、切分成 chunk,调用 EmbeddingModel 生成向量后写入 VectorStore,同时保存租户、部门、来源、版本等 metadata。用户提问时,问题也会向量化,再按权限过滤做相似度检索,把召回资料拼进 Prompt 交给模型回答。Spring AI 可以用 QuestionAnswerAdvisor 做简单 RAG,也可以用 RetrievalAugmentationAdvisor 做模块化 RAG。

Tool Calling 安全怎么保证

模型只能请求工具调用和生成参数,真正执行工具的是应用后端。后端必须校验用户权限、参数合法性、业务状态和幂等性,高风险操作要二次确认,并记录审计日志。不能让模型直接访问数据库、执行任意 SQL 或绕过业务权限。

关联知识点

本章小结

Spring AI 的核心不是“Java 调模型”,而是把 AI 应用链路放进 Spring 工程体系:ChatClient 负责模型调用入口,Advisor 链负责记忆、RAG、工具调用和增强,Embedding 与 VectorStore 支撑知识检索,Tool Calling 把模型和业务能力连接起来,生产治理负责权限、安全、观测、成本、评估和回滚。只有把这些串起来,才能从 Demo 走到可上线的商业 AI 应用。