context:工作流与大模型聊天对话整合(新增Common-Chat公共对话接口)

This commit is contained in:
zengxb
2026-02-13 17:56:55 +08:00
parent 91a44e1ba8
commit 420e05ecf3
61 changed files with 879 additions and 291 deletions

View File

@@ -1,9 +1,9 @@
package org.ruoyi.service.chat;
import org.ruoyi.common.chat.domain.dto.ChatMessageDTO;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.domain.bo.chat.ChatMessageBo;
import org.ruoyi.domain.dto.ChatMessageDTO;
import org.ruoyi.domain.vo.chat.ChatMessageVo;
import java.util.Collection;

View File

@@ -1,76 +0,0 @@
package org.ruoyi.service.chat;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.domain.bo.chat.ChatModelBo;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import java.util.Collection;
import java.util.List;
/**
* 模型管理Service接口
*
* @author ageerle
* @date 2025-12-14
*/
public interface IChatModelService {
/**
* 查询模型管理
*
* @param id 主键
* @return 模型管理
*/
ChatModelVo queryById(Long id);
/**
* 根据模型名称查询模型
*
* @param modelName 模型名称
* @return 模型管理
*/
ChatModelVo selectModelByName(String modelName);
/**
* 分页查询模型管理列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 模型管理分页列表
*/
TableDataInfo<ChatModelVo> queryPageList(ChatModelBo bo, PageQuery pageQuery);
/**
* 查询符合条件的模型管理列表
*
* @param bo 查询条件
* @return 模型管理列表
*/
List<ChatModelVo> queryList(ChatModelBo bo);
/**
* 新增模型管理
*
* @param bo 模型管理
* @return 是否新增成功
*/
Boolean insertByBo(ChatModelBo bo);
/**
* 修改模型管理
*
* @param bo 模型管理
* @return 是否修改成功
*/
Boolean updateByBo(ChatModelBo bo);
/**
* 校验并批量删除模型管理信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -1,26 +0,0 @@
package org.ruoyi.service.chat;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
* 对话Service接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface IChatService {
/**
* 客户端发送对话消息到服务端
*/
SseEmitter chat(ChatModelVo chatModelVo, ChatRequest chatRequest,SseEmitter emitter,Long userId,String tokenValue);
/**
* 获取服务提供商名称
*/
String getProviderName();
}

View File

