尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Spring AI 高频面试题及参考答案:从 ChatModel 到 Advisor 的配置骨架

发布时间:2026/9/29 22:59:16

资讯中心
01
ARTICLE

Spring AI 高频面试题及参考答案:从 ChatModel 到 Advisor 的配置骨架

Spring AI 高频面试题及参考答案:从 ChatModel 到 Advisor 的配置骨架
1. Spring AI 面试为什么总在 ChatModel 和 Advisor 上翻车Spring AI 是 Spring 生态里用来对接大模型的统一抽象层它把 ChatModel、Message、BeanOutputConverter、Advisor 这几个核心组件串成一条完整的调用链。准备 Spring AI 面试的开发者最容易在两类问题上卡住一类是概念边界模糊比如分不清 Message 角色只是语义标记、模型原生 JSON 模式不等于自动映射 Java 对象另一类是配置骨架写不出来面试官让你现场给一份 application.yml 加 Java 配置结果 Bean 装配顺序、Advisor 拦截链、conversationId 传递全乱套。这篇按面试高频考点组织从 ChatModel 装配讲到 Message 角色、BeanOutputConverter 结构化输出、Advisor 拦截顺序每个考点都配可复制的配置和一段能跑通的验证请求。接入通道我用 TaoToken 统一管理 Key 和 API 地址这样切换模型时只改配置不改业务代码面试里被问到多模型怎么切换也能直接拿这套骨架回答。适合已经写过 Spring Boot、想系统梳理 Spring AI 配置骨架的开发者也适合面试前想快速过一遍核心组件的人。2. 用 TaoToken 统一 Key 与 API 通道的前置准备Spring AI 默认的 OpenAI Starter 要求你填 api-key 和 base-url。面试场景下如果每个模型都单独配一套 Key配置会散落在多个 yml 里切换模型时容易漏改。我的做法是走 TaoToken 统一通道官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后拿到一个 KeyAPI 地址固定用 https://taotoken.net/apiSpring AI 里只需要把 base-url 指向它模型名通过配置项区分。这样做的好处是ChatModel Bean 只依赖一套凭证面试官问你怎么管理多模型密钥时你可以答统一网关 配置化模型名比每个厂商存一份 Key更工程化。注意 TaoToken 在这里的角色是统一 API 通道不是替代 Spring AI 本身ChatModel、Advisor 这些抽象仍然由 Spring AI 提供。前置清单JDK 17 或以上Spring Boot 3.2Maven 引入spring-ai-openai-spring-boot-starterTaoToken 的 API Key写入环境变量TAOTOKEN_API_KEY一个能发 HTTP 请求的终端用来做最后的验证注意API Key 不要硬编码进代码或提交到仓库用环境变量或配置中心注入这是面试里常被追问的安全点。3. 可复制的 application.yml 与 Java 配置骨架3.1 application.yml 完整配置spring: ai: openai: api-key: ${TAOTOKEN_API_KEY} base-url: https://taotoken.net/api chat: options: model: gpt-4o-mini temperature: 0.2 embedding: options: model: text-embedding-3-small app: ai: provider: taotoken default-system-prompt: 你是资深 Java 面试官回答简洁准确不编造知识点。这里base-url指向 TaoToken 的 API 地址api-key从环境变量读。temperature设 0.2 是为了结构化输出稳定后面讲 BeanOutputConverter 时会用到。3.2 ChatClient 与 Advisor 的 Java 配置Configuration public class ChatClientConfig { Bean public ChatMemory chatMemory() { return new InMemoryChatMemory(); } Bean public ChatClient chatClient(ChatModel chatModel, ChatMemory chatMemory) { return ChatClient.builder(chatModel) .defaultSystem(你是资深 Java 面试官回答简洁准确不编造知识点。) .defaultAdvisors( MessageChatMemoryAdvisor.builder(chatMemory).build(), new SimpleLoggerAdvisor() ) .build(); } }defaultAdvisors里的顺序就是拦截顺序MessageChatMemoryAdvisor 在前、SimpleLoggerAdvisor 在后请求阶段按这个顺序进响应阶段反着出。面试官问 Advisor 执行顺序时直接拿这段配置解释最清楚。3.3 Message 角色与 BeanOutputConverter 的骨架Service public class InterviewService { private final ChatClient chatClient; private final BeanOutputConverterTechAnswer converter new BeanOutputConverter(TechAnswer.class); public InterviewService(ChatClient chatClient) { this.chatClient chatClient; } public TechAnswer structuredAnswer(String question) { return chatClient.prompt() .user(u - u.text(question \n converter.getFormat())) .call() .entity(converter); } Data public static class TechAnswer { private String title; private String content; } }converter.getFormat()会把目标 Java 类的字段结构转成格式说明追加到 Prompt模型返回 JSON 后由entity(converter)完成反序列化。这里的关键分界点模型只负责输出 JSON 文本对象映射是本地 Jackson 干的不是模型能力。4. 验证 Message 角色与 Advisor 拦截顺序4.1 验证 Message 角色写一个测试方法手动构造三种 Message 发出去观察模型行为Test void verifyMessageRoles() { SystemMessage system new SystemMessage(只回答 Java 相关问题其他一律回复不相关。); UserMessage user new UserMessage(今天天气怎么样); Prompt prompt new Prompt(List.of(system, user)); ChatResponse response chatModel.call(prompt); String text response.getResult().getOutput().getText(); System.out.println(模型回复: text); assertTrue(text.contains(不相关)); }预期结果是模型回复不相关说明 SystemMessage 的约束生效了。如果去掉 SystemMessage 只发 UserMessage模型大概率会正常回答天气问题这就验证了角色只是语义标记约束靠模型遵循这个面试加分点。4.2 验证 Advisor 拦截顺序给 SimpleLoggerAdvisor 加日志再发一次带 conversationId 的请求Test void verifyAdvisorOrder() { String conversationId session_001; String answer chatClient.prompt() .user(介绍 Spring AI 的 Advisor) .advisors(a - a.param( MessageChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID, conversationId)) .call() .content(); System.out.println(回答: answer); // 第二轮验证记忆是否生效 String second chatClient.prompt() .user(我刚才问了什么) .advisors(a - a.param( MessageChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID, conversationId)) .call() .content(); System.out.println(第二轮: second); }日志里你会看到请求先经过 MessageChatMemoryAdvisor追加历史消息再经过 SimpleLoggerAdvisor打印请求响应阶段顺序反过来。第二轮提问时模型能答出你刚才问了 Spring AI 的 Advisor说明 conversationId 隔离和记忆写入都正常。4.3 验证结构化输出Test void verifyStructuredOutput() { TechAnswer answer interviewService.structuredAnswer( 用一句话解释 Spring AI 的 BeanOutputConverter); assertNotNull(answer.getTitle()); assertNotNull(answer.getContent()); System.out.println(title answer.getTitle()); System.out.println(content answer.getContent()); }如果 title 和 content 都有值说明格式提示 Jackson 反序列化链路通了。这一步失败通常是模型没按 JSON 返回或者字段名对不上下一节专门讲排查。5. 本篇常见错排查5.1 401 或 403Key 没读到最常见的是环境变量没生效。检查TAOTOKEN_API_KEY是否在当前 shell 里 export 过IDEA 里跑测试要在 Run Configuration 的 Environment variables 里单独配。另外确认 base-url 结尾没有多余斜杠https://taotoken.net/api后面不要再加/v1否则路径会拼错。5.2 BeanOutputConverter 解析失败报错通常是JsonParseException或字段为 null。三个排查方向一是模型返回里带了 json 代码块标记BeanOutputConverter 会清洗但如果模型在 JSON 前后加了大段解释文字清洗可能不彻底解决方法是把 temperature 降到 0并在 SystemMessage 里强调只输出 JSON不要任何解释二是字段名不匹配模型返回student_name而 Java 字段是studentName加JsonProperty(student_name)兜底三是模型压根没返回 JSON检查converter.getFormat()有没有真的拼进 Prompt。5.3 Advisor 顺序不对导致记忆丢失如果 MessageChatMemoryAdvisor 排在 SimpleLoggerAdvisor 后面日志里看不到追加的历史消息但记忆本身还能用。真正会出问题的是把 MessageChatMemoryAdvisor 放在自定义的业务 Advisor 之后导致业务 Advisor 拿到的是没加历史的 Prompt。记住原则记忆 Advisor 尽量靠前日志、监控类 Advisor 靠后。5.4 conversationId 没传导致会话串了MessageChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID这个参数名容易拼错拼错时 Advisor 拿不到 ID会退化成默认会话多个用户的对话混在一起。验证方法用两个不同的 conversationId 各发一轮然后交叉提问如果答出了对方的上下文就是 ID 没生效。5.5 流式场景下 Advisor 行为异常流式调用时stream().chatResponse()返回FluxChatResponseMessageChatMemoryAdvisor 在流式模式下要等整个流结束后才写入记忆。如果你在流还没消费完就去查记忆会发现历史是空的。这不是 bug是流式语义决定的面试里被问到可以主动提这一点。6. 继续深入按场景选对入口配置骨架跑通之后下一步取决于你的目标。如果是在排查接入问题、想确认 Key 和 base-url 配对了去 API Keys 页面核对凭证再对照接入文档检查参数https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果只是想快速验证某个模型在 Message 角色、结构化输出上的表现直接用模型对话页面发几轮请求比写测试类快https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果你在搭长期编码 Agent、需要稳定的多轮记忆和 Advisor 链Coding Plan 更适合它把会话管理和配额都托管了https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。面试里被问到你怎么组织 Spring AI 项目结构我的答法是ChatModel 负责模型接入Message 负责语义分层BeanOutputConverter 负责结构化落地Advisor 负责横切逻辑四者职责不重叠。把这套骨架写进项目比背概念更能打动面试官。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。