mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	1、增加 chat 和 chatStream
This commit is contained in:
		| @ -1,8 +1,8 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.app.chat; | package cn.iocoder.yudao.module.ai.controller; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
| import cn.iocoder.yudao.module.ai.controller.app.chat.vo.*; |  | ||||||
| import cn.iocoder.yudao.module.ai.service.ChatRoleService; | import cn.iocoder.yudao.module.ai.service.ChatRoleService; | ||||||
|  | import cn.iocoder.yudao.module.ai.vo.*; | ||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
| @ -0,0 +1,76 @@ | |||||||
|  | package cn.iocoder.yudao.module.ai.controller; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.exceptions.ExceptionUtil; | ||||||
|  | import cn.iocoder.yudao.framework.ai.chat.ChatResponse; | ||||||
|  | import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; | ||||||
|  | import cn.iocoder.yudao.framework.ai.config.AiClient; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
|  | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; | ||||||
|  | import reactor.core.publisher.Flux; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.function.Consumer; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @author fansili | ||||||
|  |  * @time 2024/4/13 17:44 | ||||||
|  |  * @since 1.0 | ||||||
|  |  */ | ||||||
|  | @Tag(name = "AI模块") | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/ai") | ||||||
|  | @Slf4j | ||||||
|  | @AllArgsConstructor | ||||||
|  | public class ChatController { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     private AiClient aiClient; | ||||||
|  |  | ||||||
|  |     @GetMapping("/chat") | ||||||
|  |     public CommonResult<String> chat(@RequestParam("prompt") String prompt) { | ||||||
|  |         ChatResponse callRes = aiClient.call(new Prompt(prompt), "qianWen"); | ||||||
|  |         return CommonResult.success(callRes.getResult().getOutput().getContent()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO @芋艿:调用这个方法异常,Unable to handle the Spring Security Exception because the response is already committed. | ||||||
|  |     @GetMapping(value = "/chatStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) | ||||||
|  |     public SseEmitter chatStream(@RequestParam("prompt") String prompt) { | ||||||
|  |         Utf8SseEmitter sseEmitter = new Utf8SseEmitter(); | ||||||
|  |         Flux<ChatResponse> streamResponse = aiClient.stream(new Prompt(prompt), "qianWen"); | ||||||
|  |         streamResponse.subscribe( | ||||||
|  |                 new Consumer<ChatResponse>() { | ||||||
|  |                     @Override | ||||||
|  |                     public void accept(ChatResponse chatResponse) { | ||||||
|  |                         String content = chatResponse.getResults().get(0).getOutput().getContent(); | ||||||
|  |                         try { | ||||||
|  |                             sseEmitter.send(content, MediaType.APPLICATION_JSON); | ||||||
|  |                         } catch (IOException e) { | ||||||
|  |                             log.error("发送异常{}", ExceptionUtil.getMessage(e)); | ||||||
|  |                             // 如果不是因为关闭而抛出异常,则重新连接 | ||||||
|  |                             sseEmitter.completeWithError(e); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 error -> { | ||||||
|  |                     // | ||||||
|  |                     log.error("subscribe错误 {}", ExceptionUtil.getMessage(error)); | ||||||
|  |                 }, | ||||||
|  |                 () -> { | ||||||
|  |                     log.info("发送完成!"); | ||||||
|  |                     sseEmitter.complete(); | ||||||
|  |                 } | ||||||
|  |         ); | ||||||
|  |         return sseEmitter; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,34 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.admin.chat; |  | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.ai.chat.ChatResponse; |  | ||||||
| import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; |  | ||||||
| import cn.iocoder.yudao.framework.ai.config.AiClient; |  | ||||||
| import cn.iocoder.yudao.framework.ai.config.YudaoAiClient; |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; |  | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; |  | ||||||
| import lombok.AllArgsConstructor; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @author fansili |  | ||||||
|  * @since 1.0 |  | ||||||
|  * @time 2024/4/13 17:44 |  | ||||||
|  */ |  | ||||||
| @Tag(name = "AI模块") |  | ||||||
| @RestController |  | ||||||
| @RequestMapping("/admin-api/ai") |  | ||||||
| @Slf4j |  | ||||||
| @AllArgsConstructor |  | ||||||
| public class ChatController { |  | ||||||
|  |  | ||||||
|     private final AiClient aiClient; |  | ||||||
|  |  | ||||||
|     @PostMapping("/chat") |  | ||||||
|     public CommonResult<String> chat(@RequestParam("prompt") String prompt) { |  | ||||||
|         ChatResponse callRes = aiClient.call(new Prompt(prompt), "qianWen"); |  | ||||||
|         return CommonResult.success(callRes.getResult().getOutput().getContent()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,5 +0,0 @@ | |||||||
| /** |  | ||||||
|  * author: fansili |  | ||||||
|  * time: 2024/3/4 13:08 |  | ||||||
|  */ |  | ||||||
| package cn.iocoder.yudao.module.ai.controller.admin; |  | ||||||
| @ -1,5 +0,0 @@ | |||||||
| /** |  | ||||||
|  * author: fansili |  | ||||||
|  * time: 2024/3/4 13:08 |  | ||||||
|  */ |  | ||||||
| package cn.iocoder.yudao.module.ai.controller.app; |  | ||||||
| @ -1,7 +1,7 @@ | |||||||
| package cn.iocoder.yudao.module.ai.service; | package cn.iocoder.yudao.module.ai.service; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
| import cn.iocoder.yudao.module.ai.controller.app.chat.vo.*; | import cn.iocoder.yudao.module.ai.vo.*; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * chat 角色 |  * chat 角色 | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| package cn.iocoder.yudao.module.ai.service; | package cn.iocoder.yudao.module.ai.service.impl; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
| import cn.iocoder.yudao.module.ai.controller.app.chat.vo.*; | import cn.iocoder.yudao.module.ai.service.ChatRoleService; | ||||||
|  | import cn.iocoder.yudao.module.ai.vo.*; | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| @ -1,5 +0,0 @@ | |||||||
| /** |  | ||||||
|  * author: fansili |  | ||||||
|  * time: 2024/3/3 18:14 |  | ||||||
|  */ |  | ||||||
| package cn.iocoder.yudao.module.ai.service; |  | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.admin.chat.vo; | package cn.iocoder.yudao.module.ai.vo; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.module.ai.enums.OpenAiModelEnum; | import cn.iocoder.yudao.module.ai.enums.OpenAiModelEnum; | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.app.chat.vo; | package cn.iocoder.yudao.module.ai.vo; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.app.chat.vo; | package cn.iocoder.yudao.module.ai.vo; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.app.chat.vo; | package cn.iocoder.yudao.module.ai.vo; | ||||||
| 
 | 
 | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.app.chat.vo; | package cn.iocoder.yudao.module.ai.vo; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.app.chat.vo; | package cn.iocoder.yudao.module.ai.vo; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| @ -16,24 +16,17 @@ tenant-id: 1 | |||||||
| } | } | ||||||
|  |  | ||||||
| ### chat call | ### chat call | ||||||
| POST {{baseUrl}}/admin-api/ai/chat?prompt=中国怎么样 | GET {{baseUrl}}/ai/chat?prompt=中国怎么样 | ||||||
| tenant-id: 1 | tenant-id: 1 | ||||||
| Authorization: {{token}} | Authorization: {{token}} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ### chat call | ### chat call | ||||||
| POST {{baseUrl}}/ai-api/chat | GET {{baseUrl}}/ai/chatStream?prompt=苹果是什么颜色? | ||||||
| tenant-id: 1 |  | ||||||
| Authorization: {{token}} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ### chat call |  | ||||||
| GET {{baseUrl}}/chat-role/list |  | ||||||
| tenant-id: 1 | tenant-id: 1 | ||||||
| Authorization: {{token}} | Authorization: {{token}} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "dev": { |   "dev": { | ||||||
|     "baseUrl": "http://127.0.0.1:48080", |     "baseUrl": "http://127.0.0.1:48080", | ||||||
|     "token": "Bearer 07390ff2824a4798bcfd7f9395092181" |     "token": "Bearer cff0ce99ddb14ea89c62ff4de1c31180" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -82,6 +82,12 @@ public class YiYanChatClient implements ChatClient, StreamingChatClient { | |||||||
|         YiYanChatCompletionRequest request = this.createRequest(prompt, true); |         YiYanChatCompletionRequest request = this.createRequest(prompt, true); | ||||||
|         // 调用 callWithFunctionSupport 发送请求 |         // 调用 callWithFunctionSupport 发送请求 | ||||||
|         Flux<YiYanChatCompletion> response = this.yiYanApi.chatCompletionStream(request); |         Flux<YiYanChatCompletion> response = this.yiYanApi.chatCompletionStream(request); | ||||||
|  |         response.doOnComplete(new Runnable() { | ||||||
|  |             @Override | ||||||
|  |             public void run() { | ||||||
|  |                 String a = ";"; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|         return response.map(res -> new ChatResponse(List.of(new Generation(res.getResult())))); |         return response.map(res -> new ChatResponse(List.of(new Generation(res.getResult())))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 cherishsince
					cherishsince