Commit 83a46c6987b41ed489cbad42df22295715c7dfde

Authored by qianbao
1 parent d5ff70d6

AI 对于时间的处理

src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java
@@ -89,13 +89,6 @@ public interface DynamicTableNl2SqlAiAgent { @@ -89,13 +89,6 @@ public interface DynamicTableNl2SqlAiAgent {
89 @SystemMessage(""" 89 @SystemMessage("""
90 【系统角色】 90 【系统角色】
91 你是资深MySQL 8.0.36数据分析师,严格杜绝以下错误,生成100%可执行的SELECT语句; 91 你是资深MySQL 8.0.36数据分析师,严格杜绝以下错误,生成100%可执行的SELECT语句;
92 - 【生成前自检要求】  
93 - 1. 先检查是否违反上述禁止规则,再生成SQL;  
94 - 2. 每条SQL生成后,模拟MySQL执行逻辑自检:  
95 - - 语法是否合法(无COUNT()、聚合嵌套窗口函数等);  
96 - - 字段是否存在于表结构中;  
97 - - 差异化是否满足「结构/函数/格式」2个维度;  
98 - 3. 若自检发现错误,立即重新生成,直至所有SQL符合要求。  
99 【严格禁止的错误类型(强制遵守)】 92 【严格禁止的错误类型(强制遵守)】
100 1. 语法错误: 93 1. 语法错误:
101 - 禁止使用COUNT()无参数写法,必须写COUNT(*)、COUNT(1)或COUNT(具体非空字段); 94 - 禁止使用COUNT()无参数写法,必须写COUNT(*)、COUNT(1)或COUNT(具体非空字段);
@@ -119,6 +112,13 @@ public interface DynamicTableNl2SqlAiAgent { @@ -119,6 +112,13 @@ public interface DynamicTableNl2SqlAiAgent {
119 - 在AVG聚合函数中不允许使用LAG、LEAD 等窗口函数 112 - 在AVG聚合函数中不允许使用LAG、LEAD 等窗口函数
120 - AVG(LAG(...))这种嵌套是不允许的 113 - AVG(LAG(...))这种嵌套是不允许的
121 - GROUP BY 后面不允许使用窗口函数 114 - GROUP BY 后面不允许使用窗口函数
  115 + 【生成前自检要求】
  116 + 1. 先检查是否违反上述禁止规则,再生成SQL;
  117 + 2. 每条SQL生成后,模拟MySQL执行逻辑自检:
  118 + - 语法是否合法(无COUNT()、聚合嵌套窗口函数等);
  119 + - 字段是否存在于表结构中;
  120 + - 差异化是否满足「结构/函数/格式」2个维度;
  121 + 3. 若自检发现错误,立即重新生成,直至所有SQL符合要求。
122 """) 122 """)
123 @UserMessage(""" 123 @UserMessage("""
124 【业务场景表结构信息】 124 【业务场景表结构信息】
@@ -132,8 +132,11 @@ public interface DynamicTableNl2SqlAiAgent { @@ -132,8 +132,11 @@ public interface DynamicTableNl2SqlAiAgent {
132 执行错误信息:{{errorMessage}} 132 执行错误信息:{{errorMessage}}
133 【生成要求】 133 【生成要求】
134 1. 先修复错误SQL的所有问题,确保语法/逻辑合规; 134 1. 先修复错误SQL的所有问题,确保语法/逻辑合规;
135 - 2. 生成与{{errorSql}}/{{historySqlList}}重复的语句,禁止仅修改排序字段/别名的“伪差异化”,可以使用子查询修复或者修改查询字段,不要使用窗口函数(如 LAG)的SELECT语句;  
136 - 请根据上述表结构+通用规则,生成符合要求的MySQL SELECT语句; 135 + 2. 生成与{{errorSql}}/{{historySqlList}}不重复的语句,禁止仅修改排序字段/别名的“伪差异化”,可以使用子查询修复或者修改查询字段,不要使用窗口函数(如 LAG)的SELECT语句;
  136 + 3. SQL所有字段均采用 表名.字段名 方式生成,务必确保 字段名 在相应的 表名 描述的字段中存在,如果不存在重试其它方式,直到满足条件;
  137 + 4. 自连接+子查询方式时,子查询跟自连接关联关系字段需要在子查询中查询列出现
  138 + 5. 生成语法 / 逻辑合规且与历史语句无 “伪差异化” 的 SELECT 语句,且不使用窗口函数。
  139 + 请根据上述表结构+通用规则,生成符合要求的MySQL SELECT语句;并且仅返回SQL语句
137 """) 140 """)
138 String regenerateSqlWithError(@MemoryId String userId, 141 String regenerateSqlWithError(@MemoryId String userId,
139 @V("tableNames") String tableNames, 142 @V("tableNames") String tableNames,
src/main/java/com/xly/service/XlyErpService.java
@@ -245,15 +245,15 @@ public class XlyErpService { @@ -245,15 +245,15 @@ public class XlyErpService {
245 }else{ 245 }else{
246 rawSql = aiDynamicTableNl2SqlAiAgent.regenerateSqlWithError(userId, tableNames,tableStruct,sDataNow,userInput,errorSql,errorMessage,iErroCount,historySqlList); 246 rawSql = aiDynamicTableNl2SqlAiAgent.regenerateSqlWithError(userId, tableNames,tableStruct,sDataNow,userInput,errorSql,errorMessage,iErroCount,historySqlList);
247 } 247 }
248 - String[] rawSqlA = rawSql.split(";");  
249 - if(rawSqlA.length>1){  
250 - rawSql = rawSqlA[rawSqlA.length-1];  
251 - }  
252 if (rawSql == null || rawSql.trim().isEmpty()) { 248 if (rawSql == null || rawSql.trim().isEmpty()) {
253 throw new SqlGenerateException("SQL EMPTY"); 249 throw new SqlGenerateException("SQL EMPTY");
254 } 250 }
255 // 2. 清理SQL多余符号 + 生产级强校验(核心安全保障,不可省略) 251 // 2. 清理SQL多余符号 + 生产级强校验(核心安全保障,不可省略)
256 String cleanSql = SqlValidateUtil.cleanSqlSymbol(rawSql); 252 String cleanSql = SqlValidateUtil.cleanSqlSymbol(rawSql);
  253 + String[] cleanSqlA = rawSql.split(";");
  254 + if(cleanSqlA.length>1){
  255 + cleanSql = cleanSqlA[cleanSqlA.length-1];
  256 + }
257 SqlValidateUtil.validateMysqlSql(cleanSql); 257 SqlValidateUtil.validateMysqlSql(cleanSql);
258 // 4. 执行SQL获取结构化结果 258 // 4. 执行SQL获取结构化结果
259 // Map<String,Object> params = new HashMap<>(); 259 // Map<String,Object> params = new HashMap<>();
src/main/java/com/xly/util/SqlValidateUtil.java
@@ -94,6 +94,10 @@ public class SqlValidateUtil { @@ -94,6 +94,10 @@ public class SqlValidateUtil {
94 if (sql == null) { 94 if (sql == null) {
95 return ""; 95 return "";
96 } 96 }
  97 + if(sql.contains("```sql") && sql.contains("```")){
  98 + sql=sql.split("```sql")[1];
  99 + sql=sql.split("```")[0];
  100 + }
97 return sql.replace("```sql", "") 101 return sql.replace("```sql", "")
98 .replace("```", "") 102 .replace("```", "")
99 .replaceAll("\\n|\\r", " ") 103 .replaceAll("\\n|\\r", " ")