From 45226d78ad5d481b37a78c65bc3c3906dc638f2d Mon Sep 17 00:00:00 2001
From: choweli <1030848819@qq.com>
Date: Tue, 13 May 2025 10:14:36 +0800
Subject: [PATCH 1/2] =?UTF-8?q?=E6=96=B0=E5=A2=9Ehutool-ai=E6=A8=A1?=
=?UTF-8?q?=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README-EN.md | 43 +--
README.md | 43 +--
hutool-ai/pom.xml | 45 +++
.../main/java/cn/hutool/ai/AIException.java | 87 +++++
.../java/cn/hutool/ai/AIServiceFactory.java | 80 ++++
.../src/main/java/cn/hutool/ai/AIUtil.java | 129 +++++++
.../src/main/java/cn/hutool/ai/ModelName.java | 57 +++
.../src/main/java/cn/hutool/ai/Models.java | 157 ++++++++
.../main/java/cn/hutool/ai/core/AIConfig.java | 113 ++++++
.../cn/hutool/ai/core/AIConfigBuilder.java | 118 ++++++
.../cn/hutool/ai/core/AIConfigRegistry.java | 52 +++
.../java/cn/hutool/ai/core/AIService.java | 47 +++
.../cn/hutool/ai/core/AIServiceProvider.java | 44 +++
.../java/cn/hutool/ai/core/BaseAIService.java | 105 ++++++
.../java/cn/hutool/ai/core/BaseConfig.java | 84 +++++
.../main/java/cn/hutool/ai/core/Message.java | 59 +++
.../java/cn/hutool/ai/core/package-info.java | 24 ++
.../ai/model/deepseek/DeepSeekCommon.java | 27 ++
.../ai/model/deepseek/DeepSeekConfig.java | 49 +++
.../ai/model/deepseek/DeepSeekProvider.java | 39 ++
.../ai/model/deepseek/DeepSeekService.java | 53 +++
.../model/deepseek/DeepSeekServiceImpl.java | 117 ++++++
.../ai/model/deepseek/package-info.java | 24 ++
.../hutool/ai/model/doubao/DoubaoCommon.java | 111 ++++++
.../hutool/ai/model/doubao/DoubaoConfig.java | 49 +++
.../ai/model/doubao/DoubaoProvider.java | 39 ++
.../hutool/ai/model/doubao/DoubaoService.java | 195 ++++++++++
.../ai/model/doubao/DoubaoServiceImpl.java | 354 ++++++++++++++++++
.../hutool/ai/model/doubao/package-info.java | 24 ++
.../cn/hutool/ai/model/grok/GrokCommon.java | 44 +++
.../cn/hutool/ai/model/grok/GrokConfig.java | 50 +++
.../cn/hutool/ai/model/grok/GrokProvider.java | 39 ++
.../cn/hutool/ai/model/grok/GrokService.java | 115 ++++++
.../hutool/ai/model/grok/GrokServiceImpl.java | 193 ++++++++++
.../cn/hutool/ai/model/grok/package-info.java | 24 ++
.../hutool/ai/model/openai/OpenaiCommon.java | 86 +++++
.../hutool/ai/model/openai/OpenaiConfig.java | 49 +++
.../ai/model/openai/OpenaiProvider.java | 39 ++
.../hutool/ai/model/openai/OpenaiService.java | 206 ++++++++++
.../ai/model/openai/OpenaiServiceImpl.java | 308 +++++++++++++++
.../hutool/ai/model/openai/package-info.java | 24 ++
.../java/cn/hutool/ai/model/package-info.java | 24 ++
.../main/java/cn/hutool/ai/package-info.java | 24 ++
.../services/cn.hutool.ai.core.AIConfig | 4 +
.../cn.hutool.ai.core.AIServiceProvider | 4 +
.../src/test/java/AIServiceFactoryTest.java | 41 ++
hutool-ai/src/test/java/AIUtilTest.java | 87 +++++
.../model/deepseek/DeepSeekServiceTest.java | 73 ++++
.../ai/model/doubao/DoubaoServiceTest.java | 196 ++++++++++
.../hutool/ai/model/grok/GrokServiceTest.java | 123 ++++++
.../ai/model/openai/OpenaiServiceTest.java | 168 +++++++++
hutool-all/pom.xml | 5 +
pom.xml | 1 +
53 files changed, 4253 insertions(+), 42 deletions(-)
create mode 100644 hutool-ai/pom.xml
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/AIException.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/AIUtil.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/ModelName.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/Models.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/AIConfig.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigBuilder.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/AIService.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/AIServiceProvider.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/BaseAIService.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/BaseConfig.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/Message.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/core/package-info.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekCommon.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekConfig.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekProvider.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekService.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekServiceImpl.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/package-info.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoCommon.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoConfig.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoProvider.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoService.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoServiceImpl.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/doubao/package-info.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/grok/GrokCommon.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/grok/GrokConfig.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/grok/GrokProvider.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/grok/GrokService.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/grok/GrokServiceImpl.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/grok/package-info.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/openai/OpenaiCommon.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/openai/OpenaiConfig.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/openai/OpenaiProvider.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/openai/OpenaiService.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/openai/OpenaiServiceImpl.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/openai/package-info.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/model/package-info.java
create mode 100644 hutool-ai/src/main/java/cn/hutool/ai/package-info.java
create mode 100644 hutool-ai/src/main/resources/META-INF/services/cn.hutool.ai.core.AIConfig
create mode 100644 hutool-ai/src/main/resources/META-INF/services/cn.hutool.ai.core.AIServiceProvider
create mode 100644 hutool-ai/src/test/java/AIServiceFactoryTest.java
create mode 100644 hutool-ai/src/test/java/AIUtilTest.java
create mode 100644 hutool-ai/src/test/java/cn/hutool/ai/model/deepseek/DeepSeekServiceTest.java
create mode 100644 hutool-ai/src/test/java/cn/hutool/ai/model/doubao/DoubaoServiceTest.java
create mode 100644 hutool-ai/src/test/java/cn/hutool/ai/model/grok/GrokServiceTest.java
create mode 100644 hutool-ai/src/test/java/cn/hutool/ai/model/openai/OpenaiServiceTest.java
diff --git a/README-EN.md b/README-EN.md
index aa70c0820..7e118bf2f 100755
--- a/README-EN.md
+++ b/README-EN.md
@@ -86,27 +86,28 @@ Hutool exists to reduce code search costs and avoid bugs caused by imperfect cod
## 🛠️Module
A Java-based tool class for files, streams, encryption and decryption, transcoding, regular, thread, XML and other JDK methods for encapsulation,composing various Util tool classes, as well as providing the following modules:
-| module | description |
-| -------------------|-------------------------------------------------------------------------------------------------------------------------|
-| hutool-aop | JDK dynamic proxy encapsulation to provide non-IOC faceting support |
-| hutool-bloomFilter | Bloom filtering to provide some Hash algorithm Bloom filtering |
-| hutool-cache | Simple cache |
-| hutool-core | Core, including Bean operations, dates, various Utils, etc. |
-| hutool-cron | Task scheduling with Cron expressions |
-| hutool-crypto | Provides symmetric, asymmetric and digest algorithm encapsulation |
-| hutool-db | Db operations based on ActiveRecord thinking. |
-| hutool-dfa | DFA models, such as multi-keyword lookups |
-| hutool-extra | Extension modules, third-party wrappers (template engine, mail, servlet, QR code, Emoji, FTP, word splitting, etc.) |
-| hutool-http | Http client |
-| hutool-log | Log (facade) |
-| hutool-script | Script execution encapsulation, e.g. Javascript |
-| hutool-setting | Stronger Setting Profile tools and Properties tools |
-| hutool-system | System parameter tools (JVM information, etc.) |
-| hutool-json | JSON |
-| hutool-captcha | Image Captcha |
-| hutool-poi | Tools for working with Excel and Word in POI |
-| hutool-socket | Java-based tool classes for NIO and AIO sockets |
-| hutool-jwt | JSON Web Token (JWT) implement |
+| module | description |
+|--------------------|---------------------------------------------------------------------------------------------------------------------|
+| hutool-aop | JDK dynamic proxy encapsulation to provide non-IOC faceting support |
+| hutool-bloomFilter | Bloom filtering to provide some Hash algorithm Bloom filtering |
+| hutool-cache | Simple cache |
+| hutool-core | Core, including Bean operations, dates, various Utils, etc. |
+| hutool-cron | Task scheduling with Cron expressions |
+| hutool-crypto | Provides symmetric, asymmetric and digest algorithm encapsulation |
+| hutool-db | Db operations based on ActiveRecord thinking. |
+| hutool-dfa | DFA models, such as multi-keyword lookups |
+| hutool-extra | Extension modules, third-party wrappers (template engine, mail, servlet, QR code, Emoji, FTP, word splitting, etc.) |
+| hutool-http | Http client |
+| hutool-log | Log (facade) |
+| hutool-script | Script execution encapsulation, e.g. Javascript |
+| hutool-setting | Stronger Setting Profile tools and Properties tools |
+| hutool-system | System parameter tools (JVM information, etc.) |
+| hutool-json | JSON |
+| hutool-captcha | Image Captcha |
+| hutool-poi | Tools for working with Excel and Word in POI |
+| hutool-socket | Java-based tool classes for NIO and AIO sockets |
+| hutool-jwt | JSON Web Token (JWT) implement |
+| hutool-ai | AI implement |
Each module can be introduced individually, or all modules can be introduced by introducing `hutool-all` as required.
diff --git a/README.md b/README.md
index cd1ef3981..31c9b26f6 100755
--- a/README.md
+++ b/README.md
@@ -74,27 +74,28 @@ Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu
## 🛠️包含组件
一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件:
-| 模块 | 介绍 |
-| -------------------|---------------------------------------------------------------------------------- |
-| hutool-aop | JDK动态代理封装,提供非IOC下的切面支持 |
-| hutool-bloomFilter | 布隆过滤,提供一些Hash算法的布隆过滤 |
-| hutool-cache | 简单缓存实现 |
-| hutool-core | 核心,包括Bean操作、日期、各种Util等 |
-| hutool-cron | 定时任务模块,提供类Crontab表达式的定时任务 |
-| hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
-| hutool-db | JDBC封装后的数据操作,基于ActiveRecord思想 |
-| hutool-dfa | 基于DFA模型的多关键字查找 |
-| hutool-extra | 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等) |
-| hutool-http | 基于HttpUrlConnection的Http客户端封装 |
-| hutool-log | 自动识别日志实现的日志门面 |
-| hutool-script | 脚本执行封装,例如Javascript |
-| hutool-setting | 功能更强大的Setting配置文件和Properties封装 |
-| hutool-system | 系统参数调用封装(JVM信息等) |
-| hutool-json | JSON实现 |
-| hutool-captcha | 图片验证码实现 |
-| hutool-poi | 针对POI中Excel和Word的封装 |
-| hutool-socket | 基于Java的NIO和AIO的Socket封装 |
-| hutool-jwt | JSON Web Token (JWT)封装实现 |
+| 模块 | 介绍 |
+|--------------------|------------------------------------------------|
+| hutool-aop | JDK动态代理封装,提供非IOC下的切面支持 |
+| hutool-bloomFilter | 布隆过滤,提供一些Hash算法的布隆过滤 |
+| hutool-cache | 简单缓存实现 |
+| hutool-core | 核心,包括Bean操作、日期、各种Util等 |
+| hutool-cron | 定时任务模块,提供类Crontab表达式的定时任务 |
+| hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
+| hutool-db | JDBC封装后的数据操作,基于ActiveRecord思想 |
+| hutool-dfa | 基于DFA模型的多关键字查找 |
+| hutool-extra | 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等) |
+| hutool-http | 基于HttpUrlConnection的Http客户端封装 |
+| hutool-log | 自动识别日志实现的日志门面 |
+| hutool-script | 脚本执行封装,例如Javascript |
+| hutool-setting | 功能更强大的Setting配置文件和Properties封装 |
+| hutool-system | 系统参数调用封装(JVM信息等) |
+| hutool-json | JSON实现 |
+| hutool-captcha | 图片验证码实现 |
+| hutool-poi | 针对POI中Excel和Word的封装 |
+| hutool-socket | 基于Java的NIO和AIO的Socket封装 |
+| hutool-jwt | JSON Web Token (JWT)封装实现 |
+| hutool-ai | AI大模型封装实现 |
可以根据需求对每个模块单独引入,也可以通过引入`hutool-all`方式引入所有模块。
diff --git a/hutool-ai/pom.xml b/hutool-ai/pom.xml
new file mode 100644
index 000000000..43816e5aa
--- /dev/null
+++ b/hutool-ai/pom.xml
@@ -0,0 +1,45 @@
+
+
+ 4.0.0
+
+ cn.hutool
+ hutool-parent
+ 5.8.38-SNAPSHOT
+
+
+ hutool-ai
+ ${project.artifactId}
+ Hutool AI大模型封装
+
+
+ cn.hutool.ai
+
+
+
+
+ cn.hutool
+ hutool-core
+ ${project.parent.version}
+
+
+ cn.hutool
+ hutool-http
+ ${project.parent.version}
+
+
+ cn.hutool
+ hutool-log
+ ${project.parent.version}
+ compile
+
+
+ cn.hutool
+ hutool-json
+ ${project.parent.version}
+ compile
+
+
+
+
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/AIException.java b/hutool-ai/src/main/java/cn/hutool/ai/AIException.java
new file mode 100644
index 000000000..57bad86ad
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/AIException.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai;
+
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 异常处理类
+ */
+public class AIException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 构造
+ *
+ * @param e 异常
+ */
+ public AIException(final Throwable e) {
+ super(e);
+ }
+
+ /**
+ * 构造
+ *
+ * @param message 消息
+ */
+ public AIException(final String message) {
+ super(message);
+ }
+
+ /**
+ * 构造
+ *
+ * @param messageTemplate 消息模板
+ * @param params 参数
+ */
+ public AIException(String messageTemplate, Object... params) {
+ super(StrUtil.format(messageTemplate, params));
+ }
+
+ /**
+ * 构造
+ *
+ * @param message 消息
+ * @param cause 被包装的子异常
+ */
+ public AIException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * 构造
+ *
+ * @param message 消息
+ * @param cause 被包装的子异常
+ * @param enableSuppression 是否启用抑制
+ * @param writableStackTrace 堆栈跟踪是否应该是可写的
+ */
+ public AIException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ /**
+ * 构造
+ *
+ * @param throwable 被包装的子异常
+ * @param messageTemplate 消息模板
+ * @param params 参数
+ */
+ public AIException(Throwable throwable, String messageTemplate, Object... params) {
+ super(StrUtil.format(messageTemplate, params), throwable);
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java b/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java
new file mode 100644
index 000000000..23cb87403
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai;
+
+import cn.hutool.ai.core.AIConfig;
+import cn.hutool.ai.core.AIService;
+import cn.hutool.ai.core.AIServiceProvider;
+import cn.hutool.core.util.ServiceLoaderUtil;
+
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 创建AIModelService的工厂类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class AIServiceFactory {
+
+ private static final Map providers = new ConcurrentHashMap<>();
+
+ // 加载所有 AIModelProvider 实现类
+ static {
+ final ServiceLoader loader = ServiceLoaderUtil.load(AIServiceProvider.class);
+ for (final AIServiceProvider provider : loader) {
+ providers.put(provider.getServiceName().toLowerCase(), provider);
+ }
+ }
+
+ /**
+ * 获取AI服务
+ *
+ * @param config AIConfig配置
+ * @return AI服务实例
+ * @since 5.8.38
+ */
+ public static AIService getAIService(final AIConfig config) {
+ return getAIService(config, AIService.class);
+ }
+
+ /**
+ * 获取AI服务
+ *
+ * @param config AIConfig配置
+ * @param clazz AI服务类
+ * @return clazz对应的AI服务类实例
+ * @since 5.8.38
+ * @param AI服务类
+ */
+ @SuppressWarnings("unchecked")
+ public static T getAIService(final AIConfig config, final Class clazz) {
+ final AIServiceProvider provider = providers.get(config.getModelName().toLowerCase());
+ if (provider == null) {
+ throw new IllegalArgumentException("Unsupported model: " + config.getModelName());
+ }
+
+ final AIService service = provider.create(config);
+ if (!clazz.isInstance(service)) {
+ throw new AIException("Model service is not of type: " + clazz.getSimpleName());
+ }
+
+ return (T) service;
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/AIUtil.java b/hutool-ai/src/main/java/cn/hutool/ai/AIUtil.java
new file mode 100644
index 000000000..5da188bff
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/AIUtil.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai;
+
+import cn.hutool.ai.core.AIConfig;
+import cn.hutool.ai.core.AIService;
+import cn.hutool.ai.core.Message;
+import cn.hutool.ai.model.deepseek.DeepSeekService;
+import cn.hutool.ai.model.doubao.DoubaoService;
+import cn.hutool.ai.model.grok.GrokService;
+import cn.hutool.ai.model.openai.OpenaiService;
+
+import java.util.List;
+
+/**
+ * AI工具类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class AIUtil {
+
+ /**
+ * 获取AI模型服务,每个大模型提供的功能会不一样,可以调用此方法指定不同AI服务类,调用不同的功能
+ *
+ * @param config 创建的AI服务模型的配置
+ * @param clazz AI模型服务类
+ * @return AIModelService的实现类实例
+ * @since 5.8.38
+ * @param AIService实现类
+ */
+ public static T getAIService(final AIConfig config, final Class clazz) {
+ return AIServiceFactory.getAIService(config, clazz);
+ }
+
+ /**
+ * 获取AI模型服务
+ *
+ * @param config 创建的AI服务模型的配置
+ * @return AIModelService 其中只有公共方法
+ * @since 5.8.38
+ */
+ public static AIService getAIService(final AIConfig config) {
+ return getAIService(config, AIService.class);
+ }
+
+ /**
+ * 获取DeepSeek模型服务
+ *
+ * @param config 创建的AI服务模型的配置
+ * @return DeepSeekService
+ * @since 5.8.38
+ */
+ public static DeepSeekService getDeepSeekService(final AIConfig config) {
+ return getAIService(config, DeepSeekService.class);
+ }
+
+ /**
+ * 获取Doubao模型服务
+ *
+ * @param config 创建的AI服务模型的配置
+ * @return DoubaoService
+ * @since 5.8.38
+ */
+ public static DoubaoService getDoubaoService(final AIConfig config) {
+ return getAIService(config, DoubaoService.class);
+ }
+
+ /**
+ * 获取Grok模型服务
+ *
+ * @param config 创建的AI服务模型的配置
+ * @return GrokService
+ * @since 5.8.38
+ */
+ public static GrokService getGrokService(final AIConfig config) {
+ return getAIService(config, GrokService.class);
+ }
+
+ /**
+ * 获取Openai模型服务
+ *
+ * @param config 创建的AI服务模型的配置
+ * @return OpenAIService
+ * @since 5.8.38
+ */
+ public static OpenaiService getOpenAIService(final AIConfig config) {
+ return getAIService(config, OpenaiService.class);
+ }
+
+ /**
+ * AI大模型对话功能
+ *
+ * @param config 创建的AI服务模型的配置
+ * @param prompt 需要对话的内容
+ * @return AI模型返回的Response响应字符串
+ * @since 5.8.38
+ */
+ public static String chat(final AIConfig config, final String prompt) {
+ return getAIService(config).chat(prompt);
+ }
+
+ /**
+ * AI大模型对话功能
+ *
+ * @param config 创建的AI服务模型的配置
+ * @param messages 由目前为止的对话组成的消息列表,可以设置role,content。详细参考官方文档
+ * @return AI模型返回的Response响应字符串
+ * @since 5.8.38
+ */
+ public static String chat(final AIConfig config, final List messages) {
+ return getAIService(config).chat(messages);
+ }
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/ModelName.java b/hutool-ai/src/main/java/cn/hutool/ai/ModelName.java
new file mode 100644
index 000000000..aa828a609
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/ModelName.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai;
+
+/**
+ * 模型厂商的名称(不指具体的模型)
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public enum ModelName {
+ /**
+ * deepSeek
+ */
+ DEEPSEEK("deepSeek"),
+ /**
+ * openai
+ */
+ OPENAI("openai"),
+ /**
+ * doubao
+ */
+ DOUBAO("doubao"),
+ /**
+ * grok
+ */
+ GROK("grok");
+
+ private final String value;
+
+ ModelName(final String value) {
+ this.value = value;
+ }
+
+ /**
+ * 获取值
+ *
+ * @return 值
+ */
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/Models.java b/hutool-ai/src/main/java/cn/hutool/ai/Models.java
new file mode 100644
index 000000000..dd3ac7364
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/Models.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai;
+
+/**
+ * 各模型厂商包含的model(指具体的模型)
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class Models {
+
+ // DeepSeek的模型
+ public enum DeepSeek {
+ DEEPSEEK_CHAT("deepseek-chat"),
+ DEEPSEEK_REASONER("deepseek-reasoner");
+
+ private final String model;
+
+ DeepSeek(String model) {
+ this.model = model;
+ }
+
+ public String getModel() {
+ return model;
+ }
+ }
+
+ // Openai的模型
+ public enum Openai {
+ GPT_4_5_PREVIEW("gpt-4.5-preview"),
+ GPT_4O("gpt-4o"),
+ CHATGPT_4O_LATEST("chatgpt-4o-latest"),
+ GPT_4O_MINI("gpt-4o-mini"),
+ O1("o1"),
+ O1_MINI("o1-mini"),
+ O1_PREVIEW("o1-preview"),
+ O3_MINI("o3-mini"),
+ GPT_4O_REALTIME_PREVIEW("gpt-4o-realtime-preview"),
+ GPT_4O_MINI_REALTIME_PREVIEW("gpt-4o-mini-realtime-preview"),
+ GPT_4O_AUDIO_PREVIEW("gpt-4o-audio-preview"),
+ GPT_4O_MINI_AUDIO_PREVIEW("gpt-4o-mini-audio-preview"),
+ GPT_4_TURBO("gpt-4-turbo"),
+ GPT_4_TURBO_PREVIEW("gpt-4-turbo-preview"),
+ GPT_4("gpt-4"),
+ GPT_3_5_TURBO_0125("gpt-3.5-turbo-0125"),
+ GPT_3_5_TURBO("gpt-3.5-turbo"),
+ GPT_3_5_TURBO_1106("gpt-3.5-turbo-1106"),
+ GPT_3_5_TURBO_INSTRUCT("gpt-3.5-turbo-instruct"),
+ DALL_E_3("dall-e-3"),
+ DALL_E_2("dall-e-2"),
+ TTS_1("tts-1"),
+ TTS_1_HD("tts-1-hd"),
+ WHISPER_1("whisper-1"),
+ TEXT_EMBEDDING_3_LARGE("text-embedding-3-large"),
+ TEXT_EMBEDDING_3_SMALL("text-embedding-3-small"),
+ TEXT_EMBEDDING_ADA_002("text-embedding-ada-002"),
+ OMNI_MODERATION_LATEST("omni-moderation-latest"),
+ OMNI_MODERATION_2024_09_26("omni-moderation-2024-09-26"),
+ TEXT_MODERATION_LATEST("text-moderation-latest"),
+ TEXT_MODERATION_STABLE("text-moderation-stable"),
+ TEXT_MODERATION_007("text-moderation-007"),
+ BABBAGE_002("babbage-002"),
+ DAVINCI_002("davinci-002");
+
+ private final String model;
+
+ Openai(String model) {
+ this.model = model;
+ }
+
+ public String getModel() {
+ return model;
+ }
+ }
+
+ // Doubao的模型
+ public enum Doubao {
+ DOUBAO_1_5_PRO_32K("doubao-1.5-pro-32k-250115"),
+ DOUBAO_1_5_PRO_256K("doubao-1.5-pro-256k-250115"),
+ DOUBAO_1_5_LITE_32K("doubao-1.5-lite-32k-250115"),
+ DEEPSEEK_R1("deepseek-r1-250120"),
+ DEEPSEEK_R1_DISTILL_QWEN_32B("deepseek-r1-distill-qwen-32b-250120"),
+ DEEPSEEK_R1_DISTILL_QWEN_7B("deepseek-r1-distill-qwen-7b-250120"),
+ DEEPSEEK_V3("deepseek-v3-241226"),
+ DOUBAO_PRO_4K_240515("doubao-pro-4k-240515"),
+ DOUBAO_PRO_4K_CHARACTER_240728("doubao-pro-4k-character-240728"),
+ DOUBAO_PRO_4K_FUNCTIONCALL_240615("doubao-pro-4k-functioncall-240615"),
+ DOUBAO_PRO_4K_BROWSING_240524("doubao-pro-4k-browsing-240524"),
+ DOUBAO_PRO_32K_241215("doubao-pro-32k-241215"),
+ DOUBAO_PRO_32K_FUNCTIONCALL_241028("doubao-pro-32k-functioncall-241028"),
+ DOUBAO_PRO_32K_BROWSING_241115("doubao-pro-32k-browsing-241115"),
+ DOUBAO_PRO_32K_CHARACTER_241215("doubao-pro-32k-character-241215"),
+ DOUBAO_PRO_128K_240628("doubao-pro-128k-240628"),
+ DOUBAO_PRO_256K_240828("doubao-pro-256k-240828"),
+ DOUBAO_LITE_4K_240328("doubao-lite-4k-240328"),
+ DOUBAO_LITE_4K_PRETRAIN_CHARACTER_240516("doubao-lite-4k-pretrain-character-240516"),
+ DOUBAO_LITE_32K_240828("doubao-lite-32k-240828"),
+ DOUBAO_LITE_32K_CHARACTER_241015("doubao-lite-32k-character-241015"),
+ DOUBAO_LITE_128K_240828("240828"),
+ MOONSHOT_V1_8K("moonshot-v1-8k"),
+ MOONSHOT_V1_32K("moonshot-v1-32k"),
+ MOONSHOT_V1_128K("moonshot-v1-128k"),
+ CHATGLM3_130B_FC("chatglm3-130b-fc-v1.0"),
+ CHATGLM3_130_FIN("chatglm3-130-fin-v1.0-update"),
+ MISTRAL_7B("mistral-7b-instruct-v0.2"),
+ DOUBAO_1_5_VISION_PRO_32K("doubao-1.5-vision-pro-32k-250115"),
+ DOUBAO_VISION_PRO_32K("doubao-vision-pro-32k-241008"),
+ DOUBAO_VISION_LITE_32K("doubao-vision-lite-32k-241015"),
+ DOUBAO_EMBEDDING_LARGE("doubao-embedding-large-text-240915"),
+ DOUBAO_EMBEDDING_TEXT_240715("doubao-embedding-text-240715"),
+ DOUBAO_EMBEDDING_VISION("doubao-embedding-vision-241215");
+
+ private final String model;
+
+ Doubao(String model) {
+ this.model = model;
+ }
+
+ public String getModel() {
+ return model;
+ }
+ }
+
+ // Grok的模型
+ public enum Grok {
+ GROK_2_1212("grok-2-1212"),
+ GROK_2_VISION_1212("grok-2-vision-1212"),
+ GROK_BETA("grok-beta"),
+ GROK_VISION_BETA("grok-vision-beta");
+
+ private final String model;
+
+ Grok(String model) {
+ this.model = model;
+ }
+
+ public String getModel() {
+ return model;
+ }
+ }
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfig.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfig.java
new file mode 100644
index 000000000..dffcad977
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfig.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+import java.util.Map;
+
+/**
+ * AI配置类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public interface AIConfig {
+
+ /**
+ * 获取模型(厂商)名称
+ *
+ * @return 模型(厂商)名称
+ * @since 5.8.38
+ */
+ default String getModelName() {
+ return this.getClass().getSimpleName();
+ }
+
+ /**
+ * 设置apiKey
+ *
+ * @param apiKey apiKey
+ * @since 5.8.38
+ */
+ void setApiKey(String apiKey);
+
+ /**
+ * 获取apiKey
+ *
+ * @return apiKey
+ * @since 5.8.38
+ */
+ String getApiKey();
+
+ /**
+ * 设置apiUrl
+ *
+ * @param apiUrl api请求地址
+ * @since 5.8.38
+ */
+ void setApiUrl(String apiUrl);
+
+ /**
+ * 获取apiUrl
+ *
+ * @return apiUrl
+ * @since 5.8.38
+ */
+ String getApiUrl();
+
+ /**
+ * 设置model
+ *
+ * @param model model
+ * @since 5.8.38
+ */
+ void setModel(String model);
+
+ /**
+ * 返回model
+ *
+ * @return model
+ * @since 5.8.38
+ */
+ String getModel();
+
+ /**
+ * 设置动态参数
+ *
+ * @param key 参数字段
+ * @param value 参数值
+ * @since 5.8.38
+ */
+ void putAdditionalConfigByKey(String key, Object value);
+
+ /**
+ * 获取动态参数
+ *
+ * @param key 参数字段
+ * @return 参数值
+ * @since 5.8.38
+ */
+ Object getAdditionalConfigByKey(String key);
+
+ /**
+ * 获取动态参数列表
+ *
+ * @return 参数列表Map
+ * @since 5.8.38
+ */
+ Map getAdditionalConfigMap();
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigBuilder.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigBuilder.java
new file mode 100644
index 000000000..9eb1698ab
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigBuilder.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * 用于AIConfig的创建,创建同时支持链式设置参数
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class AIConfigBuilder {
+
+ private final AIConfig config;
+
+ /**
+ * 构造
+ *
+ * @param modelName 模型厂商的名称(注意不是指具体的模型)
+ */
+ public AIConfigBuilder(final String modelName) {
+ try {
+ // 获取配置类
+ final Class extends AIConfig> configClass = AIConfigRegistry.getConfigClass(modelName);
+ if (configClass == null) {
+ throw new IllegalArgumentException("Unsupported model: " + modelName);
+ }
+
+ // 使用反射创建实例
+ final Constructor extends AIConfig> constructor = configClass.getDeclaredConstructor();
+ config = constructor.newInstance();
+ } catch (final Exception e) {
+ throw new RuntimeException("Failed to create AIConfig instance", e);
+ }
+ }
+
+ /**
+ * 设置apiKey
+ *
+ * @param apiKey apiKey
+ * @return config
+ * @since 5.8.38
+ */
+ public synchronized AIConfigBuilder setApiKey(final String apiKey) {
+ if (apiKey != null) {
+ config.setApiKey(apiKey);
+ }
+ return this;
+ }
+
+ /**
+ * 设置AI模型请求API接口的地址,不设置为默认值
+ *
+ * @param apiUrl API接口地址
+ * @return config
+ * @since 5.8.38
+ */
+ public synchronized AIConfigBuilder setApiUrl(final String apiUrl) {
+ if (apiUrl != null) {
+ config.setApiUrl(apiUrl);
+ }
+ return this;
+ }
+
+ /**
+ * 设置具体的model,不设置为默认值
+ *
+ * @param model 具体model的名称
+ * @return config
+ * @since 5.8.38
+ */
+ public synchronized AIConfigBuilder setModel(final String model) {
+ if (model != null) {
+ config.setModel(model);
+ }
+ return this;
+ }
+
+ /**
+ * 动态设置Request请求体中的属性字段,每个模型功能支持的字段请参照对应的官方文档
+ *
+ * @param key Request中的支持的属性名
+ * @param value 设置的属性值
+ * @return config
+ * @since 5.8.38
+ */
+ public AIConfigBuilder putAdditionalConfig(final String key, final Object value) {
+ if (value != null) {
+ config.putAdditionalConfigByKey(key, value);
+ }
+ return this;
+ }
+
+ /**
+ * 返回config实例
+ *
+ * @return config
+ * @since 5.8.38
+ */
+ public AIConfig build() {
+ return config;
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java
new file mode 100644
index 000000000..616644049
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+import cn.hutool.core.util.ServiceLoaderUtil;
+
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * AIConfig实现类的加载器
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class AIConfigRegistry {
+
+ private static final Map> configClasses = new ConcurrentHashMap<>();
+
+ // 加载所有 AIConfig 实现类
+ static {
+ final ServiceLoader loader = ServiceLoaderUtil.load(AIConfig.class);
+ for (final AIConfig config : loader) {
+ configClasses.put(config.getModelName().toLowerCase(), config.getClass());
+ }
+ }
+
+ /**
+ * 根据模型名称获取AIConfig实现类
+ *
+ * @param modelName 模型名称
+ * @return AIConfig实现类
+ */
+ public static Class extends AIConfig> getConfigClass(final String modelName) {
+ return configClasses.get(modelName.toLowerCase());
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIService.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIService.java
new file mode 100644
index 000000000..8bff076f8
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIService.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+import java.util.List;
+
+/**
+ * 模型公共的API功能,特有的功能在model.xx.XXService下定义
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public interface AIService {
+
+ /**
+ * 对话
+ *
+ * @param prompt user题词
+ * @return AI回答
+ * @since 5.8.38
+ */
+ String chat(String prompt);
+
+ /**
+ * 对话
+ *
+ * @param messages 由目前为止的对话组成的消息列表,可以设置role,content。详细参考官方文档
+ * @return AI回答
+ * @since 5.8.38
+ */
+ String chat(final List messages);
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIServiceProvider.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIServiceProvider.java
new file mode 100644
index 000000000..341f43a7f
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIServiceProvider.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+/**
+ * 用于加载AI服务,每一个通过SPI创建的AI服务都要实现此接口
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public interface AIServiceProvider {
+
+ /**
+ * 获取AI服务名称
+ *
+ * @return AI服务名称
+ * @since 5.8.38
+ */
+ String getServiceName();
+
+ /**
+ * 创建AI服务实例
+ *
+ * @param config AIConfig配置
+ * @param AIService实现类
+ * @return AI服务实例
+ * @since 5.8.38
+ */
+ T create(final AIConfig config);
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/BaseAIService.java b/hutool-ai/src/main/java/cn/hutool/ai/core/BaseAIService.java
new file mode 100644
index 000000000..218db8012
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/BaseAIService.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+import cn.hutool.ai.AIException;
+import cn.hutool.http.*;
+
+import java.util.Map;
+
+/**
+ * 基础AIService,包含基公共参数和公共方法
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class BaseAIService {
+
+ protected final AIConfig config;
+
+ /**
+ * 构造方法
+ *
+ * @param config AI配置
+ */
+ public BaseAIService(final AIConfig config) {
+ this.config = config;
+ }
+
+ /**
+ * 发送Get请求
+ * @param endpoint 请求节点
+ * @return 请求响应
+ */
+ protected HttpResponse sendGet(final String endpoint) {
+ //链式构建请求
+ try {
+ //设置超时3分钟
+ return HttpRequest.get(config.getApiUrl() + endpoint)
+ .header(Header.ACCEPT, "application/json")
+ .header(Header.AUTHORIZATION, "Bearer " + config.getApiKey())
+ .timeout(180000)
+ .execute();
+ } catch (final AIException e) {
+ throw new AIException("Failed to send GET request: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 发送Post请求
+ * @param endpoint 请求节点
+ * @param paramJson 请求参数json
+ * @return 请求响应
+ */
+ protected HttpResponse sendPost(final String endpoint, final String paramJson) {
+ //链式构建请求
+ try {
+ return HttpRequest.post(config.getApiUrl() + endpoint)
+ .header(Header.CONTENT_TYPE, "application/json")
+ .header(Header.ACCEPT, "application/json")
+ .header(Header.AUTHORIZATION, "Bearer " + config.getApiKey())
+ .body(paramJson)
+ .timeout(180000)
+ .execute();
+ } catch (final AIException e) {
+ throw new AIException("Failed to send POST request:" + e.getMessage(), e);
+ }
+
+ }
+
+ /**
+ * 发送表单请求
+ * @param endpoint 请求节点
+ * @param paramMap 请求参数map
+ * @return 请求响应
+ */
+ protected HttpResponse sendFormData(final String endpoint, final Map paramMap) {
+ //链式构建请求
+ try {
+ //设置超时3分钟
+ return HttpRequest.post(config.getApiUrl() + endpoint)
+ .header(Header.CONTENT_TYPE, "multipart/form-data")
+ .header(Header.ACCEPT, "application/json")
+ .header(Header.AUTHORIZATION, "Bearer " + config.getApiKey())
+ .form(paramMap)
+ .timeout(180000)
+ .execute();
+ } catch (final AIException e) {
+ throw new AIException("Failed to send POST request:" + e.getMessage(), e);
+ }
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/BaseConfig.java b/hutool-ai/src/main/java/cn/hutool/ai/core/BaseConfig.java
new file mode 100644
index 000000000..0d5cd0747
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/BaseConfig.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Config基础类,定义模型配置的基本属性
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class BaseConfig implements AIConfig {
+
+ //apiKey
+ protected volatile String apiKey;
+ //API请求地址
+ protected volatile String apiUrl;
+ //具体模型
+ protected volatile String model;
+ //动态扩展字段
+ protected Map additionalConfig = new ConcurrentHashMap<>();
+
+ @Override
+ public void setApiKey(final String apiKey) {
+ this.apiKey = apiKey;
+ }
+
+ @Override
+ public String getApiKey() {
+ return apiKey;
+ }
+
+ @Override
+ public void setApiUrl(final String apiUrl) {
+ this.apiUrl = apiUrl;
+ }
+
+ @Override
+ public String getApiUrl() {
+ return apiUrl;
+ }
+
+ @Override
+ public void setModel(final String model) {
+ this.model = model;
+ }
+
+ @Override
+ public String getModel() {
+ return model;
+ }
+
+ @Override
+ public void putAdditionalConfigByKey(final String key, final Object value) {
+ this.additionalConfig.put(key, value);
+ }
+
+ @Override
+ public Object getAdditionalConfigByKey(final String key) {
+ return additionalConfig.get(key);
+ }
+
+ @Override
+ public Map getAdditionalConfigMap() {
+ return new ConcurrentHashMap<>(additionalConfig);
+ }
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/Message.java b/hutool-ai/src/main/java/cn/hutool/ai/core/Message.java
new file mode 100644
index 000000000..cf2540021
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/Message.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.core;
+
+/**
+ * 公共Message类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class Message {
+ //角色 注意:如果设置系统消息,请放在messages列表的第一位
+ private final String role;
+ //内容
+ private final Object content;
+
+ /**
+ * 构造
+ *
+ * @param role 角色
+ * @param content 内容
+ */
+ public Message(final String role, final Object content) {
+ this.role = role;
+ this.content = content;
+ }
+
+ /**
+ * 获取角色
+ *
+ * @return 角色
+ */
+ public String getRole() {
+ return role;
+ }
+
+ /**
+ * 获取内容
+ *
+ * @return 内容
+ */
+ public Object getContent() {
+ return content;
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/package-info.java b/hutool-ai/src/main/java/cn/hutool/ai/core/package-info.java
new file mode 100644
index 000000000..855a61034
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/core/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * AI相关基础类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+
+package cn.hutool.ai.core;
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekCommon.java b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekCommon.java
new file mode 100644
index 000000000..c712b488a
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekCommon.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.deepseek;
+
+/**
+ * deepSeek公共类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DeepSeekCommon {
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekConfig.java b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekConfig.java
new file mode 100644
index 000000000..8497d6fd6
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekConfig.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.deepseek;
+
+import cn.hutool.ai.Models;
+import cn.hutool.ai.core.BaseConfig;
+
+/**
+ * DeepSeek配置类,初始化API接口地址,设置默认的模型
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DeepSeekConfig extends BaseConfig {
+
+ private final String API_URL = "https://api.deepseek.com";
+
+ private final String DEFAULT_MODEL = Models.DeepSeek.DEEPSEEK_CHAT.getModel();
+
+ public DeepSeekConfig() {
+ setApiUrl(API_URL);
+ setModel(DEFAULT_MODEL);
+ }
+
+ public DeepSeekConfig(String apiKey) {
+ this();
+ setApiKey(apiKey);
+ }
+
+ @Override
+ public String getModelName() {
+ return "deepSeek";
+ }
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekProvider.java b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekProvider.java
new file mode 100644
index 000000000..6fe344d92
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.deepseek;
+
+import cn.hutool.ai.core.AIConfig;
+import cn.hutool.ai.core.AIServiceProvider;
+
+/**
+ * 创建DeepSeek服务实现类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DeepSeekProvider implements AIServiceProvider {
+
+ @Override
+ public String getServiceName() {
+ return "deepSeek";
+ }
+
+ @Override
+ public DeepSeekService create(final AIConfig config) {
+ return new DeepSeekServiceImpl(config);
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekService.java b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekService.java
new file mode 100644
index 000000000..b601d5934
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekService.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.deepseek;
+
+import cn.hutool.ai.core.AIService;
+
+/**
+ * deepSeek支持的扩展接口
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public interface DeepSeekService extends AIService {
+
+ /**
+ * 模型beta功能
+ *
+ * @param prompt 题词
+ * @return AI的回答
+ * @since 5.8.38
+ */
+ String beta(String prompt);
+
+ /**
+ * 列出所有模型列表
+ *
+ * @return model列表
+ * @since 5.8.38
+ */
+ String models();
+
+ /**
+ * 查询余额
+ *
+ * @return 余额
+ * @since 5.8.38
+ */
+ String balance();
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekServiceImpl.java b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekServiceImpl.java
new file mode 100644
index 000000000..54c38f9dc
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/DeepSeekServiceImpl.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.deepseek;
+
+import cn.hutool.ai.core.AIConfig;
+import cn.hutool.ai.core.BaseAIService;
+import cn.hutool.ai.core.Message;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * DeepSeek服务,AI具体功能的实现
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DeepSeekServiceImpl extends BaseAIService implements DeepSeekService {
+
+ //对话补全
+ private final String CHAT_ENDPOINT = "/chat/completions";
+ //FIM补全(beta)
+ private final String BETA_ENDPOINT = "/beta/completions";
+ //列出模型
+ private final String MODELS_ENDPOINT = "/models";
+ //余额查询
+ private final String BALANCE_ENDPOINT = "/user/balance";
+
+ /**
+ * 构造函数
+ *
+ * @param config AI配置
+ */
+ public DeepSeekServiceImpl(final AIConfig config) {
+ //初始化DeepSeek客户端
+ super(config);
+ }
+
+ @Override
+ public String chat(final String prompt) {
+ // 定义消息结构
+ final List messages = new ArrayList<>();
+ messages.add(new Message("system", "You are a helpful assistant"));
+ messages.add(new Message("user", prompt));
+ return chat(messages);
+ }
+
+ @Override
+ public String chat(final List messages) {
+ final String paramJson = buildChatRequestBody(messages);
+ final HttpResponse response = sendPost(CHAT_ENDPOINT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String beta(final String prompt) {
+ final String paramJson = buildBetaRequestBody(prompt);
+ final HttpResponse response = sendPost(BETA_ENDPOINT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String models() {
+ final HttpResponse response = sendGet(MODELS_ENDPOINT);
+ return response.body();
+ }
+
+ @Override
+ public String balance() {
+ final HttpResponse response = sendGet(BALANCE_ENDPOINT);
+ return response.body();
+ }
+
+ // 构建chat请求体
+ private String buildChatRequestBody(final List messages) {
+ //使用JSON工具
+ final Map paramMap = new HashMap<>();
+ paramMap.put("model", config.getModel());
+ paramMap.put("messages", messages);
+ //合并其他参数
+ paramMap.putAll(config.getAdditionalConfigMap());
+
+ return JSONUtil.toJsonStr(paramMap);
+ }
+
+ // 构建beta请求体
+ private String buildBetaRequestBody(final String prompt) {
+ // 定义消息结构
+ //使用JSON工具
+ final Map paramMap = new HashMap<>();
+ paramMap.put("model", config.getModel());
+ paramMap.put("prompt", prompt);
+// //合并其他参数
+ paramMap.putAll(config.getAdditionalConfigMap());
+
+ return JSONUtil.toJsonStr(paramMap);
+ }
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/package-info.java b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/package-info.java
new file mode 100644
index 000000000..99b1ca414
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/deepseek/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 对deepSeek的封装实现
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+
+package cn.hutool.ai.model.deepseek;
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoCommon.java b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoCommon.java
new file mode 100644
index 000000000..494f2c668
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoCommon.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.doubao;
+
+/**
+ * doubao公共类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DoubaoCommon {
+
+ //doubao上下文缓存参数
+ public enum DoubaoContext {
+
+ SESSION("session"),
+ COMMON_PREFIX("common_prefix");
+
+ private final String mode;
+
+ DoubaoContext(String mode) {
+ this.mode = mode;
+ }
+
+ public String getMode() {
+ return mode;
+ }
+ }
+
+ //doubao视觉参数
+ public enum DoubaoVision {
+
+ AUTO("auto"),
+ LOW("low"),
+ HIGH("high");
+
+ private final String detail;
+
+ DoubaoVision(String detail) {
+ this.detail = detail;
+ }
+
+ public String getDetail() {
+ return detail;
+ }
+ }
+
+ //doubao视频生成参数
+ public enum DoubaoVideo {
+
+ //宽高比例
+ RATIO_16_9("--rt", "16:9"),//[1280, 720]
+ RATIO_4_3("--rt", "4:3"),//[960, 720]
+ RATIO_1_1("--rt", "1:1"),//[720, 720]
+ RATIO_3_4("--rt", "3:4"),//[720, 960]
+ RATIO_9_16("--rt", "9:16"),//[720, 1280]
+ RATIO_21_9("--rt", "21:9"),//[1280, 544]
+
+ //生成视频时长
+ DURATION_5("--dur", 5),//文生视频,图生视频
+ DURATION_10("--dur", 10),//文生视频
+
+ //帧率,即一秒时间内视频画面数量
+ FPS_5("--fps", 24),
+
+ //视频分辨率
+ RESOLUTION_5("--rs", "720p"),
+
+ //生成视频是否包含水印
+ WATERMARK_TRUE("--wm", true),
+ WATERMARK_FALSE("--wm", false);
+
+ private final String type;
+ private final Object value;
+
+ DoubaoVideo(String type, Object value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public Object getValue() {
+ if (value instanceof String) {
+ return (String) value;
+ } else if (value instanceof Integer) {
+ return (Integer) value;
+ } else if (value instanceof Boolean) {
+ return (Boolean) value;
+ }
+ return value;
+ }
+
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoConfig.java b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoConfig.java
new file mode 100644
index 000000000..fa7b1c8a5
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoConfig.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.doubao;
+
+import cn.hutool.ai.Models;
+import cn.hutool.ai.core.BaseConfig;
+
+/**
+ * Doubao配置类,初始化API接口地址,设置默认的模型
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DoubaoConfig extends BaseConfig {
+
+ private final String API_URL = "https://ark.cn-beijing.volces.com/api/v3";
+
+ private final String DEFAULT_MODEL = Models.Doubao.DOUBAO_1_5_LITE_32K.getModel();
+
+ public DoubaoConfig() {
+ setApiUrl(API_URL);
+ setModel(DEFAULT_MODEL);
+ }
+
+ public DoubaoConfig(String apiKey) {
+ this();
+ setApiKey(apiKey);
+ }
+
+ @Override
+ public String getModelName() {
+ return "doubao";
+ }
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoProvider.java b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoProvider.java
new file mode 100644
index 000000000..46d5be8d2
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.doubao;
+
+import cn.hutool.ai.core.AIConfig;
+import cn.hutool.ai.core.AIServiceProvider;
+
+/**
+ * 创建Doubap服务实现类
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DoubaoProvider implements AIServiceProvider {
+
+ @Override
+ public String getServiceName() {
+ return "doubao";
+ }
+
+ @Override
+ public DoubaoService create(final AIConfig config) {
+ return new DoubaoServiceImpl(config);
+ }
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoService.java b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoService.java
new file mode 100644
index 000000000..14d087115
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoService.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.doubao;
+
+import cn.hutool.ai.core.AIService;
+import cn.hutool.ai.core.Message;
+
+import java.util.List;
+
+/**
+ * doubao支持的扩展接口
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public interface DoubaoService extends AIService {
+
+ /**
+ * 图像理解:模型会依据传入的图片信息以及问题,给出回复。
+ *
+ * @param prompt 提问
+ * @param images 图片列表/或者图片Base64编码图片列表(URI形式)
+ * @param detail 手动设置图片的质量,取值范围high、low、auto,默认为auto
+ * @return AI回答
+ * @since 5.8.38
+ */
+ String chatVision(String prompt, final List images, String detail);
+
+ /**
+ * 图像理解:模型会依据传入的图片信息以及问题,给出回复。
+ *
+ * @param prompt 提问
+ * @param images 传入的图片列表地址/或者图片Base64编码图片列表(URI形式)
+ * @return AI回答
+ * @since 5.8.38
+ */
+ default String chatVision(String prompt, final List images) {
+ return chatVision(prompt, images, DoubaoCommon.DoubaoVision.AUTO.getDetail());
+ }
+
+ /**
+ * 创建视频生成任务
+ * 注意:调用该方法时,配置config中的model为您创建的推理接入点(Endpoint)ID。详细参考官方文档
+ *
+ * @param text 文本提示词
+ * @param image 图片/或者图片Base64编码图片(URI形式)
+ * @param videoParams 视频参数列表
+ * @return 生成任务id
+ * @since 5.8.38
+ */
+ String videoTasks(String text, String image, final List videoParams);
+
+ /**
+ * 创建视频生成任务
+ * 注意:调用该方法时,配置config中的model为您创建的推理接入点(Endpoint)ID。详细参考官方文档
+ *
+ * @param text 文本提示词
+ * @param image 图片/或者图片Base64编码图片(URI形式)
+ * @return 生成任务id
+ * @since 5.8.38
+ */
+ default String videoTasks(String text, String image) {
+ return videoTasks(text, image, null);
+ }
+
+ /**
+ * 查询视频生成任务信息
+ *
+ * @param taskId 通过创建生成视频任务返回的生成任务id
+ * @return 生成任务信息
+ * @since 5.8.38
+ */
+ String getVideoTasksInfo(String taskId);
+
+ /**
+ * 文本向量化
+ *
+ * @param input 需要向量化的内容列表,支持中文、英文
+ * @return 处理后的向量信息
+ * @since 5.8.38
+ */
+ String embeddingText(String[] input);
+
+ /**
+ * 图文向量化:仅支持单一文本、单张图片或文本与图片的组合输入(即一段文本 + 一张图片),暂不支持批量文本 / 图片的同时处理
+ *
+ * @param text 需要向量化的内容
+ * @param image 需要向量化的图片地址/或者图片Base64编码图片(URI形式)
+ * @return 处理后的向量信息
+ * @since 5.8.38
+ */
+ String embeddingVision(String text, String image);
+
+ /**
+ * 应用(Bot) config中model设置为您创建的应用ID
+ *
+ * @param messages 由对话组成的消息列表。如系统人设,背景信息等,用户自定义的信息
+ * @return AI回答
+ * @since 5.8.38
+ */
+ String botsChat(final List messages);
+
+ /**
+ * 分词:可以将文本转换为模型可理解的 token id,并返回文本的 tokens 数量、token id、 token 在原始文本中的偏移量等信息
+ *
+ * @param text 需要分词的内容列表
+ * @return 分词结果
+ * @since 5.8.38
+ */
+ String tokenization(String[] text);
+
+ /**
+ * 批量推理 Chat
+ * 注意:调用该方法时,配置config中的model为您创建的批量推理接入点(Endpoint)ID。详细参考官方文档
+ * 该方法不支持流式
+ *
+ * @param prompt chat内容
+ * @return AI回答
+ * @since 5.8.38
+ */
+ String batchChat(String prompt);
+
+ /**
+ * 批量推理 Chat
+ * 注意:调用该方法时,配置config中的model为您创建的批量推理接入点(Endpoint)ID。详细参考官方文档
+ * 该方法不支持流式
+ *
+ * @param messages 由对话组成的消息列表。如系统人设,背景信息等,用户自定义的信息
+ * @return AI回答
+ * @since 5.8.38
+ */
+ String batchChat(final List messages);
+
+ /**
+ * 创建上下文缓存: 创建上下文缓存,获得缓存 id字段后,在上下文缓存对话 API中使用。
+ * 注意:调用该方法时,配置config中的model为您创建的推理接入点(Endpoint)ID,
+ * 推理接入点中使用的模型需要在模型管理中开启缓存功能。详细参考官方文档
+ *
+ * @param messages 由对话组成的消息列表。如系统人设,背景信息等,用户自定义的信息
+ * @param mode 上下文缓存的类型,详细参考官方文档 默认为session
+ * @return 返回的缓存id
+ * @since 5.8.38
+ */
+ String createContext(final List messages, String mode);
+
+ /**
+ * 创建上下文缓存: 创建上下文缓存,获得缓存 id字段后,在上下文缓存对话 API中使用。
+ * 注意:调用该方法时,配置config中的model为您创建的推理接入点(Endpoint)ID,
+ * 推理接入点中使用的模型需要在模型管理中开启缓存功能。详细参考官方文档
+ *
+ * @param messages 由对话组成的消息列表。如系统人设,背景信息等,用户自定义的信息
+ * @return 返回的缓存id
+ * @since 5.8.38
+ */
+ default String createContext(final List messages) {
+ return createContext(messages, DoubaoCommon.DoubaoContext.SESSION.getMode());
+ }
+
+ /**
+ * 上下文缓存对话: 向大模型发起带上下文缓存的请求
+ * 注意:配置config中的model可以为您创建的推理接入点(Endpoint)ID,也可以是支持chat的model
+ *
+ * @param prompt 对话的内容题词
+ * @param contextId 创建上下文缓存后获取的缓存id
+ * @return AI的回答
+ * @since 5.8.38
+ */
+ String chatContext(String prompt, String contextId);
+
+ /**
+ * 上下文缓存对话: 向大模型发起带上下文缓存的请求
+ * 注意:配置config中的model可以为您创建的推理接入点(Endpoint)ID,也可以是支持chat的model
+ *
+ * @param messages 对话的信息 不支持最后一个元素的role设置为assistant。如使用session 缓存(mode设置为session)传入最新一轮对话的信息,无需传入历史信息
+ * @param contextId 创建上下文缓存后获取的缓存id
+ * @return AI的回答
+ * @since 5.8.38
+ */
+ String chatContext(final List messages, String contextId);
+
+}
diff --git a/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoServiceImpl.java b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoServiceImpl.java
new file mode 100644
index 000000000..88a24d218
--- /dev/null
+++ b/hutool-ai/src/main/java/cn/hutool/ai/model/doubao/DoubaoServiceImpl.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2025 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.hutool.ai.model.doubao;
+
+import cn.hutool.ai.core.AIConfig;
+import cn.hutool.ai.core.BaseAIService;
+import cn.hutool.ai.core.Message;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Doubao服务,AI具体功能的实现
+ *
+ * @author elichow
+ * @since 5.8.38
+ */
+public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
+
+ //对话
+ private final String CHAT_ENDPOINT = "/chat/completions";
+ //文本向量化
+ private final String EMBEDDING_TEXT = "/embeddings";
+ //图文向量化
+ private final String EMBEDDING_VISION = "/embeddings/multimodal";
+ //应用bots
+ private final String BOTS_CHAT = "/bots/chat/completions";
+ //分词
+ private final String TOKENIZATION = "/tokenization";
+ //批量推理chat
+ private final String BATCH_CHAT = "/batch/chat/completions";
+ //创建上下文缓存
+ private final String CREATE_CONTEXT = "/context/create";
+ //上下文缓存对话
+ private final String CHAT_CONTEXT = "/context/chat/completions";
+ //创建视频生成任务
+ private final String CREATE_VIDEO = "/contents/generations/tasks";
+
+ public DoubaoServiceImpl(final AIConfig config) {
+ //初始化doubao客户端
+ super(config);
+ }
+
+ @Override
+ public String chat(String prompt) {
+ // 定义消息结构
+ final List messages = new ArrayList<>();
+ messages.add(new Message("system", "You are a helpful assistant"));
+ messages.add(new Message("user", prompt));
+ return chat(messages);
+ }
+
+ @Override
+ public String chat(final List messages) {
+ String paramJson = buildChatRequestBody(messages);
+ final HttpResponse response = sendPost(CHAT_ENDPOINT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String chatVision(String prompt, final List images, String detail) {
+ String paramJson = buildChatVisionRequestBody(prompt, images, detail);
+ final HttpResponse response = sendPost(CHAT_ENDPOINT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String videoTasks(String text, String image, final List videoParams) {
+ String paramJson = buildGenerationsTasksRequestBody(text, image, videoParams);
+ final HttpResponse response = sendPost(CREATE_VIDEO, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String getVideoTasksInfo(String taskId) {
+ final HttpResponse response = sendGet(CREATE_VIDEO + "/" + taskId);
+ return response.body();
+ }
+
+
+ @Override
+ public String embeddingText(String[] input) {
+ String paramJson = buildEmbeddingTextRequestBody(input);
+ final HttpResponse response = sendPost(EMBEDDING_TEXT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String embeddingVision(String text, String image) {
+ String paramJson = buildEmbeddingVisionRequestBody(text, image);
+ final HttpResponse response = sendPost(EMBEDDING_VISION, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String botsChat(final List messages) {
+ String paramJson = buildBotsChatRequestBody(messages);
+ final HttpResponse response = sendPost(BOTS_CHAT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String tokenization(String[] text) {
+ String paramJson = buildTokenizationRequestBody(text);
+ final HttpResponse response = sendPost(TOKENIZATION, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String batchChat(String prompt) {
+ // 定义消息结构
+ final List messages = new ArrayList<>();
+ messages.add(new Message("system", "You are a helpful assistant"));
+ messages.add(new Message("user", prompt));
+ return batchChat(messages);
+ }
+
+ @Override
+ public String batchChat(final List messages) {
+ String paramJson = buildBatchChatRequestBody(messages);
+ final HttpResponse response = sendPost(BATCH_CHAT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String createContext(final List messages, String mode) {
+ String paramJson = buildCreateContextRequest(messages, mode);
+ final HttpResponse response = sendPost(CREATE_CONTEXT, paramJson);
+ return response.body();
+ }
+
+ @Override
+ public String chatContext(String prompt, String contextId) {
+ // 定义消息结构
+ final List messages = new ArrayList<>();
+ messages.add(new Message("user", prompt));
+ return chatContext(messages, contextId);
+ }
+
+ @Override
+ public String chatContext(final List messages, String contextId) {
+ String paramJson = buildChatContentRequestBody(messages, contextId);
+ final HttpResponse response = sendPost(CHAT_CONTEXT, paramJson);
+ return response.body();
+ }
+
+ // 构建chat请求体
+ private String buildChatRequestBody(final List messages) {
+ //使用JSON工具
+ final Map paramMap = new HashMap<>();
+ paramMap.put("model", config.getModel());
+ paramMap.put("messages", messages);
+ //合并其他参数
+ paramMap.putAll(config.getAdditionalConfigMap());
+
+ return JSONUtil.toJsonStr(paramMap);
+ }
+
+ //构建chatVision请求体
+ private String buildChatVisionRequestBody(String prompt, final List images, String detail) {
+ // 定义消息结构
+ final List messages = new ArrayList<>();
+ final List