From cd863705a4a550c920f74055a98d9e4cba25e7eb Mon Sep 17 00:00:00 2001 From: jerryjzhang Date: Wed, 8 Jan 2025 20:46:44 +0800 Subject: [PATCH] [improvement][chat]Opt log infos. --- .../headless/chat/corrector/LLMSqlCorrector.java | 15 ++++++++------- .../core/translator/parser/SqlQueryParser.java | 9 +++++++-- .../server/utils/ChatWorkflowEngine.java | 2 +- .../headless/server/utils/QueryUtils.java | 16 +++++++++++----- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/LLMSqlCorrector.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/LLMSqlCorrector.java index 6452da92c..9d5d0e063 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/LLMSqlCorrector.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/LLMSqlCorrector.java @@ -32,10 +32,11 @@ public class LLMSqlCorrector extends BaseSemanticCorrector { private static final String INSTRUCTION = "" + "#Role: You are a senior data engineer experienced in writing SQL." + "\n#Task: Your will be provided with a user question and the SQL written by a junior engineer," - + "please take a review and help correct it if necessary." + "\n#Rules: " - + "\n1.ALWAYS follow the output format: `opinion=(POSITIVE|NEGATIVE),sql=(corrected sql if NEGATIVE; empty string if POSITIVE)`." - + "\n2.NO NEED to check date filters as the junior engineer seldom makes mistakes in this regard." - + "\n3.SQL columns and values must be mentioned in the `#Schema`." + + "please take a review and help correct it if necessary." + + "\n#Rules: " + + "1.ALWAYS specify time range using `>`,`<`,`>=`,`<=` operator." + + "2.DO NOT calculate date range using functions." + + "3.SQL columns and values must be mentioned in the `#Schema`." + "\n#Question:{{question}} #Schema:{{schema}} #InputSQL:{{sql}} #Response:"; public LLMSqlCorrector() { @@ -46,10 +47,10 @@ public class LLMSqlCorrector extends BaseSemanticCorrector { @Data @ToString static class SemanticSql { - @Description("positive or negative opinion about the sql") + @Description("either positive or negative") private String opinion; - @Description("corrected sql") + @Description("corrected sql if negative") private String sql; } @@ -76,7 +77,7 @@ public class LLMSqlCorrector extends BaseSemanticCorrector { semanticParseInfo, chatApp.getPrompt(), exemplar); SemanticSql s2Sql = extractor.generateSemanticSql(prompt.toUserMessage().singleText()); keyPipelineLog.info("LLMSqlCorrector modelReq:\n{} \nmodelResp:\n{}", prompt.text(), s2Sql); - if ("NEGATIVE".equals(s2Sql.getOpinion()) && StringUtils.isNotBlank(s2Sql.getSql())) { + if ("NEGATIVE".equalsIgnoreCase(s2Sql.getOpinion()) && StringUtils.isNotBlank(s2Sql.getSql())) { semanticParseInfo.getSqlInfo().setCorrectedS2SQL(s2Sql.getSql()); } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java index d066043a0..859f62dca 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java @@ -1,5 +1,6 @@ package com.tencent.supersonic.headless.core.translator.parser; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper; import com.tencent.supersonic.common.jsqlparser.SqlSelectFunctionHelper; @@ -49,8 +50,12 @@ public class SqlQueryParser implements QueryParser { // check if there are fields not matched with any metric or dimension if (queryFields.size() > ontologyQuery.getMetrics().size() + ontologyQuery.getDimensions().size()) { - queryStatement - .setErrMsg("There are fields in the SQL not matched with any semantic column."); + List semanticFields = Lists.newArrayList(); + ontologyQuery.getMetrics().forEach(m -> semanticFields.add(m.getName())); + ontologyQuery.getDimensions().forEach(d -> semanticFields.add(d.getName())); + String errMsg = String.format("Querying columns[%s] not matched with semantic fields[%s].", + queryFields, semanticFields); + queryStatement.setErrMsg(errMsg); queryStatement.setStatus(QueryState.INVALID); return; } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ChatWorkflowEngine.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ChatWorkflowEngine.java index d7b7d08a1..3ac3e6d8e 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ChatWorkflowEngine.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ChatWorkflowEngine.java @@ -152,7 +152,7 @@ public class ChatWorkflowEngine { StringUtils.normalizeSpace(parseInfo.getSqlInfo().getCorrectedS2SQL()), StringUtils.normalizeSpace(parseInfo.getSqlInfo().getQuerySQL())); } catch (Exception e) { - log.warn("get sql info failed:{}", parseInfo, e); + log.warn("get sql info failed:{}", e); errorMsg.add(String.format("S2SQL:%s %s", parseInfo.getSqlInfo().getParsedS2SQL(), e.getMessage())); } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryUtils.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryUtils.java index 9129b4001..04369b922 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryUtils.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryUtils.java @@ -119,11 +119,17 @@ public class QueryUtils { if (StringUtils.isBlank(type)) { return false; } - return type.equalsIgnoreCase("int") || type.equalsIgnoreCase("bigint") - || type.equalsIgnoreCase("tinyint") || type.equalsIgnoreCase("smallint") - || type.equalsIgnoreCase("float") || type.equalsIgnoreCase("double") || type.equalsIgnoreCase("real") - || type.equalsIgnoreCase("numeric") || type.toLowerCase().startsWith("decimal") - || type.toLowerCase().startsWith("uint") || type.toLowerCase().startsWith("int"); + return type.equalsIgnoreCase("int") + || type.equalsIgnoreCase("bigint") + || type.equalsIgnoreCase("tinyint") + || type.equalsIgnoreCase("smallint") + || type.equalsIgnoreCase("float") + || type.equalsIgnoreCase("double") + || type.equalsIgnoreCase("real") + || type.equalsIgnoreCase("numeric") + || type.toLowerCase().startsWith("decimal") + || type.toLowerCase().startsWith("uint") + || type.toLowerCase().startsWith("int"); } private String getName(String nameEn) {