Skip to content

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

【面试题】1. Spring AI中ChatClient和直接使用ChatModel有什么区别?实际项目中如何选择? ​

【标准答案】ChatModel是底层模型接口,直接调用API,适合简单场景。ChatClient是Spring AI 1.0推出的统一入口,内置了Prompt模板、Advisor链、Memory管理、Structured Output等高级能力,API更流畅。

实际项目中:简单问答用ChatModel足够,但涉及RAG、Function Calling、对话历史、结构化输出时,ChatClient一行代码搞定,不需要手动拼接。推荐默认用ChatClient,只有极致性能需求才降级到ChatModel。

【面试题】2. Spring AI的Advisor机制是什么?能解决哪些问题? ​

【标准答案】Advisor是拦截器模式,可以在请求前后插入自定义逻辑。Spring AI内置了QuestionAnswerAdvisor(RAG检索)、MessageChatMemoryAdvisor(对话记忆)、SafeGuardAdvisor(安全过滤)等。

解决的问题:统一的横切关注点处理,比如检索增强、历史注入、内容过滤、日志追踪,不用每个业务方法重复写。自定义Advisor只需实现RequestResponseAdvisor接口,重写adviseRequest和adviseResponse方法,然后加入ChatClient的advisor链即可。

【面试题】3. VectorStore选型时,PGVector、Redis、Pinecone、Chroma、Milvus各有什么优劣势? ​

【标准答案】PGVector:依托PostgreSQL,部署简单,适合中小规模、已有PG基础设施的场景,但大规模向量检索性能一般。

Redis:内存级速度,适合实时性要求高的推荐系统,但容量受限、持久化需配置。

Pinecone:全托管,零运维,扩展性好,但成本较高、数据不在本地。

Chroma:轻量级嵌入式向量库,适合开发测试、小规模应用,生产环境需自己管理持久化。

Milvus:开源分布式向量库,支持亿级向量,适合大规模生产场景,但部署运维成本高。

选型建议:开发用Chroma/PGVector快速验证,生产根据规模选择Redis(小中型)、Milvus(大规模)、Pinecone(不想运维)。

【面试题】4. Spring AI的Function Calling底层是如何工作的?@Bean注册函数后发生了什么? ​

【标准答案】流程分四步:

  1. Spring AI扫描所有@Bean标记的Function,通过Jackson自动生成JSON Schema(参数名、类型、描述)。

  2. 用户提问时,LLM判断是否需要调用工具,返回tool_call指令(函数名+参数)。

  3. Spring AI自动执行函数,拿到返回值作为上下文。

  4. 将函数结果回传给LLM,生成最终回答。

@Bean函数需要满足:返回值类型明确,参数用record或POJO定义,可选添加@Description注解提供工具描述。Spring AI的ChatClient会在内部自动处理整个调度流程,开发者只需关注业务逻辑。

【面试题】5. 实际项目中如何实现Spring AI的多模型动态切换?配置怎么管理? ​

【标准答案】两种方式:

方式一:配置文件切换,通过spring.ai.openai.api-key、spring.ai.ollama.base-url等配置,结合Spring Profile实现不同环境用不同模型。

方式二:运行时切换,注入ChatModel接口,通过@Qualifier指定具体实现,或者自定义路由策略,根据请求类型(简单问答用Ollama本地模型、复杂推理用GPT-4、代码生成用Claude)动态选择。

推荐做法:核心业务逻辑依赖ChatModel抽象接口,具体实现通过配置+条件注入切换,避免硬编码绑定单一模型,方便降级和成本优化。

【面试题】6. BeanOutputConverter实现结构化输出时有哪些常见坑?如何规避? ​

【标准答案】常见坑:

  1. POJO必须有无参构造器,否则反序列化失败。

  2. 字段必须是public或有getter/setter,Jackson才能识别。

  3. 嵌套对象的Schema可能生成不完整,建议手动指定@JsonClassDescription。

  4. LLM可能返回不符合Schema的JSON,需要异常捕获+重试。

  5. 枚举类型需要明确描述可选值,否则LLM可能瞎编。

规避方法:使用record定义输出对象,字段加@Description注解,复杂场景用entity()方法显式指定Schema,生产环境加校验层确保数据合法。

【面试题】7. Spring AI的Chat Memory如何实现对话历史持久化?生产环境推荐什么方案? ​

【标准答案】内置的InMemoryChatMemory只适合单机测试,重启丢失。生产环境需要自己实现ChatMemory接口的持久化方案:

方案一:Redis存储,按sessionId为key,消息列表为value,设置过期时间自动清理。

方案二:数据库存储,设计conversation_message表,关联用户ID和会话ID,支持查询历史对话。

方案三:结合Spring AI的MessageChatMemoryAdvisor,在adviseRequest时从持久化存储加载历史,adviseResponse时保存新消息。

推荐方案:短期会话用Redis(性能好),长期归档用数据库(可审计),同时设置消息数量上限避免上下文过长。

【面试题】8. Spring AI 1.0相比之前版本有哪些重大变化?为什么要升级? ​

【标准答案】核心变化:

  1. ChatClient统一入口:替代原来的PromptTemplate+ChatModel组合,API更简洁流畅。

  2. Advisor架构标准化:所有横切能力(RAG、Memory、安全)统一通过Advisor链扩展。

  3. VectorStore接口统一:不同向量库实现同一接口,切换成本低。

  4. spring.ai.*配置前缀:所有配置项统一前缀,解决之前版本配置混乱问题。

  5. Structured Output增强:BeanOutputConverter支持更复杂类型,entity()方法直接映射。

升级理由:更规范的架构、更少的样板代码、更好的扩展性,Spring AI 1.0是稳定生产版本,后续版本会在此基础上迭代。

【面试题】9. 在微服务架构下,Spring AI的API Key如何安全管理?有哪些最佳实践? ​

【标准答案】绝对不能硬编码在代码里。推荐方案:

  1. 环境变量注入:spring.ai.openai.api-key=${OPENAI_API_KEY},容器启动时传入。

  2. 配置中心管理:结合Spring Cloud Config或Nacos,集中管理不同环境的密钥。

  3. 密钥管理服务:生产环境用Vault或云厂商的KMS,密钥加密存储,运行时动态获取。

  4. 网关层代理:所有AI请求走统一网关,网关负责注入API Key,后端服务无需感知。

  5. 密钥轮换:定期更新密钥,支持平滑切换,避免单点泄露风险。

最佳实践:最小权限原则,不同服务用不同密钥,日志脱敏,监控异常调用,配额限流防止密钥被盗刷。

【面试题】10. Spring AI的Streaming响应如何实现?有哪些性能优化技巧? ​

【标准答案】Streaming用ChatClient的stream()方法返回Flux<String>,支持响应式流式输出。

实现步骤:调用chatClient.prompt().user(question).stream().content(),拿到Flux后用WebFlux的ServerSentEvent推给前端。

性能优化:

  1. 连接复用:保持HTTP长连接,避免每次请求重建连接。

  2. 背压控制:根据客户端消费速度调节推送速率,避免内存溢出。

  3. 超时设置:合理配置spring.ai.openai.timeout,防止慢请求堆积。

  4. 熔断降级:异常时返回预设回复,不影响整体体验。

  5. 监控指标:用Micrometer记录请求延迟、Token消耗、错误率,及时发现问题。

实际项目中,Streaming比一次性返回响应感知更快,但需要处理好异常和超时逻辑。