package com.smtaiserver.smtaiserver.javaai.qwen.agent;
|
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Map.Entry;
|
import java.util.Set;
|
import java.util.TreeMap;
|
import org.apache.commons.text.similarity.JaccardSimilarity;
|
import org.dom4j.Document;
|
import org.dom4j.Element;
|
import org.dom4j.Node;
|
|
import com.smtaiserver.smtaiserver.core.SMTAIServerApp;
|
import com.smtaiserver.smtaiserver.core.SMTAIServerRequest;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord;
|
import com.smtaiserver.smtaiserver.javaai.SMTJavaAIError;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTCubeRecs;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTCubeRecs.ASTCubeRecsType;
|
import com.smtaiserver.smtaiserver.javaai.metrics.base.SMTDimensionDef;
|
import com.smtaiserver.smtaiserver.javaai.metrics.base.SMTMetricsDef;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTCubeRecsValue;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTDBMap;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTMergeResult;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTResult;
|
import com.smtaiserver.smtaiserver.javaai.llm.core.SMTLLMConnect;
|
import com.smtservlet.util.Json;
|
import com.smtservlet.util.SMTJsonWriter;
|
import com.smtservlet.util.SMTStatic;
|
|
public class SMTQwenAgentMetrics extends SMTQwenAgent
|
{
|
|
//////////////////////////////////////////////////////////////////
|
private boolean _questionToStep = false;
|
private String _promptVPROP;
|
private List<String> _metricsAlisList = new ArrayList<>();
|
private static Map<String, String[]> _mapGroupType2Match = new HashMap<>();
|
private static Map<String, String[]> _mapDiffType2Match = new HashMap<>();
|
|
static
|
{
|
_mapGroupType2Match.put("AVG", new String[]{"平均值", "平均", "AVG","sum","实时"});
|
_mapGroupType2Match.put("SUM", new String[]{"累计值", "累计", "SUM","sum","求和"});
|
_mapGroupType2Match.put("MAX", new String[]{"最大值", "最大", "MAX","max"});
|
_mapGroupType2Match.put("MIN", new String[]{"最小值", "MIN","min","最小"});
|
_mapGroupType2Match.put("COUNT", new String[]{"个数", "COUNT","count"});
|
|
_mapDiffType2Match.put("ADD", new String[]{"求和", "ADD","add","相加", "累计"});
|
_mapDiffType2Match.put("SUB", new String[]{"求差", "SUB","sub","相减", "差值"});
|
_mapDiffType2Match.put("YOY", new String[]{"同比", "YOY","yoy"});
|
_mapDiffType2Match.put("MOM", new String[]{"环比", "MOM","mom"});
|
}
|
|
@Override
|
public void initInstance(DBRecord rec) throws Exception
|
{
|
super.initInstance(rec);
|
|
try
|
{
|
Document doc = SMTStatic.convStrToXmlDoc("<ROOT>" + rec.getString("clz_arguments") + "</ROOT>");
|
Element xmlPrompt = (Element)doc.selectSingleNode("ROOT/PROMPT");
|
|
_questionToStep = "true".equals(SMTStatic.getXmlAttr(xmlPrompt, "question_to_step", "false"));
|
|
_promptVPROP = SMTStatic.trimStrLines(xmlPrompt.getText())
|
.replace("{{{DIM_NAME_LIST}}}", getDimNameList())
|
.replace("{{{METRICS_NAME_LIST}}}", getMetricsAliasList())
|
;
|
Node nodeMetricsAlias = doc.selectSingleNode("ROOT/METRICS_ALIAS");
|
if(nodeMetricsAlias != null)
|
{
|
String sMetricsAlias = SMTStatic.getXmlAttr((Element)nodeMetricsAlias, "names");
|
if(!SMTStatic.isNullOrEmpty(sMetricsAlias))
|
{
|
for(String s : sMetricsAlias.split(","))
|
{
|
_metricsAlisList.add(s);
|
}
|
}
|
}
|
}
|
catch(Exception ex)
|
{
|
throw new Exception("init mertic agent error : " + this._agentId, ex);
|
}
|
}
|
|
@Override
|
public SMTJavaAIError mergeASTList(List<Json> listASTSrc, List<Json> r_listASTTag)
|
{
|
StringBuilder sbQuestion = new StringBuilder();
|
for(Json jsonASTSrc : listASTSrc)
|
{
|
String question = jsonASTSrc.getJson("args").getJson("question").asString();
|
sbQuestion.append("问题:" + question + "\n");
|
}
|
|
Json jsonTag = Json.object(
|
"call", this.getAgentId(),
|
"args", Json.object(
|
"question", sbQuestion.toString()
|
)
|
);
|
|
r_listASTTag.add(jsonTag);
|
|
return null;
|
}
|
|
@Override
|
protected String getToolDesc(Element xmlTitle) throws Exception
|
{
|
String toolDesc = super.getToolDesc(xmlTitle);
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
if(mapId2Metrics.size() > 0)
|
{
|
toolDesc += "\n此操作包含以下指标:\n";
|
for(SMTMetricsDef metricsDef : mapId2Metrics.values())
|
{
|
toolDesc += " " + metricsDef.getTitle() + "\n";
|
}
|
}
|
return toolDesc;
|
}
|
|
private String getMetricsAliasList() throws Exception
|
{
|
Set<String> setAlias = new HashSet<>();
|
StringBuilder sbResult = new StringBuilder();
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
for(SMTMetricsDef metricsDef : mapId2Metrics.values())
|
{
|
metricsDef.addMetricsAliasToSet(setAlias);
|
}
|
|
for(String alias : setAlias)
|
{
|
sbResult.append(alias + "\n");
|
}
|
|
return sbResult.toString();
|
}
|
|
private String getDimNameList() throws Exception
|
{
|
Set<String> setExistDim = new HashSet<>();
|
StringBuilder sbResult = new StringBuilder();
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
for(SMTMetricsDef metricsDef : mapId2Metrics.values())
|
{
|
Map<String, SMTDimensionDef> mapId2DimDef = metricsDef.getDimensionMap();
|
if(mapId2DimDef == null)
|
continue;
|
|
for(SMTDimensionDef dimDef : mapId2DimDef.values())
|
{
|
if(setExistDim.contains(dimDef.getId()))
|
continue;
|
setExistDim.add(dimDef.getId());
|
sbResult.append(" " + dimDef.getId() + ":" + dimDef.getPrompt() + "\n");
|
}
|
}
|
|
return sbResult.toString();
|
}
|
|
public SMTJavaAIError callSupervisorJson(String agentId, String jsonPath, Json jsonSupervisorArg, Json jsonAST, SMTJsonWriter jsonWr, SMTAIServerRequest tranReq) throws Exception
|
{
|
tranReq.traceLLMDebug("callAgents:[\n" + SMTStatic.formatJson(jsonAST) + "\n]");
|
|
jsonWr.addKeyValue("answer_type", "summary");
|
jsonWr.beginArray("summary");
|
SMTJavaAIError aiError = queryRecordByAST(jsonPath, jsonAST.asJsonList(), tranReq);
|
jsonWr.endArray();
|
|
return aiError;
|
}
|
|
|
|
@Override
|
public SMTJavaAIError callAgents(String jsonPath, Json jsonArgs, SMTLLMConnect llm, String question, SMTAIServerRequest tranReq) throws Exception
|
{
|
long tick = System.currentTimeMillis();
|
|
// 如果发生要把问题变成步骤,调用大模型
|
if(_questionToStep)
|
{
|
tranReq.sendChunkedBlock("begin", "将问题拆解成步骤");
|
String promptToStep = (String)SMTAIServerApp.getApp().getGlobalConfig("prompt.question_to_step");
|
question = llm.callWithMessage(new String[] {promptToStep}, question, tranReq).replace("\r", "");
|
tranReq.traceLLMDebug("questionToStep:[\n" + question + "\n]");
|
tranReq.traceLLMPrompt(promptToStep);
|
tranReq.sendChunkedBlock("end", "拆解后的步骤是:" + question.replace("\r", "").replace("\n", " "));
|
}
|
|
String answer = llm.callWithMessage(new String[] {_promptVPROP}, question, tranReq).replace("\r", "");
|
Json jsonAST = SMTStatic.convLLMAnswerToJson(answer, true);
|
|
tranReq.appendCallFuncJson(jsonPath, jsonAST);
|
tranReq.traceLLMDebug("callAgents:[" + ((double)(System.currentTimeMillis() - tick) / 1000) + "秒] [\n" + SMTStatic.formatJson(jsonAST) + "\n]");
|
|
if(jsonAST.isObject())
|
{
|
String error = jsonAST.safeGetStr("error", "未知错误:" + jsonAST.toString());
|
return this.queryUnknowQuestion(error, llm, question, tranReq);
|
|
}
|
else if(!jsonAST.isArray())
|
{
|
String error = "未知错误:" + jsonAST.asString();
|
return this.queryUnknowQuestion(error, llm, question, tranReq);
|
}
|
|
return this.callAgentsByAST(jsonPath, jsonArgs, jsonAST, tranReq);
|
}
|
|
public SMTJavaAIError callAgentsByAST(String jsonPath, Json jsonArgs, Json jsonAST, SMTAIServerRequest tranReq) throws Exception
|
{
|
SMTJsonWriter jsonWrResult = tranReq.getResultJsonWr();
|
jsonWrResult.addKeyValue("answer_type", "summary");
|
jsonWrResult.beginArray("summary");
|
SMTJavaAIError aiError = queryRecordByAST(jsonPath, jsonAST.asJsonList(), tranReq);
|
jsonWrResult.endArray();
|
|
return aiError;
|
}
|
|
private SMTJavaAIError queryRecordByAST(String jsonPath, List<Json> jsonASTList, SMTAIServerRequest tranReq) throws Exception
|
{
|
SMTJsonWriter jsonWrResult = tranReq.getResultJsonWr();
|
|
ASTDBMap dbMap = new ASTDBMap();
|
try
|
{
|
ASTResult astResult = new ASTResult();
|
|
// 解析所有语法树
|
boolean existAST = false;
|
int count = jsonASTList.size();
|
for(int jsonIdx = 0; jsonIdx < count; jsonIdx ++)
|
{
|
Json jsonAST = jsonASTList.get(jsonIdx);
|
|
// 如果当前is_output = false
|
if(!jsonAST.getJson("args").safeGetBoolean("is_output", true))
|
{
|
// 如果已经存在执行器,则忽略
|
if(existAST)
|
continue;
|
|
// 如果当前执行器不是最后一个,则跳过
|
if(jsonIdx < (count -1))
|
continue;
|
}
|
|
|
existAST = true;
|
|
// 如果发现语法树报错,则直接返回错误
|
{
|
String error;
|
error = jsonAST.safeGetStr("error", null);
|
if(!SMTStatic.isNullOrEmpty(error))
|
return new SMTJavaAIError(error);
|
}
|
|
// 解析语法树
|
ASTResult curAstResult = new ASTResult();
|
SMTJavaAIError error = queryRecordAST2SQLTree("#" + SMTStatic.toString(jsonIdx) + "/", dbMap, jsonAST, null, tranReq, curAstResult);
|
if(error != null)
|
return error;
|
|
for(ASTCubeRecs cubeRecs : curAstResult._listRecordset)
|
{
|
astResult._listRecordset.add(cubeRecs);
|
}
|
}
|
|
ASTMergeResult mergeResult = new ASTMergeResult();
|
mergeResult.outputResultToJson(jsonPath, astResult, jsonWrResult);
|
//
|
// // 将生成的cube进行组合
|
// List<ASTMergeGroup> listMergeGroup = mergeASTResult(astResult);
|
//
|
// // 输出组合后的cube
|
// for(ASTMergeGroup mergeGroup : listMergeGroup)
|
// {
|
// mergeGroup.outputGroupToJson(jsonPath, jsonWr);
|
// }
|
}
|
finally
|
{
|
dbMap.close();
|
}
|
|
return null;
|
}
|
|
private SMTJavaAIError queryRecordAST2SQLTree(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
SMTJavaAIError aiError = null;
|
String call = jsonAST.getJson("call").asString();
|
Json jsonArgs = jsonAST.getJson("args");
|
|
|
if("query_metrics".equals(call))
|
{
|
aiError = call_query_metrics(jsonPath + "args/", dbMap, jsonArgs, extArg, tranReq, r_result);
|
}
|
else if("query_only_metrics".equals(call))
|
{
|
aiError = call_query_only_metrics(jsonPath + "args/", dbMap, jsonArgs, extArg, tranReq, r_result);
|
}
|
else if("agg_metrics".equals(call))
|
{
|
aiError = call_agg_metrics(jsonPath + "args/", dbMap, jsonArgs, extArg, tranReq, r_result);
|
}
|
else if("top_metrics".equals(call))
|
{
|
aiError = call_top_metrics(jsonPath + "args/", dbMap, jsonArgs, extArg, tranReq, r_result);
|
}
|
else if("diff_metrics".equals(call))
|
{
|
aiError = call_diff_metrics(jsonPath + "args/", dbMap, jsonArgs, extArg, tranReq, r_result);
|
}
|
else if("query_base_info".equals(call))
|
{
|
aiError = call_query_base_info(jsonPath + "args/", dbMap, jsonArgs, extArg, tranReq, r_result);
|
}
|
else
|
{
|
return new SMTJavaAIError("未知调用:" + call);
|
}
|
|
return aiError;
|
|
}
|
|
private SMTJavaAIError call_query_base_info(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
SMTJavaAIError error = null;
|
|
String metricsId = jsonAST.safeGetStr("metrics", null);
|
|
|
SMTMetricsDef metricsDef = null;
|
|
// 如果未配置指标,则取出第一个指标,且本配置只需要一个指标
|
if(SMTStatic.isNullOrEmpty(metricsId))
|
{
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
|
if(mapId2Metrics.size() != 1)
|
throw new Exception("call_query_base_info only one metrics : " + this.getAgentId());
|
|
for(SMTMetricsDef curMetricsDef : mapId2Metrics.values())
|
{
|
metricsDef = curMetricsDef;
|
break;
|
}
|
}
|
else
|
{
|
metricsDef = queryMetricsType(metricsId);
|
if(metricsDef == null)
|
return new SMTJavaAIError("未发现指标:" + metricsId);
|
}
|
|
if((error = metricsDef.queryMetrics(jsonPath, dbMap, jsonAST, extArg, tranReq, r_result)) != null)
|
return error;
|
|
return null;
|
}
|
|
private SMTJavaAIError call_diff_metrics(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
SMTJavaAIError error = null;
|
|
// 查询子结果集1
|
ASTResult childResult1 = new ASTResult();
|
error = queryRecordAST2SQLTree(jsonPath + "recordset1/", dbMap, jsonAST.getJson("recordset1"), extArg, tranReq, childResult1);
|
if(error != null)
|
return error;
|
|
// 查询子结果集2
|
ASTResult childResult2 = new ASTResult();
|
error = queryRecordAST2SQLTree(jsonPath + "recordset2/", dbMap, jsonAST.getJson("recordset2"), extArg, tranReq, childResult2);
|
if(error != null)
|
return error;
|
|
// 判断是否可以对比
|
if(childResult1._listRecordset.size() != 1 || childResult2._listRecordset.size() != 1)
|
return new SMTJavaAIError("查询出多个结果集无法对比");
|
|
ASTCubeRecs astCubeRecs1 = childResult1._listRecordset.get(0);
|
ASTCubeRecs astCubeRecs2 = childResult2._listRecordset.get(0);
|
if(astCubeRecs1._dimNames.size() > 0 || astCubeRecs2._dimNames.size() > 0)
|
return new SMTJavaAIError("查询多维度结果集无法对比");
|
|
// 获取对比方式
|
String userOperate = jsonAST.safeGetStr("operate", "");
|
if(SMTStatic.isNullOrEmpty(userOperate))
|
return new SMTJavaAIError("未指定对比方式");
|
String[] operate = matchGroupType(userOperate, _mapDiffType2Match);
|
if(operate == null)
|
return new SMTJavaAIError("对比方式" + userOperate + "不支持");
|
|
// 复制第一个结果集
|
List<ASTCubeRecs> listCubeRecs = new ArrayList<>();
|
for(ASTCubeRecs astResult : childResult1._listRecordset)
|
{
|
listCubeRecs.add(astResult.cloneCubeRecs());
|
}
|
|
// 附加第二个结果集
|
for(ASTCubeRecs astResult : childResult2._listRecordset)
|
{
|
listCubeRecs.add(astResult);
|
}
|
|
// 设置标题
|
astCubeRecs1._title += operate[1];
|
|
// 对比数据
|
if((error = astCubeRecs1._mapDimId2Recs.get(-1).diffValueRecords(operate[0], astCubeRecs2._mapDimId2Recs.get(-1))) != null)
|
return error;
|
|
astCubeRecs1._mapDimId2Recs.get(-1)._title += "和" + astCubeRecs2._mapDimId2Recs.get(-1)._title;
|
r_result._listRecordset.add(astCubeRecs1);
|
|
// 将原始曲线加入
|
for(ASTCubeRecs cubeRecs : listCubeRecs)
|
{
|
cubeRecs._isRawRS = true;
|
r_result._listRecordset.add(cubeRecs);
|
}
|
|
return null;
|
}
|
|
private SMTJavaAIError call_top_metrics(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
int limit = jsonAST.safeGetInt("limit", 5);
|
|
// 查询子结果集
|
SMTJavaAIError error = queryRecordAST2SQLTree(jsonPath + "recordset/", dbMap, jsonAST.getJson("recordset"), extArg, tranReq, r_result);
|
if(error != null)
|
return error;
|
|
for(ASTCubeRecs astRecs : r_result._listRecordset)
|
{
|
for(ASTCubeRecsValue astRecsValue : astRecs._mapDimId2Recs.values())
|
{
|
astRecsValue.limitRecords(limit);
|
}
|
}
|
|
return null;
|
}
|
|
private String[] matchGroupType(String operate, Map<String, String[]> mapGroupType2Match)
|
{
|
JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
|
|
String maxTitle = null;
|
String maxKey = null;
|
double maxMatch = 0;
|
for(Entry<String, String[]> entry : mapGroupType2Match.entrySet())
|
{
|
String curKey = entry.getKey();
|
for(String line : entry.getValue())
|
{
|
double curMatch = jaccardSimilarity.apply(line, operate);
|
if(curMatch == 1)
|
{
|
return new String[] {curKey, entry.getValue()[0]};
|
}
|
if(curMatch >= 0.8 && curMatch > maxMatch)
|
{
|
maxKey = curKey;
|
maxTitle = entry.getValue()[0];
|
maxMatch = curMatch;
|
}
|
}
|
}
|
|
if(maxKey == null)
|
return null;
|
|
return new String[] {maxKey, maxTitle};
|
}
|
|
private SMTJavaAIError call_agg_metrics(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
// 获取聚合操作
|
String[] operate = null;
|
String userOperate = jsonAST.safeGetStr("operate", "");
|
if(SMTStatic.isNullOrEmpty(userOperate))
|
{
|
operate = new String[]{"AVG", "平均"};
|
}
|
else
|
{
|
operate = matchGroupType(userOperate, _mapGroupType2Match);
|
if(operate == null)
|
{
|
operate = new String[]{"AVG", "平均"};
|
}
|
}
|
|
// 获取时间步长
|
String userStep = jsonAST.safeGetStr("step_time", "");
|
|
// 如果存在时间步长,且子操作是:query_metrics,则将其传递到子对象参数
|
boolean groupInQuery = false;
|
Json jsonRS = jsonAST.getJson("recordset");
|
String childCall = jsonRS.safeGetStr("call", "");
|
//if(!SMTStatic.isNullOrEmpty(userStep))
|
{
|
if("query_metrics".equals(childCall))
|
{
|
Json jsonRSArgs = jsonRS.getJson("args");
|
|
jsonRSArgs.set("step_op_key", operate[0]);
|
jsonRSArgs.set("step_op_title", operate[1]);
|
if(!SMTStatic.isNullOrEmpty(userStep))
|
{
|
jsonRSArgs.set("step_time_path", jsonPath + "step_time");
|
jsonRSArgs.set("step_time", userStep);
|
}
|
String stepDim = jsonAST.safeGetStr("dim_name", null);
|
if(!SMTStatic.isNullOrEmpty(stepDim))
|
jsonRSArgs.set("step_dim_name", stepDim);
|
groupInQuery = true;
|
}
|
|
}
|
|
// 如果存在分组,且子操作是query_base_info,则将其传递到子对象参数
|
if(operate != null && ("query_base_info".equals(childCall) || "query_only_metrics".equals(childCall)))
|
{
|
Json jsonRSArgs = jsonRS.getJson("args");
|
jsonRSArgs.set("step_op_key", operate[0]);
|
jsonRSArgs.set("step_op_title", operate[1]);
|
jsonRSArgs.set("step_time_path", jsonPath + "step_time");
|
String stepDim = jsonAST.safeGetStr("dim_name", null);
|
if(!SMTStatic.isNullOrEmpty(stepDim))
|
jsonRSArgs.set("step_dim_name", stepDim);
|
groupInQuery = true;
|
}
|
|
|
// 查询子结果集
|
SMTJavaAIError error = queryRecordAST2SQLTree(jsonPath + "recordset/", dbMap, jsonRS, null, tranReq, r_result);
|
if(error != null)
|
return error;
|
|
|
// 聚合操作
|
if(!groupInQuery)
|
{
|
for(ASTCubeRecs astRecs : r_result._listRecordset)
|
{
|
ASTCubeRecsType[] cubeRecsType = new ASTCubeRecsType[1];
|
for(ASTCubeRecsValue astRecsValue : astRecs._mapDimId2Recs.values())
|
{
|
String aggDimName = jsonAST.safeGetStr("dim_name", null);
|
if(!SMTStatic.isNullOrEmpty(aggDimName))
|
{
|
SMTDimensionDef dimDef = SMTAIServerApp.getApp().getDimensionDef(aggDimName);
|
astRecsValue._groupField = dimDef.getId();
|
astRecsValue._groupType = dimDef.getType();
|
}
|
|
cubeRecsType[0] = astRecs._recsType;
|
if((error = astRecsValue.groupValueRecords(operate[0], userStep, cubeRecsType, new String[][] {astRecs._colTitles})) != null)
|
return error;
|
astRecs._colTitles = new String[] {operate[1]};
|
if(cubeRecsType[0] == ASTCubeRecsType.SUMMARY)
|
astRecsValue._title += operate[1];
|
}
|
astRecs._recsType = cubeRecsType[0];
|
|
if(cubeRecsType[0] != ASTCubeRecsType.SUMMARY)
|
{
|
if(!SMTStatic.isNullOrEmpty(userStep))
|
{
|
int[] timeStep = SMTAIServerApp.convStrToTimeStep(userOperate);
|
astRecs._title += "每" + SMTAIServerApp.convTimeStepToStr(timeStep[0], timeStep[1]) + "的" + operate[1];
|
}
|
else
|
{
|
astRecs._title += operate[1];
|
}
|
}
|
}
|
}
|
|
return null;
|
}
|
|
private SMTJavaAIError call_query_metrics(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
// 获取指标对象
|
Object oMetrics = queryMetricsType(dbMap, jsonAST, tranReq);
|
if(oMetrics instanceof SMTJavaAIError)
|
return (SMTJavaAIError)oMetrics;
|
SMTMetricsDef matchMetrics = (SMTMetricsDef)oMetrics;
|
SMTJavaAIError error = matchMetrics.queryMetrics(jsonPath, dbMap, jsonAST, extArg, tranReq, r_result);
|
return error;
|
}
|
|
private SMTJavaAIError call_query_only_metrics(String jsonPath, ASTDBMap dbMap, Json jsonAST, Map<String, String> extArg, SMTAIServerRequest tranReq, ASTResult r_result) throws Exception
|
{
|
// 获取指标对象
|
SMTMetricsDef matchMetrics = null;
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
for(SMTMetricsDef curMatchMetrics : mapId2Metrics.values())
|
{
|
matchMetrics = curMatchMetrics;
|
break;
|
}
|
|
SMTJavaAIError error = matchMetrics.queryMetrics(jsonPath, dbMap, jsonAST, extArg, tranReq, r_result);
|
return error;
|
}
|
|
private Object queryMetricsType(ASTDBMap dbMap, Json jsonAST, SMTAIServerRequest tranReq) throws Exception
|
{
|
|
// 从参数中获取用户输入的指标类型
|
String metricsName = jsonAST.safeGetStr("metrics", "");
|
if(SMTStatic.isNullOrEmpty(metricsName))
|
{
|
for(String metricsAilas : _metricsAlisList)
|
{
|
metricsName = jsonAST.safeGetStr(metricsAilas, "");
|
if(!SMTStatic.isNullOrEmpty(metricsName))
|
{
|
SMTDimensionDef dimDef = SMTAIServerApp.getApp().getDimensionDef(metricsAilas);
|
if(dimDef == null)
|
continue;
|
JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
|
metricsName = dimDef.matchDimension(metricsName, jaccardSimilarity);
|
if(metricsName == null)
|
continue;
|
break;
|
}
|
}
|
|
if(SMTStatic.isNullOrEmpty(metricsName))
|
return new SMTJavaAIError("未解析出指标信息");
|
}
|
|
SMTMetricsDef metricsDef = queryMetricsType(metricsName);
|
if(metricsDef != null)
|
return metricsDef;
|
|
if(metricsName.startsWith("监测") && jsonAST.has("device"))
|
{
|
metricsName = jsonAST.getJson("device").asString() + jsonAST.safeGetStr("metrics", "");
|
metricsDef = queryMetricsType(metricsName);
|
}
|
|
if(metricsDef != null)
|
return metricsDef;
|
|
return new SMTJavaAIError("未找到匹配的指标:" + metricsName);
|
}
|
|
|
private SMTMetricsDef queryMetricsType(String metricsName) throws Exception
|
{
|
double minSimValue = SMTStatic.toDouble(SMTAIServerApp.getApp().getGlobalConfig("history.math.ratio"));
|
|
// 匹配指标定义
|
double maxSim = 0;
|
SMTMetricsDef matchMetrics = null;
|
TreeMap<Double, SMTMetricsDef> mapSim2Metrics = new TreeMap<>();
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
|
for(SMTMetricsDef metricsDef : mapId2Metrics.values())
|
{
|
double curSim = metricsDef.matchMetrics(metricsName, jaccardSimilarity);
|
if(curSim == 1)
|
{
|
maxSim = 1;
|
matchMetrics = metricsDef;
|
break;
|
}
|
else if(curSim >= minSimValue)
|
{
|
if(maxSim <= curSim)
|
{
|
maxSim = curSim;
|
matchMetrics = metricsDef;
|
}
|
}
|
|
mapSim2Metrics.put(curSim, metricsDef);
|
}
|
|
if(maxSim < minSimValue)
|
return null;
|
|
return matchMetrics;
|
}
|
|
@Override
|
public void queryUnknowQuestionList(String keyword, SMTAIServerRequest tranReq) throws Exception
|
{
|
Map<String, SMTMetricsDef> mapId2Metrics = SMTAIServerApp.getApp().getMetricsMap(this.getAgentId());
|
JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
|
for(SMTMetricsDef metricsDef : mapId2Metrics.values())
|
{
|
metricsDef.queryUnknowQuestionList(jaccardSimilarity, keyword, tranReq);
|
}
|
}
|
}
|