Skip to content

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 → 最终返回结果。

典型场景:

  1. QuestionAnswerAdvisor:RAG 场景,自动从向量库检索相关文档、拼接到 Prompt,增强回答质量。
  2. MessageChatMemoryAdvisor:对话记忆,自动把历史消息注入到当前 Prompt,实现多轮对话。
  3. 日志审计 Advisor:记录每次调用的耗时、Token 消耗,用于监控和计费。
  4. 安全校验 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 注册后,框架自动完成三件事:

  1. JSON Schema 自动生成:Spring AI 会通过反射读取函数的参数类型,生成符合 OpenAI/Anthropic 规范的 JSON Schema,告诉模型这个函数叫什么、参数有哪些、类型是什么。

  2. 函数注册到上下文:框架维护一个 FunctionRegistry,将 Bean 名称与实际函数映射起来,供后续调度使用。

  3. 自动注入到 Prompt:当调用 ChatClient 时,如果配置了函数,框架会把函数描述注入到系统提示词或工具列表中,让模型知道可以调用。

调用流程:用户提问 → 模型判断需要调用函数 → 返回 tool_call → Spring AI 拦截并执行函数 → 函数结果返回给模型 → 模型生成最终答案。

关键代码只需:@Bean public Function<UserInput, Output> myFunction() { return ... },后续全部由框架托管。


【面试题】5. Structured Output 中 BeanOutputConverter 的作用是什么?使用时有哪些常见的"坑"? ​

【标准答案】 BeanOutputConverter 的作用是让 LLM 的非结构化输出映射成 Java POJO,方便后续业务处理。它通过 JSON Schema 约束模型输出格式,然后反序列化为对象。

常见坑点:

  1. 字段类型不匹配:LLM 输出的 JSON 类型与 POJO 字段类型不一致,比如字符串给到了 Integer 字段,反序列化失败。建议用 String 或包装类型,增加容错。

  2. 必填字段缺失:模型有时会跳过某些字段,导致反序列化报错。可以通过 @JsonProperty(required = true) 或在 Schema 中明确 required。

  3. 嵌套对象处理复杂:复杂嵌套结构的 Schema 生成可能不完整,建议手动定义 Schema 或简化数据结构。

  4. Token 限制导致输出截断:复杂 Schema 占用大量 Token,可能把上下文撑爆。建议 Schema 简洁,只定义必要字段。

最佳实践:先用简单的 DTO 验证,确保模型能稳定输出结构化数据,再逐步扩展复杂度。


【面试题】6. Spring AI 的 ChatMemory 如何实现多轮对话记忆?InMemoryChatMemory 有什么局限性? ​

【标准答案】 ChatMemory 接口定义了对话历史的管理能力,核心方法是 add 和 get,分别用于存储和检索历史消息。

多轮对话实现:

  1. 用户每次提问,ChatClient 通过 MessageChatMemoryAdvisor 自动从 ChatMemory 中获取历史消息。
  2. 历史消息拼接到当前 Prompt,发送给模型。
  3. 模型响应后,Advisor 自动把用户问题和模型回答写入 ChatMemory。

InMemoryChatMemory 的局限性:

  1. 进程内存储:数据只存在 JVM 内存,重启丢失。
  2. 无法分布式共享:多实例部署时,对话历史无法跨实例共享。
  3. 内存泄漏风险:长对话或高频会话可能导致内存溢出,需要手动清理策略。

生产环境建议:使用持久化方案,比如 Redis、数据库,或者自己实现 ChatMemory 接口,对接外部存储。Spring AI 也提供了基于 Redis 的 ChatMemory 实现。


【面试题】7. Spring AI 1.0 正式版相比之前的里程碑版本有哪些核心更新?对开发者有什么影响? ​

