Spring AI 面试题库(2026-05-21 20:39)
【面试题】1. Spring AI 的 ChatClient 与直接使用 ChatModel 有什么区别?为什么要引入 ChatClient 统一抽象?
【标准答案】 ChatClient 是 Spring AI 1.0 推荐的统一入口,相比直接用 ChatModel 有几个核心优势:
一是职责更清晰。ChatModel 只负责"发消息、拿响应"这一件事,而 ChatClient 把 Prompt 构建、Advisor 拦截、Memory 管理等能力都封装进去了,更像一个完整的对话编排器。
二是 Fluent API 更友好。ChatClient 提供链式调用,比如 .prompt().user("xxx").advisors(xxx).call(),代码可读性好,不用手动拼 Prompt 对象。
三是扩展性强。通过 Advisor 机制,可以在不改业务代码的情况下,插入日志、限流、RAG 等能力,而 ChatModel 本身不支持这种拦截扩展。
实际项目中,简单调用可以用 ChatModel,但一旦涉及对话记忆、RAG 增强、工具调用等场景,ChatClient 是更好的选择。
【面试题】2. 请解释 Spring AI 的 Advisor 机制,并举例说明它的典型应用场景。
【标准答案】 Advisor 是 Spring AI 的核心扩展机制,本质是一个拦截器链,可以在请求发送前、响应返回后插入自定义逻辑。
工作流程:ChatClient 发起请求 → 依次经过各个 Advisor 的 aroundAdvice 方法 → 调用 ChatModel → 响应再反向流经 Advisor → 最终返回结果。
典型场景:
- QuestionAnswerAdvisor:RAG 场景,自动从向量库检索相关文档、拼接到 Prompt,增强回答质量。
- MessageChatMemoryAdvisor:对话记忆,自动把历史消息注入到当前 Prompt,实现多轮对话。
- 日志审计 Advisor:记录每次调用的耗时、Token 消耗,用于监控和计费。
- 安全校验 Advisor:检查用户输入是否包含敏感词或越权指令。
关键点:Advisor 可以获取和修改 AdvisedRequest 对象,包括 Prompt、用户输入、历史消息等,灵活度很高。
【面试题】3. 在 Spring AI 中实现 RAG,向量库选型时主要考虑哪些因素?PGVector 和 Redis 各有什么优缺点?
【标准答案】 向量库选型主要看五个维度:性能、扩展性、生态、成本、运维复杂度。
PGVector:
- 优点:基于 PostgreSQL,部署简单,关系型数据+向量检索一体化,适合中小规模数据(百万级)。
- 缺点:性能不如专用向量库,大规模 ANN 检索能力弱,水平扩展困难。
- 适用:已有 PG 集群、数据量中等、对实时性要求不极致的场景。
Redis:
- 优点:内存级速度,延迟极低,天然支持高可用和集群,适合实时性要求高的场景。
- 缺点:内存成本高,持久化需要配置,向量维度和索引能力有限(相比 Milvus/Pinecone)。
- 适用:高频查询、实时推荐、数据量可控、对延迟敏感的业务。
选型建议:百万级数据用 PGVector 或 Redis 都够用;千万级以上考虑 Milvus、Pinecone;云原生场景优先托管服务,省运维。
【面试题】4. Spring AI 的 Function Calling 是如何实现的?@Bean 注册函数后,框架做了哪些自动化工作?
【标准答案】 Spring AI 的 Function Calling 核心是"函数定义 → JSON Schema 生成 → 模型决策 → 框架调度"四步。
@Bean 注册后,框架自动完成三件事:
JSON Schema 自动生成:Spring AI 会通过反射读取函数的参数类型,生成符合 OpenAI/Anthropic 规范的 JSON Schema,告诉模型这个函数叫什么、参数有哪些、类型是什么。
函数注册到上下文:框架维护一个 FunctionRegistry,将 Bean 名称与实际函数映射起来,供后续调度使用。
自动注入到 Prompt:当调用 ChatClient 时,如果配置了函数,框架会把函数描述注入到系统提示词或工具列表中,让模型知道可以调用。
调用流程:用户提问 → 模型判断需要调用函数 → 返回 tool_call → Spring AI 拦截并执行函数 → 函数结果返回给模型 → 模型生成最终答案。
关键代码只需:@Bean public Function<UserInput, Output> myFunction() { return ... },后续全部由框架托管。
【面试题】5. Structured Output 中 BeanOutputConverter 的作用是什么?使用时有哪些常见的"坑"?
【标准答案】 BeanOutputConverter 的作用是让 LLM 的非结构化输出映射成 Java POJO,方便后续业务处理。它通过 JSON Schema 约束模型输出格式,然后反序列化为对象。
常见坑点:
字段类型不匹配:LLM 输出的 JSON 类型与 POJO 字段类型不一致,比如字符串给到了 Integer 字段,反序列化失败。建议用 String 或包装类型,增加容错。
必填字段缺失:模型有时会跳过某些字段,导致反序列化报错。可以通过
@JsonProperty(required = true)或在 Schema 中明确 required。嵌套对象处理复杂:复杂嵌套结构的 Schema 生成可能不完整,建议手动定义 Schema 或简化数据结构。
Token 限制导致输出截断:复杂 Schema 占用大量 Token,可能把上下文撑爆。建议 Schema 简洁,只定义必要字段。
最佳实践:先用简单的 DTO 验证,确保模型能稳定输出结构化数据,再逐步扩展复杂度。
【面试题】6. Spring AI 的 ChatMemory 如何实现多轮对话记忆?InMemoryChatMemory 有什么局限性?
【标准答案】 ChatMemory 接口定义了对话历史的管理能力,核心方法是 add 和 get,分别用于存储和检索历史消息。
多轮对话实现:
- 用户每次提问,ChatClient 通过 MessageChatMemoryAdvisor 自动从 ChatMemory 中获取历史消息。
- 历史消息拼接到当前 Prompt,发送给模型。
- 模型响应后,Advisor 自动把用户问题和模型回答写入 ChatMemory。
InMemoryChatMemory 的局限性:
- 进程内存储:数据只存在 JVM 内存,重启丢失。
- 无法分布式共享:多实例部署时,对话历史无法跨实例共享。
- 内存泄漏风险:长对话或高频会话可能导致内存溢出,需要手动清理策略。
生产环境建议:使用持久化方案,比如 Redis、数据库,或者自己实现 ChatMemory 接口,对接外部存储。Spring AI 也提供了基于 Redis 的 ChatMemory 实现。
【面试题】7. Spring AI 1.0 正式版相比之前的里程碑版本有哪些核心更新?对开发者有什么影响?
【标准答案】 Spring AI 1.0 正式版有几个关键更新:
ChatClient 统一入口:之前 OpenAI、Anthropic 等模型的调用方式略有差异,1.0 统一用 ChatClient,API 更一致,切换模型成本低。
Advisor 架构成熟:Advisor 机制正式稳定,支持更灵活的拦截扩展,RAG、Memory 等能力都通过 Advisor 实现,可插拔性强。
VectorStore 接口统一:各向量库的接口标准化,切换向量库只需改配置,业务代码不动。
spring.ai. 配置前缀统一*:所有配置统一用
spring.ai.model.xxx格式,告别之前不同模型配置风格不一致的问题。Observability 内置:1.0 内置了 Micrometer 指标,开箱即用监控调用次数、延迟、Token 消耗。
对开发者的影响:API 更稳定,升级成本降低,但里程碑版本的代码可能需要调整(比如 ChatModel 直接调用改为 ChatClient)。建议新项目直接用 1.0,老项目参考迁移指南。
【面试题】8. 在微服务架构下,Spring AI 应用如何管理 API Key 和实现多模型路由?
【标准答案】 API Key 管理和多模型路由是生产环境的核心问题。
API Key 管理:
- 外部化配置:不要硬编码,用 Spring Cloud Config、Vault 或 Kubernetes Secrets 管理,配置在
spring.ai.openai.api-key等属性。 - 动态刷新:结合 Spring Cloud,实现 API Key 的动态更新,无需重启服务。
- 权限隔离:不同业务线或租户使用不同的 Key,通过配置中心按环境隔离。
多模型路由:
- 配置多个 ChatModel Bean:比如
openAiChatModel、anthropicChatModel,通过@Qualifier或条件注入选择。 - 路由策略封装:根据业务需求(成本、速度、能力)动态选择模型,比如简单问答用便宜模型,复杂推理用强模型。
- 配置前缀区分:Spring AI 支持多配置源,可以通过
spring.ai.openai.xxx、spring.ai.anthropic.xxx分别配置。
实践建议:抽象一个 ModelRouter 服务,根据请求特征(用户等级、任务类型)选择模型,对外暴露统一接口,业务代码不感知具体模型。
【面试题】9. Spring AI 如何实现 Streaming 流式响应?在实际应用中需要注意什么?
【标准答案】 Spring AI 通过 Flux<String> 或 Flux<ChatResponse> 实现流式响应,底层依赖 Reactor 和 WebFlux。
实现方式:
Flux<String> stream = chatClient.prompt()
.user("写一篇文章")
.stream()
.content();返回的是响应式流,可以逐步消费。
实际应用注意点:
前端展示:流式输出需要前端支持 SSE 或 WebSocket,逐块渲染,提升用户体验。
超时和错误处理:流式调用不像同步调用容易捕获异常,需要用 Reactor 的
onErrorResume或doOnError做兜底。背压控制:如果消费速度跟不上生产速度,可能内存溢出,需要合理配置缓冲和背压策略。
Token 计费:流式模式下 Token 消耗统计更复杂,需要累加各块的结果,建议在 Advisor 中统一计数。
调试困难:流式调试不如同步直观,建议开发阶段用同步模式,生产再切流式。
【面试题】10. Spring AI 如何与 Spring Boot 生态集成?自动配置和外部化配置有哪些最佳实践?
【标准答案】 Spring AI 的核心优势之一就是与 Spring Boot 深度集成,开箱即用。
自动配置:
- Starter 依赖:引入
spring-ai-openai-spring-boot-starter等依赖,Boot 自动配置 ChatModel、EmbeddingModel 等 Bean,无需手动创建。 - 条件注入:通过配置开关控制是否启用某些功能,比如
spring.ai.openai.enabled=false禁用 OpenAI。
外部化配置:
- application.yml/properties:所有配置都在
spring.ai.xxx命名空间下,比如spring.ai.openai.api-key、spring.ai.openai.base-url。 - 多环境隔离:结合 Spring Profile,dev/test/prod 环境使用不同的 API Key、模型参数。
- 配置中心:生产环境用 Spring Cloud Config 或 Kubernetes ConfigMap,实现配置动态更新。
最佳实践:
- 敏感信息(API Key)用环境变量或 Secrets 管理,不要提交到代码库。
- 不同模型用不同配置前缀,方便切换和管理。
- 合理使用默认值,减少配置负担,但关键参数(超时、重试)要显式配置,避免踩坑。
生成时间:2026-05-21 20:39:00
题目数量:10题
覆盖考点:ChatClient架构、Advisor机制、向量库选型、Function Calling、Structured Output、ChatMemory、Spring AI 1.0更新、微服务架构、Streaming响应、Boot集成