Commit 708d66e8cf0647cb4c7afa2743794a478c8b9bce
1 parent
bd3e6589
【测试】chat 聊天(send、send-stream)
Showing
5 changed files
with
31 additions
and
43 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.java
| @@ -30,7 +30,7 @@ public class AiChatMessageController { | @@ -30,7 +30,7 @@ public class AiChatMessageController { | ||
| 30 | 30 | ||
| 31 | @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") | 31 | @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") |
| 32 | @PostMapping("/send") | 32 | @PostMapping("/send") |
| 33 | - public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @ModelAttribute AiChatMessageSendReqVO sendReqVO) { | 33 | + public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) { |
| 34 | // TODO done @fan:使用 static import;这样就 success 就行了; | 34 | // TODO done @fan:使用 static import;这样就 success 就行了; |
| 35 | return success(chatService.chat(sendReqVO)); | 35 | return success(chatService.chat(sendReqVO)); |
| 36 | } | 36 | } |
| @@ -39,7 +39,7 @@ public class AiChatMessageController { | @@ -39,7 +39,7 @@ public class AiChatMessageController { | ||
| 39 | // TODO @fan:要不要使用 Flux 来返回;可以使用 Flux<AiChatMessageRespVO> | 39 | // TODO @fan:要不要使用 Flux 来返回;可以使用 Flux<AiChatMessageRespVO> |
| 40 | @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快") | 40 | @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快") |
| 41 | @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) | 41 | @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) |
| 42 | - public SseEmitter sendMessageStream(@Validated @ModelAttribute AiChatMessageSendReqVO sendReqVO) { | 42 | + public SseEmitter sendMessageStream(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) { |
| 43 | Utf8SseEmitter sseEmitter = new Utf8SseEmitter(); | 43 | Utf8SseEmitter sseEmitter = new Utf8SseEmitter(); |
| 44 | chatService.chatStream(sendReqVO, sseEmitter); | 44 | chatService.chatStream(sendReqVO, sseEmitter); |
| 45 | return sseEmitter; | 45 | return sseEmitter; |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatModalServiceImpl.java
| @@ -97,7 +97,7 @@ public class AiChatModalServiceImpl implements AiChatModelService { | @@ -97,7 +97,7 @@ public class AiChatModalServiceImpl implements AiChatModelService { | ||
| 97 | @Override | 97 | @Override |
| 98 | public void validateAvailable(AiChatModalRespVO chatModal) { | 98 | public void validateAvailable(AiChatModalRespVO chatModal) { |
| 99 | // 对话模型是否可用 | 99 | // 对话模型是否可用 |
| 100 | - if (CommonStatusEnum.ENABLE.getStatus().equals(chatModal.getStatus())) { | 100 | + if (!CommonStatusEnum.ENABLE.getStatus().equals(chatModal.getStatus())) { |
| 101 | throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED); | 101 | throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED); |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatServiceImpl.java
| @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | ||
| 19 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; | 19 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 20 | import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper; | 20 | import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper; |
| 21 | import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper; | 21 | import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper; |
| 22 | -import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper; | ||
| 23 | import cn.iocoder.yudao.module.ai.service.AiChatConversationService; | 22 | import cn.iocoder.yudao.module.ai.service.AiChatConversationService; |
| 24 | import cn.iocoder.yudao.module.ai.service.AiChatModelService; | 23 | import cn.iocoder.yudao.module.ai.service.AiChatModelService; |
| 25 | import cn.iocoder.yudao.module.ai.service.AiChatRoleService; | 24 | import cn.iocoder.yudao.module.ai.service.AiChatRoleService; |
| @@ -48,7 +47,6 @@ import java.util.function.Consumer; | @@ -48,7 +47,6 @@ import java.util.function.Consumer; | ||
| 48 | public class AiChatServiceImpl implements AiChatService { | 47 | public class AiChatServiceImpl implements AiChatService { |
| 49 | 48 | ||
| 50 | private final AiChatClientFactory aiChatClientFactory; | 49 | private final AiChatClientFactory aiChatClientFactory; |
| 51 | - private final AiChatRoleMapper aiChatRoleMapper; | ||
| 52 | private final AiChatMessageMapper aiChatMessageMapper; | 50 | private final AiChatMessageMapper aiChatMessageMapper; |
| 53 | private final AiChatConversationMapper aiChatConversationMapper; | 51 | private final AiChatConversationMapper aiChatConversationMapper; |
| 54 | private final AiChatConversationService chatConversationService; | 52 | private final AiChatConversationService chatConversationService; |
| @@ -72,7 +70,7 @@ public class AiChatServiceImpl implements AiChatService { | @@ -72,7 +70,7 @@ public class AiChatServiceImpl implements AiChatService { | ||
| 72 | // 校验角色是否公开 | 70 | // 校验角色是否公开 |
| 73 | aiChatRoleService.validateIsPublic(aiChatRoleDO); | 71 | aiChatRoleService.validateIsPublic(aiChatRoleDO); |
| 74 | // 获取 client 类型 | 72 | // 获取 client 类型 |
| 75 | - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getModel()); | 73 | + AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform()); |
| 76 | // 保存 chat message | 74 | // 保存 chat message |
| 77 | insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(), | 75 | insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(), |
| 78 | chatModal.getModel(), chatModal.getId(), req.getContent(), | 76 | chatModal.getModel(), chatModal.getId(), req.getContent(), |
| @@ -90,13 +88,12 @@ public class AiChatServiceImpl implements AiChatService { | @@ -90,13 +88,12 @@ public class AiChatServiceImpl implements AiChatService { | ||
| 90 | ChatResponse call = chatClient.call(prompt); | 88 | ChatResponse call = chatClient.call(prompt); |
| 91 | content = call.getResult().getOutput().getContent(); | 89 | content = call.getResult().getOutput().getContent(); |
| 92 | // 更新 conversation | 90 | // 更新 conversation |
| 93 | - | ||
| 94 | } catch (Exception e) { | 91 | } catch (Exception e) { |
| 95 | content = ExceptionUtil.getMessage(e); | 92 | content = ExceptionUtil.getMessage(e); |
| 96 | } finally { | 93 | } finally { |
| 97 | // 保存 chat message | 94 | // 保存 chat message |
| 98 | insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(), | 95 | insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(), |
| 99 | - chatModal.getModel(), chatModal.getId(), req.getContent(), | 96 | + chatModal.getModel(), chatModal.getId(), content, |
| 100 | null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); | 97 | null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); |
| 101 | } | 98 | } |
| 102 | return new AiChatMessageRespVO().setContent(content); | 99 | return new AiChatMessageRespVO().setContent(content); |
| @@ -154,7 +151,7 @@ public class AiChatServiceImpl implements AiChatService { | @@ -154,7 +151,7 @@ public class AiChatServiceImpl implements AiChatService { | ||
| 154 | null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); | 151 | null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); |
| 155 | 152 | ||
| 156 | // 获取 client 类型 | 153 | // 获取 client 类型 |
| 157 | - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getModel()); | 154 | + AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform()); |
| 158 | StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum); | 155 | StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum); |
| 159 | Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt); | 156 | Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt); |
| 160 | 157 | ||
| @@ -166,7 +163,7 @@ public class AiChatServiceImpl implements AiChatService { | @@ -166,7 +163,7 @@ public class AiChatServiceImpl implements AiChatService { | ||
| 166 | String content = chatResponse.getResults().get(0).getOutput().getContent(); | 163 | String content = chatResponse.getResults().get(0).getOutput().getContent(); |
| 167 | try { | 164 | try { |
| 168 | contentBuffer.append(content); | 165 | contentBuffer.append(content); |
| 169 | - sseEmitter.send(content, MediaType.APPLICATION_JSON); | 166 | + sseEmitter.send(new AiChatMessageRespVO().setContent(content), MediaType.APPLICATION_JSON); |
| 170 | } catch (IOException e) { | 167 | } catch (IOException e) { |
| 171 | log.error("发送异常{}", ExceptionUtil.getMessage(e)); | 168 | log.error("发送异常{}", ExceptionUtil.getMessage(e)); |
| 172 | // 如果不是因为关闭而抛出异常,则重新连接 | 169 | // 如果不是因为关闭而抛出异常,则重新连接 |
| @@ -183,7 +180,7 @@ public class AiChatServiceImpl implements AiChatService { | @@ -183,7 +180,7 @@ public class AiChatServiceImpl implements AiChatService { | ||
| 183 | sseEmitter.complete(); | 180 | sseEmitter.complete(); |
| 184 | // 保存 chat message | 181 | // 保存 chat message |
| 185 | insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(), | 182 | insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(), |
| 186 | - chatModal.getModel(), chatModal.getId(), req.getContent(), | 183 | + chatModal.getModel(), chatModal.getId(), contentBuffer.toString(), |
| 187 | null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); | 184 | null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); |
| 188 | 185 | ||
| 189 | } | 186 | } |
yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-message.http
| 1 | 1 | ||
| 2 | +### chat call | ||
| 3 | +POST {{baseUrl}}/admin-api/ai/chat/message/send | ||
| 4 | +Content-Type: application/json | ||
| 5 | +Authorization: {{token}} | ||
| 6 | + | ||
| 7 | +{ | ||
| 8 | + "conversationId": "1781604279872581649", | ||
| 9 | + "content": "中国好看吗?" | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | + | ||
| 13 | +### chat call | ||
| 14 | +POST {{baseUrl}}/admin-api/ai/chat/message/send-stream | ||
| 15 | +Content-Type: application/json | ||
| 16 | +Authorization: {{token}} | ||
| 17 | + | ||
| 18 | +{ | ||
| 19 | + "conversationId": "1781604279872581649", | ||
| 20 | + "content": "苹果是什么颜色?" | ||
| 21 | +} | ||
| 22 | + | ||
| 2 | 23 | ||
| 3 | ### message list | 24 | ### message list |
| 4 | -GET {{baseUrl}}/ai/chat/message/list?chatConversationId=1781604279872581644 | 25 | +GET {{baseUrl}}/admin-api/ai/chat/message/list-by-conversation-id?conversationId=1781604279872581649 |
| 5 | Authorization: {{token}} | 26 | Authorization: {{token}} |
| 6 | 27 | ||
| 7 | 28 | ||
| 8 | ### message delete | 29 | ### message delete |
| 9 | -DELETE {{baseUrl}}/ai/chat/message/1781604279872581644/8 | 30 | +DELETE {{baseUrl}}/admin-api/ai/chat/message/delete?id=50 |
| 10 | Authorization: {{token}} | 31 | Authorization: {{token}} |
yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat.http deleted
| 1 | - | ||
| 2 | - | ||
| 3 | -### 登录 | ||
| 4 | - | ||
| 5 | -POST {{baseUrl}}/admin-api/system/auth/login | ||
| 6 | -Content-Type: application/json | ||
| 7 | -tenant-id: 1 | ||
| 8 | - | ||
| 9 | -{ | ||
| 10 | - "username": "admin", | ||
| 11 | - "password": "123456", | ||
| 12 | - "captchaVerification": "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==", | ||
| 13 | - "socialCode": "1024", | ||
| 14 | - "socialState": "9b2ffbc1-7425-4155-9894-9d5c08541d62", | ||
| 15 | - "socialCodeValid": true | ||
| 16 | -} | ||
| 17 | - | ||
| 18 | -### chat call | ||
| 19 | -GET {{baseUrl}}/ai/chat?modal=qianwen&conversationId=1781604279872581644&prompt=中国好看吗? | ||
| 20 | -Authorization: {{token}} | ||
| 21 | - | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -### chat call | ||
| 25 | -GET {{baseUrl}}/ai/chatStream?conversationId=1781604279872581644&prompt=苹果是什么颜色?&modal=yiYan3_5_8k | ||
| 26 | -Authorization: {{token}} | ||
| 27 | - | ||
| 28 | - | ||
| 29 | - | ||
| 30 | - |