From d68e2f99592dc982a722d031219f1d0b4f87ed00 Mon Sep 17 00:00:00 2001 From: Administrator <15274802129@163.com> Date: Tue, 02 Sep 2025 10:11:05 +0800 Subject: [PATCH] feat(ai): 新增 AI 流式回答功能 V3 版本 --- src/main/java/cc/mrbird/febs/ai/service/impl/AiServiceImpl.java | 17 ++++++++ src/main/java/cc/mrbird/febs/ai/controller/talk/ApiAiTalkController.java | 12 ++++++ src/main/java/cc/mrbird/febs/ai/strategy/enumerates/LlmStrategyContextEnum.java | 18 +++++++++ src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java | 25 ++++++++++++ src/main/java/cc/mrbird/febs/ai/service/AiTalkService.java | 2 + src/main/java/cc/mrbird/febs/ai/req/talk/AiTalkAnswerStream.java | 5 -- src/main/java/cc/mrbird/febs/ai/enumerates/AiPromptEnum.java | 22 +++++++++++ src/main/java/cc/mrbird/febs/ai/service/AiService.java | 2 + src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyFactory.java | 4 ++ 9 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/ai/controller/talk/ApiAiTalkController.java b/src/main/java/cc/mrbird/febs/ai/controller/talk/ApiAiTalkController.java index ce47ea2..ba73e90 100644 --- a/src/main/java/cc/mrbird/febs/ai/controller/talk/ApiAiTalkController.java +++ b/src/main/java/cc/mrbird/febs/ai/controller/talk/ApiAiTalkController.java @@ -102,4 +102,16 @@ } return aiTalkService.answerStreamV2(dto); } + + @ApiOperation("提问AI(流式带思考过程)V3") + @ApiResponses({ + @ApiResponse(code = 200, message = "流式响应", response = ApiMemberTalkStreamVo.class), + }) + @PostMapping("/answer-streamV3") + public Flux<FebsResponse> answerStreamV3(@RequestBody @Validated AiTalkAnswerStream dto) { + if (StrUtil.isEmpty(dto.getQuestion())){ + return Flux.just(new FebsResponse().fail().message("请输入问题")); + } + return aiTalkService.answerStreamV3(dto); + } } diff --git a/src/main/java/cc/mrbird/febs/ai/enumerates/AiPromptEnum.java b/src/main/java/cc/mrbird/febs/ai/enumerates/AiPromptEnum.java new file mode 100644 index 0000000..9244aa0 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/ai/enumerates/AiPromptEnum.java @@ -0,0 +1,22 @@ +package cc.mrbird.febs.ai.enumerates; + +import lombok.Getter; + +/** + * @author Administrator + */ + +@Getter +public enum AiPromptEnum { + + STREAM_NORMAL(1,"你是人工智能,请回答我提出的问题"); + + private final int code; + private final String prompt; + + AiPromptEnum(int code,String prompt) { + + this.code = code; + this.prompt = prompt; + } +} diff --git a/src/main/java/cc/mrbird/febs/ai/req/talk/AiTalkAnswerStream.java b/src/main/java/cc/mrbird/febs/ai/req/talk/AiTalkAnswerStream.java index 75b56d9..99740ed 100644 --- a/src/main/java/cc/mrbird/febs/ai/req/talk/AiTalkAnswerStream.java +++ b/src/main/java/cc/mrbird/febs/ai/req/talk/AiTalkAnswerStream.java @@ -13,16 +13,11 @@ @ApiModel(value = "AiTalkAnsStream", description = "参数") public class AiTalkAnswerStream { - @ApiModelProperty(value = "类型 1:火山 2:阿里", example = "10") - private Integer type; - @ApiModelProperty(value = "会话ID", example = "10") private String talkId; - @ApiModelProperty(value = "内容", example = "10") private String question; - @ApiModelProperty(value = "内容", example = "10") private String prompt; diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiService.java b/src/main/java/cc/mrbird/febs/ai/service/AiService.java index e5f99dc..50d8bfa 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/AiService.java +++ b/src/main/java/cc/mrbird/febs/ai/service/AiService.java @@ -16,6 +16,8 @@ */ public interface AiService { + Integer getSystemSetAiType(); + AiResponse start(List<AiMessage> aiMessageDtoList,Integer type, String productRoleId, String answer, String question); diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiTalkService.java b/src/main/java/cc/mrbird/febs/ai/service/AiTalkService.java index 414ba34..7f45d29 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/AiTalkService.java +++ b/src/main/java/cc/mrbird/febs/ai/service/AiTalkService.java @@ -26,4 +26,6 @@ FebsResponse historyPage(ApiTalkItemPageDto dto); Flux<FebsResponse> answerStreamV2(AiTalkAnswerStream dto); + + Flux<FebsResponse> answerStreamV3(AiTalkAnswerStream dto); } diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiServiceImpl.java index 73aa812..11c6794 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiServiceImpl.java @@ -13,7 +13,10 @@ import cc.mrbird.febs.ai.service.AiProductRoleService; import cc.mrbird.febs.ai.service.AiService; import cc.mrbird.febs.ai.service.AiTalkItemService; +import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyContextEnum; import cc.mrbird.febs.common.entity.FebsResponse; +import cc.mrbird.febs.mall.entity.DataDictionaryCustom; +import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; @@ -74,6 +77,7 @@ private final AiProductRoleService aiProductRoleService; private final ObjectMapper objectMapper; private final AiTalkItemService aiTalkItemService; + private final DataDictionaryCustomMapper dataDictionaryCustomMapper; @Value("${ai.service.ak}") private String ak; @@ -112,6 +116,19 @@ } @Override + public Integer getSystemSetAiType() { + Integer type = 2; + DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( + LlmStrategyContextEnum.LLM_STRATEGY.getCode(), + LlmStrategyContextEnum.LLM_STRATEGY.getCode() + ); + if (dataDictionaryCustom != null) { + type = Integer.parseInt(dataDictionaryCustom.getValue()); + } + return type; + } + + @Override public AiResponse start(List<AiMessage> aiMessageDtoList,Integer type,String productRoleId, String content, String question) { if (!StringUtils.hasText(productRoleId)) { log.warn("productRoleId 不能为空"); diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java index 2cabe56..faa3876 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java @@ -2,6 +2,7 @@ import cc.mrbird.febs.ai.entity.AiProductQuestion; import cc.mrbird.febs.ai.entity.AiTalk; +import cc.mrbird.febs.ai.enumerates.AiPromptEnum; import cc.mrbird.febs.ai.mapper.AiTalkMapper; import cc.mrbird.febs.ai.req.talk.AiTalkAnswerStream; import cc.mrbird.febs.ai.req.talk.ApiTalkDto; @@ -15,6 +16,9 @@ import cc.mrbird.febs.ai.service.AiService; import cc.mrbird.febs.ai.service.AiTalkItemService; import cc.mrbird.febs.ai.service.AiTalkService; +import cc.mrbird.febs.ai.strategy.LlmStrategyFactory; +import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyEnum; +import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto; import cc.mrbird.febs.ai.utils.UUID; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.utils.LoginUserUtil; @@ -22,6 +26,7 @@ import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.dashscope.common.Role; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -43,6 +48,7 @@ private final AiTalkItemService aiTalkItemService; private final AiProductQuestionService aiProductQuestionService; private final AiService aiService; + private final LlmStrategyFactory llmStrategyFactory; @Override public FebsResponse questionList() { @@ -121,4 +127,23 @@ return aiService.answerStreamV2(dto); } + @Override + public Flux<FebsResponse> answerStreamV3(AiTalkAnswerStream dto) { + ArrayList<LlmStrategyDto> llmStrategyDtoList = new ArrayList<>(); + if (dto.getPrompt() != null){ + LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); + llmStrategyDto.setRole(Role.SYSTEM.getValue()); + llmStrategyDto.setContent(AiPromptEnum.STREAM_NORMAL.getPrompt()); + llmStrategyDtoList.add(llmStrategyDto); + } + if (dto.getQuestion() != null){ + LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); + llmStrategyDto.setRole(Role.USER.getValue()); + llmStrategyDto.setContent(dto.getQuestion()); + llmStrategyDtoList.add(llmStrategyDto); + } + String modelName = LlmStrategyEnum.getName(aiService.getSystemSetAiType()); + return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreaming(llmStrategyDtoList); + } + } diff --git a/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyFactory.java b/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyFactory.java index 5d2e87c..d762ce3 100644 --- a/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyFactory.java +++ b/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyFactory.java @@ -1,7 +1,10 @@ package cc.mrbird.febs.ai.strategy; +import cc.mrbird.febs.mall.entity.DataDictionaryCustom; +import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper; import com.google.common.collect.Maps; import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Map; @@ -18,6 +21,7 @@ } public Map<String, LlmStrategyService> getCalculationStrategyMap() { + return llmStrategyMap; } } diff --git a/src/main/java/cc/mrbird/febs/ai/strategy/enumerates/LlmStrategyContextEnum.java b/src/main/java/cc/mrbird/febs/ai/strategy/enumerates/LlmStrategyContextEnum.java index 31254c0..6a7bf89 100644 --- a/src/main/java/cc/mrbird/febs/ai/strategy/enumerates/LlmStrategyContextEnum.java +++ b/src/main/java/cc/mrbird/febs/ai/strategy/enumerates/LlmStrategyContextEnum.java @@ -1,6 +1,24 @@ package cc.mrbird.febs.ai.strategy.enumerates; +import lombok.Getter; + +/** + * @author Administrator + */ + +@Getter public enum LlmStrategyContextEnum { + + + /** + * 1:用户提问 + * 2:AI回答 + */ + LLM_STRATEGY("LLM_STRATEGY","系统设置AI模型平台"), + + /** + * 流式响应 + */ THINK("思考过程","THINK"), CONTENT("响应内容","CONTENT"); -- Gitblit v1.9.1