@@ -4,6 +4,7 @@ import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.supervisor.SupervisorAgent;
import dev.langchain4j.agentic.supervisor.SupervisorResponseStrategy;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
@@ -23,20 +24,21 @@ import org.ruoyi.agent.WebSearchAgent;
import org.ruoyi.agent.tool.ExecuteSqlQueryTool;
import org.ruoyi.agent.tool.QueryAllTablesTool;
import org.ruoyi.agent.tool.QueryTableSchemaTool;
import org.ruoyi.common.chat.Service.IChatService;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.core.utils.ObjectUtils;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.sse.utils.SseMessageUtils;
import org.ruoyi.domain.bo.chat.ChatMessageBo;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.RoleType;
import org.ruoyi.service.chat.IChatMessageService;
import org.ruoyi.service.chat.IChatService;
import org.ruoyi.service.chat.impl.memory.PersistentChatMemoryStore;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -76,23 +78,50 @@ public abstract class AbstractStreamingChatService implements IChatService {
*/
@Override
public SseEmitter chat(ChatModelVo chatModelVo, ChatRequest chatRequest, SseEmitter emitter, Long userId, String tokenValue) {
return executeChat(chatModelVo, chatRequest, emitter, userId, tokenValue, null);
}
/**
* 定义聊天流程骨架(包含流式回调结构)
*/
@Override
public SseEmitter chat(ChatModelVo chatModelVo, ChatRequest chatRequest, SseEmitter emitter, Long userId, String tokenValue, StreamingChatResponseHandler handler) {
return executeChat(chatModelVo, chatRequest, emitter, userId, tokenValue, handler);
}
/**
* 定义聊天流程骨架
*/
public SseEmitter executeChat(ChatModelVo chatModelVo, ChatRequest chatRequest, SseEmitter emitter, Long userId, String tokenValue, StreamingChatResponseHandler handler) {
try {
String content = chatRequest.getMessages().get(0).getContent();
String content = Optional.ofNullable(chatRequest.getMessages()).filter(messages -> !messages.isEmpty())
// 对话逻辑:从 messages 筛选第一个元素
.map(messages -> messages.get(0).getContent())
.filter(StringUtils::isNotBlank)
// 工作流逻辑:从 chatMessages 筛选 UserMessage 的文本
.orElseGet(() -> Optional.ofNullable(chatRequest.getChatMessages()).orElse(List.of()).stream()
.filter(message -> message instanceof UserMessage um)
.map(message -> ((UserMessage) message).singleText())
.filter(StringUtils::isNotBlank)
.findFirst()
.orElse(""));
// 保存用户消息
saveChatMessage(chatRequest, userId, content, RoleType.USER.getName(), chatModelVo);
// 使用长期记忆增强的消息列表
List<ChatMessage> messagesWithMemory = buildMessagesWithMemory(chatRequest);
if(chatRequest.getEnableThinking()){
String msg = doAgent(content,chatModelVo);
if (chatRequest.getEnableThinking()) {
String msg = doAgent(content, chatModelVo);
SseMessageUtils.sendMessage(userId, msg);
SseMessageUtils.completeConnection(userId, tokenValue);
// 保存助手回复消息
saveChatMessage(chatRequest, userId, msg, RoleType.ASSISTANT.getName(), chatModelVo);
}else {
} else {
// 创建包含内存管理的响应处理器
StreamingChatResponseHandler handler = createResponseHandler(chatRequest, userId, tokenValue, chatModelVo);
if (ObjectUtils.isEmpty(handler)) {
handler = createResponseHandler(chatRequest, userId, tokenValue, chatModelVo);
}
// 调用具体实现的聊天方法
doChat(chatModelVo, chatRequest, messagesWithMemory, handler);
}
@@ -115,8 +144,6 @@ public abstract class AbstractStreamingChatService implements IChatService {
*/
protected List<ChatMessage> buildMessagesWithMemory(ChatRequest chatRequest) {
List<ChatMessage> messages = new ArrayList<>();
// 加载历史消息
if (enablePersistentMemory && chatRequest.getSessionId() != null) {
MessageWindowChatMemory memory = createChatMemory(chatRequest.getSessionId());
if (memory != null) {
@@ -126,8 +153,13 @@ public abstract class AbstractStreamingChatService implements IChatService {
log.debug("已加载 {} 条历史消息用于会话 {}", historicalMessages.size(), chatRequest.getSessionId());
}
}
return messages;
}
// 工作流方式
List<ChatMessage> chatMessages = chatRequest.getChatMessages();
if (!CollectionUtils.isEmpty(chatMessages)){
messages.addAll(chatMessages);
}
return messages;
}
@@ -172,16 +204,16 @@ public abstract class AbstractStreamingChatService implements IChatService {
*
* @param chatModelVo 模型配置
* @param chatRequest 聊天请求
* @param handler 响应处理器
* @param handler 响应处理器
*/
protected abstract void doChat(ChatModelVo chatModelVo, ChatRequest chatRequest, List<ChatMessage> messagesWithMemory,StreamingChatResponseHandler handler);
protected abstract void doChat(ChatModelVo chatModelVo, ChatRequest chatRequest, List<ChatMessage> messagesWithMemory, StreamingChatResponseHandler handler);
/**
* 创建标准的响应处理器
*
* @param chatRequest 聊天请求包含sessionId等上下文信息
* @param userId 用户ID
* @param tokenValue 会话令牌
* @param userId 用户ID
* @param tokenValue 会话令牌
* @param chatModelVo 模型配置
* @return 标准的流式响应处理器
*/
@@ -225,7 +257,7 @@ public abstract class AbstractStreamingChatService implements IChatService {
@Override
public void onError(Throwable error) {
log.error("{}流式响应错误: {}", getProviderName(), error.getMessage(), error);
// 发送错误消息到前端
try {
String errorMessage = String.format("模型调用失败: %s", error.getMessage());
@@ -233,7 +265,7 @@ public abstract class AbstractStreamingChatService implements IChatService {
} catch (Exception e) {
log.error("发送错误消息失败: {}", e.getMessage(), e);
}
// 关闭SSE连接避免前端一直等待
try {
SseMessageUtils.completeConnection(userId, tokenValue);
@@ -248,9 +280,9 @@ public abstract class AbstractStreamingChatService implements IChatService {
* 保存聊天消息到数据库
*
* @param chatRequest 聊天请求
* @param userId 用户ID
* @param content 消息内容
* @param role 消息角色
* @param userId 用户ID
* @param content 消息内容
* @param role 消息角色
* @param chatModelVo 模型配置
*/
private void saveChatMessage(ChatRequest chatRequest, Long userId, String content, String role, ChatModelVo chatModelVo) {
@@ -290,7 +322,7 @@ public abstract class AbstractStreamingChatService implements IChatService {
*/
public abstract String getProviderName();
protected String doAgent(String userMessage,ChatModelVo chatModelVo) {
protected String doAgent(String userMessage, ChatModelVo chatModelVo) {
// 步骤1: 配置MCP传输层 - 连接到bing-cn-mcp服务器
// 该服务提供两个工具: bing_search (必应搜索) 和 crawl_webpage (网页抓取)
McpTransport transport = new StdioMcpTransport.Builder()
@@ -357,7 +389,7 @@ public abstract class AbstractStreamingChatService implements IChatService {
SupervisorAgent supervisor = AgenticServices
.supervisorBuilder()
.chatModel(PLANNER_MODEL)
.subAgents(sqlAgent,chartGenerationAgent)
.subAgents(sqlAgent, chartGenerationAgent)
.responseStrategy(SupervisorResponseStrategy.LAST)
.build();

View File

@@ -1,5 +1,6 @@
package org.ruoyi.service.chat.impl;
import org.ruoyi.common.chat.domain.dto.ChatMessageDTO;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
@@ -9,7 +10,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.dto.ChatMessageDTO;
import org.ruoyi.service.chat.IChatMessageService;
import org.springframework.stereotype.Service;
import org.ruoyi.domain.bo.chat.ChatMessageBo;
@@ -146,7 +146,7 @@ public class ChatMessageServiceImpl implements IChatMessageService {
* @return 消息DTO列表
*/
@Override
public List<org.ruoyi.domain.dto.ChatMessageDTO> getMessagesBySessionId(Long sessionId) {
public List<ChatMessageDTO> getMessagesBySessionId(Long sessionId) {
if (sessionId == null) {
return new java.util.ArrayList<>();
}

View File

@@ -1,5 +1,9 @@
package org.ruoyi.service.chat.impl;
import org.ruoyi.common.chat.Service.IChatModelService;
import org.ruoyi.common.chat.domain.bo.chat.ChatModelBo;
import org.ruoyi.common.chat.domain.entity.chat.ChatModel;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
@@ -9,11 +13,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.service.chat.IChatModelService;
import org.springframework.stereotype.Service;
import org.ruoyi.domain.bo.chat.ChatModelBo;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.domain.entity.chat.ChatModel;
import org.ruoyi.mapper.chat.ChatModelMapper;
import java.util.List;

View File

@@ -4,16 +4,17 @@ import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.Service.IChatModelService;
import org.ruoyi.common.chat.Service.IChatService;
import org.ruoyi.common.chat.domain.dto.ChatMessageDTO;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.factory.ChatServiceFactory;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.common.sse.core.SseEmitterManager;
import org.ruoyi.domain.bo.vector.QueryVectorBo;
import org.ruoyi.domain.dto.ChatMessageDTO;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeInfoVo;
import org.ruoyi.factory.ChatServiceFactory;
import org.ruoyi.service.chat.IChatModelService;
import org.ruoyi.service.chat.IChatService;
;
import org.ruoyi.service.knowledge.IKnowledgeInfoService;
import org.ruoyi.service.vector.VectorStoreService;
import org.springframework.stereotype.Service;

View File

@@ -1,17 +1,7 @@
package org.ruoyi.service.chat.impl.memory;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.dto.ChatMessageDTO;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import java.util.ArrayList;
import java.util.List;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
/**
* 长期记忆使用示例
@@ -322,4 +312,4 @@ public class ChatMemoryUsageExample {
private boolean isTemporaryChatSession(ChatRequest request) {
return false;
}
}
}

View File

@@ -3,8 +3,8 @@ package org.ruoyi.service.chat.impl.memory;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.domain.dto.ChatMessageDTO;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.domain.dto.ChatMessageDTO;
import org.ruoyi.service.chat.IChatMessageService;
import java.util.ArrayList;

View File

@@ -5,11 +5,11 @@ import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.service.chat.impl.AbstractStreamingChatService;
import org.springframework.stereotype.Service;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import java.util.List;

View File

@@ -1,28 +1,13 @@
package org.ruoyi.service.chat.impl.provider;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.supervisor.SupervisorAgent;
import dev.langchain4j.agentic.supervisor.SupervisorResponseStrategy;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.service.tool.ToolProvider;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.agent.ChartGenerationAgent;
import org.ruoyi.agent.SqlAgent;
import org.ruoyi.agent.WebSearchAgent;
import org.ruoyi.agent.tool.ExecuteSqlQueryTool;
import org.ruoyi.agent.tool.QueryAllTablesTool;
import org.ruoyi.agent.tool.QueryTableSchemaTool;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.service.chat.impl.AbstractStreamingChatService;
import org.springframework.stereotype.Service;
@@ -57,8 +42,6 @@ public class OpenAIServiceImpl extends AbstractStreamingChatService {
}
@Override
public String getProviderName() {
return ChatModeType.OPEN_AI.getCode();

View File

@@ -1,16 +1,34 @@
package org.ruoyi.service.chat.impl.provider;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.supervisor.SupervisorAgent;
import dev.langchain4j.agentic.supervisor.SupervisorResponseStrategy;
import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.StreamableHttpMcpTransport;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.service.tool.ToolProvider;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.agent.McpAgent;
import org.ruoyi.config.McpSseConfig;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.domain.dto.request.ChatRequest;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.service.chat.impl.AbstractStreamingChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import java.util.ArrayList;
import java.util.List;
/**
@@ -23,6 +41,17 @@ import java.util.List;
@Slf4j
public class QianWenChatServiceImpl extends AbstractStreamingChatService {
@Autowired
private McpSseConfig mcpSseConfig;
/**
* 千问开发者默认地址
*/
private static final String QWEN_API_HOST = "https://dashscope.aliyuncs.com/api/v1";
// 添加文档解析的前缀字段
private static final String UPLOAD_FILE_API_PREFIX = "fileid";
@Override
protected StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo,ChatRequest chatRequest) {
return QwenStreamingChatModel.builder()
@@ -35,7 +64,98 @@ public class QianWenChatServiceImpl extends AbstractStreamingChatService {
protected void doChat(ChatModelVo chatModelVo,ChatRequest chatRequest,List<ChatMessage> messagesWithMemory,
StreamingChatResponseHandler handler) {
StreamingChatModel streamingChatModel = buildStreamingChatModel(chatModelVo,chatRequest);
streamingChatModel.chat(messagesWithMemory, handler);
// 判断是否存在需要使用阿里千问的文档解析功能
List<ChatMessage> chatMessages = hasFileIdData(messagesWithMemory);
streamingChatModel.chat(chatMessages, handler);
}
/**
* 检查是否包含fileId数据
*/
private List<ChatMessage> hasFileIdData(List<ChatMessage> messagesWithMemory) {
if (CollectionUtils.isEmpty(messagesWithMemory)) {
return messagesWithMemory;
}
// 找到包含阿里上传文件前缀的用户信息
var foundUserMessage = messagesWithMemory.stream()
.filter(message -> message instanceof UserMessage)
.map(message -> (UserMessage) message)
.filter(userMessage ->
userMessage.singleText().toLowerCase().contains(UPLOAD_FILE_API_PREFIX.toLowerCase())
)
.findFirst();
// 找到原本SystemMessage
var systemMessage = messagesWithMemory.stream()
.filter(message -> message instanceof SystemMessage)
.map(message -> (SystemMessage) message)
.findFirst();
// 判断是否存在并重新构建信息体(符合千问文档解析格式)
return foundUserMessage.map(userMsg -> {
List<ChatMessage> messages = new ArrayList<>();
messages.add(new SystemMessage(userMsg.singleText()));
systemMessage.ifPresent(sysMsg -> messages.add(new UserMessage(sysMsg.text())));
return messages;
}).orElse(messagesWithMemory);
}
/**
* 调用MCP服务智能体
* @param userMessage 用户信息
* @param chatModelVo 模型信息
* @return 返回LLM信息
*/
protected String doAgent(String userMessage,ChatModelVo chatModelVo) {
// 判断是否开启MCP服务
if (!mcpSseConfig.isEnabled()) {
return "";
}
// 步骤1根据SSE对外暴露端点连接
McpTransport httpMcpTransport = new StreamableHttpMcpTransport.Builder().
url(mcpSseConfig.getUrl()).
logRequests(true).
build();
// 步骤2开启客户端连接
McpClient mcpClient = new DefaultMcpClient.Builder()
.transport(httpMcpTransport)
.build();
// 获取所有mcp工具
List<ToolSpecification> toolSpecifications = mcpClient.listTools();
System.out.println(toolSpecifications);
// 步骤3将mcp对象包装
ToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
// 步骤4加载LLM模型对话
QwenChatModel qwenChatModel = QwenChatModel.builder()
.baseUrl(QWEN_API_HOST)
.apiKey(chatModelVo.getApiKey())
.modelName(chatModelVo.getModelName())
.build();
// 步骤5将MCP对象由智能体Agent管控
McpAgent mcpAgent = AgenticServices.agentBuilder(McpAgent.class)
.chatModel(qwenChatModel)
.toolProvider(toolProvider)
.build();
// 步骤6将所有MCP对象由超级智能体管控
SupervisorAgent supervisor = AgenticServices
.supervisorBuilder()
.chatModel(qwenChatModel)
.subAgents(mcpAgent)
.responseStrategy(SupervisorResponseStrategy.LAST)
.build();
// 步骤7调用大模型LLM
return supervisor.invoke(userMessage);
}
@Override

View File

@@ -1,7 +1,7 @@
package org.ruoyi.service.embed;
import dev.langchain4j.model.embedding.EmbeddingModel;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ModalityType;

View File

@@ -5,7 +5,7 @@ import dev.langchain4j.community.model.dashscope.QwenEmbeddingModel;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.output.Response;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.springframework.stereotype.Component;
import org.ruoyi.enums.ModalityType;

View File

@@ -7,10 +7,10 @@ import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.domain.dto.MultiModalInput;
import org.ruoyi.domain.dto.request.AliyunMultiModalEmbedRequest;
import org.ruoyi.domain.dto.response.AliyunMultiModalEmbedResponse;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ModalityType;
import org.ruoyi.service.embed.MultiModalEmbedModelService;
import org.springframework.stereotype.Component;

View File

@@ -4,7 +4,7 @@ import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.ollama.OllamaEmbeddingModel;
import dev.langchain4j.model.output.Response;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ModalityType;
import org.ruoyi.service.embed.BaseEmbedModelService;
import org.springframework.stereotype.Component;

View File

@@ -4,7 +4,7 @@ import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.model.output.Response;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ModalityType;
import org.ruoyi.service.embed.BaseEmbedModelService;
import org.springframework.stereotype.Component;

View File

@@ -1,7 +1,7 @@
package org.ruoyi.service.graph;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
/**
* 图谱LLM服务接口

View File

@@ -5,7 +5,7 @@ import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.service.graph.IGraphLLMService;
import org.springframework.stereotype.Service;

View File

@@ -10,7 +10,7 @@ import io.github.imfangs.dify.client.event.MessageEvent;
import io.github.imfangs.dify.client.model.DifyConfig;
import io.github.imfangs.dify.client.model.chat.ChatMessage;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.service.graph.IGraphLLMService;
import org.springframework.stereotype.Service;

View File

@@ -3,15 +3,15 @@ package org.ruoyi.service.graph.impl;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.Service.IChatModelService;
import org.ruoyi.common.chat.domain.bo.chat.ChatModelBo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.config.GraphExtractPrompt;
import org.ruoyi.constant.GraphConstants;
import org.ruoyi.domain.bo.chat.ChatModelBo;
import org.ruoyi.domain.dto.ExtractedEntity;
import org.ruoyi.domain.dto.ExtractedRelation;
import org.ruoyi.domain.dto.GraphExtractionResult;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.factory.GraphLLMServiceFactory;
import org.ruoyi.service.chat.IChatModelService;
import org.ruoyi.service.graph.IGraphExtractionService;
import org.ruoyi.service.graph.IGraphLLMService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

View File

@@ -2,7 +2,7 @@ package org.ruoyi.service.graph.impl;
import dev.langchain4j.model.openai.OpenAiChatModel;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.service.graph.IGraphLLMService;
import org.springframework.stereotype.Service;

View File

@@ -2,6 +2,8 @@ package org.ruoyi.service.knowledge.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import org.ruoyi.common.chat.Service.IChatModelService;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.core.domain.dto.OssDTO;
import org.ruoyi.common.core.service.OssService;
import org.ruoyi.common.core.utils.MapstructUtils;
@@ -18,13 +20,11 @@ import org.ruoyi.domain.bo.knowledge.KnowledgeInfoUploadBo;
import org.ruoyi.domain.bo.vector.StoreEmbeddingBo;
import org.ruoyi.domain.entity.knowledge.KnowledgeAttach;
import org.ruoyi.domain.entity.knowledge.KnowledgeFragment;
import org.ruoyi.domain.vo.chat.ChatModelVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeAttachVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeInfoVo;
import org.ruoyi.factory.ResourceLoaderFactory;
import org.ruoyi.mapper.knowledge.KnowledgeAttachMapper;
import org.ruoyi.mapper.knowledge.KnowledgeFragmentMapper;
import org.ruoyi.service.chat.IChatModelService;
import org.ruoyi.service.knowledge.IKnowledgeAttachService;
import org.ruoyi.service.knowledge.IKnowledgeInfoService;
import org.ruoyi.service.knowledge.ResourceLoader;