本轮 Spring AI 面试题库(带答案)
【面试题】1. Spring AI中ChatModel和ChatClient有什么本质区别?什么场景下用哪个?
【标准答案】ChatModel是底层抽象,直接对接大模型API,适合需要精细控制prompt、手动管理消息历史的场景。ChatClient是Spring AI 1.0推荐的高层统一入口,内部封装了prompt模板、Advisor链、自动memory管理,开箱即用。
实际项目里,简单对话用ChatClient,一行代码搞定;复杂场景比如需要多轮对话+RAG+工具调用组合,用ChatClient的fluent API链式调用,底层还是ChatModel执行。一句话总结:ChatClient是门面,ChatModel是引擎,日常开发用ChatClient就够了。
【面试题】2. RAG流程中TokenTextSplitter的作用是什么?为什么不能直接把整篇文档丢给向量库?
【标准答案】TokenTextSplitter负责把长文档切分成合理大小的文本块,一般按token数(比如500-1000)切分,还要考虑重叠(overlap)避免语义截断。
直接存整篇文档的三个问题:
- 向量检索是相似度匹配,文档太长会稀释关键信息,检索精度严重下降
- 大模型有上下文窗口限制,检索结果太长塞不进去
- 切分后的chunks更精准,用户问"项目价格",不会检索到"项目背景"这种无关段落
实际项目里,切分要考虑语义边界——按段落、按标题、按句子,不是简单粗暴切固定长度。overlap参数通常设50-100 token,确保边界语义不断裂。
【面试题】3. Function Calling中@Bean注册的函数,Spring AI如何自动生成JSON Schema?有什么坑?
【标准答案】Spring AI通过反射读取函数签名、参数类型、返回类型,自动生成符合OpenAI规范的JSON Schema,包括参数名、类型、描述(从JavaDoc或注解读取)。
常见坑:
- 参数类型必须简单——String/Integer/Boolean/简单POJO可以,复杂泛型、循环引用会序列化失败
- 函数名会变成tool name,命名要规范(不能用中文、空格、特殊字符)
- 返回类型不要太复杂,大模型可能解析不了嵌套过深的JSON
- POJO字段要提供默认值或允许null,大模型可能省略可选字段
- 中文参数名需要@JsonProperty映射,否则JSON key和Java字段对不上
最佳实践:函数签名加@Bean描述注解,参数用简单POJO,返回值直接String或简单对象,prompt里给few-shot示例引导格式。
【面试题】4. 多模型切换时,spring.ai.*配置如何组织?生产环境怎么管理API Key?
【标准答案】配置组织方式:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4
anthropic:
api-key: ${ANTHROPIC_API_KEY}
ollama:
base-url: http://localhost:11434生产环境API Key管理三板斧:
- 环境变量注入——${VAR}占位符,不写死在配置文件,配合CI/CD安全传递
- 集中配置中心——Spring Cloud Config或Vault统一管理,支持动态刷新
- Key轮换+多Key池——定期更新,多Key做负载均衡避免单Key被限流
多模型路由场景:A/B测试用不同模型、降级策略(主模型挂了切备用)、按成本选模型(简单问题用小模型省钱)。核心是ChatModel Bean按条件注入,@ConditionalOnProperty控制激活哪个。
【面试题】5. VectorStore接口统一后,PGVector/Redis/Pinecone/Chroma/Milvus怎么选?各自适用场景?
【标准答案】选型逻辑看三个维度:数据规模、运维成本、合规要求。
PGVector:已有PostgreSQL基础设施的团队首选,零额外运维成本,强一致性事务支持。劣势是大规模向量检索(千万级以上)性能不如专业向量库。适合中小规模、对事务有要求、已有PG生态的项目。
Redis:速度快、天然支持缓存,已有Redis集群直接复用。劣势是大规模检索精度略低、内存成本高。适合对速度要求高、数据量中等、需要实时更新的场景。
Pinecone:全托管、零运维、自动扩缩容。劣势是贵、数据出境合规问题。适合海外项目、预算充足、不想运维的团队。
Chroma:轻量级、嵌入式、开发调试友好。适合原型验证、小规模本地部署。
Milvus:开源、支持十亿级向量、检索精度高。劣势是架构复杂、运维门槛高。适合大规模生产、对成本敏感、有专业运维能力的团队。
一句话:小而美用PGVector,快用Redis,不想运维用Pinecone,大规模用Milvus,开发调试用Chroma。
【面试题】6. BeanOutputConverter实现结构化输出的原理是什么?entity()映射POJO有什么坑?
【标准答案】原理:BeanOutputConverter内部根据POJO类生成JSON Schema,附加到prompt末尾要求大模型按格式输出,然后解析JSON字符串映射成Java对象。
entity()映射常见坑:
- 字段名不匹配——POJO的userName和JSON的user_name对不上,需要@JsonProperty
- 嵌套对象复杂结构——大模型可能生成不合规的JSON,层数越深越容易出错
- 枚举类型处理——大模型可能输出枚举之外的值,需要自定义反序列化器或@JsonIgnoreProperties
- 空值处理——大模型可能返回null或省略字段,POJO字段要允许null或有默认值
- 数值精度——大模型可能把Integer写成"123.0",导致类型不匹配解析失败
- 列表泛型擦除——List<MyObj>在运行时丢失泛型信息,需要TypeReference辅助
最佳实践:POJO字段简单少嵌套、加@JsonIgnoreProperties(ignoreUnknown=true)、prompt里给few-shot示例、catch异常降级到文本解析。
【面试题】7. Chat Memory对话记忆的持久化方案有哪些?生产环境推荐怎么设计?
【标准答案】三种主流方案:
InMemoryChatMemory:适合测试、单实例、会话少且短的场景。重启丢失,不适合生产。
数据库持久化:表设计session_id、message_role、content、timestamp。用JPA/MyBatis存,session_id加索引,分页查最近N条。优势是可靠持久化,劣势是高并发下DB压力大。
Redis持久化:用List结构按session_id存消息列表,设过期时间(7天inactive自动清理)。高并发场景比DB快,适合在线实时对话。
生产环境推荐混合方案:
- Redis做热数据缓存——活跃会话走Redis,毫秒级读写
- DB做持久化兜底——Redis miss时查DB,异步写回Redis
- 消息压缩——长对话用summary总结,不存全量历史,节省token
- 隐私合规——敏感信息脱敏后存储,GDPR场景定期清理
- 多实例共享——用Redis Cluster,ChatMemory Bean必须支持并发访问
关键:MessageChatMemoryAdvisor配置MAX_CONVERSATIONS参数控制窗口大小,避免token超限。
【面试题】8. Spring AI 1.0相比0.8版本,架构层面有哪些关键变化?迁移要注意什么?
【标准答案】四大核心变化:
ChatClient统一入口:0.8版本ChatModel直接用,prompt手动拼。1.0版本ChatClient封装一切,fluent API链式调用,代码量减半。
Advisor架构:0.8版本无统一拦截机制,memory、RAG都要手动塞。1.0版本Advisor链标准化,MessageChatMemoryAdvisor、QuestionAnswerAdvisor等开箱即用,还支持自定义Advisor。
VectorStore接口统一:0.8版本各向量库API不一致,切换要改代码。1.0版本统一接口,切换只需改配置和依赖。
配置前缀标准化:spring.ai.*统一前缀,以前分散的spring.ai.openai、spring.ai.ollama等收敛,properties外部化更规范。
迁移注意项:
- ChatModel用法变了,不能直接new,通过ChatClient.builder()构建
- 手动memory管理替换成MessageChatMemoryAdvisor
- 配置文件调整spring.ai.*前缀
- VectorStore Bean名称可能有变化,@Autowired注入点要检查
- 依赖版本统一升级,spring-ai-bom管理版本
【面试题】9. 微服务架构下,Spring AI服务如何设计超时、限流、熔断?
【标准答案】三个维度设计:
超时设置:
- 大模型API调用慢,默认超时要放宽(30s-120s),区分流式和非流式
- 流式响应设更长超时,用WebClient的timeout配置
- 连接超时和读超时分开设,连接3s、读120s
限流:
- 大模型API有配额(RPM/TPM),必须做分布式限流
- 用Redis令牌桶,按用户/IP/API Key多维度限流
- 监控API调用量,接近配额提前告警
- 静默降级:超配额时返回缓存结果或切换小模型
熔断:
- Resilience4j配置:失败率50%触发熔断,等待30s后半开试探
- 熔断后降级策略三选一:返回缓存结果 / 切备用模型 / 返回友好提示
- 区分错误类型:429限流和500服务异常要分别计数
可观测性:
- Micrometer集成,追踪latency、成功/失败率、token消耗
- 关键指标:模型响应时间P99、token消耗趋势、熔断器状态
- Grafana大盘 + 告警规则,大模型API异常5分钟内发现
【面试题】10. Spring AI MCP(Model Context Protocol)是什么?解决了什么问题?实际怎么用?
【标准答案】MCP是Anthropic提出的模型上下文协议,Spring AI已集成支持。本质是让大模型能安全、标准化地访问外部资源。
解决的四个痛点:
- 工具调用标准化——以前各家大模型tool calling格式不统一(OpenAI一种、Anthropic一种),MCP统一协议,一套代码多模型复用
- 资源安全访问——大模型通过MCP Server访问本地文件、数据库、API,Server控制权限边界,不会越权
- Prompt模板共享——跨模型、跨平台复用prompt,不用每个模型重写一遍
- 调试可观测——MCP协议自带trace和log,工具调用过程透明可追踪
实际应用场景:
- 企业内部系统集成——MCP Server连接企业知识库、CRM、ERP,大模型通过协议安全查询
- 多Agent协作——不同Agent通过MCP协议通信,共享上下文和工具
- 开发工具集成——IDE、CI/CD通过MCP暴露能力给AI编程助手
Spring AI集成方式:配置MCP Server端点,ChatClient自动发现可用工具和资源,开发体验和本地Function Calling一致,但跨模型跨平台通用。