diff --git a/src/main/java/com/xly/agent/AgentSystemPrompt.java b/src/main/java/com/xly/agent/AgentSystemPrompt.java new file mode 100644 index 0000000..32972dd --- /dev/null +++ b/src/main/java/com/xly/agent/AgentSystemPrompt.java @@ -0,0 +1,12 @@ +package com.xly.agent; + +public class AgentSystemPrompt { + + public static final String sSystemPrompt= "1. 方法匹配:先精准拆解用户查询的核心业务意图,再自动匹配唯一符合用户问题的工具方法(MethodNo),禁止自创,规则如下;\n" + + " 1.1 匹配方法时,无需考虑工具描述(@TOOL)中 1.必填参数,2.选填参数,示例,parameters内容 四个部分的内容;\n" + + " 1.2 匹配方法时,只关注工具描述(@TOOL)中 “当用户” 和 “时,必须调用本工具”两个短语之间的内容;\n" + + " 1.3 调用工具前,不需要询问用户提供缺失的参数\n" + + " 2. 参数提取:提取该工具的全部参数,与描述完全一致,严格按标注类型赋值,规则如下:\n" + + " 2.1 数字无引号,为空时禁止赋值0;\n" + + " 2.2 如果有空格需要去掉空格后再提取。"; +} diff --git a/src/main/java/com/xly/agent/ErpAiAgent.java b/src/main/java/com/xly/agent/ErpAiAgent.java index 811d675..e21d367 100644 --- a/src/main/java/com/xly/agent/ErpAiAgent.java +++ b/src/main/java/com/xly/agent/ErpAiAgent.java @@ -10,18 +10,14 @@ import dev.langchain4j.service.V; * 优化后:新增场景专属交互规则,大模型仅处理当前场景业务指令 */ public interface ErpAiAgent { - @SystemMessage(""" - 1. 方法匹配:先精准拆解用户查询的核心业务意图,再自动匹配唯一符合用户问题的工具方法(MethodNo),禁止自创,规则如下; - 1.1 匹配方法时,无需考虑工具描述(@TOOL)中 1.必填参数,2.选填参数,示例,parameters内容 四个部分的内容; - 1.2 匹配方法时,只关注工具描述(@TOOL)中 “当用户” 和 “时,必须调用本工具”两个短语之间的内容; - 1.3 调用工具前,不需要询问用户提供缺失的参数 - 2. 参数提取:提取该工具的全部参数,与描述完全一致,严格按标注类型赋值,规则如下: - 2.1 数字无引号,为空时禁止赋值0; - 2.2 如果有空格需要去掉空格后再提取。 - """) - @UserMessage("用户输入:{{userInput}}") - String chat(@MemoryId String userId, @V("userInput") String userInput); + @SystemMessage("{{sSystemPrompt}}") + @UserMessage("用户输入:{{userInput}}") + String chat( + @MemoryId String userId, + @V("userInput") String userInput, + @V("sSystemPrompt") String sSystemPrompt + ); /** * 动态表结构:自然语言解释SQL执行结果 * 入参:用户问题、执行的SQL、表结构、JSON格式结果 diff --git a/src/main/java/com/xly/entity/UserSceneSession.java b/src/main/java/com/xly/entity/UserSceneSession.java index 76bf994..79f9b85 100644 --- a/src/main/java/com/xly/entity/UserSceneSession.java +++ b/src/main/java/com/xly/entity/UserSceneSession.java @@ -75,6 +75,14 @@ public class UserSceneSession { * 数据库类型 H: 缓存 D: 动态 */ private String dbCach; + /** + * @Author 钱豹 + * @Date 22:55 2026/4/13 + * @Param + * @return + * @Description AI 模板 + **/ + private String sSystemPrompt; /** * 构建场景选择提示语:展示权限内场景,引导用户选择 diff --git a/src/main/java/com/xly/service/XlyErpService.java b/src/main/java/com/xly/service/XlyErpService.java index 660106f..d779956 100644 --- a/src/main/java/com/xly/service/XlyErpService.java +++ b/src/main/java/com/xly/service/XlyErpService.java @@ -8,10 +8,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.xly.agent.ChatiAgent; -import com.xly.agent.DynamicTableNl2SqlAiAgent; -import com.xly.agent.ErpAiAgent; -import com.xly.agent.SceneSelectorAiAgent; +import com.xly.agent.*; import com.xly.config.OperableChatMemoryProvider; import com.xly.constant.CommonConstant; import com.xly.constant.ReturnTypeCode; @@ -140,7 +137,7 @@ public class XlyErpService { && ObjectUtil.isNotEmpty(session.getCurrentTool().getSInputTabelName()) && ObjectUtil.isNotEmpty(session.getCurrentTool().getSStructureMemo())) ){ - sResponMessage = aiAgent.chat(userId, input); + sResponMessage = aiAgent.chat(userId, input , AgentSystemPrompt.sSystemPrompt); } if(ObjectUtil.isNotEmpty(session.getCurrentTool()) @@ -351,7 +348,11 @@ public class XlyErpService { && ObjectUtil.isNotEmpty(session.getCurrentTool().getSInputTabelName()) && ObjectUtil.isNotEmpty(session.getCurrentTool().getSStructureMemo())) ){ - sResponMessage = aiAgent.chat(userId, input); + String sSystemPrompt = AgentSystemPrompt.sSystemPrompt; + if(ObjectUtil.isNotEmpty(session.getSSystemPrompt())){ + sSystemPrompt = session.getSSystemPrompt(); + } + sResponMessage = aiAgent.chat(userId, input,sSystemPrompt); } methodName = ObjectUtil.isNotEmpty(session.getCurrentTool())?session.getCurrentTool().getSMethodName():StrUtil.EMPTY; if(ObjectUtil.isNotEmpty(session.getCurrentTool()) @@ -947,7 +948,7 @@ public class XlyErpService { UserSceneSessionService.ERP_AGENT_CACHE.put(userId, aiAgent); // 初始化AiService 以防止热加载太慢 找不到相应的方法 try{ - aiAgent.chat(userId, "initAiService"); + aiAgent.chat(userId, "initAiService",AgentSystemPrompt.sSystemPrompt); }catch (Exception e){ e.printStackTrace(); } diff --git a/src/main/java/com/xly/tool/DynamicToolProvider.java b/src/main/java/com/xly/tool/DynamicToolProvider.java index 3203956..aab6020 100644 --- a/src/main/java/com/xly/tool/DynamicToolProvider.java +++ b/src/main/java/com/xly/tool/DynamicToolProvider.java @@ -10,11 +10,9 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.xly.agent.AgentSystemPrompt; import com.xly.config.OperableChatMemoryProvider; -import com.xly.constant.ErrorCode; -import com.xly.constant.ProcedureConstant; -import com.xly.constant.RuleCode; -import com.xly.constant.UrlErpConstant; +import com.xly.constant.*; import com.xly.entity.*; import com.xly.exception.dto.BusinessException; import com.xly.mapper.ParamRuleMapper; @@ -245,80 +243,67 @@ public class DynamicToolProvider implements ToolProvider { return ToolProviderResult.builder().addAll(executors).build(); } - /*** - * @Author 钱豹 - * @Date 15:07 2026/1/30 - * @Param [meta] - * @return dev.langchain4j.agent.tool.ToolSpecification - * @Description 参数注入 方法引导语注入(初始化调用) - **/ private ToolSpecification buildToolSpecification(ToolMeta meta) { ToolSpecification.Builder builder = ToolSpecification.builder() .name(meta.getSMethodNo()); -// .description(meta.getStoolDesc()); + StringBuffer stoolDesc = new StringBuffer(); StringBuffer sbt = new StringBuffer(); StringBuffer xt = new StringBuffer(); StringBuffer sl = new StringBuffer(); - if(ObjectUtil.isNotEmpty(meta.getStoolDesc())){ - stoolDesc.append("MethodNo:").append(meta.getSMethodNo()).append(",当用户").append(meta.getSMethodName()); -// if (meta.getIBizType()==4){ -// stoolDesc.append(",").append("并选择数据后执行["+meta.getSControlName()+"]操作"); -// } - stoolDesc.append("时,必须调用本工具").append(meta.getSMethodNo()).append(",").append(meta.getStoolDesc()); -// if (meta.getIBizType()==4){ -// stoolDesc.append(",").append("并选择数据后执行 "+meta.getSControlName()+" 操作"); -//// .append("1.全部数据生成多个单据 回复【全部确认】;2.全部数据生成一个单据 回复【合并确认】;3.按自然语义描述生成一个单据 如"1,3行确认""); -// } + // ====================== 【超级强制:必须调用工具】 ====================== + String forceToolPrompt = """ + 【重要·强制指令】 + 1. 这是当前唯一可用工具,必须调用,禁止直接回答 + 2. 用户输入包含:确认、全部确认、合并确认、行号(第1行/第一行等) + 3. 必须调用本工具,必须调用,必须调用! + """; + stoolDesc.append(forceToolPrompt); + // ======================================================================== + + if (ObjectUtil.isNotEmpty(meta.getStoolDesc())) { + stoolDesc.append("MethodNo:").append(meta.getSMethodNo()) + .append(",当用户").append(meta.getSMethodName()) + .append("时,必须调用本工具").append(meta.getSMethodNo()) + .append(",").append(meta.getStoolDesc()); } try { List paramRuleData = meta.getParamRuleList(); -// 1.必填参数:客户名称(字符串),产品名称(字符串),数量(数字); -// 2.选填参数:产品描述(字符串),生产要求(字符串); -// **强制输出标准JSON对象**: -// 示例:{\"客户名称\":\"小羚羊软件开发有限公司\",\"产品名称\":\"企业宣传册\",\"数量\":1000,\"产品描述\":\"黑色注意色差\",\"生产要求\":\"上光,覆膜\"} - Map slMap = new HashMap<>(); + Map slMap = new HashMap<>(); + for (ParamRule paramRule : paramRuleData) { -// String paramName = ObjectUtil.isEmpty(paramRule.getSParamValue())?null:paramRule.getSParamValue(); - String paramDesc = ObjectUtil.isEmpty(paramRule.getSParam())?null:paramRule.getSParam(); + String paramDesc = ObjectUtil.isEmpty(paramRule.getSParam()) ? null : paramRule.getSParam(); String paramType = paramRule.getSType(); Boolean bEmpty = paramRule.getBEmpty(); String sExampleValue = paramRule.getSExampleValue(); - //示例值,只有枚举放 - if(ObjectUtil.isNotEmpty(sExampleValue) && "enum".equals(paramType.toLowerCase())){ - //英文 -// slMap.put(paramName,sExampleValue); - //中文 - slMap.put(paramDesc,sExampleValue); + + if (ObjectUtil.isNotEmpty(sExampleValue) && "enum".equals(paramType.toLowerCase())) { + slMap.put(paramDesc, sExampleValue); } if (paramDesc == null || paramDesc.trim().isEmpty()) { continue; } - // 构建参数属性 - //{"string":"字符","integer":"数字","double":"浮点","boolean":"布尔型","array":"数组","enum":"枚举"} + List properties = new ArrayList<>(); - // 添加类型属性 -// String ,仅允许【{}】多选一,严格匹配) - String sRuleCost = getConstMeg(paramRule.getSParamConfig(),paramRule); -// 2. 付款方式:字符串类型,互斥枚举值[90天、60天、现结],默认值[现结] -// 5. 生产要求:数组类型,可多选枚举值[上光、复膜、烫金],无默认值 + String sRuleCost = getConstMeg(paramRule.getSParamConfig(), paramRule); + switch (paramType.toLowerCase()) { case "string": - if(bEmpty){ - sbt.append(paramDesc).append("(字符串").append(sRuleCost).append(")").append("、"); - }else{ - xt.append(paramDesc).append("(字符串").append(sRuleCost).append(")").append("、"); + if (bEmpty) { + sbt.append(paramDesc).append("(字符串").append(sRuleCost).append(")、"); + } else { + xt.append(paramDesc).append("(字符串").append(sRuleCost).append(")、"); } properties.add(JsonSchemaProperty.STRING); break; case "integer": case "int": - if(bEmpty){ - sbt.append(paramDesc).append("(数字").append(sRuleCost).append(")").append("、"); - }else{ - xt.append(paramDesc).append("(数字").append(sRuleCost).append(")").append("、"); + if (bEmpty) { + sbt.append(paramDesc).append("(数字").append(sRuleCost).append(")、"); + } else { + xt.append(paramDesc).append("(数字").append(sRuleCost).append(")、"); } properties.add(JsonSchemaProperty.INTEGER); break; @@ -326,91 +311,84 @@ public class DynamicToolProvider implements ToolProvider { case "double": case "float": properties.add(JsonSchemaProperty.NUMBER); - if(bEmpty){ - sbt.append(paramDesc).append("(浮点").append(sRuleCost).append(")").append("、"); - }else{ - xt.append(paramDesc).append("(浮点").append(sRuleCost).append(")").append("、"); + if (bEmpty) { + sbt.append(paramDesc).append("(浮点").append(sRuleCost).append(")、"); + } else { + xt.append(paramDesc).append("(浮点").append(sRuleCost).append(")、"); } break; case "boolean": case "bool": - if(bEmpty){ - sbt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")").append("、"); - }else{ - xt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")").append("、"); + if (bEmpty) { + sbt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")、"); + } else { + xt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")、"); } properties.add(JsonSchemaProperty.BOOLEAN); break; case "array": String sRuleArray = getArrrayBySql(paramRule); - // 生产要求:数组类型,可多选枚举值[上光、复膜、烫金],无默认值 if (ObjectUtil.isNotEmpty(sRuleArray)) { - sRuleArray = StrUtil.replace(sRuleArray,",","/"); + sRuleArray = StrUtil.replace(sRuleArray, ",", "/"); properties.add(JsonSchemaProperty.enums(sRuleArray.split("/"))); } - if(bEmpty){ - //动态SQL 或者写死默认值的 动态SQL只存在一条数据 直接给默认值 - sbt.append(paramDesc).append("(").append("数组类型") .append(",可多选枚举值 [").append(sRuleArray).append("]"); - if(ObjectUtil.isNotEmpty(paramRule.getSDefaultValue()) || (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length==1)){ - String sDefaultVal = (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length==1)?sRuleArray:paramRule.getSDefaultValue(); + if (bEmpty) { + sbt.append(paramDesc).append("(数组类型,可多选枚举值 [").append(sRuleArray).append("]"); + if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue()) || (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length == 1)) { + String sDefaultVal = (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length == 1) ? sRuleArray : paramRule.getSDefaultValue(); sbt.append(",默认值[").append(sDefaultVal).append("]"); - }else{ + } else { sbt.append(",无默认值"); } sbt.append(")、"); - }else{ - xt.append(paramDesc).append("(").append("数组类型") .append(",可多选枚举值 [").append(sRuleArray).append("]"); - if(ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())){ + } else { + xt.append(paramDesc).append("(数组类型,可多选枚举值 [").append(sRuleArray).append("]"); + if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) { xt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]"); - }else{ + } else { xt.append(",无默认值"); } xt.append(")、"); } properties.add(JsonSchemaProperty.ARRAY); - // 默认字符串数组 properties.add(JsonSchemaProperty.items(JsonSchemaProperty.STRING)); break; case "enum": - // 处理枚举值 if (ObjectUtil.isNotEmpty(sRuleCost)) { properties.add(JsonSchemaProperty.enums(sRuleCost.split("/"))); - }else{ + } else { sRuleCost = getArrrayBySql(paramRule); } - // eg: 付款方式(字符串,互斥枚举值[90天、60天、现结],默认值[现结]) - if(bEmpty){ - sbt.append(paramDesc).append("(").append("字符串") .append(",互斥枚举值 [").append(sRuleCost).append("]"); - if(ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())){ + if (bEmpty) { + sbt.append(paramDesc).append("(字符串,互斥枚举值 [").append(sRuleCost).append("]"); + if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) { sbt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]"); - }else{ + } else { sbt.append(",无默认值"); } sbt.append(")、"); - }else{ - xt.append(paramDesc).append("(").append("字符串") .append(",互斥枚举值 [").append(sRuleCost).append("]"); - if(ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())){ + } else { + xt.append(paramDesc).append("(字符串,互斥枚举值 [").append(sRuleCost).append("]"); + if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) { xt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]"); - }else{ + } else { xt.append(",无默认值"); } xt.append(")、"); } properties.add(JsonSchemaProperty.ARRAY); - // 默认字符串数组 properties.add(JsonSchemaProperty.items(JsonSchemaProperty.STRING)); break; default: properties.add(JsonSchemaProperty.STRING); break; } - // 添加描述 + if (!paramDesc.isEmpty()) { properties.add(JsonSchemaProperty.description(paramDesc)); } - // 检查是否必填 + boolean required = bEmpty; - // 添加参数 if (required) { builder.addParameter(paramDesc, properties); } else { @@ -418,31 +396,33 @@ public class DynamicToolProvider implements ToolProvider { } } - if(ObjectUtil.isNotEmpty(sbt)){ - stoolDesc - .append(System.lineSeparator()) - .append("1.必填参数:") - .append(sbt); + if (ObjectUtil.isNotEmpty(sbt)) { + stoolDesc.append(System.lineSeparator()).append("1.必填参数:").append(sbt); } - if(ObjectUtil.isNotEmpty(xt)){ - stoolDesc - .append(System.lineSeparator()) - .append("2.选填参数:") - .append(xt); + if (ObjectUtil.isNotEmpty(xt)) { + stoolDesc.append(System.lineSeparator()).append("2.选填参数:").append(xt); } - if(ObjectUtil.isNotEmpty(slMap)){ - stoolDesc - .append(System.lineSeparator()) - .append(sl) - .append("**强制输出标准JSON对象**:").append(System.lineSeparator()) - .append("示例:").append(JSONUtil.toJsonStr(slMap)); + if (ObjectUtil.isNotEmpty(slMap)) { + stoolDesc.append(System.lineSeparator()).append(sl).append("**强制输出标准JSON对象**:") + .append(System.lineSeparator()).append("示例:").append(JSONUtil.toJsonStr(slMap)); } - log.info("方法描述========================{}",stoolDesc); + + log.info("方法描述========================{}", stoolDesc); } catch (Exception e) { e.printStackTrace(); log.error("Failed to parse parameter rules: {}", meta.getSMethodName(), e); - // 参数解析失败时,创建无参数的工具规格 } + + // ====================== 【关键修复:强制添加两个参数】 ====================== + if (meta.getIBizType() == 4 || meta.getIBizType() == 5) { + // 强制添加 operateType(必填) + builder.addParameter("operateType", + JsonSchemaProperty.STRING, + JsonSchemaProperty.description("操作类型:全部确认/合并确认/单行确认") + ); + } + // ============================================================================ + builder.description(stoolDesc.toString()); return builder.build(); } @@ -628,14 +608,14 @@ public class DynamicToolProvider implements ToolProvider { String input = StrUtil.replace(userMessage.text(),"用户输入:",StrUtil.EMPTY); // {"0":"查询","1":"执行"} 查询不需要确认 Boolean isConfirmed = isConfirmed(input) || input.contains("生成") || input.contains("确认"); - //判断是否生成数据 - List> sRowData = new ArrayList<>(); - String sHandleType = "merge"; - if(4== meta.getIBizType() && ObjectUtil.isNotEmpty(session.getCurrentRowData())){ - Map sRowDataMap = UserChoseIntentParser.getSelectedRows( input, session.getCurrentRowData()); - sRowData = (List>) sRowDataMap.get("sRowData"); - sHandleType = sRowDataMap.get("sHandleType").toString(); - } +// //判断是否生成数据 +// List> sRowData = new ArrayList<>(); +// String sHandleType = "merge"; +// if(4== meta.getIBizType() && ObjectUtil.isNotEmpty(session.getCurrentRowData())){ +// Map sRowDataMap = UserChoseIntentParser.getSelectedRows( input, session.getCurrentRowData()); +// sRowData = (List>) sRowDataMap.get("sRowData"); +// sHandleType = sRowDataMap.get("sHandleType").toString(); +// } //{"1":"存储过程","2":"SQL查询","3":"第三方API","4":"ERP未清","5":"ERP列表(报表)","6":"ERP单据","7":"其它","8":"自然语言TEXT2SQL"} if((isConfirmed && (4== meta.getIBizType() ||1== meta.getIBizType())) || 2== meta.getIBizType() @@ -658,12 +638,12 @@ public class DynamicToolProvider implements ToolProvider { String askconfirmMsg =StrUtil.EMPTY; if(4== meta.getIBizType() || meta.getIBizType()==5){ askconfirmMsg = doGetFromData( meta,args,session); - return executeWithConfirmation(askconfirmMsg,operableChatMemoryProvider.get(session.getUserId()), session, meta); + return executeWithConfirmation(askconfirmMsg, session, meta); }else{ askconfirmMsg =getDefMessage(args,meta.getSControlName(),meta); } // 返回需要确认的结果 - return executeWithConfirmation(askconfirmMsg,operableChatMemoryProvider.get(session.getUserId()), session, meta); + return executeWithConfirmation(askconfirmMsg, session, meta); } /*** @@ -955,6 +935,8 @@ public class DynamicToolProvider implements ToolProvider { sReturn = executeToolAfter(meta, args,paramRuleData,session); }catch (BusinessException e) { return e.getMessage(); + }finally { + session.setSSystemPrompt(StrUtil.EMPTY); } if(meta.getIActionType()==1){ session.setBCleanMemory(true); @@ -1197,7 +1179,10 @@ public class DynamicToolProvider implements ToolProvider { rMap.put("sSlaveId",uniqueValue); rMap.put("唯一",uniqueValue); // 在行末添加隐藏数据的特殊标记(AI可以解析) - markdown.append(" "); + markdown.append(" HIDDEN_DATA:") + .append(JSONUtil.toJsonStr(rMap)) + .append(""); +// markdown.append(" "); markdown.append("\n"); machineData.add(rMap); currentRowData.put(i + 1,recordData.get(i)); @@ -1212,9 +1197,50 @@ public class DynamicToolProvider implements ToolProvider { appendConfirmAll(markdown,meta.getSControlName()); } session.setCurrentRowData(currentRowData); + // ===================== 加入这一行 ===================== + String sSystemPrompt = buildDynamicSystemPrompt(session); + session.setSSystemPrompt(sSystemPrompt); + // ====================================================== return markdown.toString(); } + public String buildDynamicSystemPrompt(UserSceneSession session) { + + // 1. 强制指令 + 固定方法编号 + String promptHead = """ + 【极强约束·必须执行】 + 1. 禁止说话!禁止解释! + 2. 必须调用工具,固定方法编号:MethodNo = queryUnprocessQuote + 3. 只输出JSON,无任何其他内容 + + 以下是【行号 → sSlaveId】对应数据: + """; + + // 2. 动态拼接行号 + 动态 sSlaveId + Map> rowDataMap = session.getCurrentRowData(); + StringBuilder rowDataSb = new StringBuilder(); + if (ObjectUtil.isNotEmpty(rowDataMap)) { + for (Map.Entry> entry : rowDataMap.entrySet()) { + int rowNum = entry.getKey(); + String sSlaveId = StrUtil.toString(entry.getValue().get("sSlaveId")); + rowDataSb.append("第").append(rowNum).append("行 → ").append(sSlaveId).append("\n"); + } + } + + // 3. 输出格式约束 + String promptFoot = """ + 【输出JSON格式·严格遵守】 + 根据用户选择的行,自动填写 sSlaveId,多行用英文逗号拼接 + { + "operateType": "全部确认/合并确认/单行确认", + "sSlaveId": "填写对应的ID,多个用逗号分隔" + } + """; + + // 拼接最终返回 + return promptHead + rowDataSb + promptFoot; + } + // 辅助方法:根据中文名查找字段名(通过映射关系转换) private List> findFieldNameByChinese(List> sAIshowfieldShow,List> rows){ //获取映射关系 @@ -1362,7 +1388,7 @@ public class DynamicToolProvider implements ToolProvider { /** * 执行方法后需要用户确认的扩展版本 */ - private String executeWithConfirmation(String initialResult,ChatMemory chatMemory, UserSceneSession session,ToolMeta meta) { + private String executeWithConfirmation(String initialResult, UserSceneSession session,ToolMeta meta) { // 第一步:执行原始操作,返回初步结果 Map step1Result = new HashMap<>(); @@ -1377,6 +1403,7 @@ public class DynamicToolProvider implements ToolProvider { // session.setSFunPrompts(userMessage); // 6. 返回确认请求 // return ToolExecutionResultMessage.from(request,userMessage); +// ToolExecutionResultMessage.from(request, text); return userMessage; } diff --git a/src/main/resources/templates/chat.html b/src/main/resources/templates/chat.html index b29b9fe..7e6b628 100644 --- a/src/main/resources/templates/chat.html +++ b/src/main/resources/templates/chat.html @@ -462,11 +462,11 @@