mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-13 02:25:06 +08:00
【优化】ai chat client自动配置和初始化。
This commit is contained in:
@ -3,10 +3,6 @@ package cn.iocoder.yudao.framework.ai;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 讯飞星火 模型
|
||||
*
|
||||
@ -24,15 +20,22 @@ import java.util.stream.Collectors;
|
||||
public enum AiPlatformEnum {
|
||||
|
||||
|
||||
YI_YAN("yiyan"),
|
||||
QIAN_WEN("qianwen"),
|
||||
XING_HUO("xinghuo"),
|
||||
YI_YAN("yiyan", "一言"),
|
||||
QIAN_WEN("qianwen", "千问"),
|
||||
XING_HUO("xinghuo", "星火"),
|
||||
|
||||
;
|
||||
|
||||
public static final Map<String, AiPlatformEnum> mapValues
|
||||
= Arrays.stream(values()).collect(Collectors.toMap(AiPlatformEnum::name, o -> o));
|
||||
private String platform;
|
||||
private String name;
|
||||
|
||||
private String value;
|
||||
public static AiPlatformEnum valueOfPlatform(String platform) {
|
||||
for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
|
||||
if (itemEnum.getPlatform().equals(platform)) {
|
||||
return itemEnum;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid MessageType value: " + platform);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.ai.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.ai.chat.ChatResponse;
|
||||
import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* ai client传入
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/14 10:27
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface AiClient {
|
||||
|
||||
ChatResponse call(Prompt prompt, String clientName);
|
||||
|
||||
Flux<ChatResponse> stream(Prompt prompt, String clientName);
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package cn.iocoder.yudao.framework.ai.config;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||
import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient;
|
||||
import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions;
|
||||
import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi;
|
||||
@ -11,15 +9,11 @@ import cn.iocoder.yudao.framework.ai.chatxinghuo.api.XingHuoApi;
|
||||
import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatClient;
|
||||
import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanOptions;
|
||||
import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanApi;
|
||||
import cn.iocoder.yudao.framework.ai.exception.AiException;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ai 自动配置
|
||||
*
|
||||
@ -32,86 +26,46 @@ import java.util.Map;
|
||||
public class YudaoAiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = AiClient.class)
|
||||
public AiClient aiClient(YudaoAiProperties yudaoAiProperties) {
|
||||
Map<String, Object> chatClientMap = buildChatClientMap(yudaoAiProperties);
|
||||
return new YudaoAiClient(chatClientMap);
|
||||
@ConditionalOnProperty(value = "yudao.ai.xinghuo.enable", havingValue = "true")
|
||||
public XingHuoChatClient xingHuoChatClient(YudaoAiProperties yudaoAiProperties) {
|
||||
YudaoAiProperties.XingHuoProperties xingHuoProperties = yudaoAiProperties.getXinghuo();
|
||||
return new XingHuoChatClient(
|
||||
new XingHuoApi(
|
||||
xingHuoProperties.getAppId(),
|
||||
xingHuoProperties.getAppKey(),
|
||||
xingHuoProperties.getSecretKey()
|
||||
),
|
||||
new XingHuoOptions().setChatModel(xingHuoProperties.getChatModel())
|
||||
);
|
||||
}
|
||||
|
||||
public Map<String, Object> buildChatClientMap(YudaoAiProperties yudaoAiProperties) {
|
||||
Map<String, Object> chatMap = new HashMap<>();
|
||||
for (Map.Entry<String, Map<String, Object>> properties : yudaoAiProperties.entrySet()) {
|
||||
String beanName = properties.getKey();
|
||||
Map<String, Object> aiPlatformMap = properties.getValue();
|
||||
|
||||
// 检查平台类型是否正确
|
||||
String aiPlatform = String.valueOf(aiPlatformMap.get("aiPlatform"));
|
||||
if (!AiPlatformEnum.mapValues.containsKey(aiPlatform)) {
|
||||
throw new AiException("AI平台名称错误! 可以参考 AiPlatformEnum 类!");
|
||||
}
|
||||
// 获取平台类型
|
||||
AiPlatformEnum aiPlatformEnum = AiPlatformEnum.mapValues.get(aiPlatform);
|
||||
// 获取 chat properties
|
||||
YudaoAiProperties.ChatProperties chatProperties = getChatProperties(aiPlatformEnum, aiPlatformMap);
|
||||
// 创建客户端
|
||||
Object chatClient = createChatClient(chatProperties);
|
||||
chatMap.put(beanName, chatClient);
|
||||
}
|
||||
return chatMap;
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "yudao.ai.qianwen.enable", havingValue = "true")
|
||||
public QianWenChatClient qianWenChatClient(YudaoAiProperties yudaoAiProperties) {
|
||||
YudaoAiProperties.QianWenProperties qianWenProperties = yudaoAiProperties.getQianwen();
|
||||
return new QianWenChatClient(
|
||||
new QianWenApi(
|
||||
qianWenProperties.getAccessKeyId(),
|
||||
qianWenProperties.getAccessKeySecret(),
|
||||
qianWenProperties.getAgentKey(),
|
||||
qianWenProperties.getEndpoint()
|
||||
),
|
||||
new QianWenOptions()
|
||||
.setAppId(qianWenProperties.getAppId())
|
||||
);
|
||||
}
|
||||
|
||||
private static Object createChatClient(YudaoAiProperties.ChatProperties chatProperties) {
|
||||
if (AiPlatformEnum.XING_HUO == chatProperties.getAiPlatform()) {
|
||||
YudaoAiProperties.XingHuoProperties xingHuoProperties = (YudaoAiProperties.XingHuoProperties) chatProperties;
|
||||
return new XingHuoChatClient(
|
||||
new XingHuoApi(
|
||||
xingHuoProperties.getAppId(),
|
||||
xingHuoProperties.getAppKey(),
|
||||
xingHuoProperties.getSecretKey()
|
||||
),
|
||||
new XingHuoOptions().setChatModel(xingHuoProperties.getChatModel())
|
||||
);
|
||||
} else if (AiPlatformEnum.QIAN_WEN == chatProperties.getAiPlatform()) {
|
||||
YudaoAiProperties.QianWenProperties qianWenProperties = (YudaoAiProperties.QianWenProperties) chatProperties;
|
||||
return new QianWenChatClient(
|
||||
new QianWenApi(
|
||||
qianWenProperties.getAccessKeyId(),
|
||||
qianWenProperties.getAccessKeySecret(),
|
||||
qianWenProperties.getAgentKey(),
|
||||
qianWenProperties.getEndpoint()
|
||||
),
|
||||
new QianWenOptions()
|
||||
.setAppId(qianWenProperties.getAppId())
|
||||
);
|
||||
} else if (AiPlatformEnum.YI_YAN == chatProperties.getAiPlatform()) {
|
||||
YudaoAiProperties.YiYanProperties yiYanProperties = (YudaoAiProperties.YiYanProperties) chatProperties;
|
||||
return new YiYanChatClient(
|
||||
new YiYanApi(
|
||||
yiYanProperties.getAppKey(),
|
||||
yiYanProperties.getSecretKey(),
|
||||
yiYanProperties.getChatModel(),
|
||||
yiYanProperties.getRefreshTokenSecondTime()
|
||||
),
|
||||
new YiYanOptions().setMax_output_tokens(2048));
|
||||
}
|
||||
throw new AiException("不支持的Ai类型!");
|
||||
}
|
||||
|
||||
|
||||
private static YudaoAiProperties.ChatProperties getChatProperties(AiPlatformEnum aiPlatformEnum, Map<String, Object> aiPlatformMap) {
|
||||
if (AiPlatformEnum.XING_HUO == aiPlatformEnum) {
|
||||
YudaoAiProperties.XingHuoProperties xingHuoProperties = new YudaoAiProperties.XingHuoProperties();
|
||||
BeanUtil.fillBeanWithMap(aiPlatformMap, xingHuoProperties, true);
|
||||
return xingHuoProperties;
|
||||
} else if (AiPlatformEnum.YI_YAN == aiPlatformEnum) {
|
||||
YudaoAiProperties.YiYanProperties yiYanProperties = new YudaoAiProperties.YiYanProperties();
|
||||
BeanUtil.fillBeanWithMap(aiPlatformMap, yiYanProperties, true);
|
||||
return yiYanProperties;
|
||||
} else if (AiPlatformEnum.QIAN_WEN == aiPlatformEnum) {
|
||||
YudaoAiProperties.QianWenProperties qianWenProperties = new YudaoAiProperties.QianWenProperties();
|
||||
BeanUtil.fillBeanWithMap(aiPlatformMap, qianWenProperties, true);
|
||||
return qianWenProperties;
|
||||
}
|
||||
throw new AiException("不支持的Ai类型!");
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "yudao.ai.yiyan.enable", havingValue = "true")
|
||||
public YiYanChatClient yiYanChatClient(YudaoAiProperties yudaoAiProperties) {
|
||||
YudaoAiProperties.YiYanProperties yiYanProperties = yudaoAiProperties.getYiyan();
|
||||
return new YiYanChatClient(
|
||||
new YiYanApi(
|
||||
yiYanProperties.getAppKey(),
|
||||
yiYanProperties.getSecretKey(),
|
||||
yiYanProperties.getChatModel(),
|
||||
yiYanProperties.getRefreshTokenSecondTime()
|
||||
),
|
||||
new YiYanOptions().setMax_output_tokens(2048));
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.ai.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.ai.chat.ChatClient;
|
||||
import cn.iocoder.yudao.framework.ai.chat.ChatResponse;
|
||||
import cn.iocoder.yudao.framework.ai.chat.StreamingChatClient;
|
||||
import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt;
|
||||
import cn.iocoder.yudao.framework.ai.exception.AiException;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* yudao ai client
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/14 10:27
|
||||
* @since 1.0
|
||||
*/
|
||||
public class YudaoAiClient implements AiClient {
|
||||
|
||||
protected Map<String, Object> chatClientMap;
|
||||
|
||||
public YudaoAiClient(Map<String, Object> chatClientMap) {
|
||||
this.chatClientMap = chatClientMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse call(Prompt prompt, String clientName) {
|
||||
if (!chatClientMap.containsKey(clientName)) {
|
||||
throw new AiException("clientName不存在!");
|
||||
}
|
||||
ChatClient chatClient = (ChatClient) chatClientMap.get(clientName);
|
||||
return chatClient.call(prompt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<ChatResponse> stream(Prompt prompt, String clientName) {
|
||||
if (!chatClientMap.containsKey(clientName)) {
|
||||
throw new AiException("clientName不存在!");
|
||||
}
|
||||
StreamingChatClient streamingChatClient = (StreamingChatClient) chatClientMap.get(clientName);
|
||||
return streamingChatClient.stream(prompt);
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package cn.iocoder.yudao.framework.ai.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||
import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
|
||||
import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoOptions;
|
||||
import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ai 自动配置
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/12 16:29
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class YudaoAiImageProperties extends LinkedHashMap<String, Map<String, Object>> {
|
||||
|
||||
private String initType;
|
||||
private QianWenProperties qianwen;
|
||||
private XingHuoOptions xinghuo;
|
||||
private YiYanProperties yiyan;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class QianWenProperties extends ChatProperties {
|
||||
/**
|
||||
* 阿里云:服务器接入点
|
||||
*/
|
||||
private String endpoint = "bailian.cn-beijing.aliyuncs.com";
|
||||
/**
|
||||
* 阿里云:权限 accessKeyId
|
||||
*/
|
||||
private String accessKeyId;
|
||||
/**
|
||||
* 阿里云:权限 accessKeySecret
|
||||
*/
|
||||
private String accessKeySecret;
|
||||
/**
|
||||
* 阿里云:agentKey
|
||||
*/
|
||||
private String agentKey;
|
||||
/**
|
||||
* 阿里云:agentKey(相当于应用id)
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class XingHuoProperties extends ChatProperties {
|
||||
private String appId;
|
||||
private String appKey;
|
||||
private String secretKey;
|
||||
private XingHuoChatModel chatModel;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class YiYanProperties extends ChatProperties {
|
||||
/**
|
||||
* appKey
|
||||
*/
|
||||
private String appKey;
|
||||
/**
|
||||
* secretKey
|
||||
*/
|
||||
private String secretKey;
|
||||
/**
|
||||
* 模型
|
||||
*/
|
||||
private YiYanChatModel chatModel = YiYanChatModel.ERNIE4_3_5_8K;
|
||||
/**
|
||||
* token 刷新时间(默认 86400 = 24小时)
|
||||
*/
|
||||
private int refreshTokenSecondTime = 86400;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ChatProperties {
|
||||
|
||||
private AiPlatformEnum aiPlatform;
|
||||
|
||||
private Float temperature;
|
||||
|
||||
private Float topP;
|
||||
|
||||
private Integer topK;
|
||||
}
|
||||
}
|
@ -7,9 +7,6 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ai 自动配置
|
||||
*
|
||||
@ -18,17 +15,21 @@ import java.util.Map;
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@ConfigurationProperties(prefix = "yudao.ai")
|
||||
public class YudaoAiProperties extends LinkedHashMap<String, Map<String, Object>> {
|
||||
public class YudaoAiProperties {
|
||||
|
||||
// private QianWenProperties qianWen;
|
||||
// private XingHuoProperties xingHuo;
|
||||
// private YiYanProperties yiYan;
|
||||
private String initSource;
|
||||
private QianWenProperties qianwen;
|
||||
private XingHuoProperties xinghuo;
|
||||
private YiYanProperties yiyan;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ChatProperties {
|
||||
|
||||
private boolean enable = false;
|
||||
|
||||
private AiPlatformEnum aiPlatform;
|
||||
|
||||
private Float temperature;
|
||||
|
Reference in New Issue
Block a user