mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-16 13:23:42 +00:00
add:集成国产大模型 ds、zhipu、qianwen
This commit is contained in:
@@ -34,11 +34,11 @@
|
|||||||
<!-- 对话基础模块 -->
|
<!-- 对话基础模块 -->
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- <dependency>-->
|
<!-- <dependency>-->
|
||||||
<!-- <groupId>io.modelcontextprotocol.sdk</groupId>-->
|
<!-- <groupId>io.modelcontextprotocol.sdk</groupId>-->
|
||||||
<!-- <artifactId>mcp-spring-webflux</artifactId>-->
|
<!-- <artifactId>mcp-spring-webflux</artifactId>-->
|
||||||
<!-- <version>0.8.0</version>-->
|
<!-- <version>0.8.0</version>-->
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ruoyi</groupId>
|
<groupId>org.ruoyi</groupId>
|
||||||
@@ -83,6 +83,63 @@
|
|||||||
<version>0.3.1</version>
|
<version>0.3.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j-open-ai</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j-core</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j-http-client-jdk</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j-community-zhipu-ai</artifactId>
|
||||||
|
<version>1.0.1-beta6</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j-community-dashscope</artifactId>
|
||||||
|
<version>1.0.1-beta6</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
<version>0.12.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.12.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.12.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.12.6</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ public enum ChatModeType {
|
|||||||
CHAT("chat", "中转模型"),
|
CHAT("chat", "中转模型"),
|
||||||
DIFY("dify", "DIFY"),
|
DIFY("dify", "DIFY"),
|
||||||
COZE("coze", "扣子"),
|
COZE("coze", "扣子"),
|
||||||
|
|
||||||
|
ZHIPU("zhipu", "智谱清言"),
|
||||||
|
|
||||||
|
DEEPSEEK("deepseek", "深度求索"),
|
||||||
|
|
||||||
|
QIANWEN("qianwen", "通义千问"),
|
||||||
|
|
||||||
VECTOR("vector", "知识库向量模型");
|
VECTOR("vector", "知识库向量模型");
|
||||||
|
|
||||||
private final String code;
|
private final String code;
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package org.ruoyi.chat.service.chat;
|
|||||||
import org.ruoyi.common.chat.request.ChatRequest;
|
import org.ruoyi.common.chat.request.ChatRequest;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对话Service接口
|
* 对话Service接口
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.ruoyi.chat.service.chat;
|
||||||
|
|
||||||
|
import dev.langchain4j.service.TokenStream;
|
||||||
|
|
||||||
|
public interface StreamAssistant {
|
||||||
|
TokenStream chat(String message);
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import com.coze.openapi.client.chat.model.ChatEvent;
|
|||||||
import com.coze.openapi.client.chat.model.ChatEventType;
|
import com.coze.openapi.client.chat.model.ChatEventType;
|
||||||
import com.coze.openapi.client.connversations.message.model.Message;
|
import com.coze.openapi.client.connversations.message.model.Message;
|
||||||
import com.coze.openapi.service.auth.TokenAuth;
|
import com.coze.openapi.service.auth.TokenAuth;
|
||||||
import com.coze.openapi.service.config.Consts;
|
|
||||||
import com.coze.openapi.service.service.CozeAPI;
|
import com.coze.openapi.service.service.CozeAPI;
|
||||||
import io.reactivex.Flowable;
|
import io.reactivex.Flowable;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -37,7 +36,6 @@ public class CozeServiceImpl implements IChatService {
|
|||||||
@Override
|
@Override
|
||||||
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
|
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
|
||||||
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
||||||
|
|
||||||
TokenAuth authCli = new TokenAuth(chatModelVo.getApiKey());
|
TokenAuth authCli = new TokenAuth(chatModelVo.getApiKey());
|
||||||
CozeAPI coze =
|
CozeAPI coze =
|
||||||
new CozeAPI.Builder()
|
new CozeAPI.Builder()
|
||||||
@@ -49,7 +47,7 @@ public class CozeServiceImpl implements IChatService {
|
|||||||
CreateChatReq.builder()
|
CreateChatReq.builder()
|
||||||
.botID(chatModelVo.getModelName())
|
.botID(chatModelVo.getModelName())
|
||||||
.userID(chatRequest.getUserId().toString())
|
.userID(chatRequest.getUserId().toString())
|
||||||
.messages(Collections.singletonList(Message.buildUserQuestionText("What can you do?")))
|
.messages(Collections.singletonList(Message.buildUserQuestionText(chatRequest.getPrompt())))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Flowable<ChatEvent> resp = coze.chat().stream(req);
|
Flowable<ChatEvent> resp = coze.chat().stream(req);
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.ruoyi.chat.service.chat.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import dev.langchain4j.model.chat.StreamingChatModel;
|
||||||
|
import dev.langchain4j.model.chat.response.ChatResponse;
|
||||||
|
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
|
||||||
|
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.ruoyi.chat.enums.ChatModeType;
|
||||||
|
import org.ruoyi.chat.service.chat.IChatService;
|
||||||
|
import org.ruoyi.common.chat.request.ChatRequest;
|
||||||
|
import org.ruoyi.domain.vo.ChatModelVo;
|
||||||
|
import org.ruoyi.service.IChatModelService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deepseek
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class DeepSeekChatImpl implements IChatService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IChatModelService chatModelService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
|
||||||
|
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
||||||
|
StreamingChatModel chatModel = OpenAiStreamingChatModel.builder()
|
||||||
|
.baseUrl(chatModelVo.getApiHost())
|
||||||
|
.apiKey(chatModelVo.getApiKey())
|
||||||
|
.modelName(chatModelVo.getModelName())
|
||||||
|
.logRequests(true)
|
||||||
|
.logResponses(true)
|
||||||
|
.temperature(0.8)
|
||||||
|
.build();
|
||||||
|
// 发送流式消息
|
||||||
|
try {
|
||||||
|
chatModel.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() {
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void onPartialResponse(String partialResponse) {
|
||||||
|
emitter.send(partialResponse);
|
||||||
|
log.info("收到消息片段: {}", partialResponse);
|
||||||
|
System.out.print(partialResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompleteResponse(ChatResponse completeResponse) {
|
||||||
|
emitter.complete();
|
||||||
|
log.info("消息结束,完整消息ID: {}", completeResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable error) {
|
||||||
|
System.err.println("错误: " + error.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("deepseek请求失败:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return ChatModeType.DEEPSEEK.getCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package org.ruoyi.chat.service.chat.impl;
|
||||||
|
|
||||||
|
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
|
||||||
|
import dev.langchain4j.community.model.zhipu.ZhipuAiStreamingChatModel;
|
||||||
|
import dev.langchain4j.model.chat.StreamingChatModel;
|
||||||
|
import dev.langchain4j.model.chat.response.ChatResponse;
|
||||||
|
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.ruoyi.chat.enums.ChatModeType;
|
||||||
|
import org.ruoyi.chat.service.chat.IChatService;
|
||||||
|
import org.ruoyi.common.chat.request.ChatRequest;
|
||||||
|
import org.ruoyi.domain.ChatMessage;
|
||||||
|
import org.ruoyi.domain.vo.ChatModelVo;
|
||||||
|
import org.ruoyi.service.IChatModelService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import static dev.langchain4j.data.message.SystemMessage.systemMessage;
|
||||||
|
import static dev.langchain4j.data.message.UserMessage.userMessage;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里通义千问
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class QianWenAiChatServiceImpl implements IChatService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IChatModelService chatModelService;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
|
||||||
|
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
||||||
|
StreamingChatModel model = QwenStreamingChatModel.builder()
|
||||||
|
.apiKey(chatModelVo.getApiKey())
|
||||||
|
.modelName(chatModelVo.getModelName())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发送流式消息
|
||||||
|
try {
|
||||||
|
model.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() {
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void onPartialResponse(String partialResponse) {
|
||||||
|
emitter.send(partialResponse);
|
||||||
|
log.info("收到消息片段: {}", partialResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompleteResponse(ChatResponse completeResponse) {
|
||||||
|
emitter.complete();
|
||||||
|
log.info("消息结束,完整消息ID: {}", completeResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable error) {
|
||||||
|
error.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("千问请求失败:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return ChatModeType.QIANWEN.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package org.ruoyi.chat.service.chat.impl;
|
||||||
|
|
||||||
|
import dev.langchain4j.agent.tool.ToolSpecification;
|
||||||
|
import dev.langchain4j.community.model.zhipu.ZhipuAiStreamingChatModel;
|
||||||
|
import dev.langchain4j.model.chat.StreamingChatModel;
|
||||||
|
import dev.langchain4j.model.chat.response.ChatResponse;
|
||||||
|
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.ruoyi.chat.enums.ChatModeType;
|
||||||
|
import org.ruoyi.chat.service.chat.IChatService;
|
||||||
|
import org.ruoyi.common.chat.request.ChatRequest;
|
||||||
|
import org.ruoyi.domain.vo.ChatModelVo;
|
||||||
|
import org.ruoyi.service.IChatModelService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 智谱AI
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class ZhipuAiChatServiceImpl implements IChatService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IChatModelService chatModelService;
|
||||||
|
|
||||||
|
|
||||||
|
ToolSpecification currentTime = ToolSpecification.builder()
|
||||||
|
.name("currentTime")
|
||||||
|
.description("currentTime")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter){
|
||||||
|
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
||||||
|
// 发送流式消息
|
||||||
|
try {
|
||||||
|
StreamingChatResponseHandler handler = new StreamingChatResponseHandler() {
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void onPartialResponse(String token) {
|
||||||
|
System.out.println(token);
|
||||||
|
emitter.send(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable error) {
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
emitter.send(error.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompleteResponse(ChatResponse response) {
|
||||||
|
emitter.complete();
|
||||||
|
log.info("消息结束,完整消息ID: {}", response.aiMessage());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
StreamingChatModel model = ZhipuAiStreamingChatModel.builder()
|
||||||
|
.model(chatModelVo.getModelName())
|
||||||
|
.apiKey(chatModelVo.getApiKey())
|
||||||
|
.logRequests(true)
|
||||||
|
.logResponses(true)
|
||||||
|
.build();
|
||||||
|
model.chat(chatRequest.getPrompt(), handler);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("智谱清言请求失败:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return ChatModeType.ZHIPU.getCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user