Skip to content

Spring AI 面试题库 ​

生成时间:2026-05-21 21:05 (Asia/Shanghai) 题目数量:10道 覆盖范围:消息类型、参数调优、RAG检索优化、Advisor实战、向量库API、多模态输出、错误处理、监控集成、Prompt模板、Agent编排


【面试题】1. Spring AI 中 UserMessage、SystemMessage、AssistantMessage 三种消息类型有什么区别?实际项目中怎么组合使用? ​

【标准答案】三种消息类型对应对话中的不同角色:

SystemMessage:系统指令,告诉模型"你是谁、该怎么回答",比如"你是专业的Java架构师,回答要简洁准确"。特点是:始终放在 Prompt 最前面,不会被模型回复覆盖,对整轮对话生效。

UserMessage:用户输入,就是用户的实际问题或请求。每轮对话至少一个 UserMessage,多模态场景还可以携带图片、文件。

AssistantMessage:模型的历史回复,用于多轮对话时告诉模型"之前你说过什么"。由 ChatMemory 自动维护,一般不需要手动构建。

组合使用套路:

java
chatClient.prompt()
    .system("你是架构师,回答要简洁")
    .user("Spring AI怎么实现RAG?")
    .call();

多轮对话时,MessageChatMemoryAdvisor 会自动把历史 UserMessage 和 AssistantMessage 拼进来,SystemMessage 只在首轮设置,后续轮次继承。

关键点:SystemMessage 的权重最高,模型会优先遵循。写 SystemMessage 时要具体,别写"你是个AI助手"这种废话,要写清楚角色定位、回答风格、禁止事项。


【面试题】2. Spring AI 调用大模型时,temperature、maxTokens、topP 这些参数怎么调?什么场景用什么值? ​

【标准答案】这三个参数直接影响模型输出质量和成本,调参核心是"确定性 vs 创造性"的权衡。

temperature(温度):控制输出的随机性。范围 0-2,默认 1。

  • 0-0.3:高确定性,适合代码生成、数据分析、结构化输出,答案稳定一致
  • 0.5-0.7:平衡模式,适合一般问答、对话,有一定创造性但不离谱
  • 0.8-1.2:高创造性,适合创意写作、故事生成,答案多变
  • 1.5+:几乎随机,生产环境不建议用

maxTokens(最大输出长度):控制模型回复的最大 token 数,不是输入。

  • 简单问答:100-300 tokens够了
  • 代码生成:500-1000 tokens
  • 文章写作:2000+ tokens
  • 注意:设太大浪费成本,设太小答案截断。建议根据任务预估,留 20% 余量

topP(核采样):控制采样范围,范围 0-1,默认 1。

  • 和 temperature 功能类似,但机制不同:topP 只从概率最高的前 P% 的 token 中采样
  • 0.1:极端确定,只从最可能的词选
  • 0.9:较开放,从90%的候选词选
  • 建议:temperature 和 topP 调一个就行,别同时调。一般用 temperature 更直观

生产配置示例:

yaml
spring:
  ai:
    openai:
      chat:
        options:
          model: gpt-4o
          temperature: 0.2  # 代码场景用低温度
          max-tokens: 500

【面试题】3. Spring AI 的 QuestionAnswerAdvisor 具体怎么用?检索到的文档如何自动拼到 Prompt 里? ​

【标准答案】QuestionAnswerAdvisor 是 Spring AI 内置的 RAG Advisor,一行代码就能把向量检索能力挂到 ChatClient 上。

基本用法:

java
@Bean
QuestionAnswerAdvisor qaAdvisor(VectorStore vectorStore) {
    return new QuestionAnswerAdvisor(vectorStore);
}

chatClient.prompt()
    .user("什么是微服务架构?")
    .advisors(qaAdvisor)
    .call();

工作流程:

  1. 用户提问发送到 ChatClient
  2. QuestionAnswerAdvisor 拦截请求,把用户问题用 EmbeddingModel 转成向量
  3. 调用 VectorStore.similaritySearch() 检索最相关的文档片段
  4. 自动把检索结果拼到 Prompt 的上下文区域,格式类似"参考以下内容回答:[文档1][文档2]..."
  5. 模型基于增强后的 Prompt 生成回答

关键参数:

  • topK:检索返回多少条文档,默认 4,建议 3-5 条,太多会撑爆 Token
  • similarityThreshold:相似度阈值,默认 0.75,低于这个分数的文档不返回
  • userTextAdvise:自定义提示词模板,可以改"参考以下内容回答"的措辞

