From 5e33db1ad33a25bd4860b3139434840f929b0d70 Mon Sep 17 00:00:00 2001 From: jiao Date: Wed, 10 Jun 2026 17:50:34 +0800 Subject: [PATCH] chore: add .gitignore for all backend modules and update generation service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 为所有后端子模块添加.gitignore文件,忽略target编译目录 2. 重构LLM客户端接口,新增支持关闭推理过程的生成方法 3. 为各模型客户端实现新的重载generate方法 4. 重构PromptEngine,替换原有话术生成逻辑为对话历史分析模式 5. 新增对话历史存档实体类和Mapper,实现单聊/群聊历史查询接口 6. 简化GenerationController,移除SSE流式生成相关代码 --- backend/analytics-service/.gitignore | 2 + backend/archive-service/.gitignore | 2 + backend/auth-service/.gitignore | 2 + backend/common/.gitignore | 2 + backend/conversation-service/.gitignore | 2 + backend/gateway/.gitignore | 2 + backend/generation-service/.gitignore | 2 + .../generation/client/BailianClient.java | 12 ++ .../generation/client/DoubaoClient.java | 13 +- .../generation/client/HunyuanClient.java | 11 + .../artedu/generation/client/LLMClient.java | 11 + .../controller/GenerationController.java | 200 +++++------------- .../generation/entity/ArchiveMessage.java | 32 +++ .../mapper/ArchiveMessageMapper.java | 39 ++++ .../generation/service/PromptEngine.java | 96 ++------- .../generation/client/BailianClient.class | Bin 6659 -> 7333 bytes .../generation/client/DoubaoClient.class | Bin 5738 -> 6438 bytes .../generation/client/HunyuanClient.class | Bin 5032 -> 5740 bytes .../artedu/generation/client/LLMClient.class | Bin 554 -> 641 bytes .../generation/client/LLMClientFactory.class | Bin 2973 -> 2991 bytes .../controller/GenerationController.class | Bin 14271 -> 9036 bytes .../controller/LlmModelController.class | Bin 7403 -> 7776 bytes .../generation/service/LlmModelService.class | Bin 7444 -> 7497 bytes .../generation/service/PromptEngine.class | Bin 6794 -> 6268 bytes .../generation/service/QianwenClient.class | Bin 6754 -> 6835 bytes backend/intent-service/.gitignore | 2 + backend/kb-admin-service/.gitignore | 2 + backend/recommendation-service/.gitignore | 2 + 28 files changed, 208 insertions(+), 226 deletions(-) create mode 100644 backend/analytics-service/.gitignore create mode 100644 backend/archive-service/.gitignore create mode 100644 backend/auth-service/.gitignore create mode 100644 backend/common/.gitignore create mode 100644 backend/conversation-service/.gitignore create mode 100644 backend/gateway/.gitignore create mode 100644 backend/generation-service/.gitignore create mode 100644 backend/generation-service/src/main/java/com/artedu/generation/entity/ArchiveMessage.java create mode 100644 backend/generation-service/src/main/java/com/artedu/generation/mapper/ArchiveMessageMapper.java create mode 100644 backend/intent-service/.gitignore create mode 100644 backend/kb-admin-service/.gitignore create mode 100644 backend/recommendation-service/.gitignore diff --git a/backend/analytics-service/.gitignore b/backend/analytics-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/analytics-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/archive-service/.gitignore b/backend/archive-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/archive-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/auth-service/.gitignore b/backend/auth-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/auth-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/common/.gitignore b/backend/common/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/common/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/conversation-service/.gitignore b/backend/conversation-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/conversation-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/gateway/.gitignore b/backend/gateway/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/gateway/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/generation-service/.gitignore b/backend/generation-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/generation-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/generation-service/src/main/java/com/artedu/generation/client/BailianClient.java b/backend/generation-service/src/main/java/com/artedu/generation/client/BailianClient.java index dc512b5..1dc304c 100644 --- a/backend/generation-service/src/main/java/com/artedu/generation/client/BailianClient.java +++ b/backend/generation-service/src/main/java/com/artedu/generation/client/BailianClient.java @@ -32,6 +32,11 @@ public class BailianClient implements LLMClient { @Override public String generate(String system, String prompt, Integer maxTokens) { + return generate(system, prompt, maxTokens, true); + } + + @Override + public String generate(String system, String prompt, Integer maxTokens, boolean thinkingDisabled) { if (model == null || model.getApiKey() == null || model.getApiKey().isEmpty()) { log.error("百炼模型配置不完整"); return null; @@ -65,6 +70,13 @@ public class BailianClient implements LLMClient { if (maxTokens != null) { parameters.put("max_tokens", maxTokens); } + + if (thinkingDisabled) { + Map thinking = new HashMap<>(); + thinking.put("type", "disabled"); + parameters.put("thinking", thinking); + } + requestBody.put("parameters", parameters); try { diff --git a/backend/generation-service/src/main/java/com/artedu/generation/client/DoubaoClient.java b/backend/generation-service/src/main/java/com/artedu/generation/client/DoubaoClient.java index 76f2bad..efe50ea 100644 --- a/backend/generation-service/src/main/java/com/artedu/generation/client/DoubaoClient.java +++ b/backend/generation-service/src/main/java/com/artedu/generation/client/DoubaoClient.java @@ -33,6 +33,11 @@ public class DoubaoClient implements LLMClient { @Override public String generate(String system, String prompt, Integer maxTokens) { + return generate(system, prompt, maxTokens, true); + } + + @Override + public String generate(String system, String prompt, Integer maxTokens, boolean thinkingDisabled) { if (model == null || model.getApiKey() == null || model.getApiKey().isEmpty()) { log.error("豆包模型配置不完整"); return null; @@ -59,12 +64,18 @@ public class DoubaoClient implements LLMClient { if (maxTokens != null) { requestBody.put("max_tokens", maxTokens); } - // 从 configJson 读取 temperature,默认 0.7 + Double temperature = parseTemperature(); if (temperature != null) { requestBody.put("temperature", temperature); } + if (thinkingDisabled) { + Map thinking = new HashMap<>(); + thinking.put("type", "disabled"); + requestBody.put("thinking", thinking); + } + try { HttpEntity> entity = new HttpEntity<>(requestBody, headers); Map response = restTemplate.postForObject(url, entity, Map.class); diff --git a/backend/generation-service/src/main/java/com/artedu/generation/client/HunyuanClient.java b/backend/generation-service/src/main/java/com/artedu/generation/client/HunyuanClient.java index 6d692ab..77bb282 100644 --- a/backend/generation-service/src/main/java/com/artedu/generation/client/HunyuanClient.java +++ b/backend/generation-service/src/main/java/com/artedu/generation/client/HunyuanClient.java @@ -32,6 +32,11 @@ public class HunyuanClient implements LLMClient { @Override public String generate(String system, String prompt, Integer maxTokens) { + return generate(system, prompt, maxTokens, true); + } + + @Override + public String generate(String system, String prompt, Integer maxTokens, boolean thinkingDisabled) { if (model == null || model.getApiKey() == null || model.getApiKey().isEmpty()) { log.error("混元模型配置不完整"); return null; @@ -58,6 +63,12 @@ public class HunyuanClient implements LLMClient { if (maxTokens != null) { requestBody.put("MaxTokens", maxTokens); } + + if (thinkingDisabled) { + Map thinking = new HashMap<>(); + thinking.put("type", "disabled"); + requestBody.put("thinking", thinking); + } try { HttpEntity> entity = new HttpEntity<>(requestBody, headers); diff --git a/backend/generation-service/src/main/java/com/artedu/generation/client/LLMClient.java b/backend/generation-service/src/main/java/com/artedu/generation/client/LLMClient.java index 38d825f..c2e9f00 100644 --- a/backend/generation-service/src/main/java/com/artedu/generation/client/LLMClient.java +++ b/backend/generation-service/src/main/java/com/artedu/generation/client/LLMClient.java @@ -26,6 +26,17 @@ public interface LLMClient { */ String generate(String system, String prompt, Integer maxTokens); + /** + * 文本生成(支持system消息和关闭推理过程) + * + * @param system 系统提示词 + * @param prompt 用户提示词 + * @param maxTokens 最大token数 + * @param thinkingDisabled 是否关闭推理过程 + * @return 生成的文本 + */ + String generate(String system, String prompt, Integer maxTokens, boolean thinkingDisabled); + /** * 获取当前使用的模型配置 */ diff --git a/backend/generation-service/src/main/java/com/artedu/generation/controller/GenerationController.java b/backend/generation-service/src/main/java/com/artedu/generation/controller/GenerationController.java index fba74ed..ca3d71d 100644 --- a/backend/generation-service/src/main/java/com/artedu/generation/controller/GenerationController.java +++ b/backend/generation-service/src/main/java/com/artedu/generation/controller/GenerationController.java @@ -2,24 +2,20 @@ package com.artedu.generation.controller; import com.artedu.common.result.Result; import com.artedu.generation.client.LLMClient; +import com.artedu.generation.entity.ArchiveMessage; +import com.artedu.generation.mapper.ArchiveMessageMapper; import com.artedu.generation.service.LlmModelService; import com.artedu.generation.service.PromptEngine; import com.artedu.generation.service.QianwenClient; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; -import javax.validation.constraints.NotBlank; -import java.io.IOException; -import java.util.ArrayList; +import javax.validation.constraints.NotBlank; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; @Slf4j @Validated @@ -36,31 +32,21 @@ public class GenerationController { @Autowired private LlmModelService llmModelService; - private final ExecutorService sseExecutor = Executors.newCachedThreadPool(); - - private static final List> STYLES = List.of( - Map.of("id", "friendly", "name", "亲和风格", "desc", "温暖亲切,像朋友聊天"), - Map.of("id", "professional", "name", "专业风格", "desc", "数据驱动,专业权威"), - Map.of("id", "urgent", "name", "促单风格", "desc", "制造紧迫感,促成决策") - ); + @Autowired + private ArchiveMessageMapper archiveMessageMapper; @PostMapping("/utterance") public Result> generateUtterance( - @NotBlank(message = "message不能为空") @RequestParam("message") String message, - @RequestParam(value = "context", required = false) String context, - @RequestParam(value = "customerProfile", required = false) String customerProfile, - @RequestParam(value = "conversationContext", required = false) String conversationContext, - @RequestParam(value = "referenceUtterances", required = false) String referenceUtterances, - @NotBlank(message = "intent不能为空") @RequestParam("intent") String intent, - @NotBlank(message = "stage不能为空") @RequestParam("stage") String stage, - @RequestParam(value = "stageLabel", required = false) String stageLabel, - @RequestParam(value = "intentLabel", required = false) String intentLabel) { + @RequestParam(value = "fromUser", required = false) String fromUser, + @RequestParam(value = "toUser", required = false) String toUser, + @RequestParam(value = "roomid", required = false) String roomid) { - String[] promptPair = promptEngine.buildUtterancePrompt( - message, context, customerProfile, conversationContext, - referenceUtterances, intent, stage, stageLabel, intentLabel); + String chatContext = buildChatContext(fromUser, toUser, roomid); + + String[] promptPair = promptEngine.buildUtterancePrompt(chatContext); String systemPrompt = promptPair[0]; String userPrompt = promptPair[1]; + String generated = qianwenClient.generate(systemPrompt, userPrompt, 800); Map result = new HashMap<>(); @@ -72,6 +58,43 @@ public class GenerationController { return Result.success(result); } + private String buildChatContext(String fromUser, String toUser, String roomid) { + List messages; + boolean isGroupChat = roomid != null && !roomid.isEmpty(); + + long startTime = getTodayStartTime(); + long endTime = getTodayEndTime(); + + if (isGroupChat) { + messages = archiveMessageMapper.selectGroupChatMessages(roomid, startTime, endTime); + } else { + if (fromUser == null || fromUser.isEmpty() || toUser == null || toUser.isEmpty()) { + log.warn("单聊模式需要fromUser和toUser参数"); + return null; + } + toUser = "[\""+toUser+"\"]"; + messages = archiveMessageMapper.selectSingleChatMessages(fromUser, toUser, startTime, endTime); + } + + if (messages == null || messages.isEmpty()) { + return null; + } + + StringBuilder sb = new StringBuilder(); + for (ArchiveMessage msg : messages) { + sb.append(msg.getCreatedAt()).append(" ").append(msg.getFromRole()).append(msg.getContent()).append("\n"); + } + return sb.toString().trim(); + } + + private long getTodayStartTime() { + return java.time.LocalDate.now().atStartOfDay(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli(); + } + + private long getTodayEndTime() { + return java.time.LocalDate.now().plusDays(1).atStartOfDay(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli() - 1; + } + @PostMapping("/summary") public Result> generateSummary( @NotBlank(message = "context不能为空") @RequestParam("context") String context) { @@ -85,131 +108,6 @@ public class GenerationController { return Result.success(result); } - /** - * 流式生成多风格话术(SSE) - * 页面打开即自动推荐 3 条不同风格话术 - */ - @GetMapping(value = "/utterance-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public SseEmitter streamUtterance( - @NotBlank(message = "message不能为空") @RequestParam("message") String message, - @RequestParam(value = "context", required = false) String context, - @RequestParam(value = "customerProfile", required = false) String customerProfile, - @RequestParam(value = "conversationContext", required = false) String conversationContext, - @RequestParam(value = "referenceUtterances", required = false) String referenceUtterances, - @NotBlank(message = "intent不能为空") @RequestParam("intent") String intent, - @NotBlank(message = "stage不能为空") @RequestParam("stage") String stage, - @RequestParam(value = "stageLabel", required = false) String stageLabel, - @RequestParam(value = "intentLabel", required = false) String intentLabel) { - - SseEmitter emitter = new SseEmitter(120000L); // 2分钟超时 - - sseExecutor.execute(() -> { - try { - // 1. 发送开始事件,告知前端3种风格 - Map startEvent = new HashMap<>(); - startEvent.put("type", "start"); - startEvent.put("styles", STYLES); - emitter.send(SseEmitter.event().name("start").data(startEvent)); - - // 2. 构建 system + user prompt - String systemPrompt = promptEngine.buildSystemPrompt(stageLabel, intentLabel); - String userPrompt = promptEngine.buildMultiStyleUserPrompt( - message, context, customerProfile, conversationContext, - referenceUtterances, intent, stage, stageLabel, intentLabel); - - // 3. 调用 LLM 生成(非流式,后台一次完成) - long startTime = System.currentTimeMillis(); - String generated = qianwenClient.generate(systemPrompt, userPrompt, 1200); - log.info("多风格话术生成完成, elapsed={}ms", System.currentTimeMillis() - startTime); - - // 4. 解析出3条话术 - List utterances = parseMultiStyle(generated); - if (utterances.size() < 3) { - // 如果解析失败,用回退方案:把整个内容当一条 - while (utterances.size() < 3) { - utterances.add(generated != null ? generated : "生成失败,请稍后重试"); - } - } - - // 5. 逐条逐字流式推送给前端(伪流式,打字机效果) - for (int i = 0; i < Math.min(3, utterances.size()); i++) { - String text = utterances.get(i); - String styleId = STYLES.get(i).get("id"); - - // 先发送该条话术的起始事件 - Map itemStart = new HashMap<>(); - itemStart.put("type", "item-start"); - itemStart.put("styleId", styleId); - itemStart.put("index", i); - emitter.send(SseEmitter.event().name("item-start").data(itemStart)); - - // 逐字推送(每20-40ms推送一个字,模拟打字速度) - for (int j = 0; j < text.length(); j++) { - String ch = text.substring(j, j + 1); - Map chunk = new HashMap<>(); - chunk.put("type", "chunk"); - chunk.put("styleId", styleId); - chunk.put("text", ch); - chunk.put("index", i); - emitter.send(SseEmitter.event().name("chunk").data(chunk)); - Thread.sleep(25); // 25ms/字,约 40字/秒 - } - - // 该条话术完成 - Map complete = new HashMap<>(); - complete.put("type", "complete"); - complete.put("styleId", styleId); - complete.put("fullText", text); - complete.put("index", i); - emitter.send(SseEmitter.event().name("complete").data(complete)); - } - - // 6. 全部完成 - Map done = new HashMap<>(); - done.put("type", "done"); - done.put("model", qianwenClient.getCurrentModel() != null - ? qianwenClient.getCurrentModel().getModelName() : "default"); - emitter.send(SseEmitter.event().name("done").data(done)); - emitter.complete(); - - } catch (Exception e) { - log.error("流式生成失败", e); - try { - Map error = new HashMap<>(); - error.put("type", "error"); - error.put("message", e.getMessage()); - emitter.send(SseEmitter.event().name("error").data(error)); - } catch (IOException ignored) {} - emitter.completeWithError(e); - } - }); - - return emitter; - } - - /** - * 解析多风格话术,按 "|||" 分隔 - */ - private List parseMultiStyle(String text) { - List result = new ArrayList<>(); - if (text == null || text.isEmpty()) return result; - - // 去掉常见的AI输出前缀 - String cleaned = text.replaceAll("^(风格一[::]?|风格二[::]?|风格三[::]?|亲和风格[::]?|专业风格[::]?|促单风格[::]?)", "").trim(); - - // 按 ||| 分隔 - String[] parts = cleaned.split("\\|\\|\\|"); - for (String part : parts) { - String trimmed = part.trim(); - if (!trimmed.isEmpty() && trimmed.length() > 5) { - // 去掉可能的风格标签前缀 - trimmed = trimmed.replaceAll("^(风格[一二三四五][::]?|【.*?】[::]?)", "").trim(); - result.add(trimmed); - } - } - return result; - } - /** * 通用文本生成接口(供其他服务调用) */ diff --git a/backend/generation-service/src/main/java/com/artedu/generation/entity/ArchiveMessage.java b/backend/generation-service/src/main/java/com/artedu/generation/entity/ArchiveMessage.java new file mode 100644 index 0000000..7da48ba --- /dev/null +++ b/backend/generation-service/src/main/java/com/artedu/generation/entity/ArchiveMessage.java @@ -0,0 +1,32 @@ +package com.artedu.generation.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("archive_messages") +public class ArchiveMessage { + @TableId(type = IdType.AUTO) + private Long id; + private String msgid; + private Long seq; + private String corpId; + private String action; + private String fromUser; + private String fromRole; + private String toUser; + private String tolist; + private String roomid; + private String msgtype; + private Long msgtime; + private String content; + private String mediaData; + private Integer decryptStatus; + private String sessionId; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; +} \ No newline at end of file diff --git a/backend/generation-service/src/main/java/com/artedu/generation/mapper/ArchiveMessageMapper.java b/backend/generation-service/src/main/java/com/artedu/generation/mapper/ArchiveMessageMapper.java new file mode 100644 index 0000000..18f15c2 --- /dev/null +++ b/backend/generation-service/src/main/java/com/artedu/generation/mapper/ArchiveMessageMapper.java @@ -0,0 +1,39 @@ +package com.artedu.generation.mapper; + +import com.artedu.generation.entity.ArchiveMessage; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface ArchiveMessageMapper extends BaseMapper { + + @Select("") + List selectSingleChatMessages(@Param("fromUser") String fromUser, + @Param("toUser") String toUser, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime); + + @Select("SELECT created_at, from_role, content FROM archive_messages " + + "WHERE roomid = #{roomid} " + + "AND msgtime >= #{startTime} AND msgtime < #{endTime} AND msgtype='text' " + + "AND content IS NOT NULL AND content != '' " + + "ORDER BY msgtime DESC") + List selectGroupChatMessages(@Param("roomid") String roomid, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime); +} \ No newline at end of file diff --git a/backend/generation-service/src/main/java/com/artedu/generation/service/PromptEngine.java b/backend/generation-service/src/main/java/com/artedu/generation/service/PromptEngine.java index b0feabd..92bd109 100644 --- a/backend/generation-service/src/main/java/com/artedu/generation/service/PromptEngine.java +++ b/backend/generation-service/src/main/java/com/artedu/generation/service/PromptEngine.java @@ -10,20 +10,24 @@ public class PromptEngine { /** * 构建生成话术的系统提示词(角色设定) */ - public String buildSystemPrompt(String stageLabel, String intentLabel) { + public String buildSystemPrompt(String chatHistoryContext) { StringBuilder sb = new StringBuilder(); - sb.append("你是「小九」,第九联盟(CG美术培训)的资深课程顾问,从业8年。"); - sb.append("第九联盟专注CG数字艺术教育10年,累计培养8000+学员,合作企业包括腾讯、网易、米哈游等500+家。"); - sb.append("6大校区:上海、西安、厦门、武汉、青岛、合肥。"); - sb.append("\n\n回复原则:\n"); - sb.append("1. 语气像微信聊天一样自然亲切,不要机械生硬、不要堆砌数据\n"); - sb.append("2. 结合学员具体情况给针对性建议,不要泛泛而谈\n"); - sb.append("3. 适当用学员成功案例或真实数据增强说服力,点到为止\n"); - sb.append("4. 长度控制在150-250字,简洁有力\n"); - sb.append("5. 如知道学员真实姓名则称呼姓名,不知道真实姓名时绝对不要编造名字,可以直接用自然的方式开头\n"); - if (stageLabel != null && !stageLabel.isEmpty()) { - sb.append("6. 当前处于「").append(stageLabel).append("」阶段,回复要匹配该阶段的沟通目标\n"); - } + sb.append("资深销售教练,仅输出符合规范的 3 条推荐回复话术,全程禁止输出任何对话分析、客户判断、前置解读、总结说明文字,任何分析类文字一律不写,正文只保留 3 条话术条目。\n"); + sb.append("## 对话历史\n"); + sb.append(chatHistoryContext); + sb.append("\n"); + sb.append("## 说明\n"); + sb.append("其中INTERNAL表示销售,EXTERNAL表示客户\n"); + sb.append(" ## 内置分析逻辑(仅 AI 内部运算,绝对不能打印 / 展示出来)\n"); + sb.append("内部自动完成 5 项分析,仅用于生成话术,不对外输出:1. 客户意图;2. 情绪状态;3. 购买阶段;4. 关键信号;5. 未解决问题\n"); + sb.append("## 硬性输出铁律(违规判定:出现任何分析文字直接不合格)\n"); + sb.append("禁止输出:客户情况总结、对话解读、阶段判断、需求分析、前置铺垫、过渡介绍、标题说明、总述段落;\n"); + sb.append("全文只能存在 3 条话术条目,除此以外无任何文字,不能加开头、结尾、备注类语句;\n"); + sb.append("每条话术固定三要素,缺一不可:完整话术文本、预期效果、INTERNAL 语气;\n"); + sb.append("单条话术文本≤100 字,整体风格专业、自然、有温度。\n"); + sb.append("## 单条话术固定格式(严格遵守,不改动结构)\n"); + sb.append("1、李先生您好,这个产品标准版 9800/年。不过不同企业的需求差别很大,方便说一下您这边大概的使用场景和人数吗?我可以帮您推荐最合适的版本,避免买多了浪费。\n"); + sb.append("2、价格方面我先给您一个参考——标准版 9800/年。上周有个和您同行做电商的客户,用了我们系统后客服效率提升了 40%。要不我发一份他们的使用案例给您看看?\n"); return sb.toString(); } @@ -76,14 +80,11 @@ public class PromptEngine { * 构建完整话术 Prompt(system + user 分离) * 返回 String[]{systemPrompt, userPrompt} */ - public String[] buildUtterancePrompt(String message, String context, - String customerProfile, String conversationContext, - String referenceUtterances, - String intent, String stage, - String stageLabel, String intentLabel) { - String system = buildSystemPrompt(stageLabel, intentLabel); - String user = buildUserPrompt(message, context, customerProfile, conversationContext, - referenceUtterances, intent, stage, stageLabel, intentLabel); + public String[] buildUtterancePrompt(String chatHistoryContext) { + String system = buildSystemPrompt(chatHistoryContext); +// String user = buildUserPrompt(message, context, customerProfile, conversationContext, +// referenceUtterances, intent, stage, stageLabel, intentLabel); + String user = ""; return new String[]{system, user}; } @@ -128,59 +129,6 @@ public class PromptEngine { return sb.toString(); } - /** - * 构建多风格话术的用户提示词 - * 一次生成 3 条不同风格的话术,用特定分隔符 - */ - public String buildMultiStyleUserPrompt(String message, String context, - String customerProfile, String conversationContext, - String referenceUtterances, - String intent, String stage, - String stageLabel, String intentLabel) { - StringBuilder sb = new StringBuilder(); - - if (customerProfile != null && !customerProfile.isEmpty()) { - sb.append("【学员画像】\n").append(customerProfile).append("\n\n"); - } - - String history = null; - if (conversationContext != null && !conversationContext.isEmpty()) { - history = conversationContext; - } else if (context != null && !context.isEmpty()) { - history = context; - } - if (history != null && !history.isEmpty()) { - sb.append("【最近对话】\n").append(history).append("\n\n"); - } - - String stageDisplay = (stageLabel != null && !stageLabel.isEmpty()) ? stageLabel : stage; - String intentDisplay = (intentLabel != null && !intentLabel.isEmpty()) ? intentLabel : intent; - sb.append("【当前阶段】").append(stageDisplay).append("\n"); - sb.append("【学员意图】").append(intentDisplay).append("\n\n"); - - if (referenceUtterances != null && !referenceUtterances.isEmpty()) { - sb.append("【参考话术风格】\n").append(referenceUtterances).append("\n\n"); - } - - sb.append("学员最新消息:\"").append(message).append("\"\n\n"); - sb.append("请为这条学员消息生成3种不同风格的回复话术,每种风格完全不同,让学员有更多选择:\n\n"); - sb.append("风格一【亲和风格】:语气温暖、亲切、像朋友聊天,拉近距离,适合建立好感\n"); - sb.append("风格二【专业风格】:用数据、案例、专业分析增强说服力,适合建立信任\n"); - sb.append("风格三【促单风格】:制造紧迫感,强调限时优惠或名额有限,适合促成决策\n\n"); - sb.append("要求:\n"); - sb.append("- 每条话术150-250字\n"); - sb.append("- 直接输出话术内容,不要加任何前缀或解释\n"); - sb.append("- 每条话术独立成行,用「|||」分隔\n\n"); - sb.append("输出格式示例:\n"); - sb.append("亲和风格话术内容...\n"); - sb.append("|||\n"); - sb.append("专业风格话术内容...\n"); - sb.append("|||\n"); - sb.append("促单风格话术内容..."); - - return sb.toString(); - } - public String buildSummaryPrompt(String context) { return "请对以下对话进行简要总结(50字以内),提炼学员核心需求和当前阶段:\n\n" + context; } diff --git a/backend/generation-service/target/classes/com/artedu/generation/client/BailianClient.class b/backend/generation-service/target/classes/com/artedu/generation/client/BailianClient.class index ea4b949e6844fe59aa43dabe4a20f390eb11fd2c..ec3b8fd4ee481cf421ca2c715a6a56ae7a34c819 100644 GIT binary patch literal 7333 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 Q$(-ZMq^K6Bis^{`7p<{9 literal 6659 zcmbVR3wRXO75;BFyED5P5Jq_{Dnvmc57<&bF#$BZ0|}skAV^DxWLOq9yUXk>&#G0c zg7VOUB1%E)18J=yU?706wuV+)Ywb&IwJ!tMm$mN)mHu~THd#ml)bHEO+_`h_Ip>~x z{{NgidG+IiF8~-Wx`&VlpMrc1egp)%EjE@Jk+_kFMy4-VY}VNVfl;wU%pN1)8&p)Q zKouxSTG2>4WyKQFg_hA^E>BuZBFoJMk-B)yOxTg@%(OkzY)Hio+YCX0FNgwY3c6_M zit_}D>yix-!?Ml#OeAV1Ov|ui$wYScSR)pX8HsU@ECJ2RktQ&>>iR3H3kJ&3DRq=*uIj}s$xji)WL@xo=Gt(59I;g76M>V!|LirhcDigLD zHLdcZ_M<`wqmP0MHC%*?1ui=$!vum+)2>LxrkX1SE*R9I+TMr+7@{yM9 zcYkpE`eV;O{r-XVEl;mIdf&bRl%Q0>U=2eMp;l+3awKpIOv_4I0zEqLVNtF0#!wBP zmag!YILnHwj8aTnWZS89StL?#q!*>@k|}eD5s$6RBr(3aV|52@$jjb%(xh98kT7l%AP42 zrlN`jV5CxJqMq36XxrLFwI`D+8INfirpxVA?W7xda(UNkxDGXpG%k;D>_BKcndOps zW(jn67Lc)H@yKLGLbZ_!VWu=)m%%ef!(6FNBR(7qk0X!^Fb|(m@L3J>@i}^>O#)}r zh*X9~jLbE{CB9rxdp)^G^SV?l;OZL8blQlTX%+NRzLkudDi+dl>6K~QY*4X?j;(Vy zQkt_^!xE5*@{$}h=bTjMc;sy6Io{#g2-pOz$q*DOxY9t%N)qxa2ta=tpmATcz-Vbl;- z<0hG2ZWb8b(PBH2;Vy!9#cGXs#+1vE1fk#-4Y%Spnw?6f?TJat^@hN_T*>WexxLfI z#f@~j{D$_9?QoZG7wGL$U&V~d<1cP*d1(8wT?bn>t#3KFS;d|7ZZc!jrE+`MYPbt` zGqf0n0+;6+=9$r&*q3 zsDdvGoZrSM6IRrjDVfMs>^Nm9yKg(T`N@{Yo;|+rak-Qbw&4*CUy(=+Nu;{qkqRD@ zi+Wt(s$8F)%Vy>*bEm+tGbE`G53f7A<>8}y?>oL>f6K=E&4vYLeLZt{0e0c53ceOyQ&9hEq%0A-jX@OCazt51Fn4MB2;01AWu&h61mTJ|>>=MRq4bMtf zbfGIq_6uXtDQW4$y)>eAq{C(*^uu!+8nK_0Bk9D5CDKgExy~B5$gpb6r5Q6(XOwxnl|yB&ZQj1Cc$FnXt63_(%WQj^a7KK~ zT{}t(>thXMGlprJAumP0uHpN5gT|#}tC+Z14^@WnCVr^kM;d;NpJcO+Qxto}9I?1e z^3rq?c+XQ!%9eX7-s)t9?eOppex~5(8s5cw0);t6Ae#*=jGd5^Q89~&k2_wlkW4P0 zoeb7LcmGe_KbJ+xosyP*so_^L1Ip|;-5PH$G)S)@{08qUXwh&K$5t7KvqIIk*} zFsEf0&(=(X2y@ETIwM|dSTXtRb>`cPV)R;RCknhn%PGf>^0RVKcAImf(R02uqm33@ zJA=%nGo4gQ+RPb{mBbw49zp2f&da>EyhC6hfVwe*PEJ-eDdu+0vLD91+nd@#AzMjkHomrk+7>sg_%Lb|U=)lZ# zT8{M|(#MpKp%o)O(M)n|jcwE|p?f?td8~5_MS&vnd&jZrZc5v^kZxz;>XE14AswzZ_0*C+SNfQ}_O4jrG&5D<>@f;F*d!mu+IbMSdlc`7C_V&b&VB@+L#VjqIdprLFY@qvUUlU2+MCy& z6cWY-6#obI^mHfVkNA*J6yqo(QuyXio{EW_<>NcGSd^4D;)305yHW!j0rYhw6}n?u zC9%N9N6vc{f5u-pL(1&s%Jl6+5M2PVuXrE2HKUKbHKKPjx_PZe^xcZ{_F#ZMs0qcK zyxV>8sj~cVelrTf`OXMMA6Axs2qU=aE6e<0{~nBN#F(&OAA1Pn**Q_4)QHMfnU#&G zZp4g3n8|mwWr1)&pY6W9z6m$@FgyE3DQU)t5~_F*L&Az~_@77K9G_mNn|ie50Ae+B z^7+u9M@!{{J9j6#a%i&DeWK{4VdYe*YFO3NddBS>+|2Q+zI<@&_?2NbJAUj1(DdPoRj`{)~(P7=+7E%l zI3D0J_)%PeeYg@YVu4Y_agMXs}A7iWtV!Y^qN#atT&qrd47>%i7 z63^w8m@Z~xhM0$IMH1JEr92?tj9Re3Yx>C-K_$&T~ zAf-j|cl-k(%9)Hi*(#ufLM&q}Yn*pJ{)vAvb{VbYFmVg5 z{)m357E$~MCkWk}#1;52B?ow-xCj^Lpr6B?lO*_aIkU!Pwv*gUhU%knPwDv zEqzZT_H9M?V()oB4(x@2?h`qGjdc>BZo65atS3zd>A za?!1Xl_PL0excQ3Qp-yoNOzTyNSe__(#1CfwxW+*+&4Mm6%V{bx?E*g^);c{p#=Rq zt&<%{zZMQk354|b1a>0dcK|qkthWBs>S>;ZmXN~BJwL-@_QH1qkA~sOtMp272_fJqS> zjg%zO9H5l74w@CtUxb$#!zyQ%@MxqESGCM`63qb_JlPOqOJZH{bL}Vxxq0LZ9edg5 zf~~jWn3YUZ1l$k`H=iH;4as=;CaSBuU9G&UiXA&v7Qpks3); nD#JvUCepl19Q{C0FF1f-@5KOF6A33vxz&qKGLdCfp6K>J3XM{q diff --git a/backend/generation-service/target/classes/com/artedu/generation/client/DoubaoClient.class b/backend/generation-service/target/classes/com/artedu/generation/client/DoubaoClient.class index 831798f951275b48432675fe38c19da12d3c0e5a..b4858b7a1f39ba57f5a05d3c1be3f58aced35a38 100644 GIT binary patch literal 6438 zcmbtY33yc175;Cw_cD12Ff1~P5EV2FVcH^!6Ba`t5=dACf}j;&l1DORGH-bECV)%b zs!|2PiVIqCUr@`U7zm4Cm)P39#n#sDH33>%Yinz3QTyNbUM52lww5o<+;`{RbIv{I zKmR%Rz46KJR{=~E0R?FSg>`0gP`7NOJ`rp%qK2j0VKW-6i-e7+9h_<=YIU>Rc~Foc z(0`fUq6Z^-v>`aVc9~IUE65T!|Aa!Ss;XTH0_hR6LBL;SS`EQ?Wa)*=f>mZigJG2l zoOO93YKNPR%4kbC9Thb8R&0xh1pNtT!S87gY7FpC<_0 ztAbUL=4!c+J2cCP+w+a)SVXrCffCn{m=%sTEVcAzV})ro1y>lgUFW|%WjVL26X=&{ z*q+3b6cpA7WRz2|4+Ak+!61P%dY-F7ud_{Sm4+cWLm<1su-)?tj4G(=c4c`)kH z&|kqh0>#cTPR%Pm()Zor^JFl<&HBpuW|I-+ zu?MCs=rUE>HCEbnp+MFDYS-dE4ot)1tKzoN?8C*lM8S9h?38jsLkRS`L}pnmJkwYu zFsPsp1wKr~WCa9%3In+3)^I7x1e9=m8a+b+OpV1V%9+xKx8L5e=C;n~9`D$6*OA-S z9@@9%on31?wyf#AZ$}QM;W7mk6xcIqG)zY&v)iyN(-IimhodB9FUCv_RVmglup%mE z5jTyt9gBy8q_w6obWugp$1kyPuw`tpu2Hvxe2zs7$$D`Ga|qr}JaFq1PK$+=tl`_Vchn!F+*pkGrSZs1NJ&SH%nsHCV{gmd%+{Rass(zjF4h zB{SyDroAKkWFbdma(AgzxJbidTq%$jH|%ng@Q>P3G6}HYR74cksQA12dV_B~} z>AkP8Mgi->Kxb*f4o8AzmZh(%3de09mSTj8Wuz0!j2J4$sc0tJ>fH0^z{GL|F&?XX zbG07RV1ah0nM(y0r5f*6tyCU4jTtX791E$WGzST+P|(7VbZeJZYgh@H33`2f4*+}G zWQJVFGbQ4NrQimE0o?+o>+wcP_u+bZ@*Iiun>E}bk*+aMomwXAjy(GpHQa{VsVSDA zx5uB-NmJ9?Ge^a0Qg5>nkLwLaT*aLNK62R-+aWVaTWd6|#ofejOt<2OETOVhNLY;Y zv4kO8hKNzBV!c2P8L4ZXiZ9EOK)kBhKxOsexU5?BD(>eKOGUJaNvhyMf%A@=O)>+g zIaS?<2k?+ASq}?L?CaQl$#4Ugh}hv8J(4hF2qlx`;}H#;@F+nPGvjuJX}N9@xGGh0 z?^4klI&LMuG6mvY0q;Gf;&FkYE=QKlsXV-YL&w9L4sG7uaqrrW-5XRqDPi7dhDlm7 z)K6=82G26o#6XXXJiZQz(8(&EXB*K&(UA=s4{zNX%D?Ug71Jdfe^v7CmXoGzm#!Kq zdYiOqyM%aUpQw77NAOUk;uTg+*N8(K9_?Jco_`&8J}Oo3)UeB;{CcA{(V$}YG3IW& z_0WdrI-c5oc*oPyTp#x0RR#OH_`+#Mr>(3rVv@r(?3an+lZoQOSt@u&|A#SBNnVhgG?x^;npIX)Gq)DN22-$jIjNy!e1RUY@b?yKOEj{)siac|$2Go8TC^ovE8)8!HJW!QtQ(fF`}k)kCVx)FzYp z>ouB}rI;t}pOErQbG=6=I=wT;o0(KPi7LjO&Q32Pa^F>_a^TZ4D=A!x|Gy4+jHKLo zwqDmnr#P-t@N-7r;d{qBZX^}F-BksgS+8egxVku>mo>I#r_|QbdX@FpDHXDl;-!Iw zXk;I3mRiz06lTv0H$**dKc=F1LF>6CHPRj`Cz1c(5xB@r_l_-3bgtfc=!LDF58c8B zuye!K&NVkXHr12z-`l&UoBGz@bL5V7GGjY69Fmlfu|l_^l4_2~lKw~LKv#R(oj9^W zzN_KSGVyciEjBJo!woayX4HrG@VSgwwsE`S1Zg)bKC-n=5D$$E1!HS&L?~ zQ5jq?HI+p@U#j?&h8%wO$<9sd^HU0HzS~iE6C>Rwgml}MtjV2Aoqr@kHcFl|NEPmb zllRR$Ug{;r11xvUGZR*wQ4y9`%mLDft~UTM_brD1YOK9B5W#?x8Z9QLaZK^TM`K+AmAwsKU<_nqugdVdV=pUX@Y48*!?;5m&@uvTd)U_GP>x zc<-!p>ds3XkMk}5FGx>R@y!CUO%?3S--#&h)$%{3={qm~K?`*EI1Fcd+ZIq+8s`TW?Zoh+J;-0Q6X(8y^NNaJ z!KiK#eq?Y_fS+ej=b0EpVN%=>cQYJh~*K6`$)VbfhD+$X%2anvHRu z&}>J%JbAVwUOJvPb60%&yAvJvI1Ez;qq2o5yjK&C^x%w*7}+Jz7x4M-@!y-2bzi{ej`!e! zMFBOCwG$gdK59HKkjbTH`aYz$;wuMWhH?Tque-i^%=1kk$Nxkdo=U?3Btlw1Ye#NC zYr}H_8!=QmaWhxE;H+rFiwwoKfR^5dt#X6uf63cwhH?YB{)qQ9F_b5F?r1}68UlIS zLO%J}7Vx!VkF@nb2E`zqnLJfIkG-Nov^d`@#b)_UV93;XhC!FPGn{BGKruhZU@ReW zDM2xnqiRB80YTHqBC{Ohc`3UDccT=K@r}r4Ou}wVMmtx(fik?w9dEOE{T3B?7nOJ) zGw=~+iY!zKKi@5kz+5p7^F)a645ng%sK6CsJ{E~OEEX-i*{{UaVjY%&*;Kf1U*GV#+#283Q$?CzLK4;cs z3}TK1mo>9I36h{CvrEOlA$rpAJIYAI?;T#R;7H1J(Ef)ubfodNbhz6xSGG-$CsJhR zC1vM1k>Se_d4s10St~vyLL_@$;WEabs>nLiUDhch+x(?^bUVh6_OEkNtsNy@!&xP- z;e(AhyW{{qXvIHw;iGL;GV4C!-aT!ydJPh3a@O%s8KxxjtjMWgH!${JAVO{=!fv94 zHxsS5Ftcvu$~#a_OwPrf&M7XWuV|ll3Kb!dL45JTj3SXq%%yRsUt|e|I?GuNCFX>K yIq64t)j_V3xXDJ^hnT`Z=aCLnPNa!!Aqy%CtYG;R1H?c+@jZtaB!-Bg2>cfYmI4j{ literal 5738 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 VEtK#&$qYW570pLq7mbDg{vQnMj==x` diff --git a/backend/generation-service/target/classes/com/artedu/generation/client/LLMClient.class b/backend/generation-service/target/classes/com/artedu/generation/client/LLMClient.class index b7246166e14ba481bf4210515fe6089022bd59d0..9a2ee921dcb3be15ac4f75a345aa317f7a95df02 100644 GIT binary patch delta 103 zcmZ3*(#Xnn>ff$?3=9mm48jw+ZZi5zjFOv}CdC*vu|ag>V;)9lHWo$(Rt7c(1~API jr8&SfCj%Fl=4Rjl)4U9P42%r?K+~8Q1b{3-FiQvkCN>P@ delta 93 zcmZoff$?3=9k=3_|P-OpFX_lN}kwCaUe-Y{baJXwAyP$iT|L#=rok*}*gi e11Ff~V&DeTJPf=Hj0}80Gng3ofh++qOAr9E%LzaL diff --git a/backend/generation-service/target/classes/com/artedu/generation/client/LLMClientFactory.class b/backend/generation-service/target/classes/com/artedu/generation/client/LLMClientFactory.class index 6976415fde11e2e1ec7368c02a394ca1e9e4707e..fe3ef456f3bc8752d885c2483a75ee357cad5ad8 100644 GIT binary patch literal 2991 zcma)8+fN)-9R7yeEXx!r6{TR6s-;}rii#F!m2S(WU1%*xtyXc^oi0OXXK;3gO6&bv zZ}q_!FK=o>v{A7&i!H_&A8gV;LZ4`Bd@<3)2aWojGs8td!zR1u{LVSQ+xPo^=j^4w zE_?%E2i{VVr=U6MWMaDO87V)OHf+PyJ=3vcNy{{BFP2F3#pSF^PkN3!siHtZ*_b|| z$1L4W$M%nm8A(q;zU8D9lqVcF9m`rr?;MLIoOIf7+Z9wF^li_~7`^s{nKef&qtmt> zPkPA;70bztILBh$fo~&46)m3V-P1of9Pf`_pckPdy%v|>rePWrAZVv8?Kd-UvR zpFU2_;sG;l>z?l#3P#qb))AbO`6L`W-JVz*B<(xtFw#M!Y}4CG4C?BK6cogrlo7>x zY*10I;QHl=gg|Pz78Q&)ZFm7v3burK%0S|lp3Sz`uLQIhG^(KxMJhHbs9hU0QBiU8YZ9hy^!u3+!yVLFB3a6$ZVlnwHyKMC+;Gh=tO3% zpq}BZZeUp&?IQ2HHQa;k1epdN7*7%BR42o&p3g~iAbXNE-Oas0N>ppd4iz2blZ=1m z5e++WF9~Bj?&}t7Ua?y84+;038g?PBpoH!ZxXy%`GF%1M&U=@X9`Ia~-4y{_S{>0% z%hc^Cy3wnm=Ushu{Hxe59&`+dB+4Q2{N^(usA+%1g;q>kbUhDDb>rl4WX^d3?%!t?*@r6-7I-i?l770mqqm39Rf&nu-c zEciUC!NeF*8}~_&dsZpwN;Rgf)Z%dbie9(-OnrhU{=uzhKyA(vK0x^hKa z%7rov1zXqHQ6x)JPmUVA75=M?VfhyxNM3M7!5XF6fqlFb;wxXjJ@@H5b2DczfA!K&?|vi@d`V#S^0E#M z{RsdzECo+Ka`i*P)vFp_6PH_&Yh;`WGD?+5iR-XzN#s(4Z8G5aZqn#7#S2lfka~E< z-zGA}W!=iat&ARrk40@C|ABh**RP{ zi^{_@s5*yDUvN1OH}N+r50y}{6g6@cROibU8i{dKxL(*WgUyR-A_72@Dq3&=H{%wr z72{TH;R+*A{y+g^g0iXMA_|r1v)I&-Lv0RC-(p*$@q1J@o=1y<99p^FnnT;WC~TbO z{J#F?izq7J-QS!;*WtE;9QK`|?JxONKe_tr9*&)7K0fVn?4SPq#LFBX{?2a``Hucj zTiL?V|M|lTvH$!&|CdV~-`ZGEzCVZi-@{{5Fex0A!tfN1P#Ba#+Z6Uw7?Q%CDeR)~ zpcHDRa2JK$QfQn)9fgOaP(Fp~SsXb`d>-waLgg%UF;8-?%_1e{NBhFen{r4WI*aSd zk2N#N%z2C#plO=H<;z-h@qZ5ZPo@ABEb&Ips?dmPG;_CwP`8o}+X?TF?Eb5$!_VCP z4Ndr6Jdb?uG_)$!EPD;D?4$((j|m(XHkD#Lfk~F-Dt(>cERUMujJlh`wHDeui6^=9 z6ty}~TJ$GsRc!m46f01%l~WS18~77@IcmYDq~ve%C*0=|d4fcEdVxjTLn^K(5IH;} zAb9>fUd+QHqe|&C2>V`?;Xav!sHZUVO28+{Xhw_T0MAp07S#hDcQKA`sTz>77_Z|E MDkyl9zj-+Q57U?$UH||9 literal 2973 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 TUHrLQ82rZ4O7x4A7(o07-XZS} literal 14271 zcmds834B!5)jwylyvgJxBr_yra4A))NeB)GK}{$Mh%6?E2C+zOolIWBz+@)Q!lqQV zswfC`L5o^9ETB~oHH5{b3$$8WyDwjBR}%31y0>5J*YY*}pZngMyh$d2==W>C{xr^g z=iPhmz2~0uKg+wm{`Y+^6VV0yLl3zqN26Sw@+hCFWMOb|Fc1kw+X7cMFEm0)ru+%v zXgE2MDW|e(u7})Ippi$XLeiPeRNYg_a3m0lMMJ50+=wOvQ0~) z9Br%rSEE$TAGjhp&NFrT0F7WOx-lG#E-|80B4OwZ)94e(^eSg}2=y#FTceRWeTdFs zD(zF-8PTNCX2hAa#lc9*xU!Y0ymE%6Z%SZR5Adj@Dvhdj8bvisqmF+t8S^u_E&YQw zT=8yC!(M=MQPwGHbe_E%WmVIIi3N?p4iAl{95gngk%CMwa<0s@XQ!T66z4K5lAA7u;U{9Lc*t;5J@_>=G`i`-OnL3G79%2}yF{l; zX%f?rHX}L3wERYS$5aLL&Mr(WJe*t>Xo$3{t~i1zbeTp|b-J9UF@5NyM!_60rD8BE z*p34jYQu@s9^5no(rPhUgQ-Z;Lsw9PMvXenqAQs`;Ft%^c3?={NT6TfYW0JGiBu?L zB!FP!vdA!Fd)XK$qrXb0tEq{}tBklQ)!rVAFSAYf94A}r@SO)?kwnnfh=R^#x;V=a zhm9RatK9SvwI#Izjjm(5G!}0QBsv5+TH_Gnl309EV2RNj5D1GH$w2$!P@vsNE{L@R zg3)L!X(DYCaI`%vaFhr4LB!vA)k7bnk85;;SYnW=xX%(BV$n8ufXbQ9eF+iLnMWb< zI4$ztu?O|GYOWWoTXkxq1<<^BD$0C*YidPEn?jeE_+v_t3qz*(#SKX9?cH78qxlb9uJAxXweH>3)qK z(CO2%(J>A*J#JKHTy5N#GK6~p0K92gB5AY>uLpH{NEiv##7CiiMyE&UQ48#YOXtKE z8BySISq9kKpeK>V<2pS-Tj7u*mU~HSbzl(iu;Vq`A6Wx{PoJf28g18U2R((*B>M&j z84az+J}xsIj~(4q59$&_D*g$;znXpP-Sj!8(|UG4*7MN1?u|Q-+`IkAmbGv1f8gk| zTYI)Y*8Q0~#hE>;(@xq2C2I|ap|BZF%2p%irU!9SyXkq2UeM`95&t0DbRg{1_GY6c zeTW*iImcLvP-G8vX|z|TeY79pb#`g>-zRLq5O#njr;?=?--j@wkbtvIlyuX}OcT{A zTHv`x9J%+Ap4&HdZ+-6Q3s3&`!20f&?&)5)!4wiCcXZ85hr2fP+`F@9{i+daE*a#e zSD|T+$1lM6Tf*&7F60skndeJ79TY>$O@x;lvb!(q^c4wp5cHXGhnrp(17FsG=;#fx z<|MKbH+@}#rsT4Skq~|ShECt4Z-LY_XI{fp1Og={PN%I*`N8k#^j-R%NMo^zgXcg~ z-mA|VDSlemO_ub*h(mfmpdV`VA3FVre#|uc{hk2Ah^kPmHS1Zv-_xo6{6wdp($6q+ zOE8JRBV%S8s@{J|O6c+noqkD&ML&!v^!J*|_kSA6v@57brz7H=O3esT0j3R*74)`F z|4IMFdXO{DDL<^R+{c|Z<{phdhHyZs`r{B@g?bLO$bL@W7)mA zL$JPb<-M_Y`g2x8c;^Kd>52%JbYCsgG^ z<>whIvb568XJBM#K`Oe)%^!e}lW;a>-a+K|@Yy_4;}7Y44xgK$B4(utLlY6hK(LyN z3}mjGtAO8dO&!Q?3^$L$Q)?;`5eMex(dg9@iyE+Q4(MD(`5GhHHp5&c*r`iHMu$|J z+&mUK)$`)2?gJa0rvxS8aXOD@WaD{8JRU;{qS`6HfwqQ)#+ImHUDh|=&2RM z-1H+i&q6%s4BXv3TSRXpLT2dpQ;?dV^?0M+U?u~aIU3EwI)*Ygo zb9BCjkqx_IsO+q8uESE$f%^G=Q7oWR{u@;m>(gSa)u(_Aj2IAi<_GvmG0X+-(LCX zkr%cdedXz%wT}pgSJp`6bL;a*p4luG-Xc;#);9eV1>)SAinriakn|;iu5-hQFcQj1 z=_&w__M)sFuh|Gj6MWpp&ItLq znF|hgO1hqm=}PVDU%E8QbkHgKfyVwXK{;{ZN+i}-!m$<&SduINPze!-Qi)`&U4JgennH#9%Ti8;tt1>V5tyYMp%3s%eIbw(Bi}6ViGuXy6=K40J`FLaf*_=~lw@3H z*W)Xrg*~E*MNP?IXc3qzJ{sS|bnM?jHQtqRrsW|L8J86;q}tewxWEY%vtx-QB-bGy zG@v7@f{$Yjr0g#sOlM@m(i|LE1~i?kj%{fGW5dV{V7c;rD3Oc@plGG z`xjM@ufCVXQu4_})OX#WEC*T52^H|vPdY!K%9KnMkzjjsOK@aAU>!Mz>BxI8KK+0A z!X*h`2%kK7A^wo27D%-LftElOhs`iDo>VnYsV&G0sSM%eObH9^@BuI;SyGw9)uc0M z9KL%36wAEq;%QPJzb{u2u76sVYbEDNBso|rlr6Zyx8Q0AUVlAd_RUq(nL$jq1y7Vn{xJ#lx@h>l%Mm=QsFkOlS24_u=Sbd{YTD zDBZ${pq05H4o4u<_w~D0~I*_rq0jv3rHenL=jr4Du%enA^nQy8h;lBj{#!KCIOAV zZ{LYhNo&ToEMWn?OmWc%Q3Z4%y342GQm;hIC0ApJxm8h_+Y}8qkOt83p{pOwD_5k@ zf4F>fz`F%9mcvv)aN(GPc_Aoum;-f3(yR9nS9g*2A{9NSdM?6$6A<7azuKW zeYu^Zcw&xm2jvML{vG-b0c}(cEBGOm**9-${#;prvD#Gx-x}6=AKD_!eFXOGC8L2^&Onv&K(#>M%!maqb zZ9YLbxAQtI?HtM}hhp3Ta$SP&EYC}~*Ox>4Ecyn%3w<9h07JVcZxl`muEWnp(9w+Z zrtA1qeb0%0&&htzDf2nabG^-Tao;=}Y}%4OzDxV@S!O@qO}k7*rzdgpa?a-~Men59 zjiQS+B`r#m=ghJdIoF@-y>_&vn7Ni><|xH1R}8L%8qB6)xDqsinsA}#8l`|2n9S1( zc)n6QxG<{Zd!Q07j2NzzBM0M3m2%{!mBXa0rd;cE?#*&K_o>sti8)SZvpNM7>C+P1 zY)dB&>D&pi1t$0h3dT6 zrAuwUSlP}3SlU7g;ERU7-BAL67V5{CO{r&(9gJm1$-9kJBaoyfUq} z&h2-jUtNI!e0&R?Ex+sBTWPqzz`Ma_Q&&*qFW5^PU3BeQjkoo_TGJn(zW`wTB5u_l zg8zGss_1pV^H*smy+QNo>lCIpDGu6Fd^i_HnGQgm30rssworhc0e%!Mf!5_|;{e`1n^C>^3CKqPwUY9VkxxSfy%)aMZR6@D0X?87 zuVn~x!aD#16aV0KX%s(cna7{t48$EMOn_AH!`~MCJq#b$XdwdxJEq3Oh0)#2D5* z?nq0z1CoA5soMg6mUlwZX8_P&h2rI4{DlsPF1O$DuJk(rYf-!*lyi){8tpko!=Qe) zem$2(s=EhBwZtWnE6@xkt__EQ`vJBGZ7CJ{3%##-ziJ7f(EGLB^rrbRs*AoYFTM|i zF5F9Rxge;Yi({)9-AUalQ1dw>Ilo6<9IY$rqF-HDERN5w`-@6*cUfUv$!_|C_s@7) zUTnZM?4@^dsM=q$hyGqy>MvD?1N=CruX&ok)L(Ll-2Renl<#9Ukz!l#&vM3l%e?tk z$1cu!oE!Y5W!}A9;DTrqbw2DN{W#XgMSFRO`DUoS?J|Fv_cb4Tt$mmIc&LA9-$Qws zH?1fl2h~#qQDzGwXMA~Cx!(s=dz|8aUm2cqZ|LNTx?%Pd75)mD;&h8^g>wo#oarCd z_h#UH7$);o*z*nL5nX)N+H%0;9rg_6{&Jb2(&AI@oBoUnj z)-rV;U+gdJms?Inru6K)1oC+)i)NIvDqQ z!1)F)!llXKw2`ZU`sET+bq~GZdV*eb3E;gwp&!!?T=X(&n>UhYD_GOVu=*Bn-&-zz+i_hN*X3S7;+541v>?5a|! zhfecdB`WnOq8nU=ydQfj#?_2>l;bFYY~JFR0B5Dx(@b2ASV>;2dMvIstRx-#n8Ppg zD-yuD4%(oImPiZ2MN5J(ImLr22+L6|Nvq%~L6fv9PqieiLgECPq*X|q(30>D-W@GT zs|r+0!aI+0Vu%JTsjP-n%zdv;?|U`&ZSHn8R;P9WKX311b$S=8@qaD>g8AoE+zT}+ zRSs~Ta)8Kmvi>{Pq{AiR^(G?Rg5K1NO`gJ7Bx4d?xR1d}_R<Ekr6r*%2Q*|7ftlSkPA<^2*O3DF}>7C`U$(Dqx7E0e}$U4 z`PFpkW4Q_&iDr3=yZEx_1-y!UJk!SwK5q2!l|H_zi<=bjT1A|vi1TgY^@{j$MGS)2 z#i8fvO(~wR0;u7t3Q&Prs!)WfMy@jou|y3`!*ecw9{pVW1?Aq$5rH8#;xFRwOBikD nBM12q`XJ}$FXR2!`Az(N3luN(><0*Fznx#e-{J4^56J%yqtZ!q diff --git a/backend/generation-service/target/classes/com/artedu/generation/controller/LlmModelController.class b/backend/generation-service/target/classes/com/artedu/generation/controller/LlmModelController.class index ce732eac3d2618fc9423ab4a72f6505c77450956..99e086753084675126b848c020ee1777f6683a35 100644 GIT binary patch literal 7776 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 literal 7444 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 sGA$c?j!T5fo*FgVd_98j|1Kw%{EC2ui literal 6794 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 diff --git a/backend/generation-service/target/classes/com/artedu/generation/service/QianwenClient.class b/backend/generation-service/target/classes/com/artedu/generation/service/QianwenClient.class index 84fa7e0f321cafb76b516dd3f2041ee562323114..7f7cf2c1c89cabd014bc2738598e1087bfee011d 100644 GIT binary patch delta 3286 zcmZ8j3w%@M75{&E-J6@6KGGMr6j~^hrfH2}K}iFX+6o9QNCoMtV`+OSfix+}4G*{3 zx#`AG9^L0Qhg9d>#BGk1qM_k6Hn-wr@2A75(+!>O;hc4Dh~W8dnlje*_r1?K|8vg& zoZDCG56{he_Ttf#02Z)f2^Iz)zl%*B7<6|_urcIq3~dSdBcW)Ie?{j;y~|**Mq)h- zp5?K4k3SJvU%%16Jl4~r#~TJt|hAjUTX1pSl{i zN}x#P{eNautVKJ2&05boc$saHXEknD@e!<}pl%JtqYOp-Eo*`5U87J~LMl2@%Xiy~ zWd=uIJl5OC_vD1@9C1C7j8OjFZAPeTQ%k7tmJnrFLhqFkGveWB4?k#Y&2=G&J`sed z(7TX3a>Hiewy4;OZQNyF!S3K4_BwerKCa>uxRdX-&*8CLf4K zUJMYW`jX_yb=7>fa|&;Fl&$EJaX;w_N9jVw7fCGR?z;7{cyEY~9-v?u`ZikaBSXER zZR?EKCOw*vv7h#Rp*ZEp(BlaS4>8Ojs%ev#7)IX`J=9I73I+w~9>Jp$zRECN-1BnD zNqPSozRs(qpgf2JDjvr-ctl!I_$>mkC~0hn#lv@)Pm``Hw~8NPl)B25Jj)|WrQ^r= zsf3^KeM%*1`5AuBPbl+{H{~$>D0{2^{ z@soKHf6-OUUgGb#s$Hw`vLM3?GXBIDsgqjI;WY`bG89~S@=%X&!5k4p-8^V$lX=U!OyCtEsVUgCxv~PDfHH$rWY9}h{V(@ z3ZymJ+o{JD=3+T2%VpG30u)%IgBZXXk$S+jS9^m zVHqW;K)*N!y`}~_F55_mgmhlb5lpW+h8gWgQ1ujMT~?7}V$LVj#iS^o)BtKm242*d z`lu^r^f86739rHCC6wcAP0G<^iEZE4(Mh2|I%QXfv^HVbNewJCgbh^$#r&Ibz0`|B_h z0aRfzW??0j#%fd(Cu^wvU1j24NYN&2ZP-BPc1%Gt zHqtu>Hj#8LEEloXCLt&xa-Q6!?+~J<`vKqpX%IHNS>J7%Z4@P%%~xBOM$CpxFdUkF zsHV0qh0R&`;llF%3KGmf^iDwZB0dh$Yl0OC^qOF;WV^zICd?_RYgzYqnL_oLu()gHW#W*I-CeTu*vgj&`CY$K$Ga4q)`G`}W zB>kjy0-bLhokBDd0kmDlG%bVaE;Nl}nnSaYmNVh{l(3g!t|$vo5-Vsl>DEs!X82|i zpR0Cccipf3RPZvI2u-<>7#=$;0?c3Xf^B=bN4bmY5dU!HWaW6nO8J>3V#;mV;-7xK8Fi9hgWgloNZJnmx?>sbG)M@ z!?(LL;mc-}j}Lz2L#JSDtKg}N*A2Qs%q!k~m<3CAy?r~`DFeI^#? zC}Q-9qw&9_%0e*{?e$?=iMCzkI}L~Dy&<3H{WLCFa03T8EWP$F+Cho@QOt|EPMY@2=O`wvI5{kgtFdRWDikvk)t43z*Zy*jhIVcik!GN-;OJD)YHHWKh#sN&yG% zC9C(5`dzf&O^tL9uEl^^i!~Wz6aECp{V7HjlTCkSpn&Bw53Ec7$2IXxxR!aAb&b9% c&i7Gm=Er(HJ5RB)umZAgVTIWbAu9qt06Ipmpa1{> delta 3150 zcmZWr3wRXO75?wO?(EF$X0wpc2_Q+RA;~5#VxVOcAUrIkBs>~YZ}?tjnC!RaqG&3W>|p+^8Tv9T%~aB{eGxZz<4Y>HkV4JV?>Sa@mICUc#|;Ax2` z~Y}>6niNL@AYyg?kel znl^>oQn8qs7LU4{*oVZM?zu`UKCELAJ|bp$sv0!3>1dY(#>C8|nT}fKs<^drfw>`? zNmv@Huv8LU#;~|nOyv_rrN(L0L^~f}q7u_;S(^?W*IGFHu>$A(ifqlB<`& zWtn|sWhh5?v~R7I+H59!6>O#Vo@koNZJFs_j&0&;Z{3(aDWXqe2gi*%`td1-Y7y29 zakuIfjcSY1hnsYK1~-c>>a4M!qkMBS*2YvienZrXr;-YGipSJ2&ALU$7jdh2OP$7U z6AfCevJ1PVs0YLvt(C|N@c>(1$?>I21!<+@$(WS#mvwvvUlseco&LS}I>$G3+=YD% zQ*1QLbiY`qw`lj^n;iG*_!hoRNh&=ZR@BP$if8n&vKRO1xF6pU+&5W!0N>;IzK$Q@ zhhnO4vRLh#L5hD+#{nD^clu_qhs9IAW^xVb7)DM6{4;4&4@-F+5zGCv*&|}NzgBC- zF}cr2I35!(`perC{D_p)*4BPz&%Rf7?mm6wrqjd2k;?5mR2;{MjuTSZs#Lbw+Z&CU z3Z7tqf|Im;sfB@OuU&p0rj*%M%$=A~lvp zD*lKUIbPE7GX5kcI4VT5qiNvfPO+Uea+1`1(yiF$sPnq4jd9XgW7|L=O9|EgC4Bj~e@54|Zv}eCgPuY+`4b+8l{DmwXte=Je{))fR z$YeXr2V*J)=j4kIBQUT2A(UrP5pf&t5p)>tP(u!tPDDJ0X9P13pe9)FISNOo({Sg| zz>vk%j!xI;%Z!drH-)J(hcUAwhdE9doKpsfkq+L;Xeh4bv9VJCv`ShC!wgcA-Zgc3fOshQB@JD z|KhFu)?hDDkr6`@S}2Q;MhM#pl*x*&4CS!eaH4?8a7nbZRYi1nm5sO2HRU6WVhZ6L z-lq5zbre&mfJvqNvTX0cL?x4$&LdpFG>t~NTFIAdjm+nO)SOf&sICRQf%>pgNb8Wd zS3ZCvM-zP{!BVNW!&pn&jmi=SyMpU;*xbLn?(@L*3cop&~j zz)$ZM3AQl*`hJ5K7xYn<8zPFK9KiN0K5Zz$&jvrA#TO1^SEu1Nlp)+6@e(67c!%K) z?s1aFv$!*&8fq3_JAk|Qqgk5!M{t!r9>bntd^e)i8`=;CBf8v?hl?p7;(!rj~nhRek{+A?X*RFnyP)Ay20D_=%RzNW8Agu1#xOzUT-&3 z`5wn)(%U<9wV$MWyO&g^llLqxkk5^3JdYGv9?ZibY$b~$jazV$Hb}v4Bp723QsBMl zWKQOyZgBx)n45W|R#<6KD`XXp7+Lla>xYZ^@@I_6o*_@C4TUKL#RfoD0RUMA0A%q( zTJLCDmD0-7*#hT9TnEmf(edPXmJVtx{|CaglcSGg7suX}g`Y36TVzJ-%4AN(sDXY8O$e)zT{MsUWYD%)g zbW_srNwOR^<#NhF8E}?J6~2+>u&H?A;O8-(z%z{|Ihal#=wha)g!crEE*c{QPjL?8 z83On#8&H1%;iQJ(uWiSY#u4}$kKt4nFHnQBC)*ENPMGOgLB$3Av*N|AD8nwgNp7Qk zza7&tV4uKxnpaJ`>SKPJS7ek|q`<3;j^uNBUN=&xJTdxc6SF^#5~GX6`wnXCU2(Ls wb8r?2me7Cl0YZ|$mt?1qKi;4=j6WPijl7W9dzu4vVv>@qOt5(Eu`$5^0FrLFasU7T diff --git a/backend/intent-service/.gitignore b/backend/intent-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/intent-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/kb-admin-service/.gitignore b/backend/kb-admin-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/kb-admin-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file diff --git a/backend/recommendation-service/.gitignore b/backend/recommendation-service/.gitignore new file mode 100644 index 0000000..59a54cd --- /dev/null +++ b/backend/recommendation-service/.gitignore @@ -0,0 +1,2 @@ +target/ +target \ No newline at end of file