mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-10 19:51:00 +00:00
[feature][chat]Introduce LLM-based DataInterpreter. #1828
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package com.tencent.supersonic.chat.server.processor.execute;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.server.agent.Agent;
|
||||
import com.tencent.supersonic.chat.server.pojo.ExecuteContext;
|
||||
import com.tencent.supersonic.common.pojo.ChatApp;
|
||||
import com.tencent.supersonic.common.pojo.enums.AppModule;
|
||||
import com.tencent.supersonic.common.util.ChatAppManager;
|
||||
import dev.langchain4j.data.message.AiMessage;
|
||||
import dev.langchain4j.model.chat.ChatLanguageModel;
|
||||
import dev.langchain4j.model.input.Prompt;
|
||||
import dev.langchain4j.model.input.PromptTemplate;
|
||||
import dev.langchain4j.model.output.Response;
|
||||
import dev.langchain4j.provider.ModelProvider;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class DataInterpretProcessor implements ExecuteResultProcessor {
|
||||
|
||||
private static final Logger keyPipelineLog = LoggerFactory.getLogger("keyPipeline");
|
||||
|
||||
public static final String APP_KEY = "DATA_INTERPRETER";
|
||||
private static final String INSTRUCTION = ""
|
||||
+ "#Role: You are a data expert who communicates with business users everyday."
|
||||
+ "\n#Task: Your will be provided with a question asked by a user and the relevant "
|
||||
+ "result data queried from the databases, please interpret the data and organize a brief answer."
|
||||
+ "\n#Rules: " + "\n1.The `#Answer` must use the same language as the `#Question`."
|
||||
+ "\n#Question:{{question}} #Data:{{data}} #Answer:";
|
||||
|
||||
public DataInterpretProcessor() {
|
||||
ChatAppManager.register(APP_KEY, ChatApp.builder().prompt(INSTRUCTION).name("结果数据解读")
|
||||
.appModule(AppModule.CHAT).description("通过大模型对结果数据做提炼总结").enable(false).build());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void process(ExecuteContext executeContext, QueryResult queryResult) {
|
||||
Agent agent = executeContext.getAgent();
|
||||
ChatApp chatApp = agent.getChatAppConfig().get(APP_KEY);
|
||||
if (Objects.isNull(chatApp) || !chatApp.isEnable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> variable = new HashMap<>();
|
||||
variable.put("question", executeContext.getQueryText());
|
||||
variable.put("data", queryResult.getTextResult());
|
||||
|
||||
Prompt prompt = PromptTemplate.from(chatApp.getPrompt()).apply(variable);
|
||||
ChatLanguageModel chatLanguageModel =
|
||||
ModelProvider.getChatModel(chatApp.getChatModelConfig());
|
||||
Response<AiMessage> response = chatLanguageModel.generate(prompt.toUserMessage());
|
||||
String anwser = response.content().text();
|
||||
keyPipelineLog.info("DataInterpretProcessor modelReq:\n{} \nmodelResp:\n{}", prompt.text(),
|
||||
anwser);
|
||||
if (StringUtils.isNotBlank(anwser)) {
|
||||
queryResult.setTextResult(anwser);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,13 @@ import com.tencent.supersonic.headless.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.headless.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.headless.server.facade.service.SemanticLayerService;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* DimensionRecommendProcessor recommend some dimensions related to metrics based on configuration
|
||||
@@ -37,7 +38,8 @@ public class DimensionRecommendProcessor implements ExecuteResultProcessor {
|
||||
if (!firstMetric.isPresent()) {
|
||||
return;
|
||||
}
|
||||
List<SchemaElement> dimensionRecommended = getDimensions(firstMetric.get().getId(), dataSetId);
|
||||
List<SchemaElement> dimensionRecommended =
|
||||
getDimensions(firstMetric.get().getId(), dataSetId);
|
||||
queryResult.setRecommendedDimensions(dimensionRecommended);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ com.tencent.supersonic.chat.server.processor.parse.ParseResultProcessor=\
|
||||
com.tencent.supersonic.chat.server.processor.execute.ExecuteResultProcessor=\
|
||||
com.tencent.supersonic.chat.server.processor.execute.MetricRecommendProcessor,\
|
||||
com.tencent.supersonic.chat.server.processor.execute.DimensionRecommendProcessor,\
|
||||
com.tencent.supersonic.chat.server.processor.execute.MetricRatioProcessor
|
||||
com.tencent.supersonic.chat.server.processor.execute.MetricRatioProcessor,\
|
||||
com.tencent.supersonic.chat.server.processor.execute.DataInterpretProcessor
|
||||
|
||||
### auth-authentication SPIs
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ com.tencent.supersonic.chat.server.processor.parse.ParseResultProcessor=\
|
||||
com.tencent.supersonic.chat.server.processor.execute.ExecuteResultProcessor=\
|
||||
com.tencent.supersonic.chat.server.processor.execute.MetricRecommendProcessor,\
|
||||
com.tencent.supersonic.chat.server.processor.execute.DimensionRecommendProcessor,\
|
||||
com.tencent.supersonic.chat.server.processor.execute.MetricRatioProcessor
|
||||
com.tencent.supersonic.chat.server.processor.execute.MetricRatioProcessor,\
|
||||
com.tencent.supersonic.chat.server.processor.execute.DataInterpretProcessor
|
||||
|
||||
### auth-authentication SPIs
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ public class BaseTest extends BaseApplication {
|
||||
SemanticParseInfo semanticParseInfo = parseResp.getSelectedParses().get(0);
|
||||
ChatExecuteReq request = ChatExecuteReq.builder().queryText(parseResp.getQueryText())
|
||||
.user(DataUtils.getUser()).parseId(semanticParseInfo.getId())
|
||||
.queryId(parseResp.getQueryId()).chatId(chatId).saveAnswer(true).build();
|
||||
.queryId(parseResp.getQueryId()).chatId(chatId).agentId(agentId).saveAnswer(true)
|
||||
.build();
|
||||
QueryResult queryResult = chatQueryService.execute(request);
|
||||
queryResult.setChatContext(semanticParseInfo);
|
||||
return queryResult;
|
||||
|
||||
Reference in New Issue
Block a user