踩坑:如果检索不到文档(相似度都低于阈值),Advisor 不会报错,只是不拼上下文,模型纯靠自己的知识回答。建议在 Advisor 后面加一个日志 Advisor,监控检索命中率。


【面试题】4. Spring AI 的 VectorStore 接口有哪些核心方法?add、delete、search 分别怎么用? ​

【标准答案】VectorStore 接口是 Spring AI 1.0 统一的向量存储抽象,四个核心方法覆盖增删改查:

add(添加向量):

java
List<Document> docs = List.of(
    new Document("Spring AI是Java生态的AI框架", Map.of("source", "官网")),
    new Document("RAG通过向量检索增强模型回答", Map.of("source", "文档"))
);
vectorStore.add(docs);
  • 入参是 Document 列表,每个 Document 包含 content(文本)、metadata(元数据)、embedding(向量,可自动生成)
  • Spring AI 会自动调用 EmbeddingModel 生成向量,不需要手动算

delete(删除向量):

java
vectorStore.delete(List.of("doc-id-1", "doc-id-2"));
  • 按 Document ID 删除,ID 在 add 时自动生成或手动指定
  • 批量删除时,部分失败不影响其他,返回失败的 ID 列表

search(相似度检索):

java
List<Document> results = vectorStore.similaritySearch(
    SearchRequest.query("什么是RAG")
        .withTopK(5)
        .withSimilarityThreshold(0.7)
);
  • query 是查询文本,框架自动转向量
  • topK 返回最相似的 K 条
  • similarityThreshold 过滤低分结果

query(带过滤条件检索):

java
SearchRequest request = SearchRequest.query("微服务")
    .withTopK(3)
    .withFilterExpression("source == '官网' && year >= 2024");
  • 支持元数据过滤表达式,类似 SQL WHERE
  • 不同 VectorStore 实现的过滤语法略有差异,PGVector 用 SQL 表达式,Redis 用 RediSearch 语法

实际项目建议:批量 add 时控制每批 100 条以内,避免单次请求太大;delete 后最好验证一下确实删掉了;search 时 topK 别设太大,否则 Token 爆炸。


【面试题】5. Spring AI 的 EmbeddingModel 如何选型?OpenAI vs 本地模型各有什么优劣势? ​

【标准答案】EmbeddingModel 选型核心看三点:成本、延迟、语言覆盖。

OpenAI text-embedding-3-small:

  • 优势:成本低(每百万 token 仅 $0.02)、延迟低(100-200ms)、多语言支持好、1536 维适中
  • 劣势:国内访问不稳定、数据出境合规问题
  • 适合:海外项目、追求性价比、多语言场景

OpenAI text-embedding-3-large:

  • 优势:维度更高(3072)、语义捕捉更精准
  • 劣势:成本翻倍、存储空间翻倍
  • 适合:对检索精度要求极高的场景

本地模型(Ollama + bge-large-zh):

  • 优势:完全本地化、零 API 成本、中文效果好、无数据出境问题
  • 劣势:需要 GPU 支撑、部署运维成本、延迟比云端高
  • 适合:国内合规项目、敏感数据场景、有 GPU 资源的团队

智谱 embedding-3:

  • 优势:国产合规、中文效果好、价格便宜
  • 劣势:英文效果一般、API 稳定性略逊于 OpenAI
  • 适合:纯中文场景、国产化替代需求

选型建议:

  • 快速验证阶段:直接用 OpenAI text-embedding-3-small,最省事
  • 生产落地阶段:看合规要求,国内项目用智谱或本地部署,海外用 OpenAI
  • 混合方案:写入用本地模型(成本可控),查询用云端模型(延迟低),但注意必须同一模型才能保证向量空间一致

【面试题】6. Spring AI 如何实现错误处理和重试机制?模型调用失败时怎么优雅降级? ​

【标准答案】Spring AI 本身没有内置重试,但可以和 Spring Retry 或 Resilience4j 无缝集成。

方案一:Spring Retry:

java
@Retryable(
    value = {ApiException.class, TimeoutException.class},
    maxAttempts = 3,
    backoff = @Backoff(delay = 1000, multiplier = 2)
)
public String callModel(String prompt) {
    return chatClient.prompt().user(prompt).call().content();
}
  • 对 API 调用超时、限流等瞬时错误自动重试
  • exponential backoff 退避策略,避免瞬间打爆
  • 最多重试 3 次,失败后抛异常

方案二:Resilience4j 熔断降级:

