Skip to content

本轮 Spring AI 面试题库(带答案)

【面试题】1. Spring AI中ChatClient和直接用ChatModel有什么区别?生产环境推荐哪种? ​

【标准答案】ChatModel是最底层的模型调用抽象,直接传Prompt拿ChatResponse,功能裸露但用法原始。ChatClient是在ChatModel之上封装的Fluent API入口,提供了链式调用、Advisor自动织入、结构化输出entity()、对话记忆自动管理等高级能力。生产环境强烈推荐用ChatClient,原因有三:一是代码可读性高,prompt().user(msg).advisors(...).call().entity(Foo.class) 一行搞定;二是Advisor机制让横切关注点(记忆、RAG、日志)解耦,不用每个地方手写;三是Spring AI 1.0正式版已经把ChatClient定位为统一入口,ChatModel更多是框架内部使用的SPI。面试时一句话总结:ChatModel是"发动机",ChatClient是"方向盘+仪表盘",开车当然用方向盘。

【面试题】2. Spring AI的Advisor机制是什么?能解决什么架构问题?举例说明。 ​

【标准答案】Advisor是Spring AI借鉴Spring MVC拦截器/Filter思路设计的请求-响应拦截链。核心接口有两个方法:adviseRequest处理请求、adviseResponse处理响应,按Order排序组成链式调用。它解决的架构问题是:AI应用中大量横切关注点(对话记忆注入、RAG检索增强、日志追踪、Prompt模板变量替换、限流熔断)如果每个都写在业务代码里,就是面条代码。有了Advisor,这些能力可以独立封装、按需组合。典型例子:MessageChatMemoryAdvisor在请求前自动从ChatMemory读取历史消息拼入Prompt,QuestionAnswerAdvisor在请求前自动从VectorStore检索相关文档拼入上下文,都不用改业务逻辑。面试要点:Advisor = AI领域的AOP,是Spring AI架构设计的核心亮点。

【面试题】3. RAG流程中TokenTextSplitter的作用是什么?切分策略怎么选? ​

【标准答案】TokenTextSplitter是把长文档按Token数切块的工具,因为大模型有上下文窗口限制,VectorStore的Embedding也有最大长度约束,必须先切分再存储再检索。关键参数有三个:chunkSize(每块大小)、overlapSize(块间重叠)、separator(切分分隔符)。切分策略选择:如果文档有明确结构(Markdown标题、HTML标签),优先按语义边界切分,chunkSize设800-1200 tokens,overlapSize设10%-20%保证上下文不丢失;如果是纯文本无结构,用默认的换行/段落切分,overlapSize适当加大到25%。实际踩坑点:chunkSize太小会丢失语义完整性(一个表被切成两半),太大则检索精度下降(无关内容太多)。最佳实践是先按段落/章节切,再对超长段落二次切分,overlap兜底。面试加分点:提一嘴Spring AI还支持自定义Splitter实现,可以按业务语义定制。

【面试题】4. Spring AI的Function Calling完整调用流程是怎样的?@Bean注册的函数怎么被模型发现? ​

【标准答案】完整流程分五步:①开发人员用@Bean注册一个java.util.Function实现,Spring AI自动扫描到这个Bean;②框架根据函数签名和参数类型,自动生成JSON Schema描述(函数名、参数名、参数类型、描述);③用户发起ChatClient请求时,Spring AI把可用函数列表(Function Definitions)拼入请求发给大模型;④大模型判断需要调用工具时,返回tool_call响应(包含函数名+参数JSON);⑤Spring AI拦截tool_call,根据函数名从Bean容器找到对应Function实例,反序列化参数后调用,把结果拼回Prompt再次请求大模型,拿到最终自然语言回答。关键点:整个调度循环对业务代码透明,开发者只需定义函数+注册Bean,不用手写调度逻辑。面试时强调"自动Schema生成"和"自动调度循环"这两个核心自动化能力。

【面试题】5. BeanOutputConverter和entity()在结构化输出中分别扮演什么角色?有什么坑? ​

【标准答案】BeanOutputConverter是底层工具,做三件事:根据目标POJO类生成JSON Schema约束、把Schema拼入Prompt指导模型输出JSON、解析模型返回的JSON字符串反序列化为Java对象。entity()是ChatClient提供的Fluent API快捷方法,内部就是调用BeanOutputConverter,一行call().entity(Foo.class)替代手动三步走。常见坑有四个:一是模型可能不严格遵守Schema,返回多余字段或格式不对,entity()默认会抛异常,生产环境要加try-catch或设strictMode;二是嵌套对象复杂时Schema生成可能不完整,建议加@JsonPropertyOrder和@Schema注解明确约束;三是枚举类型需要用@Schema(enumAsRef=true)处理;四是List泛型擦除问题,entity(List.class)会丢泛型信息,要用new ParameterizedTypeReference<List<Foo>>(){}解决。面试加分:提一下Spring AI 1.0对结构化输出做了增强,支持MapOutputConverter和ListOutputConverter处理更灵活的场景。

【面试题】6. ChatMemory接口和InMemoryChatMemory在生产环境够用吗?持久化方案怎么设计? ​

