Spring AI配置多个ChatModel后为什么总是调用默认模型?
文章摘要
Spring AI多模型项目中,Bean注入、ChatClient复用和路由结果传递任何一处出错,都会让所有流量落到默认模型。
一、问题为什么容易误判
项目已经配置快速、平衡和强模型,但实际调用始终不变。
常见表现包括:
- 启动时报Bean歧义
- 日志显示已路由但实际模型未变
- 备用模型从未命中
- 不同环境路由结果不同
这类问题不能只通过重复请求或更换模型解决。应先把调用链拆开,确认故障发生在输入、配置、状态、检索、工具、模型还是输出阶段。
二、完整调用链
用户请求 → Spring AI配置多个ChatModel后为什么总是调用默认模型前置处理 → 核心服务 → 模型/数据/工具 → 输出校验 → 用户
排查时要为每一段记录输入摘要、版本、耗时、错误类型和关联ID,避免只看最终异常。
三、最常见的根因
- 重新使用Builder创建了无路由客户端
- @Primary覆盖了预期Qualifier
- 路由Key与注册表不一致
- 条件Bean未在生产生效
- 路由结果只记录未参与选择
四、推荐排查顺序
- 列出全部ChatModel和ChatClient Bean
- 为客户端命名并使用Qualifier
- 建立统一ClientRegistry
- 记录requested_tier与actual_model
- 编写模型命中集成测试
一次只改变一个变量,并保留变更前后的Trace。否则即使问题消失,也无法确认真正原因。
五、核心实现示例
public RouteDecision route(AiTask task, TenantPolicy policy) {
if (task.highRisk()) return RouteDecision.powerful("高风险任务");
if (policy.remainingBudgetRatio() = 7
? RouteDecision.powerful("复杂任务")
: RouteDecision.balanced("默认路由");
}
示例只展示关键控制点。生产项目还应补充参数校验、异常映射、超时、重试边界、租户权限和审计字段。
六、需要记录的观测指标
- request_id与tenant_id
- 实际模型、Prompt和配置版本
- 阶段耗时与错误分类
- 重试、回退和取消次数
- 最终业务状态与成本
七、容易踩的误区
- 只看最终错误,不检查中间阶段
- 把所有异常都当成模型质量问题
- 同时修改多个配置后无法定位原因
- 在日志中记录完整敏感输入
- 没有为问题建立可回放测试样本
八、上线前检查清单
□ 完整调用链可追踪
□ 关键配置和版本进入Trace
□ 错误类型有稳定业务映射
□ 异常场景有自动化回归
□ 高风险失败默认拒绝
九、如何建立最小可复现环境
针对“Spring AI配置多个ChatModel后为什么总是调用默认模型?”这类问题,建议不要直接在生产环境反复修改配置。可以建立一个只包含单个入口、单个测试租户和固定测试数据的最小环境,并固定以下变量:
代码提交版本
Prompt版本
模型与Provider
配置中心版本
测试数据或索引版本
请求参数
预期结果
先在最小环境稳定复现,再逐层替换真实组件。每次实验只修改一个变量,并保存请求Trace、配置快照和输出差异。这样才能判断修复是来自代码、配置、模型、数据还是偶然波动。
十、修复后怎样灰度验证
修复不能只验证一条成功请求。推荐依次执行:
- 回放最初失败样本,确认问题不再出现;
- 运行同类边界样本,防止只修复表面现象;
- 使用影子流量比较修复前后的错误率、延迟和成本;
- 先对内部用户或低风险租户开放;
- 连续观察关键指标后再扩大流量;
- 保留旧配置和快速回滚开关。
发生过的故障还应进入回归测试集。只有能够自动阻止同类问题再次上线,排查工作才真正形成了工程资产。
总结
多模型路由必须在调用层真正选择不同客户端,并通过实际模型元数据验证。
延伸阅读
如果你正在关注企业级 AI 应用、Spring AI、RAG、Agent 与大模型工程化落地,欢迎访问 智元界:
https://www.zyentor.com/
智元界将持续分享可运行的技术实战、架构设计、问题排查与企业应用案例。