java
CircuitBreaker breaker = CircuitBreaker.ofDefaults("modelCall");
String result = breaker.executeSupplier(() -> 
    chatClient.prompt().user(prompt).call().content()
);
  • 连续失败 N 次后熔断器打开,后续请求直接降级
  • 半开状态下试探性调用,成功则恢复
  • 适合处理模型服务故障、API 额度耗尽等持续性错误

降级策略:

java
@Recover
public String fallback(String prompt, Exception e) {
    // 降级方案1:切备用模型
    return fallbackChatClient.prompt().user(prompt).call().content();
    // 降级方案2:返回预设答案
    return "模型暂时不可用,请稍后重试";
    // 降级方案3:调用本地知识库
    return localKB.search(prompt);
}

常见错误类型处理:

  • Token 超限:截断历史或简化 Prompt 后重试
  • Rate Limit:等待退避后重试,或切备用 API Key
  • 模型过载:降级到轻量模型或排队等待
  • 内容违规:返回预设合规提示,不重试

生产建议:ChatClient 调用必须包一层重试/熔断,裸调用一个异常就让整个服务挂掉,代价太大。


【面试题】7. Spring AI 与 Micrometer 监控如何集成?能观测哪些核心指标? ​

【标准答案】Spring AI 1.0 内置 Micrometer 支持,开箱即用,只需引入依赖和配置暴露端点。

依赖配置:

xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-core</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

核心指标:

  1. ai.chat.token.usage:Token 消耗量,分 input_tokens 和 output_tokens,直接挂钩成本
  2. ai.chat.latency:调用延迟,P50/P95/P99 分位数,监控响应速度
  3. ai.chat.calls:调用次数,分成功/失败统计,计算成功率
  4. ai.chat.errors:错误次数,按错误类型分类(超时、限流、违规等)
  5. ai.vector.store.operations:向量库操作次数,监控 add/search QPS

指标标签:

  • model:调用的模型名(gpt-4o、claude-3-5-sonnet)
  • provider:模型提供商(openai、anthropic、ollama)
  • operation:操作类型(chat、embedding、vector-search)

Grafana 监控面板建议:

  • Token 成本看板:按 model 分组统计,计算每日成本
  • 响应延迟看板:P95 延迟趋势,设置阈值告警
  • 错误率看板:失败率超过 5% 触发告警
  • 向量库看板:检索命中率、延迟分布

自定义埋点:

java
chatClient.prompt()
    .user(prompt)
    .advisors(new MetricsAdvisor(meterRegistry))
    .call();

在 Advisor 中埋点,记录检索命中率、Advisor 执行耗时等业务指标。


【面试题】8. Spring AI 的 Prompt 模板如何构建?变量注入和模板语法有哪些规范? ​

【标准答案】Spring AI 提供 PromptTemplate 类处理模板化提示词,支持变量注入和条件逻辑。

基本用法:

java
PromptTemplate template = new PromptTemplate("""
    你是{role},请用{style}风格回答以下问题:
    
    问题:{question}
    
    要求:
    - 回答长度不超过{maxLength}字
    - 必须包含示例代码
    """);

Prompt prompt = template.create(Map.of(
    "role", "Java架构师",
    "style", "简洁专业",
    "question", "Spring AI怎么实现RAG?",
    "maxLength", "500"
));

chatClient.prompt(prompt).call();

