你以前做支付系统时微信支付挂了自动切支付宝——恭喜你已经会多模型策略了。一个模型不够用第2讲我们用一个DeepSeek跑通了所有示例感觉好像一个模型就够了。但一进生产环境你马上会遇到这几个问题场景问题你在Java里见过吗文档总结需要高质量输出DeepSeek便宜但不够好通义千问贵但质量高核心支付走银联小额走微信模型厂商API偶尔挂掉所有请求全部失败用户骂娘主库挂了没有从库全站500一个API Key额度用完突然开始403半夜被叫起来充钱短信通道余额不足验证码发不出去不同场景对速度/成本要求不同用通义做简单问题改写太贵用豆包做深度总结质量不够高并发缓存读Redis复杂查询走MySQL多模型策略不是锦上添花而是生产必需。本质上你需要一层路由抽象把业务代码和具体模型解耦。这个概念对Java工程师来说根本不陌生——它就是策略模式。策略模式从支付渠道到模型路由先回忆一下你做支付系统时的代码// Java支付系统——策略模式publicinterfacePaymentStrategy{PayResultpay(PayRequestrequest);}Service(wechatPay)publicclassWechatPayStrategyimplementsPaymentStrategy{publicPayResultpay(PayRequestrequest){/* 调微信支付API */}}Service(alipay)publicclassAlipayStrategyimplementsPaymentStrategy{publicPayResultpay(PayRequestrequest){/* 调支付宝API */}}// 路由根据业务场景选择支付渠道ServicepublicclassPaymentRouter{AutowiredprivateMapString,PaymentStrategystrategyMap;publicPayResultroute(Stringchannel,PayRequestrequest){returnstrategyMap.get(channel).pay(request);}}现在把支付渠道换成大模型// AI应用——策略模式一模一样的结构publicinterfaceLlmStrategy{Stringchat(Stringprompt);}Service(deepseek)publicclassDeepSeekStrategyimplementsLlmStrategy{publicStringchat(Stringprompt){/* 调DeepSeek API */}}Service(qwen)publicclassQwenStrategyimplementsLlmStrategy{publicStringchat(Stringprompt){/* 调通义千问API */}}// 路由根据业务场景选择模型ServicepublicclassLlmRouter{AutowiredprivateMapString,LlmStrategystrategyMap;publicStringroute(Stringscene,Stringprompt){StringmodelNamesceneModelMapping.get(scene);returnstrategyMap.get(modelName).chat(prompt);}}对照表支付系统多模型系统共同的设计模式PaymentStrategyLlmStrategy策略接口WechatPay / AlipayDeepSeek / Qwen / Doubao策略实现PaymentRouterLlmRouter路由分发支付渠道配置表场景-模型映射表配置驱动微信挂了切支付宝通义挂了切豆包自动降级Fallback结构完全一样只是调用的外部服务从银行变成了大模型。如果你做过支付渠道切换、短信通道路由、或者任何多供应商的系统那你已经理解了多模型策略的核心思想。三种多模型场景场景一按业务路由——不同的活派给不同的模型这是最常见的场景。不同业务对模型的要求不同文档总结质量优先 → 通义千问qwen3-max贵但输出质量高 知识检索速度优先 → 字节豆包doubao-1-6便宜快速够用就行 问题改写轻量任务 → 字节豆包doubao-1-6改写不需要多强的模型 联网搜索需要插件 → 通义千问qwen3-max-search自带搜索能力Java类比跟你在电商系统里大额走银联、小额走微信、跨境走PayPal完全一样。场景二自动降级——主模型挂了切备用模型厂商的API不是百分百可靠。通义千问维护了、豆包限流了你的系统不能跟着挂。主模型通义千问→ 调用失败 → 自动切到备用豆包→ 还失败 → 切兜底DeepSeekJava类比跟MySQL主从切换、Redis Sentinel哨兵模式一个逻辑。场景三负载均衡——分散调用量当调用量大时单个模型/Key的QPS上限会成为瓶颈。把请求分散到多个模型或多个API Key上。请求1 → 通义千问Key-A 请求2 → 通义千问Key-B 请求3 → 通义千问Key-C ← 三个Key轮询单Key压力降为1/3Java类比Nginx的upstream轮询、Ribbon的负载均衡、甚至数据库连接池。LangChain4j实现多模型配置在第2讲中我们的application.yml只配了一个模型。现在扩展为多模型# application.yml —— 多模型配置app:llm:# 模型定义每个模型一套连接参数models:deepseek:base-url:https://api.deepseek.comapi-key:${DEEPSEEK_API_KEY}model-name:deepseek-chattemperature:0.7max-tokens:4096qwen:base-url:https://dashscope.aliyuncs.com/compatible-mode/v1api-key:${QWEN_API_KEY}model-name:qwen3-maxtemperature:0.7max-tokens:8192doubao:base-url:https://ark.cn-beijing.volces.com/api/v3api-key:${DOUBAO_API_KEY}model-name:doubao-seed-1-6-251015temperature:0.7max-tokens:4096# 场景-模型映射业务代码只写场景名具体模型由这里决定scene-mapping:summary:qwen# 文档总结 → 通义质量优先retrieval:doubao# 知识检索 → 豆包速度优先rewrite:doubao# 问题改写 → 豆包轻量任务chat:deepseek# 通用对话 → DeepSeek性价比注意这个设计的关键点模型定义和场景映射分离。模型定义管有哪些模型可用场景映射管哪个场景用哪个模型。想切换模型改一行YAML就完事不碰Java代码。配置类ConfigurationConfigurationProperties(prefixapp.llm)DatapublicclassLlmProperties{/** 模型定义 */privateMapString,ModelConfigmodels;/** 场景→模型映射 */privateMapString,StringsceneMapping;DatapublicstaticclassModelConfig{privateStringbaseUrl;privateStringapiKey;privateStringmodelName;privateDoubletemperature;privateIntegermaxTokens;}}模型工厂一次性创建所有模型实例ConfigurationpublicclassLlmModelFactory{BeanpublicMapString,ChatLanguageModelchatModelMap(LlmPropertiesproperties){MapString,ChatLanguageModelmodelMapnewHashMap();properties.getModels().forEach((name,config)-{ChatLanguageModelmodelOpenAiChatModel.builder().baseUrl(config.getBaseUrl()).apiKey(config.getApiKey()).modelName(config.getModelName()).temperature(config.getTemperature()).maxTokens(config.getMaxTokens()).build();modelMap.put(name,model);});returnmodelMap;}}这里用的是OpenAiChatModel——同一个类接所有模型。为什么因为DeepSeek、通义千问、豆包全都实现了OpenAI兼容API格式/chat/completions所以只需要改baseUrl和apiKey就能切换厂商。这个设计在后面的生产实录里会详细展开。场景路由器ServicepublicclassLlmRouter{privatefinalMapString,ChatLanguageModelchatModelMap;privatefinalLlmPropertiesproperties;publicLlmRouter(MapString,ChatLanguageModelchatModelMap,LlmPropertiesproperties){this.chatModelMapchatModelMap;this.propertiesproperties;}/** * 根据业务场景路由到对应模型 * 跟 PaymentRouter.route(wechat, request) 一模一样 */publicStringchat(Stringscene,Stringprompt){// 1. 查场景→模型映射类似查支付渠道配置表StringmodelNameproperties.getSceneMapping().get(scene);if(modelNamenull){modelNamedeepseek;// 兜底默认模型}// 2. 获取对应模型实例ChatLanguageModelmodelchatModelMap.get(modelName);// 3. 调用returnmodel.generate(prompt);}}业务代码中使用RestControllerRequestMapping(/ai)publicclassSmartChatController{AutowiredprivateLlmRouterllmRouter;GetMapping(/summary)publicStringsummary(RequestParamStringtext){// 业务代码只写我要做总结具体用哪个模型不关心returnllmRouter.chat(summary,请总结以下内容text);}GetMapping(/rewrite)publicStringrewrite(RequestParamStringquery){// 问题改写场景配置指向了doubaoreturnllmRouter.chat(rewrite,请改写以下问题query);}}自动降级Fallback路由解决了正常情况下用哪个模型的问题但如果模型挂了怎么办你需要一个Fallback机制。ServicepublicclassResilientLlmRouter{privatefinalMapString,ChatLanguageModelchatModelMap;privatefinalLlmPropertiesproperties;/** 降级链主模型 → 备用模型列表 */privatefinalMapString,ListStringfallbackChainMap.of(qwen,List.of(deepseek,doubao),// 通义挂了 → 先试DeepSeek → 再试豆包deepseek,List.of(qwen,doubao),doubao,List.of(deepseek,qwen));publicStringchatWithFallback(Stringscene,Stringprompt){StringprimaryModelproperties.getSceneMapping().get(scene);// 先试主模型try{returnchatModelMap.get(primaryModel).generate(prompt);}catch(Exceptione){log.warn(主模型[{}]调用失败: {},primaryModel,e.getMessage());}// 主模型失败按降级链依次尝试ListStringfallbacksfallbackChain.getOrDefault(primaryModel,List.of(deepseek));for(StringfallbackModel:fallbacks){try{log.info(降级到备用模型: {},fallbackModel);returnchatModelMap.get(fallbackModel).generate(prompt);}catch(Exceptione){log.warn(备用模型[{}]也失败: {},fallbackModel,e.getMessage());}}// 所有模型都挂了——这很少见但必须处理thrownewRuntimeException(所有LLM模型均不可用请检查API状态);}}Java类比理解Sentinel限流降级 LLM自动降级 ────────────── ────────── 主调用 → Service A 主调用 → 通义千问 降级 → fallback方法 降级 → 切到DeepSeek 再降级 → 返回兜底数据 再降级 → 切到豆包 全挂 → 触发告警 全挂 → 抛异常 告警如果你用过Spring Cloud的SentinelResource或Hystrix的HystrixCommand这个降级链的逻辑你一定不陌生。生产实录实录一配置驱动的场景-模型映射在我们的生产项目中我们用YAML配置了完整的场景-模型映射跟上面的代码几乎一模一样# 配置结构示例基于生产实践整理scene-model:properties:knowledgeSummary:qwen3-max# 文档AI总结 → 通义大杯质量优先knowledgeRetrieval:doubao-1-6# 知识库检索 → 豆包速度优先queryRewrite:doubao-1-6# 问题改写 → 豆包轻量任务够用internetSearch:qwen3-max-search# 联网搜索 → 通义搜索插件documentTagging:doubao-1-6# 文档打标签 → 豆包updateChatName:doubao-1-6# 更新会话标题 → 豆包knowledgeTagExtract:qwen3-max# 标签提取 → 通义需要理解能力imageDesc:doubao-1-6# 图片理解 → 豆包VLJava代码中用常量类定义所有场景名防止字符串散落// 来自生产项目的SceneConstant.javapublicinterfaceSceneConstant{interfaceScene{StringKNOWLEDGE_SUMMARYknowledgeSummary;StringKNOWLEDGE_RETRIEVALknowledgeRetrieval;StringQUERY_REWRITEqueryRewrite;StringINTERNET_SEARCHinternetSearch;StringDOCUMENT_TAGGINGdocumentTagging;StringUPDATE_CHAT_NAMEupdateChatName;// ...其他场景}}这个设计的好处是什么运营说文档总结效果不行换个更好的模型——运维改一行YAML重启服务业务代码一行不动。开发说豆包新出了1.8版本想试试——在模型定义里加一个doubao1p8场景映射指过去就行。关键心法业务代码只认场景别名如knowledgeSummary绝不硬编码模型名。跟你做支付系统时业务代码只认payChannel不直接写微信还是支付宝是同一个道理。实录二所有模型统一走OpenAI兼容格式我们的生产项目接入了三家模型厂商字节豆包、阿里通义、百度千帆。按传统思维每家的API不一样得写三套调用代码。但实际上我们只写了一套# 字节豆包 —— /chat/completionsdoubao-1-6:url:https://ark.cn-beijing.volces.com/api/v3/chat/completionsmodel:doubao-seed-1-6-251015# 阿里通义 —— /chat/completionsqwen3-max:url:https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completionsmodel:qwen3-max# 百度千帆 —— /chat/completionsqianfan:url:https://qianfan.baidubce.com/v2/chat/completionsmodel:ernie-3.5-8k三个厂商三个不同的域名但API格式完全一样——都是POST /chat/completions请求体和响应体都遵循OpenAI的格式规范。这意味着切模型只需要改URL API Key调用代码零修改LangChain4j的OpenAiChatModel通吃所有厂商不需要引入各家的专属SDK新增模型厂商零开发成本——只要它也支持OpenAI兼容格式目前国内主流厂商都支持这就是为什么第2讲让你用langchain4j-open-ai而不是langchain4j-deepseek——因为前者是通用钥匙一把开所有锁。实录三LLM模型网关我们另一个项目更进一步做了一个独立的LLM网关服务llm-gateway所有模型调用都经过这个网关业务服务A ──┐ 业务服务B ──┤──→ LLM Gateway ──→ 豆包API / 通义API / 千帆API 业务服务C ──┘ │ ├── 多API Key池管理Key-A额度用完自动切Key-B ├── 按渠道分发不同租户走不同Key池 ├── 调用计费记录每次token消耗 ├── Token缓存与自动刷新双重检查锁防并发 └── 统一错误处理资源点不足/敏感拦截/限流这个网关做的事情本质上就是一个模型层面的API Gateway——你可以类比成Nginx或Spring Cloud Gateway只不过它代理的不是HTTP接口而是LLM调用。对于个人项目或中小团队不需要做这么重。但架构思维值得学习当你的系统接入了3个以上的模型厂商、有5个以上的API Key需要管理时一个统一的网关层会让运维轻松很多。本讲要点多模型策略 策略模式——跟你做支付渠道切换、短信通道路由一模一样的设计模式三种场景按业务路由不同活不同模型、自动降级挂了切备用、负载均衡分散调用量配置驱动模型定义和场景映射分离切模型改YAML不改代码OpenAI兼容格式国内主流厂商豆包/通义/千帆/DeepSeek都支持/chat/completions一个OpenAiChatModel通吃降级链主模型→备用1→备用2→兜底异常跟Sentinel/Hystrix的降级逻辑完全一致生产级最佳实践场景别名用常量类管理、多API Key池轮询、统一网关层动手练习基础参照本讲代码配置DeepSeek 通义千问两个模型实现LlmRouter的场景路由——summary走通义chat走DeepSeek进阶给ResilientLlmRouter加一个功能——调用失败时记录失败次数连续失败3次的模型自动熔断60秒提示用一个ConcurrentHashMapString, AtomicInteger记录失败次数再加一个时间戳判断熔断窗口思考题如果你要实现多API Key轮询——同一个模型有3个Key轮流使用——你会怎么设计跟数据库连接池有什么异同下一讲预告第5讲Prompt Engineering——给LLM写需求文档你以为写提示词很简单当你需要让LLM稳定输出JSON格式、精确执行指令、避免胡说八道时Prompt设计就成了一门工程学科。第5讲将用LangChain4j的PromptTemplate实现参数化Prompt并分享生产中踩过的Prompt调优大坑。从第5讲开始课程正式进入RAG核心区——Prompt工程、RAG全链路、文档解析、向量检索、Agent工作流……这些才是AI应用开发中最值钱的技能也是面试中被问得最多的部分。「Java转AI实战」完整目录共16讲讲次标题阶段第1讲Java工程师的AI转型地图LLM基础第2讲开发环境搭建与第一次LLM调用LLM基础第3讲流式输出——LLM的分页查询LLM基础第4讲多模型策略——LLM的负载均衡本文LLM基础第5讲Prompt Engineering——给LLM写需求文档RAG核心第6讲RAG全景——为什么LLM需要开卷考试RAG核心第7讲文档解析——把非结构化数据变成可检索的文本RAG核心第8讲智能切分——文档的分库分表RAG核心第9讲Embedding向量化——文本的序列化RAG核心第10讲检索策略——从SQL查询到语义搜索RAG核心第11讲端到端RAG应用——把前5讲串起来RAG核心第12讲从对话到行动——Agent是什么Agent实战第13讲MCP协议——AI的标准API网关Agent实战第14讲Agent实战——构建一个能执行任务的AI助手Agent实战第15讲从Demo到生产——你的Java经验在这里爆发生产进阶第16讲转型行动指南——从会了到找到AI工作求职落地前4讲LLM基础已免费发布。第5讲起进入RAG核心区——这是整个课程最硬核、信息密度最高的部分也是AI应用开发面试中被问到最多的内容。获取完整课程 持续更新的AI实战内容你已经读完了免费的前4讲。如果你的感受是原来AI应用开发跟我想的不一样这些设计模式我确实都用过——那说明这个系列适合你。但说实话前4讲只是开胃菜。真正的硬菜从第5讲开始Prompt工程怎么让LLM稳定输出JSON、RAG检索链路中文档切分 → 向量化 → 混合检索 → Rerank精排每一步的工程实现、Agent工作流引擎的责任链设计、MCP协议的服务注册与工具调用——这些内容全部配有真实生产项目的代码和架构图不是理论概念堆砌是一线工程师的生产实录。完整的16讲课程和持续更新的AI实战内容都在知识星球**「Java转AI实战内参」**里。除了课程本身星球里还有生产案例持续更新每周分享RAG/Agent/MCP的实战踩坑和解决方案真实项目架构拆解教育行业AI助手平台的完整设计文档和核心代码解析面试题库与模拟面试Java转AI岗的高频面试题 答题思路 项目经验包装一对一答疑技术问题、简历优化、职业规划有问必答星球定价199/年首年限时优惠99元——不到一顿火锅钱。如果你正在认真考虑从Java转型AI应用开发这199块的投入可能是你今年最值的一笔。