Spring AI核心概念与架构#
一句话答案#
Spring AI 是 Spring 官方的 Java LLM 应用框架(1.0 已 GA),把模型调用、Prompt、工具调用、RAG、记忆、可观测性统一成 Spring 风格的抽象,核心入口是 ChatClient + Advisor 链,最大价值是「可移植 + 与 Spring Boot 生态无缝融合 + 原生 MCP 支持」。
核心要点
1. 整体定位#
LangChain 之于 Python,Spring AI 之于 Java。它不是模型,而是统一抽象层:屏蔽 OpenAI / Anthropic / Azure / Ollama / DashScope 等 Provider 差异,用 Spring Boot Starter + 自动配置开箱即用,application.yml 配 key 和模型即可切换厂商。
2. 核心抽象#
| 抽象 | 作用 |
|---|---|
| ChatModel / EmbeddingModel | 模型调用的底层接口(同步/流式) |
| ChatClient | Fluent API 入口,链式构建请求(类比 RestClient/WebClient) |
| Prompt / PromptTemplate | 消息与提示词模板(System/User/Assistant) |
| Advisor | 拦截器链,把 RAG、记忆、日志等横切关注点织入请求 |
| ToolCallback / @Tool | 工具(函数)调用 |
| VectorStore | 向量库统一接口(Milvus/Redis/PgVector/…) |
| ChatMemory | 对话历史管理 |
3. ChatClient + Advisor(最该懂的两点)#
String answer = chatClient.prompt()
.user(question)
.advisors(new QuestionAnswerAdvisor(vectorStore), // RAG:自动检索注入上下文
new MessageChatMemoryAdvisor(chatMemory)) // 记忆:自动拼历史
.call().content();javaAdvisor 是 Spring AI 的精髓——RAG、记忆、安全检查都做成可插拔的拦截器链,类似 Servlet Filter / Spring Interceptor,不用手写”检索→拼 Prompt→调模型”的样板。
4. Function Calling(工具调用)#
用 @Tool 注解或 ToolCallback 注册工具,Spring AI 自动把方法签名转成 JSON Schema 交给 LLM,LLM 决定调用后框架负责回调执行并把结果回传。注意:回调签名是固定的,要给工具传额外的运行时上下文(如租户、用户态)需走侧信道(ThreadLocal)。
5. 结构化输出与 RAG ETL#
- 结构化输出:
.entity(MyDto.class)用 BeanOutputConverter 把 LLM 文本映射成 Java 对象(底层即 Schema/格式约束 + 解析),见 结构化输出与约束解码 - RAG ETL:DocumentReader(PDF/Markdown)→ TextSplitter 分块 → EmbeddingModel 向量化 → VectorStore 入库;检索侧用 QuestionAnswerAdvisor 自动召回
6. MCP 与可观测性#
- MCP 原生支持:spring-ai-mcp 同时提供 Client 和 Server,工具可标准化暴露给外部,见 MCP协议原理
- 可观测性:基于 Micrometer 暴露 token 用量、调用延迟等 Metrics 与 Tracing,天然接入 Spring Boot Actuator 体系
面试回答(2分钟版)
Spring AI 是 Spring 官方的 Java 大模型应用框架,1.0 已经 GA,定位类似 Java 世界的 LangChain,但更贴 Spring 生态。它本质是个统一抽象层,屏蔽 OpenAI、Anthropic、Ollama、DashScope 这些厂商的差异,用 Spring Boot Starter 自动配置,改个 yml 就能切模型。核心抽象几块:底层是 ChatModel 和 EmbeddingModel,对外入口是 ChatClient,一个 Fluent API 链式构建请求,类比 RestClient。最有特色的是 Advisor,它把 RAG、对话记忆、日志这些横切关注点做成可插拔的拦截器链,比如挂一个 QuestionAnswerAdvisor 就自动完成检索并注入上下文,挂 MessageChatMemoryAdvisor 就自动拼历史,不用手写样板。工具调用用 @Tool 注解,框架自动把方法签名转成 JSON Schema 给 LLM,但回调签名是固定的,要传额外上下文得走 ThreadLocal 侧信道。结构化输出用 .entity 直接映射成 Java 对象。RAG 有完整的 ETL 链:DocumentReader 读文档、TextSplitter 分块、向量化入 VectorStore,检索用 Advisor 自动召回。还原生支持 MCP,能做 Server 也能做 Client,可观测性基于 Micrometer 接入 Actuator。选它而不选 LangChain 的核心原因就是 Java 技术栈和 Spring 生态的无缝融合。
追问与易错
追问方向:
- Spring AI 和 LangChain 怎么选? → 看技术栈:Java/Spring Boot 团队选 Spring AI(生态融合、类型安全、运维体系复用),Python 团队选 LangChain。功能上 LangChain 生态更大更前沿,Spring AI 更稳更工程化
- Advisor 具体解决什么问题? → 把”检索→拼 Prompt→调模型→存记忆”这套样板抽成可组合的拦截器链,类似 Servlet Filter;RAG/记忆/安全护栏都能做成 Advisor 插拔,不污染业务代码
- Spring AI 的工具调用有什么坑? → 回调签名固定,无法直接给工具方法传业务上下文(租户、用户态),需要 ThreadLocal 侧信道绕过;这也是 DocMind 用 AgentToolContext 的原因
- ChatClient 和 ChatModel 区别? → ChatModel 是底层模型接口(裸调用),ChatClient 是上层 Fluent 封装,带 Advisor、默认 System Prompt、结构化输出转换等便利能力,业务一般用 ChatClient
- Spring AI 怎么做 RAG? → ETL 侧:DocumentReader+TextSplitter+EmbeddingModel+VectorStore 灌库;查询侧:QuestionAnswerAdvisor 自动检索并把上下文拼进 Prompt
易错点:
- ❌ “Spring AI = 某个大模型” → 它是抽象框架,本身不含模型,要配 Provider
- ❌ “工具方法能随便加参数” → 回调签名固定,额外上下文必须走侧信道
- ❌ “切换模型要改代码” → 面向 ChatModel 接口编程时,换 Provider 只改依赖和配置
项目实践(DocMind): DocMind 用 Spring AI 而非 LangChain/LangGraph,原因是 Java 技术栈 + 需深度定制 ReAct 循环 + MCP 原生支持。同一个 Tool Bean 走双路径:内部 Agent 用 Spring AI Function Calling 调,外部客户端用 spring-ai-mcp 的 MCP Server HTTP 暴露。因 Spring AI 工具回调签名固定,工具结果通过 AgentToolContext(ThreadLocal 侧信道)绕过 LLM 直接回传 Agent。可观测性由 Langfuse 做全链路追踪。