Spring AI 面试题库(2026-05-23 15:50)
【面试题】1. Spring AI中ChatClient和ChatModel有什么区别?实际开发中该如何选择?
【标准答案】ChatModel是底层抽象,直接处理Prompt返回ChatResponse,需要手动管理对话历史和上下文。ChatClient是高层门面,内置了Fluent API、Advisor链式处理、对话记忆自动管理。
选型原则:
- 简单单轮问答、纯模型调用 → 用ChatModel,更轻量
- 对话系统、RAG、Function Calling、需要记忆 → 用ChatClient,开箱即用
- 新项目优先ChatClient,Spring AI 1.0已将其作为统一入口
实际代码:chatClient.prompt().user("你好").call().content() 一行搞定,比ChatModel省去很多样板代码。
【面试题】2. RAG中TokenTextSplitter分块大小的设置策略是什么?分块太大或太小有什么问题?
【标准答案】核心原则:平衡语义完整性和检索精度。
分块太大(>1000 tokens):
- 检索精度下降,噪音多
- 单块包含多个主题,相似度计算不准确
- LLM处理成本高
分块太小(<100 tokens):
- 语义被截断,上下文丢失
- 检索召回率低,漏掉相关内容
- 分块数量爆炸,向量库压力大
推荐配置:
- 一般文档:512-768 tokens,overlap 50-100
- 代码/结构化文档:256-512 tokens
- 配合向量库topK参数调整:分块小则K调大
实际项目用TokenTextSplitter时,会先跑几批测试数据,看检索命中率再调优。
【面试题】3. Spring AI的Advisor机制是如何工作的?你能说出几个内置Advisor的用途?
【标准答案】Advisor是请求-响应拦截器,采用责任链模式,可以在请求发往模型前、响应返回后插入自定义逻辑。
执行流程:Request → Advisor1 → Advisor2 → ChatModel → Advisor2 → Advisor1 → Response
内置Advisor:
- QuestionAnswerAdvisor:RAG场景,自动做相似度检索,把相关文档注入Prompt
- MessageChatMemoryAdvisor:对话记忆,自动在请求中添加历史消息
- PromptTruncateAdvisor:截断过长Prompt,防超限
自定义Advisor:实现CallAroundAdvisor或StreamAroundAdvisor,重写aroundCall()方法。
典型应用:添加系统提示词、日志审计、敏感词过滤、Token计费统计。
【面试题】4. Spring AI Function Calling的tool_call调度流程是怎样的?如何注册自定义工具?
【标准答案】完整流程:
- 用户提问 → LLM判断需要调用工具
- LLM返回
tool_call请求(包含函数名+参数JSON) - Spring AI解析请求,从ApplicationContext查找匹配的@Bean函数
- 执行函数,获取返回结果
- 将结果作为tool消息回传LLM
- LLM整合结果,生成最终回复
注册自定义工具:
@Bean
public Function<WeatherRequest, WeatherResponse> weatherTool() {
return request -> weatherService.getWeather(request.city());
}关键点:
- Spring AI自动生成JSON Schema供LLM理解参数结构
- 函数签名要清晰,参数用record或POJO
- 配置
spring.ai.openai.functions.weather.description可自定义工具描述
【面试题】5. Spring AI中如何实现多模型切换?比如开发用Ollama本地模型,生产用OpenAI?
【标准答案】Spring AI的多模型切换通过spring.ai.*配置前缀+依赖管理实现。
方案一:Profile切换
# application-dev.yml
spring.ai.ollama.base-url: http://localhost:11434
# application-prod.yml
spring.ai.openai.api-key: ${OPENAI_API_KEY}方案二:代码层ChatModel注入
@Profile("dev")
@Bean
ChatModel chatModel(OllamaChatModel model) { return model; }
@Profile("prod")
@Bean
ChatModel chatModel(OpenAiChatModel model) { return model; }方案三:运行时动态选择
@Service
public class ChatRouter {
private final Map<String, ChatModel> models;
public ChatResponse chat(String model, String prompt) {
return models.get(model).call(new Prompt(prompt));
}
}实际项目推荐Profile方式,配置外部化,不用改代码。
【面试题】6. VectorStore向量库选型时,PGVector、Redis、Pinecone、Milvus各有什么适用场景?
【标准答案】
- PGVector:已有PostgreSQL基础设施的项目,一体化省运维,但性能一般,适合中小规模(百万级)
- Redis:已有Redis集群可复用,延迟低,适合高频检索,但向量维度受限(通常≤1536)
- Pinecone:全托管SaaS,零运维,适合快速上线、团队小、不想管基础设施,但成本高、数据出域
- Milvus:开源专业向量库,高性能、分布式、支持十亿级,适合大规模企业级部署,但运维复杂度高
- Chroma:轻量级,适合原型开发、本地测试,不推荐生产高并发
选型逻辑:
- 快速原型 → Chroma/PGVector
- 已有基础设施 → Redis/PGVector复用
- 大规模生产 → Milvus/Pinecone
- 数据敏感不出域 → Milvus/PGVector自建
【面试题】7. Spring AI的Structured Output结构化输出如何保证格式稳定?有哪些常见坑?
【标准答案】Spring AI通过BeanOutputConverter+JSON Schema约束实现结构化输出。
用法:
var converter = new BeanOutputConverter<>(MyRecord.class);
String schema = converter.getFormat();
String response = chatClient.prompt()
.user(prompt + schema)
.call()
.content();
MyRecord result = converter.convert(response);常见坑:
- Schema过长:复杂POJO的Schema可能超Token限制,LLM会截断或忽略
- 嵌套对象解析失败:深嵌套结构LLM难以稳定输出,建议扁平化
- 枚举值不准:LLM可能输出Schema未定义的值,需校验
- 多语言模型差异:不同模型对JSON Schema理解能力不同,OpenAI最强,本地模型较弱
- 强制格式:用
.entity(MyRecord.class)比手动解析更稳定,Spring AI会自动重试
最佳实践:Schema尽量简单、字段加description提示、输出后校验。
【面试题】8. Spring AI的ChatMemory对话记忆如何实现持久化?生产环境推荐什么方案?
【标准答案】Spring AI提供ChatMemory接口,默认InMemoryChatMemory只存内存,重启丢失。
持久化方案:
方案一:数据库持久化
public class JdbcChatMemory implements ChatMemory {
private final JdbcTemplate jdbc;
@Override
public void add(String conversationId, List<Message> messages) {
// 序列化Message存入数据库
}
@Override
public List<Message> get(String conversationId) {
// 从数据库加载
}
}方案二:Redis持久化
- 用Redis List存储,天然支持LPUSH/LRANGE
- 设置TTL自动清理过期对话
- 高性能,适合高并发场景
方案三:混合架构
- 近期热数据 → Redis
- 历史归档 → 数据库/OSS
生产推荐:
- 用户少、对话短 → InMemory足够
- 有状态服务 → Redis
- 合规审计要留痕 → 数据库持久化
关键点:MessageChatMemoryAdvisor会自动调用ChatMemory,无需手动管理历史消息插入。
【面试题】9. Spring AI微服务部署时,API Key如何安全管理?有哪几种方案?
【标准答案】API Key泄露是重大安全隐患,生产环境必须加密存储+动态注入。
方案一:环境变量
spring.ai.openai.api-key: ${OPENAI_API_KEY}容器化部署时通过K8s Secret或Docker secrets注入,不进代码库。
方案二:配置中心加密
- Spring Cloud Config + Jasypt加密
- Vault动态注入
- Nacos加密配置
方案三:网关代理
- API网关统一管理Key
- 下游服务无Key,只传请求
- 集中审计、限流
方案四:Key轮换
- 定期更换API Key
- 支持多Key负载均衡,单Key泄露影响小
生产推荐:网关代理 + Vault动态注入,双重保险。开发环境用.env文件但要加.gitignore。
【面试题】10. Spring AI 1.0正式版相比之前的Milestone版本,有哪些重要更新?
【标准答案】Spring AI 1.0 GA(2024年底发布)是里程碑版本,架构全面升级:
核心更新:
- ChatClient统一入口:取代直接用ChatModel,Fluent API更简洁
- Advisor架构:责任链模式统一处理Prompt增强、记忆、RAG等
- VectorStore接口统一:所有向量库实现同一接口,切换成本低
- 配置前缀标准化:全部用
spring.ai.*前缀,配置更规范 - Observability集成:原生支持Micrometer指标、追踪链路
- 多模态支持:图像、音频输入输出能力增强
- Streaming响应优化:
stream()方法返回Flux,支持WebFlux响应式
迁移注意点:
- 旧版
AiClient废弃 → 改用ChatClient - VectorStore API变化 → 检查方法签名
- 配置属性名调整 → 更新application.yml
升级建议:新项目直接用1.0,老项目按迁移指南逐步升级,API变化较大需要回归测试。
生成时间:2026-05-23 15:50 | 共10题