From 83a46c6987b41ed489cbad42df22295715c7dfde Mon Sep 17 00:00:00 2001 From: qianbao Date: Tue, 10 Mar 2026 13:57:35 +0800 Subject: [PATCH] AI 对于时间的处理 --- src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java | 21 ++++++++++++--------- src/main/java/com/xly/service/XlyErpService.java | 8 ++++---- src/main/java/com/xly/util/SqlValidateUtil.java | 4 ++++ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java b/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java index 75d6e34..3552cf0 100644 --- a/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java +++ b/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java @@ -89,13 +89,6 @@ public interface DynamicTableNl2SqlAiAgent { @SystemMessage(""" 【系统角色】 你是资深MySQL 8.0.36数据分析师,严格杜绝以下错误,生成100%可执行的SELECT语句; - 【生成前自检要求】 - 1. 先检查是否违反上述禁止规则,再生成SQL; - 2. 每条SQL生成后,模拟MySQL执行逻辑自检: - - 语法是否合法(无COUNT()、聚合嵌套窗口函数等); - - 字段是否存在于表结构中; - - 差异化是否满足「结构/函数/格式」2个维度; - 3. 若自检发现错误,立即重新生成,直至所有SQL符合要求。 【严格禁止的错误类型(强制遵守)】 1. 语法错误: - 禁止使用COUNT()无参数写法,必须写COUNT(*)、COUNT(1)或COUNT(具体非空字段); @@ -119,6 +112,13 @@ public interface DynamicTableNl2SqlAiAgent { - 在AVG聚合函数中不允许使用LAG、LEAD 等窗口函数 - AVG(LAG(...))这种嵌套是不允许的 - GROUP BY 后面不允许使用窗口函数 + 【生成前自检要求】 + 1. 先检查是否违反上述禁止规则,再生成SQL; + 2. 每条SQL生成后,模拟MySQL执行逻辑自检: + - 语法是否合法(无COUNT()、聚合嵌套窗口函数等); + - 字段是否存在于表结构中; + - 差异化是否满足「结构/函数/格式」2个维度; + 3. 若自检发现错误,立即重新生成,直至所有SQL符合要求。 """) @UserMessage(""" 【业务场景表结构信息】 @@ -132,8 +132,11 @@ public interface DynamicTableNl2SqlAiAgent { 执行错误信息:{{errorMessage}} 【生成要求】 1. 先修复错误SQL的所有问题,确保语法/逻辑合规; - 2. 生成与{{errorSql}}/{{historySqlList}}重复的语句,禁止仅修改排序字段/别名的“伪差异化”,可以使用子查询修复或者修改查询字段,不要使用窗口函数(如 LAG)的SELECT语句; - 请根据上述表结构+通用规则,生成符合要求的MySQL SELECT语句; + 2. 生成与{{errorSql}}/{{historySqlList}}不重复的语句,禁止仅修改排序字段/别名的“伪差异化”,可以使用子查询修复或者修改查询字段,不要使用窗口函数(如 LAG)的SELECT语句; + 3. SQL所有字段均采用 表名.字段名 方式生成,务必确保 字段名 在相应的 表名 描述的字段中存在,如果不存在重试其它方式,直到满足条件; + 4. 自连接+子查询方式时,子查询跟自连接关联关系字段需要在子查询中查询列出现 + 5. 生成语法 / 逻辑合规且与历史语句无 “伪差异化” 的 SELECT 语句,且不使用窗口函数。 + 请根据上述表结构+通用规则,生成符合要求的MySQL SELECT语句;并且仅返回SQL语句 """) String regenerateSqlWithError(@MemoryId String userId, @V("tableNames") String tableNames, diff --git a/src/main/java/com/xly/service/XlyErpService.java b/src/main/java/com/xly/service/XlyErpService.java index 07c4e98..5cdda28 100644 --- a/src/main/java/com/xly/service/XlyErpService.java +++ b/src/main/java/com/xly/service/XlyErpService.java @@ -245,15 +245,15 @@ public class XlyErpService { }else{ rawSql = aiDynamicTableNl2SqlAiAgent.regenerateSqlWithError(userId, tableNames,tableStruct,sDataNow,userInput,errorSql,errorMessage,iErroCount,historySqlList); } - String[] rawSqlA = rawSql.split(";"); - if(rawSqlA.length>1){ - rawSql = rawSqlA[rawSqlA.length-1]; - } if (rawSql == null || rawSql.trim().isEmpty()) { throw new SqlGenerateException("SQL EMPTY"); } // 2. 清理SQL多余符号 + 生产级强校验(核心安全保障,不可省略) String cleanSql = SqlValidateUtil.cleanSqlSymbol(rawSql); + String[] cleanSqlA = rawSql.split(";"); + if(cleanSqlA.length>1){ + cleanSql = cleanSqlA[cleanSqlA.length-1]; + } SqlValidateUtil.validateMysqlSql(cleanSql); // 4. 执行SQL获取结构化结果 // Map params = new HashMap<>(); diff --git a/src/main/java/com/xly/util/SqlValidateUtil.java b/src/main/java/com/xly/util/SqlValidateUtil.java index 75d3f55..0d7fd99 100644 --- a/src/main/java/com/xly/util/SqlValidateUtil.java +++ b/src/main/java/com/xly/util/SqlValidateUtil.java @@ -94,6 +94,10 @@ public class SqlValidateUtil { if (sql == null) { return ""; } + if(sql.contains("```sql") && sql.contains("```")){ + sql=sql.split("```sql")[1]; + sql=sql.split("```")[0]; + } return sql.replace("```sql", "") .replace("```", "") .replaceAll("\\n|\\r", " ") -- libgit2 0.22.2