接大模型最危险的一行代码,是写在业务里的 baseUrl
2024 年到 2026 年,团队接大模型的方式变了好几轮:先是某家闭源 API,然后国产模型陆续可用,接着又有人要求本地私有化部署。价格、合规政策、可用性,几乎每个季度都在变。
于是很多项目里出现了这样的代码:
java
// 三年前没人预料到,这三行会变成技术债
String url = "https://api.xxx.com/v1/chat/completions";
String key = "sk-xxxxxxxx";
它不是 bug,运行得好好的。真正的代价出现在要换模型的时候------你会发现模型供应商的信息已经渗透进了 Service、Controller、甚至前端配置里,改动面比预估大一个数量级。
一、QuickBlue 的做法:模型配置化 + 工厂化
QuickBlue(原生 AI 微服务快速开发平台)在 QuickBlue-ai 服务(8084)里,用一张表加一层工厂解决了这件事。
第一步,把模型变成数据。 AiragModel 实体(airag_model 表)记录一个模型的全部信息:
| 字段 | 含义 |
|---|---|
provider |
供应商标识 |
modelName / modelType |
模型名称与类型(对话 / 嵌入等) |
baseUrl |
API 域名,私有化或中转地址填这里 |
credential |
凭证(百度千帆为 apiKey,secretKey 格式) |
modelParams |
JSON 参数:temperature / maxTokens / topP 等 |
sysOrgCode / tenantId |
部门与租户归属 |
activateFlag |
是否激活 |
第二步,用工厂把差异收进实现层。 ChatModelFactoryManager 在 Spring 启动时扫描所有 ChatModelFactory 实现,按 provider 注册进 ConcurrentHashMap:
java
for (ChatModelFactory factory : factories) {
factoryMap.put(factory.getProvider().toLowerCase(), factory);
}
目前内置 6 个工厂实现:OpenAiChatModelFactory、DashScopeChatModelFactory(通义千问)、ZhipuChatModelFactory(智谱)、QianfanChatModelFactory(百度千帆)、OllamaChatModelFactory(本地私有模型)、AnthropicChatModelFactory。
每个工厂统一产出三种能力:ChatModel(同步)、StreamingChatModel(流式)、EmbeddingModel(向量化)。业务侧只面对 ChatModelFactoryManager 一个入口,代码里没有一处 if (provider == ...)。
还有一个很实用的兜底:
java
factory = factoryMap.get("openai");
log.warn("未找到模型工厂: {}, 使用OpenAI兼容模式", provider);
任何自称 OpenAI 协议兼容的模型服务(各类中转、网关、本地 vLLM/Ollama 兼容端点),即使没有专属工厂,也能直接填 baseUrl 接进来。
二、切换模型,到底要动几下
答案是:一下,且不重启。
模型管理接口在 AiragModelController(/ai/model/**):
text
POST /ai/model # 新增模型(填 provider / baseUrl / credential / 参数)
PUT /ai/model/activate/{id} # 激活该模型
GET /ai/model/default # 读取当前默认模型
GET /ai/model/list # 列出已激活模型
也就是说,从"用云端大模型"切到"用本地 Ollama 私有模型"的完整操作是:在后台新增一条模型记录,baseUrl 填 http://内网地址:11434,modelName 填本地模型名,点激活。业务代码、配置文件、前端页面,一行都不用改。
三、为什么"中立"这件事值得被单独设计
因为它同时解决了三个不同角色关心的问题:
| 角色 | 关心的事 | 模型中立带来的结果 |
|---|---|---|
| 架构师 | 不想被厂商绑定 | 供应商是配置项,换厂商不改代码 |
| 合规/安全 | 数据能不能出境 | 可切到本地 Ollama 或私有化部署,数据不出内网 |
| 财务/管理者 | 成本能不能控 | 按场景选模型:贵的做复杂推理,便宜的做摘要分类 |
尤其第二条。当凭证集中存放在 airag_model.credential 字段里、而不是散落在各个 application.yml 与前端常量中,密钥随代码仓库泄露的风险面就被大幅收窄------这是很多团队在等保与代码审计环节被反复提的问题。
技术选型上,QuickBlue 基于 LangChain4j (dev.langchain4j)构建这一层,而不是自己写 HTTP 客户端拼协议。好处是协议演进由社区承担,新增供应商只是多写一个工厂类。
四、中立只是底座的一半
模型能换,只是前提;真正让 AI 产生业务价值的,是它上面那层:RAG 知识库 (AiragKnowledgeService,知识 / 记忆双类型 + 向量检索)、应用编排 (AiragApp,开场白、提示词、知识库关联、记忆开关、变量配置)、会话管理 (AiragSession / AiragMessage,多轮对话 + SSE 流式输出)。这三层都通过同一个工厂取模型,所以换模型时它们自动跟随,不需要各自适配。
五、上手
- 在线体验:ide.budaos.com
- (账号
admin,密码nq963369#),可直接进入 AI 模型 / 知识库 / 应用编排页面操作 - 本地搭建:README 快速搭建章节,向导式安装 10 分钟完成
- 接口文档:
http://localhost:8080/doc.html→QuickBlue-ai分组
**模型是发动机,可以随时换;底座是你自己的,不能换。**把发动机的接口标准化,才谈得上什么时候换都不慌。