【标准答案】 Spring AI 1.0 正式版有几个关键更新:

  1. ChatClient 统一入口:之前 OpenAI、Anthropic 等模型的调用方式略有差异,1.0 统一用 ChatClient,API 更一致,切换模型成本低。

  2. Advisor 架构成熟:Advisor 机制正式稳定,支持更灵活的拦截扩展,RAG、Memory 等能力都通过 Advisor 实现,可插拔性强。

  3. VectorStore 接口统一:各向量库的接口标准化,切换向量库只需改配置,业务代码不动。

  4. spring.ai. 配置前缀统一*:所有配置统一用 spring.ai.model.xxx 格式,告别之前不同模型配置风格不一致的问题。

  5. Observability 内置:1.0 内置了 Micrometer 指标,开箱即用监控调用次数、延迟、Token 消耗。

对开发者的影响:API 更稳定,升级成本降低,但里程碑版本的代码可能需要调整(比如 ChatModel 直接调用改为 ChatClient)。建议新项目直接用 1.0,老项目参考迁移指南。


【面试题】8. 在微服务架构下,Spring AI 应用如何管理 API Key 和实现多模型路由? ​

【标准答案】 API Key 管理和多模型路由是生产环境的核心问题。

API Key 管理:

  1. 外部化配置:不要硬编码,用 Spring Cloud Config、Vault 或 Kubernetes Secrets 管理,配置在 spring.ai.openai.api-key 等属性。
  2. 动态刷新:结合 Spring Cloud,实现 API Key 的动态更新,无需重启服务。
  3. 权限隔离:不同业务线或租户使用不同的 Key,通过配置中心按环境隔离。

多模型路由:

  1. 配置多个 ChatModel Bean:比如 openAiChatModel、anthropicChatModel,通过 @Qualifier 或条件注入选择。
  2. 路由策略封装:根据业务需求(成本、速度、能力)动态选择模型,比如简单问答用便宜模型,复杂推理用强模型。
  3. 配置前缀区分:Spring AI 支持多配置源,可以通过 spring.ai.openai.xxx、spring.ai.anthropic.xxx 分别配置。

实践建议:抽象一个 ModelRouter 服务,根据请求特征(用户等级、任务类型)选择模型,对外暴露统一接口,业务代码不感知具体模型。


【面试题】9. Spring AI 如何实现 Streaming 流式响应?在实际应用中需要注意什么? ​

【标准答案】 Spring AI 通过 Flux<String> 或 Flux<ChatResponse> 实现流式响应,底层依赖 Reactor 和 WebFlux。

实现方式:

java
Flux<String> stream = chatClient.prompt()
    .user("写一篇文章")
    .stream()
    .content();

返回的是响应式流,可以逐步消费。

实际应用注意点:

  1. 前端展示:流式输出需要前端支持 SSE 或 WebSocket,逐块渲染,提升用户体验。

  2. 超时和错误处理:流式调用不像同步调用容易捕获异常,需要用 Reactor 的 onErrorResume 或 doOnError 做兜底。

  3. 背压控制:如果消费速度跟不上生产速度,可能内存溢出,需要合理配置缓冲和背压策略。

  4. Token 计费:流式模式下 Token 消耗统计更复杂,需要累加各块的结果,建议在 Advisor 中统一计数。

  5. 调试困难:流式调试不如同步直观,建议开发阶段用同步模式,生产再切流式。


【面试题】10. Spring AI 如何与 Spring Boot 生态集成?自动配置和外部化配置有哪些最佳实践? ​

【标准答案】 Spring AI 的核心优势之一就是与 Spring Boot 深度集成,开箱即用。

自动配置:

  1. Starter 依赖:引入 spring-ai-openai-spring-boot-starter 等依赖,Boot 自动配置 ChatModel、EmbeddingModel 等 Bean,无需手动创建。
  2. 条件注入:通过配置开关控制是否启用某些功能,比如 spring.ai.openai.enabled=false 禁用 OpenAI。

外部化配置:

  1. application.yml/properties:所有配置都在 spring.ai.xxx 命名空间下,比如 spring.ai.openai.api-key、spring.ai.openai.base-url。
  2. 多环境隔离:结合 Spring Profile,dev/test/prod 环境使用不同的 API Key、模型参数。
  3. 配置中心:生产环境用 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集成