模板语法规范:

  • 变量占位符:{variableName},双大括号,和 Spring AI 1.0 统一
  • 条件语法:{#if condition}内容{#endif},支持简单逻辑
  • 循环语法:{#for item in items}{item}{#endfor},批量注入
  • 默认值:{variable:defaultValue},变量不存在时用默认值

资源文件加载:

java
PromptTemplate template = new PromptTemplate(
    new ClassPathResource("prompts/qa-template.st")  // StringTemplate 格式
);
  • 模板文件放在 resources/prompts/ 目录
  • 支持外部化,不同环境用不同模板

多模板组合:

java
Prompt systemPrompt = new PromptTemplate("系统指令模板").create(vars);
Prompt userPrompt = new PromptTemplate("用户问题模板").create(vars);
chatClient.prompt()
    .messages(systemPrompt, userPrompt)
    .call();

踩坑点:

  • 变量名别用中文,部分模板引擎解析有问题
  • 模板文件用 UTF-8 编码,中文模板要检查编码
  • 变量注入用 Map.of() 时 key 必须是字符串

【面试题】9. Spring AI 如何实现多模态输出?比如让模型生成图片或语音? ​

【标准答案】Spring AI 目前对多模态输出的支持还有限,主要依赖各模型厂商的独立 API,需要自行封装。

图片生成(DALL-E):

java
@Bean
ImageModel imageModel(OpenAiImageModel openAiImageModel) {
    return openAiImageModel;
}

ImageResponse response = imageModel.call(
    new ImagePrompt("画一只可爱的虾", 
        ImageOptionsBuilder.builder()
            .withModel("dall-e-3")
            .withWidth(1024)
            .withHeight(1024)
            .build()
    )
);
String imageUrl = response.getResult().getOutput().getUrl();
  • OpenAI DALL-E 3 是主流选择
  • 返回图片 URL 或 Base64 数据
  • 也可以用 Stable Diffusion 等开源模型(需 Ollama 代理)

语音输出(TTS):

java
// Spring AI 暂无内置 TTS 抽象,需直接调 OpenAI API
HttpResponse response = HttpClient.newHttpClient().send(
    HttpRequest.newBuilder()
        .uri(URI.create("https://api.openai.com/v1/audio/speech"))
        .header("Authorization", "Bearer " + apiKey)
        .POST(HttpRequest.BodyPublishers.ofString("""
            {"model":"tts-1","input":"你好","voice":"nova"}
            """))
        .build(),
    HttpResponse.BodyHandlers.ofByteArray()
);
byte[] audioData = response.body();
  • OpenAI TTS-1 是性价比首选,延迟低
  • 智谱、阿里云也有国产 TTS API
  • 本地部署可用 Edge-TTS、Coqui TTS

多模态流水线示例:

java
// 先让 ChatModel 生成图片描述
String description = chatClient.prompt()
    .user("为'可爱的虾'生成一个图片描述")
    .call().content();

// 再调 DALL-E 生成图片
String imageUrl = imageModel.call(new ImagePrompt(description))
    .getResult().getOutput().getUrl();

// 最后调 TTS 生成语音解释
byte[] audio = ttsService.generate("这张图片展示了...");

未来 Spring AI 会统一多模态输入输出接口,目前需要组合使用。


【面试题】10. 面试情景题:如果面试官问"你在项目中用过 Spring AI 吗?遇到过什么坑?",怎么回答才能让面试官印象深刻? ​

【标准答案】这道题是开放型,面试官想听真实项目经验,不是背诵知识点。建议用"项目背景 + 具体问题 + 解决方案 + 最终效果"四段式回答。

参考回答模板:

"我们项目是一个智能客服系统,用 Spring AI 做知识库问答。我负责 RAG 部分的设计和落地。

遇到的坑主要有三个:

第一个是 Token 管理问题。上线后发现长对话经常报 Token 超限错误。排查发现是 ChatMemory 没设 maxMessages,历史消息无限累积。解决方案是在 MessageChatMemoryAdvisor 里配置 maxHistorySize=10,只保留最近 10 轮对话,同时把 SystemMessage 精简到 100 token 以内。效果是 Token 消耗降低了 60%,对话稳定性大幅提升。

第二个是向量检索命中率低。用户问专业问题时,检索出来的文档经常不相关。原因是 TokenTextSplitter 的 chunkSize 设太大(2000),导致检索粒度粗糙。我们把 chunkSize 改成 500、overlap 设 100,同时在元数据里加上文档来源和分类,用 filterExpression 做精准过滤。命中率从 30% 提升到 75%。

第三个是多模型切换的配置混乱。项目同时用 OpenAI 和智谱,配置文件散乱,切换时要改代码。我们做了统一封装,用 RoutingChatModel 根据用户等级路由:VIP 用户走 GPT-4,普通用户走智谱 GLM-4。配置中心化后,切模型只需改一行配置,灰度发布也方便了。

这套方案上线后,客服系统问答准确率从 65% 提升到 85%,每月节省 Token 成本约 2 万,面试官可以看我们的 Grafana 监控面板验证数据。"

回答技巧:

  • 有数据、有对比、有结论,别只说"解决了问题"
  • 提到的坑要具体,别泛泛说"调参困难"
  • 效果用数字量化,面试官会追问细节
  • 准备一个图表或监控截图,视觉冲击力强

本轮题目覆盖:消息类型组合、参数调优实战、QuestionAnswerAdvisor用法、VectorStore API详解、EmbeddingModel选型、错误处理与重试、Micrometer监控集成、Prompt模板构建、多模态输出、面试情景问答。均为新题,不与之前轮次重复。