【代码优化】AI:完善 DeepSeekChatTests、XingHuoChatModelTests 单测,方便大家快速体验

This commit is contained in:
YunaiV 2024-07-06 17:37:17 +08:00
parent 4daff93313
commit 59c853b54d
10 changed files with 74 additions and 67 deletions

View File

@ -2,11 +2,11 @@ package cn.iocoder.yudao.framework.ai.config;
import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactory;
import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactoryImpl;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatClient;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOptions;
import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOptions;
import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
@ -34,22 +34,9 @@ public class YudaoAiAutoConfiguration {
// ========== 各种 AI Client 创建 ==========
@Bean
@ConditionalOnProperty(value = "yudao.ai.xinghuo.enable", havingValue = "true")
public XingHuoChatClient xingHuoChatClient(YudaoAiProperties yudaoAiProperties) {
YudaoAiProperties.XingHuoProperties properties = yudaoAiProperties.getXinghuo();
XingHuoChatOptions options = XingHuoChatOptions.builder()
.model(properties.getModel())
.temperature(properties.getTemperature())
.maxTokens(properties.getMaxTokens())
.topK(properties.getTopK())
.build();
return new XingHuoChatClient(properties.getAppKey(), properties.getSecretKey(), options);
}
@Bean
@ConditionalOnProperty(value = "yudao.ai.deepseek.enable", havingValue = "true")
public DeepSeekChatClient deepSeekChatClient(YudaoAiProperties yudaoAiProperties) {
public DeepSeekChatModel deepSeekChatModel(YudaoAiProperties yudaoAiProperties) {
YudaoAiProperties.DeepSeekProperties properties = yudaoAiProperties.getDeepSeek();
DeepSeekChatOptions options = DeepSeekChatOptions.builder()
.model(properties.getModel())
@ -57,7 +44,20 @@ public class YudaoAiAutoConfiguration {
.maxTokens(properties.getMaxTokens())
.topP(properties.getTopP())
.build();
return new DeepSeekChatClient(properties.getApiKey(), options);
return new DeepSeekChatModel(properties.getApiKey(), options);
}
@Bean
@ConditionalOnProperty(value = "yudao.ai.xinghuo.enable", havingValue = "true")
public XingHuoChatModel xingHuoChatClient(YudaoAiProperties yudaoAiProperties) {
YudaoAiProperties.XingHuoProperties properties = yudaoAiProperties.getXinghuo();
XingHuoChatOptions options = XingHuoChatOptions.builder()
.model(properties.getModel())
.temperature(properties.getTemperature())
.maxTokens(properties.getMaxTokens())
.topK(properties.getTopK())
.build();
return new XingHuoChatModel(properties.getAppKey(), properties.getSecretKey(), options);
}
@Bean

View File

@ -13,16 +13,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
public class YudaoAiProperties {
/**
* 讯飞星火
*/
private XingHuoProperties xinghuo;
/**
* DeepSeek
*/
private DeepSeekProperties deepSeek;
/**
* 讯飞星火
*/
private XingHuoProperties xinghuo;
/**
* Midjourney 绘图
*/

View File

@ -9,10 +9,10 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.ai.config.YudaoAiAutoConfiguration;
import cn.iocoder.yudao.framework.ai.config.YudaoAiProperties;
import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatClient;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration;
import com.alibaba.cloud.ai.tongyi.TongYiConnectionProperties;
import com.alibaba.cloud.ai.tongyi.chat.TongYiChatModel;
@ -59,10 +59,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
return buildTongYiChatModel(apiKey);
case YI_YAN:
return buildYiYanChatModel(apiKey);
case XING_HUO:
return buildXingHuoChatClient(apiKey);
case DEEP_SEEK:
return buildDeepSeekChatClient(apiKey);
return buildDeepSeekChatModel(apiKey);
case XING_HUO:
return buildXingHuoChatModel(apiKey);
case OPENAI:
return buildOpenAiChatModel(apiKey, url);
case OLLAMA:
@ -82,7 +82,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
case YI_YAN:
return SpringUtil.getBean(QianFanChatModel.class);
case XING_HUO:
return SpringUtil.getBean(XingHuoChatClient.class);
return SpringUtil.getBean(XingHuoChatModel.class);
case OPENAI:
return SpringUtil.getBean(OpenAiChatModel.class);
case OLLAMA:
@ -112,7 +112,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
case OPENAI:
return buildOpenAiImageModel(apiKey, url);
case STABLE_DIFFUSION:
return buildStabilityAiImageClient(apiKey, url);
return buildStabilityAiImageModel(apiKey, url);
default:
throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
}
@ -168,6 +168,24 @@ public class AiModelFactoryImpl implements AiModelFactory {
return new QianFanChatModel(qianFanApi);
}
/**
* 可参考 {@link YudaoAiAutoConfiguration#deepSeekChatModel(YudaoAiProperties)}
*/
private static DeepSeekChatModel buildDeepSeekChatModel(String apiKey) {
return new DeepSeekChatModel(apiKey);
}
/**
* 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)}
*/
private static XingHuoChatModel buildXingHuoChatModel(String key) {
List<String> keys = StrUtil.split(key, '|');
Assert.equals(keys.size(), 3, "XingHuoChatClient 的密钥需要 (appid|appKey|secretKey) 格式");
String appKey = keys.get(1);
String secretKey = keys.get(2);
return new XingHuoChatModel(appKey, secretKey);
}
/**
* 可参考 {@link OpenAiAutoConfiguration}
*/
@ -194,22 +212,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
return new OllamaChatModel(ollamaApi);
}
/**
* 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)}
*/
private static XingHuoChatClient buildXingHuoChatClient(String key) {
List<String> keys = StrUtil.split(key, '|');
Assert.equals(keys.size(), 3, "XingHuoChatClient 的密钥需要 (appid|appKey|secretKey) 格式");
String appKey = keys.get(1);
String secretKey = keys.get(2);
return new XingHuoChatClient(appKey, secretKey);
}
private static DeepSeekChatClient buildDeepSeekChatClient(String apiKey) {
return new DeepSeekChatClient(apiKey);
}
private StabilityAiImageModel buildStabilityAiImageClient(String apiKey, String url) {
private StabilityAiImageModel buildStabilityAiImageModel(String apiKey, String url) {
url = StrUtil.blankToDefault(url, StabilityAiApi.DEFAULT_BASE_URL);
StabilityAiApi stabilityAiApi = new StabilityAiApi(apiKey, StabilityAiApi.DEFAULT_IMAGE_MODEL, url);
return new StabilityAiImageModel(stabilityAiApi);

View File

@ -29,7 +29,7 @@ import static cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOpti
* @author fansili
*/
@Slf4j
public class DeepSeekChatClient implements ChatModel {
public class DeepSeekChatModel implements ChatModel {
private static final String BASE_URL = "https://api.deepseek.com";
@ -43,15 +43,15 @@ public class DeepSeekChatClient implements ChatModel {
*/
private final OpenAiApi openAiApi;
public DeepSeekChatClient(String apiKey) {
public DeepSeekChatModel(String apiKey) {
this(apiKey, DeepSeekChatOptions.builder().model(MODEL_DEFAULT).temperature(0.7F).build());
}
public DeepSeekChatClient(String apiKey, DeepSeekChatOptions options) {
public DeepSeekChatModel(String apiKey, DeepSeekChatOptions options) {
this(apiKey, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
public DeepSeekChatClient(String apiKey, DeepSeekChatOptions options, RetryTemplate retryTemplate) {
public DeepSeekChatModel(String apiKey, DeepSeekChatOptions options, RetryTemplate retryTemplate) {
Assert.notEmpty(apiKey, "apiKey 不能为空");
Assert.notNull(options, "options 不能为空");
Assert.notNull(retryTemplate, "retryTemplate 不能为空");

View File

@ -29,7 +29,7 @@ import static cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOption
* @author fansili
*/
@Slf4j
public class XingHuoChatClient implements ChatModel {
public class XingHuoChatModel implements ChatModel {
private static final String BASE_URL = "https://spark-api-open.xf-yun.com";
@ -43,16 +43,16 @@ public class XingHuoChatClient implements ChatModel {
*/
private final OpenAiApi openAiApi;
public XingHuoChatClient(String apiKey, String secretKey) {
public XingHuoChatModel(String apiKey, String secretKey) {
this(apiKey, secretKey,
XingHuoChatOptions.builder().model(MODEL_DEFAULT).temperature(0.7F).build());
}
public XingHuoChatClient(String apiKey, String secretKey, XingHuoChatOptions options) {
public XingHuoChatModel(String apiKey, String secretKey, XingHuoChatOptions options) {
this(apiKey, secretKey, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
public XingHuoChatClient(String apiKey, String secretKey, XingHuoChatOptions options, RetryTemplate retryTemplate) {
public XingHuoChatModel(String apiKey, String secretKey, XingHuoChatOptions options, RetryTemplate retryTemplate) {
Assert.notEmpty(apiKey, "apiKey 不能为空");
Assert.notEmpty(secretKey, "secretKey 不能为空");
Assert.notNull(options, "options 不能为空");

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.framework.ai.chat;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatClient;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
@ -13,13 +13,13 @@ import java.util.ArrayList;
import java.util.List;
/**
* {@link DeepSeekChatClient} 集成测试
* {@link DeepSeekChatModel} 集成测试
*
* @author 芋道源码
*/
public class DeepSeekChatTests {
public class DeepSeekChatModelTests {
private final DeepSeekChatClient chatModel = new DeepSeekChatClient("sk-e94db327cc7d457d99a8de8810fc6b12");
private final DeepSeekChatModel chatModel = new DeepSeekChatModel("sk-e94db327cc7d457d99a8de8810fc6b12");
@Test
public void testCall() {

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.framework.ai.chat;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.messages.Message;
@ -17,7 +17,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* {@link XingHuoChatClient} 集成测试
* {@link XingHuoChatModel} 集成测试
*
* @author 芋道源码
*/

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.framework.ai.chat;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
@ -13,13 +13,13 @@ import java.util.ArrayList;
import java.util.List;
/**
* {@link XingHuoChatClient} 集成测试
* {@link XingHuoChatModel} 集成测试
*
* @author fansili
*/
public class XingHuoChatClientTests {
public class XingHuoChatModelTests {
private final XingHuoChatClient chatModel = new XingHuoChatClient(
private final XingHuoChatModel chatModel = new XingHuoChatModel(
"cb6415c19d6162cda07b47316fcb0416",
"Y2JiYTIxZjA3MDMxMjNjZjQzYzVmNzdh");

View File

@ -19,7 +19,7 @@ import java.util.List;
*
* @author fansili
*/
public class YiYanChatTests {
public class YiYanChatModelTests {
private final QianFanApi qianFanApi = new QianFanApi(
"qS8k8dYr2nXunagK4SSU8Xjj",

View File

@ -153,6 +153,9 @@ spring:
spring:
ai:
qianfan: # 文心一言
api-key: x0cuLZ7XsaTCU08vuJWO87Lg
secret-key: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK
ollama:
base-url: http://127.0.0.1:11434
chat:
@ -162,9 +165,6 @@ spring:
base-url: https://api.gptsapi.net
stabilityai:
api-key: sk-e53UqbboF8QJCscYvzJscJxJXoFcFg4iJjl1oqgE7baJETmx
qianfan: # 文心一言
api-key: x0cuLZ7XsaTCU08vuJWO87Lg
secret-key: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK
cloud:
ai:
tongyi: # 通义千问
@ -173,6 +173,10 @@ spring:
yudao:
ai:
deep-seek:
enable: true
api-key: sk-e94db327cc7d457d99a8de8810fc6b12
model: deepseek-chat
xinghuo:
enable: true
appId: 13c8cca6