【标准答案】InMemoryChatMemory是Spring AI内置的内存实现,数据存JVM堆内存,重启即丢失,多实例部署时各实例记忆不共享。开发调试够用,生产环境绝对不够。持久化方案设计:最简方案是自定义ChatMemory实现类,底层用Redis(Hash结构,key=conversationId,field=消息序号,value=JSON序列化的Message),读写快且天然支持TTL过期清理。进阶方案用数据库(PG/MySQL),加conversation_id索引,配合定时任务清理过期会话。设计要点:一是消息要存角色和内容,Message对象序列化要完整;二是读取时按时间排序,避免乱序;三是加容量上限(如最近50轮),防止Prompt过长超Token限制;四是多实例共享存储,保证任意节点都能恢复对话上下文。面试一句话:ChatMemory是接口,InMemoryChatMemory是Demo级别实现,生产用Redis/DB自己实现,核心是共享+持久+限长+过期。

【面试题】7. Spring AI如何实现多模型动态切换?配置层面和代码层面分别怎么做? ​

【标准答案】配置层面:Spring AI 1.0用spring.ai.*统一配置前缀,不同模型有独立前缀如spring.ai.openai.api-key、spring.ai.ollama.base-url、spring.ai.zhipuai.api-key。可以在application.yml中同时配置多个模型,通过spring.ai.chat.model=openai/ollama/zhipuai指定默认模型,也可以通过环境变量动态切换。代码层面:各模型有独立的ChatModel实现类(OpenAiChatModel、OllamaChatModel等),都注册为Spring Bean。需要动态切换时,可以注入Map<String, ChatModel>按key选取,或者用自定义路由Advisor根据请求特征(用户等级、任务类型、成本控制)动态选择ChatModel。更优雅的方案是封装一个DelegatingChatModel,内部持有多ChatModel引用,按策略路由。面试亮点:提一下这种设计和数据库多数据源路由是同一思路,体现架构能力。

【面试题】8. VectorStore接口统一了哪些操作?不同实现(PGVector/Redis/Pinecone/Chroma/Milvus)怎么选? ​

【标准答案】VectorStore接口统一了三个核心操作:add(写入文档+Embedding)、delete(按ID删除)、similaritySearch(向量相似度检索)。上层RAG代码只依赖接口,不关心底层实现。选型依据:PGVector——已有PostgreSQL基础设施、数据量中等(百万级以内)、希望向量数据和业务数据同库管理的场景,运维成本低;Redis——已有Redis集群、需要超低延迟检索、数据量不太大的场景,注意Redis向量搜索精度有限;Pinecone——全托管、不想运维、需要大规模(亿级)向量检索的场景,但成本高且数据出境;Chroma——轻量级开源、适合本地开发和中小规模部署,社区活跃;Milvus——大规模生产级开源方案,支持十亿级向量、丰富的索引类型,但运维复杂度高。面试总结语:小规模用PGVector复用现有基础设施,中规模用Chroma/Milvus自建,大规模用Pinecone/Milvus集群,选型的核心权衡是规模、成本、运维复杂度三要素。

【面试题】9. Spring AI 1.0正式版相比M5/RC版本有哪些关键变化?升级要注意什么? ​

【标准答案】四大关键变化:一是ChatClient成为唯一推荐入口,之前版本的ChatModel直接调用方式虽然还能用但不推荐,PromptTemplate也被ChatClient的Fluent API取代;二是Advisor架构正式定型,取代了之前版本的RequestResponseAdvisor等实验性设计,接口更清晰,Order排序机制更成熟;三是VectorStore接口统一,add/delete/similaritySearch方法签名稳定,各实现的配置项统一到spring.ai.vectorstore.前缀下;四是spring.ai.配置前缀全面规范化,M5时期各模块配置前缀混乱(有spring.ai.openai、有spring.ai.chat),1.0统一为spring.ai.<provider>.<feature>结构。升级注意点:一是API包名和类名有Breaking Change,比如一些类的包路径从experimental移到正式路径;二是配置项key可能需要重命名,建议diff旧新application.yml;三是自定义Advisor要适配新接口签名。面试时强调:1.0的意义是API稳定性承诺,之前版本是Experimental随时可能变,1.0之后可以放心上生产。

【面试题】10. Spring AI生产环境如何做可观测性(Observability)和性能优化? ​

【标准答案】可观测性三个维度:一是Metrics指标,Spring AI集成了Micrometer,自动暴露chat.client.calls、token.usage等指标,接入Prometheus+Grafana即可监控调用量、延迟、Token消耗、错误率;二是Tracing链路追踪,结合Micrometer Tracing+Zipkin/Jaeger,一次AI请求从ChatClient→Advisor链→ChatModel→HTTP调用全链路可追踪;三是Logging日志,关键节点(请求入参、模型选择、Token数、响应耗时)结构化输出到ELK。性能优化五个方向:一是异步Streaming响应,ChatClient.stream()逐Token返回,用户体验从等5秒变成0.5秒出首字;二是Prompt精简,控制上下文长度,RAG检索用TopK=3-5而非10,减少Token消耗;三是模型路由,简单问答用小模型(GPT-3.5/Qwen-Turbo),复杂推理用大模型(GPT-4/Claude),成本降70%以上;四是缓存,相同问题的Embedding结果和模型响应做缓存(Redis/本地),避免重复调用;五是超时限流熔断,ChatClient调用加Resilience4j,设3-5秒超时+滑动窗口限流+熔断降级返回兜底答案。面试时这样总结:可观测性是AI应用上生产的前提,性能优化核心是"少调模型、调对模型、快速返回"。