|
@@ -4,16 +4,17 @@ package com.ch.jedge.jbot2.llm.pickers;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.ch.jedge.jbot2.context.JedgeTalkSession;
|
|
|
import com.ch.jedge.jbot2.llm.JedgeLLMBaseObject;
|
|
|
import com.ch.jedge.jbot2.llm.JedgeLLMContext;
|
|
|
import com.ch.jedge.jbot2.llm.request.JedgeLLMRequest;
|
|
|
-import com.ch.jedge.jbot2.context.JedgeTalkSession;
|
|
|
import com.ch.jedge.utils.JedgeLlmUtil;
|
|
|
import com.changhong.jedge.JMgbusUtil;
|
|
|
import com.changhong.qlib.QData;
|
|
|
import com.changhong.qlib.QDataList;
|
|
|
import com.changhong.qlib.intf.QIData;
|
|
|
import com.changhong.qlib.util.StringUtils;
|
|
|
+import com.changhong.qlib.util.file.FileUtils;
|
|
|
|
|
|
import java.lang.reflect.Constructor;
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
@@ -24,6 +25,7 @@ import java.util.*;
|
|
|
* 可动态添加dataset的item项.当item项超过一定的数量时,需要执行多级分类.
|
|
|
*/
|
|
|
public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
+ protected String complex_tpl;
|
|
|
protected JedgeLLMRequest llmRequest = null;
|
|
|
public String params_; //所需要提取的参数及其说明,可能需要多次调用,确认最终参数。参数提取,可能需要额外的一次请求。
|
|
|
|
|
@@ -31,10 +33,7 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
protected JedgeLLMResultValidator validator_ = null; //结果校验器,检验结果是否包含某些参数,主要针对特定的消息格式模板进行
|
|
|
|
|
|
protected final Map<String, QIData> mDatasetMap = new HashMap<>();
|
|
|
- private String role = "";
|
|
|
- private String cmd = "";
|
|
|
- private String fmt = "";
|
|
|
- private String prefix = "";
|
|
|
+ private String pickerKey = "";
|
|
|
|
|
|
public JedgeLLMParamPicker(JedgeLLMContext llmCtx, Class<? extends JedgeLLMRequest> requestClass) {
|
|
|
super(llmCtx);
|
|
@@ -90,13 +89,42 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
}
|
|
|
|
|
|
public QIData pickParamsFromQuery(JedgeTalkSession s, String query, String paramKey, String... para) {
|
|
|
- String dataset = prepareDataset(paramKey);
|
|
|
- String realQuery = llmRequest.getRealPrompt(s, query, para);
|
|
|
- if(StringUtils.isValidStr(dataset)) {
|
|
|
- realQuery = dataset + realQuery;
|
|
|
+ String realQuery = "";
|
|
|
+ String recKey = StringUtils.getSubStrAfter(pickerKey,'/', -1);
|
|
|
+ if(recKey==null) recKey = pickerKey;
|
|
|
+
|
|
|
+ if(StringUtils.isValidStr(complex_tpl)) {
|
|
|
+// realQuery = complex_tpl.replaceAll("\\{query}", query);
|
|
|
+ realQuery = complex_tpl.replace("{query}", query);
|
|
|
+ } else return null;
|
|
|
+ if(complex_tpl.contains("{data}")) {
|
|
|
+ String dataset = prepareDataset(paramKey);
|
|
|
+ if(StringUtils.isNotValidStr(dataset)) dataset = "{}";
|
|
|
+// realQuery = realQuery.replaceAll("\\{data}", dataset);
|
|
|
+ realQuery = realQuery.replace("{data}", dataset);
|
|
|
+ }
|
|
|
+ if(complex_tpl.contains("{data_keys}")) {
|
|
|
+ //替换KeyList
|
|
|
+ String targetKeyList = getDataKeyList(paramKey);
|
|
|
+ if(StringUtils.isNotValidStr(targetKeyList)) targetKeyList = "";
|
|
|
+// realQuery = realQuery.replaceAll("\\{data_keys}", targetKeyList);
|
|
|
+ realQuery = realQuery.replace("{data_keys}", targetKeyList);
|
|
|
+ }
|
|
|
+ if(complex_tpl.contains("{example}")) {
|
|
|
+ //替换KeyList
|
|
|
+ String examples = getDataExamples(paramKey);
|
|
|
+ if(StringUtils.isNotValidStr(examples))
|
|
|
+ examples = "";
|
|
|
+// realQuery = realQuery.replaceAll("\\{example}", examples);
|
|
|
+ realQuery = realQuery.replace("{example}", examples);
|
|
|
}
|
|
|
+
|
|
|
+ llmContext.recorder.recordRawRequest(recKey, realQuery, query);
|
|
|
+
|
|
|
QIData lmRsp = llmRequest.makeChatRequest(s, realQuery);
|
|
|
|
|
|
+ llmContext.recorder.recordRawResponse(recKey, lmRsp ,query);
|
|
|
+
|
|
|
if(validator_!=null && !validator_.validateResult(lmRsp)) {
|
|
|
//再次LLM Request,提取专有参数结果。
|
|
|
return JMgbusUtil.MgbusResult(402, "Validate failed.");
|
|
@@ -104,27 +132,46 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
return lmRsp;
|
|
|
}
|
|
|
|
|
|
- protected String prepareDataset(String... paramKey) {
|
|
|
+ //获取示例,新增模块如何解析的example
|
|
|
+ private String getDataExamples(String... paramKey) {
|
|
|
+ return null;
|
|
|
+// StringBuilder re = new StringBuilder();
|
|
|
+// if(paramKey!=null && paramKey.length>0) {
|
|
|
+// synchronized (mDatasetMap) {
|
|
|
+// for (String k : paramKey) {
|
|
|
+// QIData d = mDatasetMap.get(k);
|
|
|
+// if (d != null) {
|
|
|
+// re.append(d.getData("val").toJSONString(true));
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// return re.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getDataKeyList(String... paramKey) {
|
|
|
StringBuilder re = new StringBuilder();
|
|
|
- if(paramKey==null || paramKey.length==0 || paramKey[0]==null) {
|
|
|
+ if(paramKey!=null && paramKey.length>0) {
|
|
|
synchronized (mDatasetMap) {
|
|
|
- for (String k : mDatasetMap.keySet()) {
|
|
|
+ for (String k : paramKey) {
|
|
|
QIData d = mDatasetMap.get(k);
|
|
|
if (d != null) {
|
|
|
- re.append(d.getName()).append(':');
|
|
|
- re.append(d.getString("d")).append(',');
|
|
|
- re.append("取值依据:").append(d.getData("val").toJSONString()).append('.');
|
|
|
+ re.append(StringUtils.ListToString(JedgeLlmUtil.getSortedKeyList(d.getData("val")), ','));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ return re.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected String prepareDataset(String... paramKey) {
|
|
|
+ StringBuilder re = new StringBuilder();
|
|
|
+ if(paramKey!=null && paramKey.length>0) {
|
|
|
synchronized (mDatasetMap) {
|
|
|
for (String k : paramKey) {
|
|
|
QIData d = mDatasetMap.get(k);
|
|
|
if (d != null) {
|
|
|
- re.append(d.getName()).append(':');
|
|
|
- re.append(d.getString("d")).append(',');
|
|
|
- re.append("取值依据:").append(d.getData("val").toJSONString()).append('.');
|
|
|
+ re.append(d.getData("val").toJSONString(true));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -138,42 +185,14 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public boolean loadPickerFromData(QIData defs) {
|
|
|
- JSONArray ta = defs.getJsonArray("targets");
|
|
|
- String targets = null;
|
|
|
- if(ta!=null)
|
|
|
- targets = JedgeLlmUtil.StringFromStringJSONArray(ta);
|
|
|
- else
|
|
|
- targets = defs.getString("targets");
|
|
|
-
|
|
|
- String cmd = defs.getString("cmd");
|
|
|
- String fmt = defs.getString("fmt");
|
|
|
- String role = defs.getString("role");
|
|
|
- String prefix = defs.getString("prefix");
|
|
|
- String[] targetDefs = null;
|
|
|
- if(ta!=null)
|
|
|
- targetDefs = targets.split(",");
|
|
|
- else {
|
|
|
- targetDefs = getParamDatasetValues(defs, targets);
|
|
|
- if (targetDefs == null) {
|
|
|
- targetDefs = new String[]{targets};
|
|
|
- }
|
|
|
- }
|
|
|
- if(StringUtils.isNotValidStr(cmd) || StringUtils.isNotValidStr(fmt))
|
|
|
- return false;
|
|
|
- loadDataset(defs);
|
|
|
- defineDataPicker( targetDefs, role, cmd, fmt, prefix);
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
public boolean loadPickerFromFile(String filename) {
|
|
|
- QIData defs = QData.fromFile(filename);
|
|
|
- if(defs.isEmpty()) return false;
|
|
|
- return loadPickerFromData(defs);
|
|
|
+ pickerKey = FileUtils.getFilenameWithoutExt(filename);
|
|
|
+ complex_tpl = StringUtils.readStringFromFile(filename);
|
|
|
+ return StringUtils.isValidStr(pickerKey) && StringUtils.isValidStr(complex_tpl);
|
|
|
}
|
|
|
|
|
|
//移除数据项
|
|
|
- public void addDataToDatasetItem(String dmKey, String valKey, String val) {
|
|
|
+ public void addDataToDatasetItem(String dmKey, String dmName, String valKey, String val) {
|
|
|
QIData ds;
|
|
|
synchronized (mDatasetMap) {
|
|
|
ds = mDatasetMap.get(dmKey);
|
|
@@ -187,16 +206,17 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
JSONObject vals = ds.getJsonObject("val");
|
|
|
if(vals==null) {
|
|
|
vals = new JSONObject();
|
|
|
+ ds.setName(dmName);
|
|
|
ds.put("val", vals);
|
|
|
}
|
|
|
vals.put(valKey, val);
|
|
|
- rebuildLLMRequest();
|
|
|
+ rebuildLLMRequest(dmKey);
|
|
|
}
|
|
|
|
|
|
- private void rebuildLLMRequest() {
|
|
|
+ private void rebuildLLMRequest(String dmKey) {
|
|
|
QIData ds;
|
|
|
synchronized (mDatasetMap) {
|
|
|
- ds = mDatasetMap.get("name");
|
|
|
+ ds = mDatasetMap.get(mDatasetMap.containsKey("name")?"name":dmKey);
|
|
|
}
|
|
|
String[] targetDefs;
|
|
|
if(ds!=null) {
|
|
@@ -205,7 +225,7 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
} else {
|
|
|
targetDefs = new String[0];
|
|
|
}
|
|
|
- llmRequest.setTemplateStr(targetDefs, role, cmd, fmt, prefix);
|
|
|
+ // llmRequest.setTemplateStr(targetDefs, role, cmd, fmt, prefix);
|
|
|
}
|
|
|
|
|
|
//增加数据项
|
|
@@ -217,10 +237,37 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
if(ds!=null) {
|
|
|
JSONObject vals = ds.getJsonObject("val");
|
|
|
if(vals.remove(valKey)!=null)
|
|
|
- rebuildLLMRequest();
|
|
|
+ rebuildLLMRequest(dmKey);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public boolean loadPickerFromData(QIData defs) {
|
|
|
+ JSONArray ta = defs.getJsonArray("targets");
|
|
|
+ String targets = null;
|
|
|
+ if(ta!=null)
|
|
|
+ targets = JedgeLlmUtil.StringFromStringJSONArray(ta);
|
|
|
+ else
|
|
|
+ targets = defs.getString("targets");
|
|
|
+
|
|
|
+ String cmd = defs.getString("cmd");
|
|
|
+ String fmt = defs.getString("fmt");
|
|
|
+ String role = defs.getString("role");
|
|
|
+ String prefix = defs.getString("prefix");
|
|
|
+ String[] targetDefs = null;
|
|
|
+ if(ta!=null)
|
|
|
+ targetDefs = targets.split(",");
|
|
|
+ else {
|
|
|
+ targetDefs = getParamDatasetValues(defs, targets);
|
|
|
+ if (targetDefs == null) {
|
|
|
+ targetDefs = new String[]{targets};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotValidStr(cmd) || StringUtils.isNotValidStr(fmt))
|
|
|
+ return false;
|
|
|
+ loadDataset(defs);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
public void loadDataset(QIData defs) {
|
|
|
JSONArray datasets = defs.getJsonArray("datasets");
|
|
|
if(datasets==null || datasets.isEmpty())
|
|
@@ -279,12 +326,7 @@ public class JedgeLLMParamPicker extends JedgeLLMBaseObject {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- protected void defineDataPicker(String[] targetDefs, String role, String cmd, String fmt, String prefix) {
|
|
|
- //todo:: 从直接值中建立DataSetMap
|
|
|
- this.role = role;
|
|
|
- this.cmd = cmd;
|
|
|
- this.fmt = fmt;
|
|
|
- this.prefix = prefix;
|
|
|
- llmRequest.setTemplateStr(targetDefs, role, cmd, fmt, prefix);
|
|
|
+ public String getPikerKey() {
|
|
|
+ return pickerKey;
|
|
|
}
|
|
|
}
|