Commit 275d1fb6275f18806158f4faba06baac34159011

Authored by YunaiV
1 parent 9de9e938

【优化】AI:简化 AiChatMessageDO 消息表,去除 tokens、temperature、maxTokens、maxContexts 字段,因为 …

…spring-ai 没有返回 tokens 相关的字段
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageAddReqVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotEmpty;
5   -import jakarta.validation.constraints.NotNull;
6   -import lombok.Data;
7   -
8   -@Schema(description = "管理后台 - AI 聊天消息发送 Request VO")
9   -@Data
10   -public class AiChatMessageAddReqVO {
11   -
12   - @Schema(description = "聊天对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
13   - @NotNull(message = "聊天对话编号不能为空")
14   - private Long conversationId;
15   -
16   - @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "帮我写个 Java 算法")
17   - @NotEmpty(message = "聊天内容不能为空")
18   - private String content;
19   -
20   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageAddRespVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -
6   -import java.time.LocalDateTime;
7   -
8   -@Schema(description = "管理后台 - AI 聊天消息 Add Response VO")
9   -@Data
10   -public class AiChatMessageAddRespVO {
11   -
12   - @Schema(description = "用户信息")
13   - private AiChatMessageRespVO userMessage;
14   -
15   - @Schema(description = "系统信息")
16   - private AiChatMessageRespVO systemMessage;
17   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageRespVO.java
... ... @@ -21,9 +21,6 @@ public class AiChatMessageRespVO {
21 21 @Schema(description = "用户编号", example = "4096")
22 22 private Long userId; // 仅当 user 发送时非空
23 23  
24   - @Schema(description = "用户头像", example = "http://xxx")
25   - private Long avatarUrl; // 仅当 user 发送时非空
26   -
27 24 @Schema(description = "角色编号", example = "888")
28 25 private Long roleId; // 仅当 assistant 回复时非空
29 26  
... ... @@ -33,15 +30,9 @@ public class AiChatMessageRespVO {
33 30 @Schema(description = "模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123")
34 31 private Long modelId;
35 32  
36   - @Schema(description = "模型图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "123")
37   - private String modelImage;
38   -
39 33 @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,你好啊")
40 34 private String content;
41 35  
42   - @Schema(description = "消耗 Token 数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
43   - private Integer tokens;
44   -
45 36 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-05-12 12:51")
46 37 private LocalDateTime createTime;
47 38  
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/chat/AiChatMessageDO.java
... ... @@ -78,32 +78,7 @@ public class AiChatMessageDO extends BaseDO {
78 78 * 聊天内容
79 79 */
80 80 private String content;
81   - /**
82   - * 消耗 Token 数量
83   - */
84   - private Integer tokens;
85 81  
86 82 // TODO 芋艿:是否作为上下文语料?use_context,待定
87 83  
88   - // ========== 会话配置 ==========
89   -
90   - /**
91   - * 温度参数
92   - *
93   - * 冗余 {@link AiChatConversationDO#getTemperature()}
94   - */
95   - private Double temperature;
96   - /**
97   - * 单条回复的最大 Token 数量
98   - *
99   - * 冗余 {@link AiChatConversationDO#getMaxTokens()}
100   - */
101   - private Integer maxTokens;
102   - /**
103   - * 上下文的最大 Message 数量
104   - *
105   - * 冗余 {@link AiChatConversationDO#getMaxContexts()}
106   - */
107   - private Integer maxContexts;
108   -
109 84 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatServiceImpl.java
... ... @@ -9,7 +9,6 @@ import org.springframework.ai.chat.ChatClient;
9 9 import org.springframework.ai.chat.ChatResponse;
10 10 import org.springframework.ai.chat.StreamingChatClient;
11 11 import org.springframework.ai.chat.messages.MessageType;
12   -import org.springframework.ai.chat.prompt.ChatOptionsBuilder;
13 12 import org.springframework.ai.chat.prompt.Prompt;
14 13 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
15 14 import cn.iocoder.yudao.module.ai.config.AiChatClientFactory;
... ... @@ -72,8 +71,7 @@ public class AiChatServiceImpl implements AiChatService {
72 71 AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
73 72 // 保存 chat message
74 73 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
75   - chatModel.getModel(), chatModel.getId(), req.getContent(),
76   - null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
  74 + chatModel.getModel(), chatModel.getId(), req.getContent());
77 75 String content = null;
78 76 int tokens = 0;
79 77 try {
... ... @@ -94,28 +92,21 @@ public class AiChatServiceImpl implements AiChatService {
94 92 } finally {
95 93 // 保存 chat message
96 94 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
97   - chatModel.getModel(), chatModel.getId(), content,
98   - tokens, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
  95 + chatModel.getModel(), chatModel.getId(), content);
99 96 }
100 97 return new AiChatMessageRespVO().setContent(content);
101 98 }
102 99  
103 100 private AiChatMessageDO insertChatMessage(Long conversationId, MessageType messageType, Long loginUserId, Long roleId,
104   - String model, Long modelId, String content, Integer tokens, Double temperature,
105   - Integer maxTokens, Integer maxContexts) {
  101 + String model, Long modelId, String content) {
106 102 AiChatMessageDO insertChatMessageDO = new AiChatMessageDO()
107   - .setId(null)
108 103 .setConversationId(conversationId)
109 104 .setType(messageType.getValue())
110 105 .setUserId(loginUserId)
111 106 .setRoleId(roleId)
112 107 .setModel(model)
113 108 .setModelId(modelId)
114   - .setContent(content)
115   - .setTokens(tokens)
116   - .setTemperature(temperature)
117   - .setMaxTokens(maxTokens)
118   - .setMaxContexts(maxContexts);
  109 + .setContent(content);
119 110 insertChatMessageDO.setCreateTime(LocalDateTime.now());
120 111 // 增加 chat message 记录
121 112 aiChatMessageMapper.insert(insertChatMessageDO);
... ... @@ -134,15 +125,13 @@ public class AiChatServiceImpl implements AiChatService {
134 125 AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
135 126 StreamingChatClient chatClient = chatClientFactory.getStreamingChatClient(platform);
136 127  
137   - // 2. 插入 user 发送消息 TODO tokens 计算
  128 + // 2. 插入 user 发送消息
138 129 AiChatMessageDO userMessage = insertChatMessage(conversation.getId(), MessageType.USER, userId, conversation.getRoleId(),
139   - conversation.getModel(), conversation.getId(), sendReqVO.getContent(),
140   - null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
  130 + conversation.getModel(), conversation.getId(), sendReqVO.getContent());
141 131  
142 132 // 3.1 插入 system 接收消息
143 133 AiChatMessageDO systemMessage = insertChatMessage(conversation.getId(), MessageType.SYSTEM, userId, conversation.getRoleId(),
144   - conversation.getModel(), conversation.getId(), conversation.getSystemMessage(),
145   - 0, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
  134 + conversation.getModel(), conversation.getId(), conversation.getSystemMessage());
146 135 // 3.2 创建 chat 需要的 Prompt
147 136 // TODO 消息上下文
148 137 Prompt prompt = new Prompt(sendReqVO.getContent());
... ... @@ -150,11 +139,8 @@ public class AiChatServiceImpl implements AiChatService {
150 139 Flux<ChatResponse> streamResponse = chatClient.stream(prompt);
151 140 // 3.3 转换 flex AiChatMessageRespVO
152 141 StringBuffer contentBuffer = new StringBuffer();
153   - AtomicInteger tokens = new AtomicInteger(0); // TODO token 计算不对;
154 142 return streamResponse.map(res -> {
155 143 contentBuffer.append(res.getResult().getOutput().getContent());
156   - tokens.incrementAndGet();
157   -
158 144 AiChatMessageSendRespVO.Message send = new AiChatMessageSendRespVO.Message().setId(userMessage.getId())
159 145 .setType(MessageType.USER.getValue()).setCreateTime(userMessage.getCreateTime())
160 146 .setContent(sendReqVO.getContent());
... ... @@ -167,17 +153,13 @@ public class AiChatServiceImpl implements AiChatService {
167 153 // 保存 chat message
168 154 aiChatMessageMapper.updateById(new AiChatMessageDO()
169 155 .setId(systemMessage.getId())
170   - .setContent(contentBuffer.toString())
171   - .setTokens(tokens.get())
172   - );
  156 + .setContent(contentBuffer.toString()));
173 157 }).doOnError(throwable -> {
174 158 log.error("发送错误 {}!", throwable.getMessage());
175 159 // 更新错误信息 TODO 貌似不应该更新异常
176 160 aiChatMessageMapper.updateById(new AiChatMessageDO()
177 161 .setId(systemMessage.getId())
178   - .setContent(throwable.getMessage())
179   - .setTokens(tokens.get())
180   - );
  162 + .setContent(throwable.getMessage()));
181 163 });
182 164 }
183 165  
... ...