Spring Boot 3 接入 AI 大模型实战:通用兼容架构设计与实现
本文分享一个基于 Spring Boot 3 的 AI 大模型开发框架,重点讲解如何通过通用兼容架构实现"一个模块接入10+大模型"的设计思路。
背景
在 Java 项目中接入 AI 大模型时,开发者通常面临以下问题:
- 每个大模型需要单独编写适配代码,维护成本高
- 不同模型的 API 格式差异大,切换模型需要重写业务逻辑
- 流式输出、工具调用、对话记忆等功能需要重复实现
基于这些问题,我设计了一个基于 OpenAI API 兼容标准 的通用架构,实现"配置即接入"的目标。
环境要求
- Java 17+
- Maven 3.6.3+
- Spring Boot 3.2+
架构设计思路
核心问题
目前主流大模型(豆包、通义千问、智谱、Kimi、DeepSeek 等)都兼容 OpenAI API 规范,只是 baseUrl 和认证方式不同。
解决方案
采用"通用兼容 + 特殊适配"的设计模式:
- 1 个通用模块
think-ai4j-provider-openai-compat处理所有 OpenAI 兼容模型 - 通过配置区分不同模型,无需编写额外代码
- 特殊签名协议的模型(如腾讯 TC3-HMAC-SHA256)单独建模块
架构图
think-ai4j/
├── think-ai4j-core/ # 核心模块:统一接口定义
├── think-ai4j-provider-openai-compat/ # 通用兼容模块:所有OpenAI格式模型
├── think-ai4j-memory/ # 内存记忆
├── think-ai4j-memory-redis/ # Redis 持久化记忆
├── think-ai4j-tool/ # 工具调用
├── think-ai4j-rag/ # RAG 检索增强
├── think-ai4j-agent/ # Agent 框架
├── think-ai4j-spring-boot-starter/ # Spring Boot 自动配置
└── think-ai4j-example/ # 示例项目
核心接口设计
ChatProvider 接口
所有大模型 Provider 都实现统一的接口:
public interface ChatProvider {
String getProviderName();
AiResponse chat(ChatRequest request);
Flux<String> stream(ChatRequest request);
}
业务代码只依赖接口,不依赖具体实现,实现模型自由切换。
通用兼容 Provider 实现
核心实现思路是:
- 从配置中读取
baseUrl、apiKey、model - 构建标准 OpenAI 格式的 HTTP 请求
- 解析标准 OpenAI 格式的响应
public class OpenAiCompatProvider implements ChatProvider {
private final String providerName;
private final String baseUrl;
private final String defaultModel;
private final String apiKey;
private final OkHttpClient httpClient;
@Override
public AiResponse chat(ChatRequest request) {
String requestBody = buildRequestBody(request, false);
Request httpRequest = new Request.Builder()
.url(baseUrl + "/chat/completions")
.header("Authorization", "Bearer " + apiKey)
.post(RequestBody.create(requestBody, JSON))
.build();
try (Response response = httpClient.newCall(httpRequest).execute()) {
return parseResponse(response.body().string());
}
}
}
HTTP 连接池优化
为了保证高性能,共享 OkHttp 连接池:
think:
ai:
compat:
httpClient:
connectionPool:
max-idle-connections: 50
keep-alive-minutes: 5
timeout:
connect-seconds: 30
read-seconds: 60
Spring Boot 自动配置
通过 Spring Boot Starter 实现零配置集成:
@Configuration
@ConditionalOnClass(OpenAiCompatProvider.class)
@ConditionalOnProperty(prefix = "think.ai.compat", name = "providers")
static class OpenAiCompatAutoConfiguration {
@Bean
public List<ChatProvider> openAiCompatProviders(OpenAiCompatConfig config) {
return config.getProviders().stream()
.<ChatProvider>map(providerConfig ->
new OpenAiCompatProvider(providerConfig, config.getHttpClient()))
.toList();
}
}
配置文件中的每个 provider 自动注册为 Bean,并注入到 ChatProviderRegistry。
实战接入
配置文件
think:
ai:
default-provider: doubao
compat:
providers:
- name: doubao
baseUrl: https://ark.cn-beijing.volces.com/api/v3
apiKey: your-api-key
model: ep-xxxxx
- name: moonshot
baseUrl: https://api.moonshot.cn/v1
apiKey: your-api-key
model: moonshot-v1-8k
memory:
type: memory
max-messages: 20
新增模型只需加一段配置,无需改代码。
简单对话
@Autowired
private AiChat chat;
String result = chat.ask("你好");
带系统提示词
String result = chat.system("你是Java专家").ask("如何设计单例模式?");
流式输出
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> stream(@RequestParam String q) {
return chat.stream(q);
}
切换模型
String result = chat.provider("glm").ask("你好");
进阶功能
工具调用(Function Calling)
通过 @AiTool 注解,让 AI 可以调用你的 Java 方法:
@Component
public class WeatherTool {
@AiTool("查询天气")
public String getWeather(@ToolParam(description = "城市名称") String city) {
return "晴天,25度";
}
}
框架会自动将方法元信息转换为 OpenAI 的 tool 格式,并处理调用流程。
对话记忆
支持内存记忆和 Redis 持久化记忆:
think:
ai:
memory:
type: redis
max-messages: 50
ttl-minutes: 120
@Autowired
private ChatMemory memory;
memory.addMessage("user-123", AiMessage.user("我叫小明"));
List<AiMessage> history = memory.getMessages("user-123");
RAG 文档问答
@Autowired
private RagPipeline ragPipeline;
ragPipeline.ingest(List.of(
new Document("公司规定年假为15天"),
new Document("加班费按每小时100元计算")
));
String answer = ragPipeline.query("年假有多少天?");
Agent 智能代理
Agent agent = new Agent("助手", "你是一个专业的助手", chat)
.addToolBean(new WeatherTool())
.addToolBean(new SearchTool());
String result = agent.execute("北京天气如何?");
技术细节
流式输出实现
基于 OkHttp SSE + Reactor Flux 实现:
@Override
public Flux<String> stream(ChatRequest request) {
return Flux.create(sink -> {
EventSourceListener listener = new EventSourceListener() {
@Override
public void onEvent(EventSource eventSource, String id, String type, String data) {
if ("[DONE]".equals(data)) {
sink.complete();
return;
}
JsonNode jsonNode = objectMapper.readTree(data);
String content = jsonNode.get("choices").get(0).get("delta").get("content").asText();
sink.next(content);
}
};
EventSources.createFactory(httpClient).newEventSource(httpRequest, listener);
});
}
错误处理
- HTTP 异常:包装为
AiException,携带 provider 名称和错误码 - 解析异常:记录日志并抛出详细错误信息
- 流式失败:区分 response 为 null 和 t.getMessage() 的情况
空指针防护
在响应解析中增加多层 null 检查:
JsonNode contentNode = message.get("content");
if (contentNode != null && !contentNode.isNull()) {
response.setContent(contentNode.asText());
}
总结
通过通用兼容架构,实现了:
- 配置即接入:新增大模型只需改配置文件,无需编写代码
- 接口统一:业务代码只依赖
AiChat接口,不关心底层实现 - 高性能:共享 OkHttp 连接池,可配置超时参数
- 功能完整:支持同步对话、流式输出、工具调用、记忆、RAG、Agent
对于 Java 开发者来说,这种架构可以大大降低接入 AI 大模型的成本。
源码地址
- Gitee: https://gitee.com/hongxinge/think-ai4j
- GitHub: https://github.com/hongxinge/ThinkAi4j
代码已开源,欢迎交流讨论。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)