mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-12 20:51:48 +00:00
(improvement)(chat) add responder to fill additional information, such as entity information (#173)
* (improvement)(chat) add responder to fill additional information, such as entity information --------- Co-authored-by: jolunoluo
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package com.tencent.supersonic.chat.parser.plugin.function;
|
||||
package com.tencent.supersonic.chat.parser.llm.dsl;
|
||||
|
||||
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
@@ -17,7 +17,6 @@ import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.config.LLMParserConfig;
|
||||
import com.tencent.supersonic.chat.parser.SatisfactionChecker;
|
||||
import com.tencent.supersonic.chat.parser.plugin.function.ModelResolver;
|
||||
import com.tencent.supersonic.chat.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.query.llm.dsl.DslQuery;
|
||||
import com.tencent.supersonic.chat.query.llm.dsl.LLMReq;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.tencent.supersonic.chat.parser.plugin.function;
|
||||
package com.tencent.supersonic.chat.parser.llm.dsl;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.tencent.supersonic.chat.parser.plugin.function;
|
||||
package com.tencent.supersonic.chat.parser.llm.dsl;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
@@ -1,98 +0,0 @@
|
||||
package com.tencent.supersonic.chat.parser.plugin.embedding;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaMapInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilters;
|
||||
import com.tencent.supersonic.chat.service.ConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
@Component("EmbeddingEntityResolver")
|
||||
public class EmbeddingEntityResolver {
|
||||
private ConfigService configService;
|
||||
|
||||
public EmbeddingEntityResolver(ConfigService configService) {
|
||||
this.configService = configService;
|
||||
}
|
||||
|
||||
|
||||
private Long getEntityValue(Long modelId, Long entityElementId, QueryContext queryCtx, ChatContext chatCtx) {
|
||||
Long entityId = null;
|
||||
QueryFilters queryFilters = queryCtx.getRequest().getQueryFilters();
|
||||
if (queryFilters != null) {
|
||||
entityId = getEntityValueFromQueryFilter(queryFilters.getFilters());
|
||||
if (entityId != null) {
|
||||
log.info("get entity id:{} model id:{} from query filter :{} ", entityId, modelId, queryFilters);
|
||||
return entityId;
|
||||
}
|
||||
}
|
||||
entityId = getEntityValueFromSchemaMapInfo(modelId, queryCtx.getMapInfo(), entityElementId);
|
||||
log.info("get entity id:{} from schema map Info :{} ",
|
||||
entityId, JSONObject.toJSONString(queryCtx.getMapInfo()));
|
||||
if (entityId == null || entityId == 0) {
|
||||
Long entityIdFromChat = getEntityValueFromParseInfo(chatCtx.getParseInfo(), entityElementId);
|
||||
if (entityIdFromChat != null && entityIdFromChat > 0) {
|
||||
entityId = entityIdFromChat;
|
||||
}
|
||||
}
|
||||
return entityId;
|
||||
}
|
||||
|
||||
private Long getEntityValueFromQueryFilter(List<QueryFilter> queryFilters) {
|
||||
if (CollectionUtils.isEmpty(queryFilters)) {
|
||||
return null;
|
||||
}
|
||||
QueryFilter filter = queryFilters.get(0);
|
||||
String value = String.valueOf(filter.getValue());
|
||||
if (StringUtils.isNumeric(value)) {
|
||||
return Long.parseLong(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Long getEntityValueFromParseInfo(SemanticParseInfo semanticParseInfo, Long entityElementId) {
|
||||
Set<QueryFilter> filters = semanticParseInfo.getDimensionFilters();
|
||||
if (CollectionUtils.isEmpty(filters)) {
|
||||
return null;
|
||||
}
|
||||
for (QueryFilter filter : filters) {
|
||||
if (entityElementId.equals(filter.getElementID())) {
|
||||
String value = String.valueOf(filter.getValue());
|
||||
if (StringUtils.isNumeric(value)) {
|
||||
return Long.parseLong(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private Long getEntityValueFromSchemaMapInfo(Long modelId, SchemaMapInfo schemaMapInfo, Long entityElementId) {
|
||||
List<SchemaElementMatch> schemaElementMatchList = schemaMapInfo.getMatchedElements(modelId);
|
||||
if (CollectionUtils.isEmpty(schemaElementMatchList)) {
|
||||
return null;
|
||||
}
|
||||
for (SchemaElementMatch schemaElementMatch : schemaElementMatchList) {
|
||||
if (Objects.equals(schemaElementMatch.getElement().getId(), entityElementId)) {
|
||||
if (StringUtils.isNumeric(schemaElementMatch.getWord())) {
|
||||
return Long.parseLong(schemaElementMatch.getWord());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.tencent.supersonic.chat.parser.plugin.function;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.config.FunctionCallInfoConfig;
|
||||
import com.tencent.supersonic.chat.parser.ParseMode;
|
||||
import com.tencent.supersonic.chat.parser.SatisfactionChecker;
|
||||
import com.tencent.supersonic.chat.parser.plugin.PluginParser;
|
||||
@@ -37,7 +36,7 @@ public class FunctionBasedParser extends PluginParser {
|
||||
|
||||
@Override
|
||||
public boolean checkPreCondition(QueryContext queryContext) {
|
||||
FunctionCallInfoConfig functionCallConfig = ContextUtils.getBean(FunctionCallInfoConfig.class);
|
||||
FunctionCallConfig functionCallConfig = ContextUtils.getBean(FunctionCallConfig.class);
|
||||
String functionUrl = functionCallConfig.getUrl();
|
||||
if (StringUtils.isBlank(functionUrl) || SatisfactionChecker.check(queryContext)) {
|
||||
log.info("functionUrl:{}, skip function parser, queryText:{}", functionUrl,
|
||||
@@ -134,7 +133,7 @@ public class FunctionBasedParser extends PluginParser {
|
||||
}
|
||||
|
||||
public FunctionResp requestFunction(FunctionReq functionReq) {
|
||||
FunctionCallInfoConfig functionCallInfoConfig = ContextUtils.getBean(FunctionCallInfoConfig.class);
|
||||
FunctionCallConfig functionCallInfoConfig = ContextUtils.getBean(FunctionCallConfig.class);
|
||||
String url = functionCallInfoConfig.getUrl() + functionCallInfoConfig.getPluginSelectPath();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.tencent.supersonic.chat.config;
|
||||
package com.tencent.supersonic.chat.parser.plugin.function;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -6,7 +6,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@Data
|
||||
public class FunctionCallInfoConfig {
|
||||
public class FunctionCallConfig {
|
||||
@Value("${functionCall.url:}")
|
||||
private String url;
|
||||
|
||||
@@ -2,18 +2,15 @@ package com.tencent.supersonic.chat.query.llm.dsl;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.component.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryState;
|
||||
import com.tencent.supersonic.chat.parser.llm.dsl.DSLParseResult;
|
||||
import com.tencent.supersonic.chat.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.query.plugin.PluginSemanticQuery;
|
||||
import com.tencent.supersonic.chat.service.SemanticService;
|
||||
import com.tencent.supersonic.chat.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.utils.QueryReqBuilder;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.QueryTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ExplainResp;
|
||||
@@ -66,9 +63,6 @@ public class DslQuery extends PluginSemanticQuery {
|
||||
queryResult.setQueryMode(QUERY_MODE);
|
||||
queryResult.setQueryState(QueryState.SUCCESS);
|
||||
|
||||
// add model info
|
||||
EntityInfo entityInfo = ContextUtils.getBean(SemanticService.class).getEntityInfo(parseInfo, user);
|
||||
queryResult.setEntityInfo(entityInfo);
|
||||
parseInfo.setProperties(null);
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilters;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryState;
|
||||
import com.tencent.supersonic.chat.plugin.Plugin;
|
||||
@@ -57,8 +56,6 @@ public class WebPageQuery extends PluginSemanticQuery {
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
ModelSchema modelSchema = semanticService.getModelSchema(parseInfo.getModelId());
|
||||
parseInfo.setModel(modelSchema.getModel());
|
||||
EntityInfo entityInfo = semanticService.getEntityInfo(parseInfo, user);
|
||||
queryResult.setEntityInfo(entityInfo);
|
||||
queryResult.setQueryState(QueryState.SUCCESS);
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryState;
|
||||
import com.tencent.supersonic.chat.query.QueryManager;
|
||||
@@ -211,10 +210,6 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
|
||||
queryResult.setQueryMode(queryMode);
|
||||
queryResult.setQueryState(QueryState.SUCCESS);
|
||||
|
||||
// add Model info
|
||||
EntityInfo entityInfo = ContextUtils.getBean(SemanticService.class)
|
||||
.getEntityInfo(parseInfo, user);
|
||||
queryResult.setEntityInfo(entityInfo);
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
@@ -260,10 +255,6 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
|
||||
queryResult.setQueryMode(queryMode);
|
||||
queryResult.setQueryState(QueryState.SUCCESS);
|
||||
|
||||
// add Model info
|
||||
EntityInfo entityInfo = ContextUtils.getBean(SemanticService.class)
|
||||
.getEntityInfo(parseInfo, user);
|
||||
queryResult.setEntityInfo(entityInfo);
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.tencent.supersonic.chat.queryresponder;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.SolvedQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SolvedQueryRecallResp;
|
||||
import java.util.List;
|
||||
|
||||
public interface QueryResponder {
|
||||
|
||||
void saveSolvedQuery(SolvedQueryReq solvedQueryReq);
|
||||
|
||||
List<SolvedQueryRecallResp> recallSolvedQuery(String queryText, Integer agentId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tencent.supersonic.chat.responder.execute;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.service.SemanticService;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
|
||||
public class EntityInfoExecuteResponder implements ExecuteResponder {
|
||||
|
||||
@Override
|
||||
public void fillResponse(QueryResult queryResult, SemanticParseInfo semanticParseInfo, ExecuteQueryReq queryReq) {
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
EntityInfo entityInfo = semanticService.getEntityInfo(semanticParseInfo, queryReq.getUser());
|
||||
queryResult.setEntityInfo(entityInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.tencent.supersonic.chat.responder.execute;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
|
||||
public interface ExecuteResponder {
|
||||
|
||||
void fillResponse(QueryResult queryResult, SemanticParseInfo semanticParseInfo, ExecuteQueryReq queryReq);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tencent.supersonic.chat.responder.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.service.SemanticService;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.List;
|
||||
|
||||
public class EntityInfoParseResponder implements ParseResponder {
|
||||
|
||||
@Override
|
||||
public void fillResponse(ParseResp parseResp, QueryContext queryContext) {
|
||||
List<SemanticParseInfo> selectedParses = parseResp.getSelectedParses();
|
||||
if (CollectionUtils.isEmpty(selectedParses)) {
|
||||
return;
|
||||
}
|
||||
QueryReq queryReq = queryContext.getRequest();
|
||||
selectedParses.forEach(parseInfo -> {
|
||||
String queryMode = parseInfo.getQueryMode();
|
||||
if (QueryManager.isEntityQuery(queryMode)) {
|
||||
EntityInfo entityInfo = ContextUtils.getBean(SemanticService.class)
|
||||
.getEntityInfo(parseInfo, queryReq.getUser());
|
||||
parseInfo.setEntityInfo(entityInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.tencent.supersonic.chat.responder.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.query.QueryManager;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ExplainResp;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ExplainSqlParseResponder implements ParseResponder {
|
||||
|
||||
@Override
|
||||
public void fillResponse(ParseResp parseResp, QueryContext queryContext) {
|
||||
List<SemanticParseInfo> selectedParses = parseResp.getSelectedParses();
|
||||
if (CollectionUtils.isEmpty(selectedParses)) {
|
||||
return;
|
||||
}
|
||||
QueryReq queryReq = queryContext.getRequest();
|
||||
selectedParses.forEach(parseInfo -> {
|
||||
addExplainSql(queryReq, parseInfo);
|
||||
});
|
||||
}
|
||||
|
||||
private void addExplainSql(QueryReq queryReq, SemanticParseInfo parseInfo) {
|
||||
SemanticQuery semanticQuery = QueryManager.createQuery(parseInfo.getQueryMode());
|
||||
if (Objects.isNull(semanticQuery)) {
|
||||
return;
|
||||
}
|
||||
semanticQuery.setParseInfo(parseInfo);
|
||||
ExplainResp explain = semanticQuery.explain(queryReq.getUser());
|
||||
if (Objects.isNull(explain)) {
|
||||
return;
|
||||
}
|
||||
parseInfo.getSqlInfo().setQuerySql(explain.getSql());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.tencent.supersonic.chat.responder.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
|
||||
public interface ParseResponder {
|
||||
|
||||
void fillResponse(ParseResp parseResp, QueryContext queryContext);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.supersonic.chat.responder.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SolvedQueryRecallResp;
|
||||
import com.tencent.supersonic.chat.utils.SolvedQueryManager;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class SolvedQueryParseResponder implements ParseResponder {
|
||||
|
||||
@Override
|
||||
public void fillResponse(ParseResp parseResp, QueryContext queryContext) {
|
||||
SolvedQueryManager solvedQueryManager = ContextUtils.getBean(SolvedQueryManager.class);
|
||||
List<SolvedQueryRecallResp> solvedQueryRecallResps =
|
||||
solvedQueryManager.recallSolvedQuery(queryContext.getRequest().getQueryText(),
|
||||
queryContext.getRequest().getAgentId());
|
||||
parseResp.setSimilarSolvedQuery(solvedQueryRecallResps);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,11 +54,11 @@ public class ChatQueryController {
|
||||
}
|
||||
|
||||
@PostMapping("execute")
|
||||
public Object execute(@RequestBody ExecuteQueryReq queryCtx,
|
||||
public Object execute(@RequestBody ExecuteQueryReq queryReq,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
queryCtx.setUser(UserHolder.findUser(request, response));
|
||||
return queryService.performExecution(queryCtx);
|
||||
queryReq.setUser(UserHolder.findUser(request, response));
|
||||
return queryService.performExecution(queryReq);
|
||||
}
|
||||
|
||||
@PostMapping("queryContext")
|
||||
|
||||
@@ -227,8 +227,8 @@ public class SemanticService {
|
||||
|
||||
QueryResultWithSchemaResp queryResultWithColumns = null;
|
||||
try {
|
||||
queryResultWithColumns = semanticInterpreter.queryByStruct(QueryReqBuilder.buildStructReq(semanticParseInfo),
|
||||
user);
|
||||
queryResultWithColumns = semanticInterpreter.queryByStruct(
|
||||
QueryReqBuilder.buildStructReq(semanticParseInfo), user);
|
||||
} catch (Exception e) {
|
||||
log.warn("setMainModel queryByStruct error, e:", e);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,10 @@ import com.tencent.supersonic.chat.api.pojo.request.DimensionValueReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.SolvedQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryState;
|
||||
import com.tencent.supersonic.chat.parser.llm.dsl.DSLParseResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SolvedQueryRecallResp;
|
||||
import com.tencent.supersonic.chat.persistence.dataobject.ChatParseDO;
|
||||
import com.tencent.supersonic.chat.persistence.dataobject.ChatQueryDO;
|
||||
import com.tencent.supersonic.chat.persistence.dataobject.CostType;
|
||||
@@ -30,15 +28,14 @@ import com.tencent.supersonic.chat.query.QuerySelector;
|
||||
import com.tencent.supersonic.chat.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.query.llm.dsl.DslQuery;
|
||||
import com.tencent.supersonic.chat.query.llm.dsl.LLMResp;
|
||||
import com.tencent.supersonic.chat.queryresponder.QueryResponder;
|
||||
import com.tencent.supersonic.chat.responder.execute.ExecuteResponder;
|
||||
import com.tencent.supersonic.chat.responder.parse.ParseResponder;
|
||||
import com.tencent.supersonic.chat.service.ChatService;
|
||||
import com.tencent.supersonic.chat.service.QueryService;
|
||||
import com.tencent.supersonic.chat.service.SemanticService;
|
||||
import com.tencent.supersonic.chat.service.StatisticsService;
|
||||
import com.tencent.supersonic.chat.utils.ComponentFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ExplainResp;
|
||||
import com.tencent.supersonic.chat.utils.SolvedQueryManager;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.FilterExpression;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||
import java.util.List;
|
||||
@@ -49,10 +46,8 @@ import java.util.HashMap;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
@@ -79,7 +74,7 @@ public class QueryServiceImpl implements QueryService {
|
||||
@Autowired
|
||||
private StatisticsService statisticsService;
|
||||
@Autowired
|
||||
private QueryResponder queryResponder;
|
||||
private SolvedQueryManager solvedQueryManager;
|
||||
|
||||
@Value("${time.threshold: 100}")
|
||||
private Integer timeThreshold;
|
||||
@@ -87,6 +82,8 @@ public class QueryServiceImpl implements QueryService {
|
||||
private List<SchemaMapper> schemaMappers = ComponentFactory.getSchemaMappers();
|
||||
private List<SemanticParser> semanticParsers = ComponentFactory.getSemanticParsers();
|
||||
private QuerySelector querySelector = ComponentFactory.getQuerySelector();
|
||||
private List<ParseResponder> parseResponders = ComponentFactory.getParseResponders();
|
||||
private List<ExecuteResponder> executeResponders = ComponentFactory.getExecuteResponders();
|
||||
|
||||
@Override
|
||||
public ParseResp performParsing(QueryReq queryReq) {
|
||||
@@ -124,17 +121,6 @@ public class QueryServiceImpl implements QueryService {
|
||||
.map(SemanticQuery::getParseInfo)
|
||||
.sorted(Comparator.comparingDouble(SemanticParseInfo::getScore).reversed())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
selectedParses.forEach(parseInfo -> {
|
||||
String queryMode = parseInfo.getQueryMode();
|
||||
if (QueryManager.isEntityQuery(queryMode)) {
|
||||
EntityInfo entityInfo = ContextUtils.getBean(SemanticService.class)
|
||||
.getEntityInfo(parseInfo, queryReq.getUser());
|
||||
parseInfo.setEntityInfo(entityInfo);
|
||||
}
|
||||
addExplainSql(queryReq, parseInfo);
|
||||
|
||||
});
|
||||
List<SemanticParseInfo> candidateParses = queryCtx.getCandidateQueries().stream()
|
||||
.map(SemanticQuery::getParseInfo).collect(Collectors.toList());
|
||||
parseResult = ParseResp.builder()
|
||||
@@ -154,25 +140,12 @@ public class QueryServiceImpl implements QueryService {
|
||||
.state(ParseResp.ParseState.FAILED)
|
||||
.build();
|
||||
}
|
||||
List<SolvedQueryRecallResp> solvedQueryRecallResps =
|
||||
queryResponder.recallSolvedQuery(queryCtx.getRequest().getQueryText(), queryReq.getAgentId());
|
||||
parseResult.setSimilarSolvedQuery(solvedQueryRecallResps);
|
||||
for (ParseResponder parseResponder : parseResponders) {
|
||||
parseResponder.fillResponse(parseResult, queryCtx);
|
||||
}
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
private void addExplainSql(QueryReq queryReq, SemanticParseInfo parseInfo) {
|
||||
SemanticQuery semanticQuery = QueryManager.createQuery(parseInfo.getQueryMode());
|
||||
if (Objects.isNull(semanticQuery)) {
|
||||
return;
|
||||
}
|
||||
semanticQuery.setParseInfo(parseInfo);
|
||||
ExplainResp explain = semanticQuery.explain(queryReq.getUser());
|
||||
if (Objects.isNull(explain)) {
|
||||
return;
|
||||
}
|
||||
parseInfo.getSqlInfo().setQuerySql(explain.getSql());
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResult performExecution(ExecuteQueryReq queryReq) throws Exception {
|
||||
ChatParseDO chatParseDO = chatService.getParseInfo(queryReq.getQueryId(),
|
||||
@@ -202,7 +175,7 @@ public class QueryServiceImpl implements QueryService {
|
||||
if (queryReq.isSaveAnswer() && QueryState.SUCCESS.equals(queryResult.getQueryState())) {
|
||||
chatCtx.setParseInfo(parseInfo);
|
||||
chatService.updateContext(chatCtx);
|
||||
queryResponder.saveSolvedQuery(SolvedQueryReq.builder().parseId(queryReq.getParseId())
|
||||
solvedQueryManager.saveSolvedQuery(SolvedQueryReq.builder().parseId(queryReq.getParseId())
|
||||
.queryId(queryReq.getQueryId())
|
||||
.agentId(chatQueryDO.getAgentId())
|
||||
.modelId(parseInfo.getModelId())
|
||||
@@ -211,6 +184,9 @@ public class QueryServiceImpl implements QueryService {
|
||||
chatCtx.setQueryText(queryReq.getQueryText());
|
||||
chatCtx.setUser(queryReq.getUser().getName());
|
||||
chatService.updateQuery(queryReq.getQueryId(), queryResult, chatCtx);
|
||||
for (ExecuteResponder executeResponder : executeResponders) {
|
||||
executeResponder.fillResponse(queryResult, parseInfo, queryReq);
|
||||
}
|
||||
} else {
|
||||
chatService.deleteChatQuery(queryReq.getQueryId());
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.tencent.supersonic.chat.parser.plugin.function.ModelResolver;
|
||||
import com.tencent.supersonic.chat.parser.llm.dsl.ModelResolver;
|
||||
import com.tencent.supersonic.chat.query.QuerySelector;
|
||||
import com.tencent.supersonic.chat.responder.execute.ExecuteResponder;
|
||||
import com.tencent.supersonic.chat.responder.parse.ParseResponder;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
@@ -18,9 +20,10 @@ public class ComponentFactory {
|
||||
|
||||
private static List<SchemaMapper> schemaMappers = new ArrayList<>();
|
||||
private static List<SemanticParser> semanticParsers = new ArrayList<>();
|
||||
|
||||
private static List<SemanticCorrector> dslCorrections = new ArrayList<>();
|
||||
private static SemanticInterpreter semanticInterpreter;
|
||||
private static List<ParseResponder> parseResponders = new ArrayList<>();
|
||||
private static List<ExecuteResponder> executeResponders = new ArrayList<>();
|
||||
private static QuerySelector querySelector;
|
||||
private static ModelResolver modelResolver;
|
||||
public static List<SchemaMapper> getSchemaMappers() {
|
||||
@@ -35,6 +38,14 @@ public class ComponentFactory {
|
||||
return CollectionUtils.isEmpty(dslCorrections) ? init(SemanticCorrector.class, dslCorrections) : dslCorrections;
|
||||
}
|
||||
|
||||
public static List<ParseResponder> getParseResponders() {
|
||||
return CollectionUtils.isEmpty(parseResponders) ? init(ParseResponder.class, parseResponders) : parseResponders;
|
||||
}
|
||||
|
||||
public static List<ExecuteResponder> getExecuteResponders() {
|
||||
return CollectionUtils.isEmpty(executeResponders)
|
||||
? init(ExecuteResponder.class, executeResponders) : executeResponders;
|
||||
}
|
||||
|
||||
public static SemanticInterpreter getSemanticLayer() {
|
||||
if (Objects.isNull(semanticInterpreter)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.tencent.supersonic.chat.queryresponder;
|
||||
package com.tencent.supersonic.chat.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
@@ -30,20 +30,14 @@ import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DefaultQueryResponder implements QueryResponder {
|
||||
|
||||
public class SolvedQueryManager {
|
||||
|
||||
private EmbeddingConfig embeddingConfig;
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
public DefaultQueryResponder(EmbeddingConfig embeddingConfig,
|
||||
RestTemplate restTemplate) {
|
||||
public SolvedQueryManager(EmbeddingConfig embeddingConfig) {
|
||||
this.embeddingConfig = embeddingConfig;
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveSolvedQuery(SolvedQueryReq solvedQueryReq) {
|
||||
String queryText = solvedQueryReq.getQueryText();
|
||||
try {
|
||||
@@ -62,7 +56,6 @@ public class DefaultQueryResponder implements QueryResponder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SolvedQueryRecallResp> recallSolvedQuery(String queryText, Integer agentId) {
|
||||
List<SolvedQueryRecallResp> solvedQueryRecallResps = Lists.newArrayList();
|
||||
try {
|
||||
@@ -81,6 +74,7 @@ public class DefaultQueryResponder implements QueryResponder {
|
||||
String jsonBody = JSONObject.toJSONString(map, SerializerFeature.WriteMapNullValue);
|
||||
HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);
|
||||
log.info("[embedding] request body:{}, url:{}", jsonBody, url);
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
ResponseEntity<List<EmbeddingResp>> embeddingResponseEntity =
|
||||
restTemplate.exchange(requestUrl, HttpMethod.POST, entity,
|
||||
new ParameterizedTypeReference<List<EmbeddingResp>>() {
|
||||
@@ -100,9 +94,9 @@ public class DefaultQueryResponder implements QueryResponder {
|
||||
}
|
||||
String id = embeddingRetrieval.getId();
|
||||
SolvedQueryRecallResp solvedQueryRecallResp = SolvedQueryRecallResp.builder()
|
||||
.queryText(embeddingRetrieval.getQuery())
|
||||
.queryId(getQueryId(id)).parseId(getParseId(id))
|
||||
.build();
|
||||
.queryText(embeddingRetrieval.getQuery())
|
||||
.queryId(getQueryId(id)).parseId(getParseId(id))
|
||||
.build();
|
||||
solvedQueryRecallResps.add(solvedQueryRecallResp);
|
||||
querySet.add(embeddingRetrieval.getQuery());
|
||||
}
|
||||
@@ -143,6 +137,7 @@ public class DefaultQueryResponder implements QueryResponder {
|
||||
.fromHttpUrl(url).build().encode().toUri();
|
||||
HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);
|
||||
log.info("[embedding] request body :{}, url:{}", jsonBody, url);
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
ResponseEntity<String> responseEntity = restTemplate.exchange(requestUrl,
|
||||
HttpMethod.POST, entity, new ParameterizedTypeReference<String>() {});
|
||||
log.info("[embedding] result body:{}", responseEntity);
|
||||
@@ -152,4 +147,5 @@ public class DefaultQueryResponder implements QueryResponder {
|
||||
}
|
||||
return ResponseEntity.of(Optional.empty());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.tencent.supersonic.chat.api.component.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.config.DefaultMetric;
|
||||
@@ -41,7 +40,7 @@ public class MockBeansConfiguration {
|
||||
when(chatService.getOrCreateContext(1)).thenReturn(context);
|
||||
}
|
||||
|
||||
public static void buildHttpSemanticServiceImpl(SemanticInterpreter httpSemanticInterpreter, List<DimSchemaResp> dimensionDescs,
|
||||
public static void buildHttpSemanticServiceImpl(List<DimSchemaResp> dimensionDescs,
|
||||
List<MetricSchemaResp> metricDescs) {
|
||||
DefaultMetric defaultMetricDesc = new DefaultMetric();
|
||||
defaultMetricDesc.setUnit(3);
|
||||
|
||||
@@ -20,8 +20,8 @@ com.tencent.supersonic.chat.api.component.SemanticInterpreter=\
|
||||
com.tencent.supersonic.chat.query.QuerySelector=\
|
||||
com.tencent.supersonic.chat.query.HeuristicQuerySelector
|
||||
|
||||
com.tencent.supersonic.chat.parser.plugin.function.ModelResolver=\
|
||||
com.tencent.supersonic.chat.parser.plugin.function.HeuristicModelResolver
|
||||
com.tencent.supersonic.chat.parser.llm.dsl.ModelResolver=\
|
||||
com.tencent.supersonic.chat.parser.llm.dsl.HeuristicModelResolver
|
||||
|
||||
com.tencent.supersonic.auth.authentication.interceptor.AuthenticationInterceptor=\
|
||||
com.tencent.supersonic.auth.authentication.interceptor.DefaultAuthenticationInterceptor
|
||||
@@ -36,4 +36,12 @@ com.tencent.supersonic.chat.api.component.SemanticCorrector=\
|
||||
com.tencent.supersonic.chat.corrector.WhereCorrector, \
|
||||
com.tencent.supersonic.chat.corrector.GroupByCorrector, \
|
||||
com.tencent.supersonic.chat.corrector.HavingCorrector, \
|
||||
com.tencent.supersonic.chat.corrector.GlobalAfterCorrector
|
||||
com.tencent.supersonic.chat.corrector.GlobalAfterCorrector
|
||||
|
||||
com.tencent.supersonic.chat.responder.parse.ParseResponder=\
|
||||
com.tencent.supersonic.chat.responder.parse.EntityInfoParseResponder, \
|
||||
com.tencent.supersonic.chat.responder.parse.ExplainSqlParseResponder, \
|
||||
com.tencent.supersonic.chat.responder.parse.SolvedQueryParseResponder
|
||||
|
||||
com.tencent.supersonic.chat.responder.execute.ExecuteResponder=\
|
||||
com.tencent.supersonic.chat.responder.execute.EntityInfoExecuteResponder
|
||||
@@ -21,8 +21,8 @@ com.tencent.supersonic.chat.api.component.SemanticInterpreter=\
|
||||
com.tencent.supersonic.chat.query.QuerySelector=\
|
||||
com.tencent.supersonic.chat.query.HeuristicQuerySelector
|
||||
|
||||
com.tencent.supersonic.chat.parser.plugin.function.ModelResolver=\
|
||||
com.tencent.supersonic.chat.parser.plugin.function.HeuristicModelResolver
|
||||
com.tencent.supersonic.chat.parser.llm.dsl.ModelResolver=\
|
||||
com.tencent.supersonic.chat.parser.llm.dsl.HeuristicModelResolver
|
||||
|
||||
com.tencent.supersonic.auth.authentication.interceptor.AuthenticationInterceptor=\
|
||||
com.tencent.supersonic.auth.authentication.interceptor.DefaultAuthenticationInterceptor
|
||||
@@ -36,4 +36,12 @@ com.tencent.supersonic.chat.api.component.SemanticCorrector=\
|
||||
com.tencent.supersonic.chat.corrector.WhereCorrector, \
|
||||
com.tencent.supersonic.chat.corrector.GroupByCorrector, \
|
||||
com.tencent.supersonic.chat.corrector.HavingCorrector, \
|
||||
com.tencent.supersonic.chat.corrector.GlobalAfterCorrector
|
||||
com.tencent.supersonic.chat.corrector.GlobalAfterCorrector
|
||||
|
||||
com.tencent.supersonic.chat.responder.parse.ParseResponder=\
|
||||
com.tencent.supersonic.chat.responder.parse.EntityInfoParseResponder, \
|
||||
com.tencent.supersonic.chat.responder.parse.ExplainSqlParseResponder, \
|
||||
com.tencent.supersonic.chat.responder.parse.SolvedQueryParseResponder
|
||||
|
||||
com.tencent.supersonic.chat.responder.execute.ExecuteResponder=\
|
||||
com.tencent.supersonic.chat.responder.execute.EntityInfoExecuteResponder
|
||||
Reference in New Issue
Block a user