Commit 7a66a435f936c4c6e2cfc5cd78b94ea0361ee110

Authored by xiaoxin
1 parent bec2aafe

【增加】AI:写作模版构建

yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/write/AiWriteController.java
1 1 package cn.iocoder.yudao.module.ai.controller.admin.write;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.ai.controller.admin.write.vo.AiWriteGenerateReqVO;
4 5 import cn.iocoder.yudao.module.ai.service.write.AiWriteService;
5 6 import io.swagger.v3.oas.annotations.Operation;
6 7 import io.swagger.v3.oas.annotations.tags.Tag;
7 8 import jakarta.annotation.Resource;
8 9 import jakarta.annotation.security.PermitAll;
  10 +import jakarta.validation.Valid;
9 11 import org.springframework.http.MediaType;
10 12 import org.springframework.web.bind.annotation.PostMapping;
  13 +import org.springframework.web.bind.annotation.RequestBody;
11 14 import org.springframework.web.bind.annotation.RequestMapping;
12 15 import org.springframework.web.bind.annotation.RestController;
13 16 import reactor.core.publisher.Flux;
... ... @@ -22,8 +25,8 @@ public class AiWriteController {
22 25  
23 26 @PostMapping(value = "/generate-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
24 27 @PermitAll
25   - @Operation(summary = "作文生产(流式)", description = "流式返回,响应较快")
26   - public Flux<CommonResult<String>> generateComposition() {
27   - return writeService.generateComposition();
  28 + @Operation(summary = "写作生成(流式)", description = "流式返回,响应较快")
  29 + public Flux<CommonResult<String>> generateComposition(@RequestBody @Valid AiWriteGenerateReqVO generateReqVO) {
  30 + return writeService.generateComposition(generateReqVO);
28 31 }
29 32 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/write/vo/AiWriteGenerateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.write.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - AI 写作生成 Request VO")
  8 +@Data
  9 +public class AiWriteGenerateReqVO {
  10 +
  11 + @Schema(description = "写作内容", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "田忌赛马")
  12 + private String content;
  13 +
  14 + @Schema(description = "原文", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "领导我要辞职")
  15 + private String originalContent;
  16 +
  17 + @Schema(description = "回复内容", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "准了")
  18 + private String replyContent;
  19 +
  20 + @Schema(description = "长度", requiredMode = Schema.RequiredMode.REQUIRED, example = "中等")
  21 + @NotBlank(message = "长度不能为空")
  22 + private String length;
  23 +
  24 + @Schema(description = "格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "文章")
  25 + @NotBlank(message = "格式不能为空")
  26 + private String format;
  27 +
  28 + @Schema(description = "语气", requiredMode = Schema.RequiredMode.REQUIRED, example = "随意")
  29 + @NotBlank(message = "语气不能为空")
  30 + private String tone;
  31 +
  32 + @Schema(description = "语言", requiredMode = Schema.RequiredMode.REQUIRED, example = "中文")
  33 + @NotBlank(message = "语言不能为空")
  34 + private String language;
  35 +
  36 +
  37 + @Schema(description = "写作类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  38 + private Integer writeType;
  39 +}
0 40 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteService.java
1 1 package cn.iocoder.yudao.module.ai.service.write;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.ai.controller.admin.write.vo.AiWriteGenerateReqVO;
4 5 import reactor.core.publisher.Flux;
5 6  
6 7 /**
... ... @@ -11,7 +12,7 @@ import reactor.core.publisher.Flux;
11 12 public interface AiWriteService {
12 13  
13 14  
14   - Flux<CommonResult<String>> generateComposition();
  15 + Flux<CommonResult<String>> generateComposition(AiWriteGenerateReqVO generateReqVO);
15 16  
16 17  
17 18 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteServiceImpl.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
7 7 import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoOptions;
8 8 import cn.iocoder.yudao.framework.ai.core.model.yiyan.YiYanChatOptions;
9 9 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  10 +import cn.iocoder.yudao.module.ai.controller.admin.write.vo.AiWriteGenerateReqVO;
10 11 import cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants;
11 12 import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
12 13 import jakarta.annotation.Resource;
... ... @@ -37,11 +38,11 @@ public class AiWriteServiceImpl implements AiWriteService {
37 38  
38 39  
39 40 @Override
40   - public Flux<CommonResult<String>> generateComposition() {
  41 + public Flux<CommonResult<String>> generateComposition(AiWriteGenerateReqVO generateReqVO) {
41 42 StreamingChatClient chatClient = apiKeyService.getStreamingChatClient(6L);
42 43 AiPlatformEnum platform = AiPlatformEnum.validatePlatform("QianWen");
43 44 ChatOptions chatOptions = buildChatOptions(platform, "qwen-72b-chat", 1.0, 1000);
44   - Prompt prompt = new Prompt("请直接写一篇关于 气候变化 的文章,格式为自动,语气为自动,语言为自动,长度为自动。请确保涵盖主要观点,不需要标题,不需要任何额外的解释或道歉。", chatOptions);
  45 + Prompt prompt = new Prompt(buildWritingPrompt(generateReqVO), chatOptions);
45 46 Flux<ChatResponse> streamResponse = chatClient.stream(prompt);
46 47 // 3.3 流式返回
47 48 StringBuffer contentBuffer = new StringBuffer();
... ... @@ -54,11 +55,23 @@ public class AiWriteServiceImpl implements AiWriteService {
54 55 }).doOnComplete(() -> {
55 56 log.info("generateComposition complete, content: {}", contentBuffer);
56 57 }).onErrorResume(error -> {
  58 + log.error("[AI 写作] 发生异常", error);
57 59 return Flux.just(error(ErrorCodeConstants.AI_CHAT_STREAM_ERROR));
58 60 });
59 61 }
60 62  
61 63  
  64 + private String buildWritingPrompt(AiWriteGenerateReqVO generateReqVO) {
  65 + String template = "请直接写一篇关于 [{}] 的文章,格式为:{},语气为:{},语言为:{},长度为:{}。请确保涵盖主要内容,不需要任何额外的解释或道歉。";
  66 + String content = generateReqVO.getContent();
  67 + String format = generateReqVO.getFormat();
  68 + String tone = generateReqVO.getTone();
  69 + String language = generateReqVO.getLanguage();
  70 + String length = generateReqVO.getLength();
  71 + return StrUtil.format(template, content, format, tone, language, length);
  72 + }
  73 +
  74 + // TODO 芋艿:复用
62 75 private static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens) {
63 76 Float temperatureF = temperature != null ? temperature.floatValue() : null;
64 77 //noinspection EnhancedSwitchMigration
... ...