Spring AI 面试题库
生成时间:2026-05-22 00:17 | 第N轮
【面试题】1. Spring AI 中 ChatClient 和 ChatModel 的区别是什么?日常开发该用哪个?
【标准答案】ChatModel 是底层模型抽象接口,直接对接大模型 API,你传 Prompt 它返回 ChatResponse,属于"裸调用"。ChatClient 是 Spring AI 1.0 推出的统一入口,基于 Fluent API 风格,内置了 Advisor 链、对话记忆、结构化输出等能力,是高层编排工具。日常开发必须用 ChatClient,它把 ChatModel 包了一层,所有增强能力都在这一层叠加。只有在需要极细粒度控制原始请求/响应时才直接用 ChatModel。一句话:ChatModel 是引擎,ChatClient 是方向盘,你开车用方向盘。
【面试题】2. Spring AI 的 Advisor 机制怎么理解?能解决什么问题?举个实际场景。
【标准答案】Advisor 本质是拦截器链,在请求发给模型前和响应返回后各有一个切面——CallAroundAdvisor 请求前拦截、StreamAroundAdvisor 流式拦截。它能解决的问题:日志审计、Prompt 增强、对话记忆注入、RAG 检索注入等,全部用 Advisor 叠加,不用改业务代码。实际场景:你有一个客服 Bot,需要同时加对话记忆和 RAG 知识库检索,用 MessageChatMemoryAdvisor + QuestionAnswerAdvisor 两个 Advisor 串起来,ChatClient.builder() 里 .defaultAdvisors() 一加就完事,零侵入。
【面试题】3. Spring AI 做 RAG 时,TokenTextSplitter 切分文档有哪些坑?怎么避免语义断裂?
【标准答案】最大的坑是按 token 数硬切,不考虑语义边界,一句话或一个代码块被拦腰截断,检索到的片段上下文不全,模型回答质量直接崩。避免方法:第一,切分时开启 setCopyOverlapping 做重叠切分,重叠 50-100 token,保证上下文衔接;第二,切分前先按自然段落/标题/章节做预拆分,再用 TokenTextSplitter 对超长段落二次切;第三,文档元数据(来源、章节标题)必须保留,检索返回时带上 metadata 帮模型理解片段出处。生产环境千万别裸用 TokenTextSplitter,至少配合重叠策略。
【面试题】4. Spring AI 的 VectorStore 接口统一了哪些实现?选型时怎么决策?
【标准答案】Spring AI 通过 VectorStore 接口统一了 PGVector、Redis(RedisStack)、Pinecone、Chroma、Milvus、Weaviate 等实现,业务代码只依赖接口,切换实现只改配置。选型决策:PGVector——已有 PostgreSQL 基础设施、数据量中等、要事务一致性,首选它,零额外运维;Milvus——十亿级向量、高并发检索、有专业运维团队,选它;Pinecone——不想运维、要全托管、海外业务,选它;Chroma——开发测试、原型验证,轻量快速;Redis——已有 Redis 且向量规模不大、需要低延迟,可用。核心原则:别过度设计,先 PGVector 跑起来,性能不够再升级。
【面试题】5. Spring AI Function Calling 的 tool_call 调度流程是怎样的?@Bean 注册函数后底层发生了什么?
【标准答案】流程分四步:第一步,你在代码里写一个返回类型明确的函数,加 @Bean 注册到 Spring 容器,Spring AI 自动扫描生成 JSON Schema(函数名、参数类型、描述);第二步,ChatClient 把函数描述塞进 Prompt 的 tools 字段发给大模型;第三步,模型判断需要调工具,返回 tool_call 请求(函数名+参数 JSON);第四步,Spring AI 拦截 tool_call,自动反序列化参数、调用对应 Bean 方法、拿到返回值,把结果拼回对话再发给模型,模型给出最终回答。关键点:整个过程是框架自动编排的,你只写函数定义和注册,调度逻辑零代码。注意函数签名要清晰,参数用基本类型或简单 POJO,别搞复杂嵌套,否则 Schema 生成容易出问题。
【面试题】6. Spring AI Structured Output 用 BeanOutputConverter 和直接用 entity() 有什么区别?各自适合什么场景?
【标准答案】BeanOutputConverter 是早期方案,你需要手动创建转换器、拼 Prompt 指令、解析输出,流程是:converter.getFormat() 拼到 Prompt 里 → 模型输出 JSON 字符串 → converter.parse() 反序列化。entity() 是 ChatClient Fluent API 的封装,一行 .entity(MyPojo.class) 搞定,内部自动处理格式指令注入和解析。日常开发用 entity(),简洁不出错。BeanOutputConverter 适合需要自定义格式指令、对输出 Schema 做精细控制、或者不用 ChatClient 的场景。坑提醒:entity() 底层依赖 JSON Schema 约束模型输出,模型能力弱时可能不严格遵守格式,务必加 @JsonProperty 和 @JsonPropertyDescription 注解给模型更多提示。
【面试题】7. Spring AI 对话记忆的 MessageChatMemoryAdvisor 是怎么工作的?生产环境怎么持久化?
【标准答案】MessageChatMemoryAdvisor 工作原理:请求发出前,Advisor 从 ChatMemory 实现中取出历史消息,注入到 Prompt 的 messages 列表里;响应返回后,把当前轮的 UserMessage 和 AssistantMessage 写回 ChatMemory。它维护的是一个滑动窗口,通过 chatMemoryRetrieveSize 控制取最近 N 轮。生产环境持久化方案:InMemoryChatMemory 只能用于开发测试,生产必须换。推荐方案一:基于 Redis 实现 ChatMemory 接口,key 用 conversationId,value 存消息列表 JSON,设 TTL 自动过期;方案二:基于数据库(如 PostgreSQL)存,表结构 conversation_id + role + content + timestamp,查询时按时间排序取最近 N 条。注意点:消息过长要截断或摘要,否则 token 爆炸。
【面试题】8. Spring AI 多模型切换怎么做?spring.ai.* 配置前缀的优先级和坑有哪些?
【标准答案】多模型切换核心是 spring.ai.* 配置前缀体系。比如 spring.ai.openai.api-key、spring.ai.ollama.base-url、spring.ai.zhipu.api-key,每个模型独立配置。切换方式:一是通过 Properties 外部化,不同环境 application.yml 配不同模型;二是运行时通过代码注入多个 ChatModel Bean,用 @Qualifier 按名切换;三是用 Spring AI 的 ChatClient 动态指定模型。优先级坑:当同时配了多个模型 starter,Spring Boot 自动配置会注册多个 ChatModel Bean,此时必须用 @Primary 或 @Qualifier 消歧义,否则启动报错。另一个坑是:模型降级场景下,别在配置层面切,用代码层 try-catch 切换备用模型更可控。
【面试题】9. Spring AI 微服务部署时,API Key 管理和限流熔断怎么做?
【标准答案】API Key 管理三原则:一不入代码,用 Vault 或 K8s Secret 管理,Spring 通过 spring.ai.* 配置注入;二要隔离,不同服务用不同 Key,避免一个 Key 泄露全线崩溃;三要轮换,定期更换,配合 Vault 动态 Secret 实现无感轮换。限流熔断:Spring AI 本身不带限流,但深度集成 Spring Cloud 生态——用 Resilience4j 做熔断降级,当模型 API 响应超时或报错率超阈值自动降级到备用模型;用 Bucket4j 或 Sentinel 做限流,按用户/租户维度控制 QPS,防止恶意调用打爆配额。超时配置:spring.ai.openai.chat.options.temperature 设置模型参数,超时用 spring.ai.*.connect-timeout 和 read-timeout 控制。生产环境必须配超时+熔断+降级三件套,裸奔必出事。
【面试题】10. Spring AI 1.0 正式版相比之前 Milestone 版本,架构上有哪些根本性变化?为什么要升级?
【标准答案】三大根本性变化:第一,ChatClient 成为统一入口,之前你直接用 ChatModel 裸调,所有增强自己写,现在 ChatClient 一把梭,Fluent API 链式调用,开发体验质变;第二,Advisor 架构确立,之前没有统一的拦截器机制,对话记忆、RAG、日志各写各的,现在全部标准化为 Advisor 链,可插拔可排序,符合 Spring 的设计哲学;第三,VectorStore 接口统一+配置前缀标准化,spring.ai.* 配置体系成型,多模型多向量库的切换从"改代码"变成"改配置"。为什么要升级?Milestone 版本 API 不稳定、很多类已废弃、文档和社区都跟着 1.0 走,不升级等于技术债越积越多。升级注意事项:包名和类名有 breaking change,特别是 ChatClient 用法完全重构,必须按迁移指南改。