├── .gitignore
├── README.md
├── chat_rest
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── am
│ │ └── chat
│ │ └── bi
│ │ ├── ChatBIApplication.java
│ │ ├── comm
│ │ ├── AppCode.java
│ │ ├── ErrorCode.java
│ │ ├── Result.java
│ │ ├── ResultMeta.java
│ │ ├── StateCode.java
│ │ └── Utils.java
│ │ ├── config
│ │ └── SwaggerConfiguration.java
│ │ ├── controller
│ │ └── LLMsController.java
│ │ ├── domain
│ │ ├── dao
│ │ │ └── SchemaMetaInfo.java
│ │ └── vo
│ │ │ └── ResponseVo.java
│ │ └── service
│ │ ├── LLMsService.java
│ │ └── impl
│ │ └── LLMsServiceImpl.java
│ ├── resources
│ ├── application-dev.yml
│ ├── application.yml
│ ├── assembly.xml
│ ├── dev
│ │ └── setenv.sh
│ ├── logback-dev.xml
│ ├── logback.xml
│ ├── press
│ │ └── setenv.sh
│ ├── prod
│ │ └── setenv.sh
│ ├── sql
│ │ └── mysql.sql
│ └── test
│ │ └── setenv.sh
│ └── shell
│ ├── comm.sh
│ ├── start.sh
│ └── stop.sh
├── chat_ui
└── pom.xml
├── doc
└── photo
│ ├── 模块架构.jpeg
│ └── 自动生成图表.png
├── plugins
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── am
│ └── chat
│ └── bi
│ └── utils
│ ├── AliLLMsUtil.java
│ ├── LLMsResultUtil.java
│ └── PromptUtil.java
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | target
3 | *.iml
4 | .DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | 自定义BI改变了传统IT主导开发固定报表的时代,让数据能够即席分析达到所见即所得,随着大模型的兴起与火热,LLMs 结合数据可视化技术,通过问答的方式能够让系统智能与数据交互与生成图表,无论是BI copilot还是ChatBI, 除了替代之前小助手功能只能查询已有报表数据外,更多的是省略创建dashboard的时候图表的拖拉拽操作,让系统自动生成的图表能够在dashboard中布局应用。
3 | 
4 |
5 | #### 一、实现思路主要考虑
6 |
7 | 1、如果没有大模型或者大模型服务宕机,自动化生成可视化工程化就不能实现?
8 |
9 | —— 直接解耦,大模型不能影响主体工程,图表这块不能大模型生成。
10 |
11 | 2、如果大模型正常服务能够推理,是否所有的问答都要经过推理服务?
12 |
13 | —— 大模型的推理是否那么靠谱稳定、对应响应的耗时以及对应采用商业大模型服务的费用成本因素。
14 |
15 | 3、以SQL交互为核心的配套组件,通过系统化的工程来达到生产可用要求。
16 |
17 | 借鉴[SQLChat](https://github.com/sqlchat/sqlchat), [DB-GPT](https://github.com/csunny/DB-GPT), 的开源项目思路,确定以SQL生成为核心,和数据库交互获取数据,通过data + 可视化图表组件方式实现。不考虑大模型自动生成图表的方式,主要考虑一是美观,二是灵活性,三最主要的是性能是否可控,尤其是大量查询的data很大时,是否分页等可以手动人为干预控制;而靠大模型自动生成图表类似markdown/html估计不会很理想。
18 |
19 |
20 | #### 二、主要思路框架
21 | 
22 |
23 | #### 三、说明
24 | 1、是否有表,指标字段,维度字段列级的查询权限,以及行级 ${input_dim_conditions} <= ${user_has_permission},否直接报权限不足。
25 |
26 | 2、如果维度、度量,都来自于一张表,解析查询条件,然后sql模版组装:
27 | ```sql
28 | select ${input_dim_names} , ${input_metric_names} from ${get_meta_table_name} where ${input_dim_conditions} [group by $s] [order by $s];
29 | ```
30 | 这种sql组装拼接成熟度很高,不一定直接依赖大模型服务,唯一有难点的就是文本中对应条件的解析。
31 |
32 | 3、 如果维度、度量都来自于多张表,则查找相似匹配的问题对应的答案Sql:
33 |
34 | ①、如果有对应sql, 则直接应用,可能只组装的就是sql的where条件。
35 |
36 | ②、如果有相似sql, 例如2张表的join找2张表join的sql模版则对应需要增加子查询方式与拼接where, 即
37 | ```sql
38 | select ${input_dim_names} , ${input_metric_names} from ( ${get_query_sql} ) TT where ${input_dim_conditions} [group by $s] [order by $s];
39 | ```
40 |
41 | **属于可选步骤(也可以直接调用大模型能力)**,这里where一般可以,sql引擎都支持谓词下推,但是子查询多列可能带来性能影响,不是所有的sql引擎都支持列剪裁。 同时注意相似如果是2张表join,则不能找3张表join的sql语句去拼接。
42 |
43 | ③、如果sql为null或者校验error的sql, 则通过提示词(问题、schema)交给大模型推理返回推理生成查询sql。
44 |
45 | 整体框架可能存在不足,但是相信随着时间的进步,大模型会越来越稳定可靠,响应快 以及细分领域SQL LLMs的诞生;也相信利他主义的开源者,会诞生更优秀的ChatBI项目。
46 | #### 四、模块结构
47 |
48 | |--rest api层
49 |
50 | |-- server 服务层,调用解析,执行sql,和数据库交互
51 |
52 | |-- mapper 元数据匹配
53 |
54 | |--validate sql校验
55 |
56 | |--common
57 |
58 | |--parse 文本解析
59 |
60 | |--plugins 大模型插件,和大模型交互,智能生成
61 |
--------------------------------------------------------------------------------
/chat_rest/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | chatBI
7 | com.am
8 | 1.0-SNAPSHOT
9 |
10 |
11 | 4.0.0
12 |
13 | chat_rest
14 |
15 |
16 |
17 | org.springframework.boot
18 | spring-boot-starter
19 |
20 |
21 | logback-classic
22 | ch.qos.logback
23 |
24 |
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 |
32 | org.springframework
33 | spring-context-support
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-websocket
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-configuration-processor
44 | true
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-test
50 | test
51 |
52 |
53 |
54 | io.springfox
55 | springfox-swagger2
56 |
57 |
58 |
59 | io.springfox
60 | springfox-swagger-ui
61 |
62 |
63 |
64 | com.github.pagehelper
65 | pagehelper-spring-boot-starter
66 |
67 |
68 | mybatis-spring-boot-starter
69 | org.mybatis.spring.boot
70 |
71 |
72 |
73 |
74 |
75 | org.mybatis.spring.boot
76 | mybatis-spring-boot-starter
77 |
78 |
79 | org.springframework.boot
80 | spring-boot-starter
81 |
82 |
83 |
84 |
85 |
86 | com.alibaba
87 | druid-spring-boot-starter
88 |
89 |
90 |
91 | mysql
92 | mysql-connector-java
93 | runtime
94 |
95 |
96 |
97 | org.mybatis.spring.boot
98 | mybatis-spring-boot-starter-test
99 |
100 |
101 |
102 |
103 | org.projectlombok
104 | lombok
105 |
106 |
107 |
108 | org.apache.commons
109 | commons-lang3
110 |
111 |
112 |
113 | ch.qos.logback
114 | logback-classic
115 |
116 |
117 | logback-core
118 | ch.qos.logback
119 |
120 |
121 |
122 |
123 | ch.qos.logback
124 | logback-core
125 |
126 |
127 |
128 | redis.clients
129 | jedis
130 |
131 |
132 |
133 | com.google.code.gson
134 | gson
135 |
136 |
137 |
138 | com.am
139 | plugins
140 | compile
141 | 1.0-SNAPSHOT
142 |
143 |
144 |
145 |
146 |
147 | dev
148 |
149 | dev
150 |
151 |
152 | true
153 |
154 |
155 |
156 | test
157 |
158 | test
159 |
160 |
161 |
162 | prod
163 |
164 | prod
165 |
166 |
167 |
168 | press
169 |
170 | press
171 |
172 |
173 |
174 |
175 |
176 | ${project.artifactId}
177 | src/main/java
178 | src/main/shell
179 |
180 |
181 | src/main/resources
182 |
183 | *.xml
184 | **/*.xml
185 | *.yml
186 | static/
187 | templates/
188 | mapper/
189 |
190 |
191 |
192 |
193 |
194 |
195 | org.mybatis.generator
196 | mybatis-generator-maven-plugin
197 | 1.3.2
198 |
199 |
200 | mysql
201 | mysql-connector-java
202 | 5.1.38
203 |
204 |
205 |
206 |
207 | Generate MyBatis Artifacts
208 | none
209 |
210 | generate
211 |
212 |
213 |
214 |
215 |
216 | src/main/resources/generatorConfig.xml
217 | true
218 |
219 |
220 |
221 |
222 | org.apache.maven.plugins
223 | maven-jar-plugin
224 | 3.0.2
225 |
226 |
227 |
228 | false
229 |
230 |
231 | true
232 | lib/
233 | ${start-class}
234 |
235 |
236 |
237 | config/
238 |
239 |
240 |
241 | *.xml
242 | *.conf
243 | *.yml
244 | *.properties
245 |
246 |
247 |
248 |
249 | org.apache.maven.plugins
250 | maven-assembly-plugin
251 |
252 |
253 | src/main/resources/assembly.xml
254 |
255 | false
256 |
257 |
258 |
259 | make-assembly
260 | package
261 |
262 | single
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/ChatBIApplication.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.boot.web.servlet.ServletComponentScan;
9 |
10 | @SpringBootApplication
11 | @ServletComponentScan
12 | @MapperScan(basePackages = { "com.am.chat.bi.dao" })
13 | public class ChatBIApplication {
14 | private static final Logger LOG = LoggerFactory.getLogger(ChatBIApplication.class);
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(ChatBIApplication.class, args);
18 | LOG.info("ChatBIApplication start run!");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/comm/AppCode.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.comm;
2 |
3 | /**
4 | * @author wpl
5 | * 后期数据库配置
6 | */
7 | public enum AppCode {
8 | VSKIT(1, "vskit")
9 | ;
10 | private int code;
11 | private String appName;
12 |
13 | AppCode(int code, String appName) {
14 | this.code = code;
15 | this.appName = appName;
16 | }
17 |
18 | public int getCode() {
19 | return code;
20 | }
21 |
22 | public String getAppName() {
23 | return appName;
24 | }
25 |
26 | public static String getAppName(int code) {
27 | switch (code){
28 | case 1:
29 | case 2:
30 | default:
31 | return VSKIT.getAppName();
32 | }
33 | }
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/comm/ErrorCode.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.comm;
2 |
3 | /**
4 | * @author wpl
5 | */
6 | public enum ErrorCode {
7 | SUCCESS(1000, "success"),
8 | FAIL(1010, "fail"),
9 | FAIL_LLMs(1020, "fail LLMs"),
10 | FAIL_INSERT(1001, "fail insert"),
11 | FAIL_UPDATE(1002, "fail update"),
12 | FAIL_SELECT(1003, "fail select"),
13 | FAIL_UPLOAD(1004, "fail upload"),
14 | FAIL_EXPORT(1005, "fail export"),
15 | FAIL_DEL(1006, "fail delete"),
16 | FAIL_RUN_TASK(1007, "fail run task"),
17 | ;
18 |
19 | private int code;
20 | private String msg;
21 |
22 | ErrorCode(int code, String msg) {
23 | this.code = code;
24 | this.msg = msg;
25 | }
26 |
27 | public int getCode() {
28 | return code;
29 | }
30 |
31 | public String getMsg() {
32 | return msg;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/comm/Result.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.comm;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import org.apache.commons.lang3.builder.ToStringBuilder;
7 | import org.apache.commons.lang3.builder.ToStringStyle;
8 |
9 | /**
10 | * @author wpl
11 | */
12 | @Data
13 | @ApiModel
14 | public class Result {
15 |
16 | @ApiModelProperty(value = "元数据", required = true)
17 | private ResultMeta meta;
18 |
19 | @ApiModelProperty(value = "返回结果")
20 | private T response;
21 |
22 | public Result() {}
23 |
24 | private Result(ErrorCode errorCode) {
25 | this.meta = new ResultMeta(errorCode);
26 | }
27 |
28 | public static Result success() {
29 | return new Result<>(ErrorCode.SUCCESS);
30 | }
31 |
32 | public static Result fail(ErrorCode errorCode) {
33 | return new Result<>(errorCode);
34 | }
35 |
36 | public static boolean isSuccess(Result result) {
37 | return result != null && result.meta != null && result.meta.getCode() == 0;
38 | }
39 |
40 | public Result withErrorMsg(String msg) {
41 | this.meta.setMsg(msg);
42 | return this;
43 | }
44 |
45 | public Result withResponse(T response) {
46 | this.response = response;
47 | return this;
48 | }
49 |
50 | @Override
51 | public String toString() {
52 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/comm/ResultMeta.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.comm;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 |
7 | /**
8 | * @Author: wpl
9 | */
10 | @Data
11 | @ApiModel
12 | public class ResultMeta {
13 |
14 | @ApiModelProperty(value = "错误码", required = true)
15 | private int code;
16 | @ApiModelProperty(value = "描述", required = true)
17 | private String msg;
18 |
19 | public ResultMeta() {}
20 |
21 | public ResultMeta(ErrorCode errorCode) {
22 | this.code = errorCode.getCode();
23 | this.msg = errorCode.getMsg();
24 | }
25 |
26 | void setMsg(String msg) {
27 | this.msg = this.msg + " : " + msg;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/comm/StateCode.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.comm;
2 |
3 | /**
4 | * @author wpl
5 | */
6 | public enum StateCode {
7 | IS_ADD(0),
8 | IS_UPDATE(1),
9 | IS_DEL(2)
10 | ;
11 |
12 | private Integer code;
13 | StateCode(Integer code) {
14 | this.code = code;
15 | }
16 |
17 | public static StateCode getStateCode(Integer code) {
18 | switch (code){
19 | case 1:
20 | return IS_UPDATE;
21 | case 2:
22 | return IS_DEL;
23 | default:
24 | return IS_ADD;
25 | }
26 | }
27 |
28 | public Integer getCode() {
29 | return code;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/comm/Utils.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.comm;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.text.ParseException;
8 | import java.text.SimpleDateFormat;
9 | import java.util.Date;
10 | import java.util.concurrent.atomic.AtomicLong;
11 |
12 | public class Utils {
13 | private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
14 | public static String getStringDate(Date date) {
15 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
16 | String dateString = formatter.format(date);
17 | return dateString;
18 | }
19 |
20 | public static Date getStringToDate(String date) {
21 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
22 | try {
23 | Date result = formatter.parse(date);
24 | return result;
25 | } catch (ParseException e) {
26 | e.printStackTrace();
27 | LOG.error("string date 解析出错", e);
28 | }
29 | return null;
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/config/SwaggerConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import springfox.documentation.builders.ApiInfoBuilder;
7 | import springfox.documentation.builders.PathSelectors;
8 | import springfox.documentation.builders.RequestHandlerSelectors;
9 | import springfox.documentation.service.ApiInfo;
10 | import springfox.documentation.spi.DocumentationType;
11 | import springfox.documentation.spring.web.plugins.Docket;
12 | import springfox.documentation.swagger2.annotations.EnableSwagger2;
13 |
14 |
15 | /**
16 | * @author wpl
17 | */
18 | @EnableSwagger2
19 | @Configuration
20 | public class SwaggerConfiguration {
21 | @Value("${com.am.chat.bi.api.doc.path:com.am.chat.bi}")
22 | private String path;
23 |
24 | @Value("${com.am.chat.bi.api.doc.title:Chat BI Platform API doc}")
25 | private String title;
26 |
27 | @Value("${com.am.chat.bi.api.doc.version:1.0}")
28 | private String version;
29 |
30 | @Value("${com.am.chat.bi.api.doc.description:Chat BI Platform API doc}")
31 | private String description;
32 |
33 | @Bean
34 | public Docket createApi() {
35 | return new Docket(DocumentationType.SWAGGER_2)
36 | .apiInfo(apiInfo())
37 | .pathMapping("/")
38 | .select()
39 | .apis(RequestHandlerSelectors.basePackage(path))
40 | .paths(PathSelectors.any())
41 | .build();
42 | }
43 |
44 | private ApiInfo apiInfo() {
45 | return new ApiInfoBuilder()
46 | .title(title)
47 | .description(description)
48 | .version(version)
49 | .build();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/controller/LLMsController.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.controller;
2 |
3 |
4 | import com.am.chat.bi.comm.Result;
5 | import com.am.chat.bi.service.LLMsService;
6 | import io.swagger.annotations.Api;
7 | import io.swagger.annotations.ApiOperation;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.MediaType;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.web.bind.annotation.PostMapping;
13 | import org.springframework.web.bind.annotation.RequestBody;
14 | import org.springframework.web.bind.annotation.RequestMapping;
15 | import org.springframework.web.bind.annotation.RestController;
16 |
17 | @RestController
18 | @RequestMapping("/chat")
19 | @Api(value = "大模型服务", description = "大模型服务", tags = {"LLMs APIß"})
20 | public class LLMsController {
21 |
22 | @Autowired
23 | LLMsService llMsService;
24 |
25 | @PostMapping(value = "/intention", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
26 | @ApiOperation(value = "查询意图", notes = "查询意图", response = Result.class)
27 | public ResponseEntity> intention(@RequestBody String queryContent) {
28 | Result result = llMsService.getIntention(queryContent);
29 | return new ResponseEntity<>(result, HttpStatus.OK);
30 | }
31 |
32 | @PostMapping(value = "/dimMetrics", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
33 | @ApiOperation(value = "查询维度指标", notes = "查询维度指标", response = Result.class)
34 | public ResponseEntity> dimMetrics(@RequestBody String queryContent) {
35 | Result result = llMsService.getDimMetric(queryContent);
36 | return new ResponseEntity<>(result, HttpStatus.OK);
37 | }
38 |
39 | @PostMapping(value = "/querySql", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
40 | @ApiOperation(value = "生成查询sql", notes = "生成查询sql", response = Result.class)
41 | public ResponseEntity> querySql(@RequestBody String queryContent) {
42 | Result result = llMsService.getSql(queryContent);
43 | return new ResponseEntity<>(result, HttpStatus.OK);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/domain/dao/SchemaMetaInfo.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.domain.dao;
2 |
3 | public class SchemaMetaInfo {
4 | }
5 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/domain/vo/ResponseVo.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.domain.vo;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author wpl
7 | * @param
8 | */
9 | @Data
10 | public class ResponseVo {
11 | //返回插入或者修改的主键id
12 | private String name;
13 | private T value;
14 | }
15 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/service/LLMsService.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.service;
2 |
3 | import com.am.chat.bi.comm.Result;
4 |
5 | public interface LLMsService {
6 | Result getIntention(String queryContent);
7 | Result getDimMetric(String queryContent);
8 | Result getSql(String queryContent);
9 | }
10 |
--------------------------------------------------------------------------------
/chat_rest/src/main/java/com/am/chat/bi/service/impl/LLMsServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.service.impl;
2 |
3 | import com.am.chat.bi.comm.ErrorCode;
4 | import com.am.chat.bi.comm.Result;
5 | import com.am.chat.bi.domain.vo.ResponseVo;
6 | import com.am.chat.bi.service.LLMsService;
7 | import com.am.chat.bi.utils.AliLLMsUtil;
8 | import com.am.chat.bi.utils.LLMsResultUtil;
9 | import com.am.chat.bi.utils.PromptUtil;
10 | import com.google.gson.JsonElement;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.stereotype.Service;
14 |
15 | @Service
16 | public class LLMsServiceImpl implements LLMsService {
17 |
18 | private static final Logger LOG = LoggerFactory.getLogger(LLMsServiceImpl.class);
19 |
20 | @Override
21 | public Result getIntention(String queryContent) {
22 | LOG.info("chat query content: {}", queryContent);
23 | try {
24 | String intentionPrompt = PromptUtil.getIntentionPrompt(queryContent);
25 | String intentionResult = AliLLMsUtil.getResult(intentionPrompt);
26 | String result = LLMsResultUtil.getIntentionResult(intentionResult);
27 |
28 | ResponseVo responseVo = new ResponseVo();
29 | responseVo.setName("result");
30 | responseVo.setValue(result);
31 |
32 | return Result.success().withResponse(responseVo);
33 | } catch (Exception e) {
34 | LOG.error("用户查询意图大模型结果判断异常:", e);
35 | return Result.fail(ErrorCode.FAIL_LLMs).withErrorMsg(e.getMessage());
36 | }
37 | }
38 |
39 | @Override
40 | public Result getDimMetric(String queryContent) {
41 | LOG.info("chat query content: {}", queryContent);
42 | try {
43 | String dimensionMetricPrompt = PromptUtil.getDimensionMetricPrompt(queryContent);
44 | String dimensionMetricResult = AliLLMsUtil.getResult(dimensionMetricPrompt);
45 |
46 | String dimMetricJson = LLMsResultUtil.getDimMetricJson(dimensionMetricResult);
47 |
48 | JsonElement dimensions = LLMsResultUtil.getJsonValue(dimMetricJson, "dimensions");
49 | JsonElement metrics = LLMsResultUtil.getJsonValue(dimMetricJson, "metrics");
50 |
51 | ResponseVo responseVo = new ResponseVo();
52 | responseVo.setName("dimensions");
53 | responseVo.setValue(dimensions);
54 |
55 | responseVo.setName("metrics");
56 | responseVo.setValue(metrics);
57 | return Result.success().withResponse(responseVo);
58 | } catch (Exception e) {
59 | LOG.error("用户查询大模型维度指标解析异常:", e);
60 | return Result.fail(ErrorCode.FAIL_LLMs).withErrorMsg(e.getMessage());
61 | }
62 | }
63 |
64 | @Override
65 | public Result getSql(String queryContent) {
66 | LOG.info("chat query content: {}", queryContent);
67 | try {
68 | //TODO: 待补充数据库类型,基于解析的元数据信息
69 | String schemaInfo = "{\n" +
70 | " \"schema\":\"report_db\",\n" +
71 | " \"tables\":[\n" +
72 | " \"dim_table\",\n" +
73 | " \"metric_table\"\n" +
74 | " ],\n" +
75 | " \"dim_table\":[\n" +
76 | " {\n" +
77 | " \"dim_date\":\"date\",\n" +
78 | " \"dim_app_id\":\"int\",\n" +
79 | " \"dim_app_name\":\"varchar\"\n" +
80 | " },\n" +
81 | " {\n" +
82 | " \"count_date\":\"date\",\n" +
83 | " \"app_id\":\"int\",\n" +
84 | " \"app_pv\":\"bigint\",\n" +
85 | " \"app_uv\":\"bigint\"\n" +
86 | " }\n" +
87 | " ]\n" +
88 | "}";
89 |
90 | String sqlPrompt = PromptUtil.getSqlPrompt(queryContent,"postgresql",schemaInfo, null);
91 | LOG.info("LLMs sql prompt content: {}", sqlPrompt);
92 | String sqlResult = AliLLMsUtil.getResult(sqlPrompt);
93 | String result = LLMsResultUtil.getSqlResult(sqlResult);
94 |
95 | ResponseVo responseVo = new ResponseVo();
96 | responseVo.setName("result");
97 | responseVo.setValue(result);
98 |
99 | return Result.success().withResponse(responseVo);
100 | } catch (Exception e) {
101 | LOG.error("用户查询大模型生成sql异常:", e);
102 | return Result.fail(ErrorCode.FAIL_LLMs).withErrorMsg(e.getMessage());
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/application-dev.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8498
3 |
4 | security:
5 | basic:
6 | enabled=false:
7 |
8 | spring:
9 | datasource:
10 | name: dev
11 | url: jdbc:mysql://127.0.0.1:3306/chat_bi?characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
12 | username: root
13 | password: 123456
14 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | context-path: /chatBI
3 | tomcat:
4 | accesslog:
5 | enabled: false
6 | buffered: false
7 | directory:
8 | pattern: common
9 | awaitTerminationInSec: 30
10 |
11 | spring:
12 | profiles:
13 | ## dev, test, prod
14 | active: dev
15 | datasource:
16 | type: com.alibaba.druid.pool.DruidDataSource
17 | driver-class-name: com.mysql.jdbc.Driver
18 | druid:
19 | filters:
20 | # 初始化大小,最小,最大
21 | initial-size: 1
22 | max-active: 20
23 | min-idle: 1
24 | # 配置获取连接等待超时的时间
25 | max-wait: 5000
26 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
27 | time-between-eviction-runs-millis: 60000
28 | # 配置一个连接在池中最小生存的时间,单位是毫秒
29 | min-evictable-idle-time-millis: 30000
30 | validation-query: select 'x'
31 | test-while-idle: true
32 | test-on-borrow: false
33 | test-on-return: false
34 | pool-prepared-statements: true
35 | max-open-prepared-statements: 20
36 | # 配置监控页面密码登录
37 | # stat-view-servlet:
38 | # login-password: druid
39 | # login-username: druid
40 | http:
41 | multipart:
42 | max-file-size: 1024MB
43 | max-request-size: 1024MB
44 |
45 | mybatis:
46 | mapperLocations: classpath:mapper/*.xml
47 | configuration:
48 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
49 |
50 | pagehelper:
51 | helperDialect: mysql
52 | reasonable: true
53 |
54 | management:
55 | health:
56 | redis:
57 | enabled: false
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/assembly.xml:
--------------------------------------------------------------------------------
1 |
5 | ${project.version}
6 |
7 |
8 | tar.gz
9 |
10 |
11 | true
12 |
13 |
14 |
15 |
16 |
17 |
18 | lib
19 | false
20 |
21 |
22 |
23 |
24 |
25 |
26 | ${project.basedir}
27 | /
28 |
29 | README*
30 | LICENSE*
31 | NOTICE*
32 |
33 |
34 |
35 |
36 |
37 | src/main/resources
38 | config/
39 |
40 |
41 | *.xml
42 | *.yml
43 | static/
44 | templates/
45 | mapper/
46 |
47 |
48 | logback-test.xml
49 | generatorConfig.xml
50 | application-*.yml
51 |
52 |
53 |
54 |
55 | src/main/resources
56 | config/
57 |
58 | application-${env}.yml
59 |
60 |
61 |
62 |
63 |
64 | ${project.build.scriptSourceDirectory}
65 | bin
66 |
67 | *.*
68 |
69 | true
70 | 0755
71 |
72 |
73 |
74 | src/main/resources/${env}
75 | bin
76 |
77 | setenv.sh
78 |
79 |
80 |
81 |
82 |
83 | ${project.build.directory}
84 |
85 |
86 | *.jar
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/dev/setenv.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PRG="$0"
3 | PRGDIR=`dirname "$PRG"`
4 | BASE_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
5 |
6 | #server内存配置
7 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -server -Xms1G -Xmx1G -Xmn512M -XX:PermSize=128M -XX:MaxPermSize=256M -Xss512k -XX:SurvivorRatio=8"
8 |
9 | #gc
10 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent -XX:+CMSScavengeBeforeRemark"
11 |
12 | #gc日志
13 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \
14 | -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1"
15 |
16 | #内存溢出
17 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof"
18 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/logback-dev.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | UTF-8
9 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | UTF-8
9 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
10 |
11 |
12 |
13 |
14 |
15 |
16 | INFO
17 |
18 |
19 | DEBUG
20 |
21 |
22 |
23 |
24 | ${log.home}/label_%d{yyyy-MM-dd}_%i.log
25 |
26 | 100MB
27 | 7
28 | 10GB
29 |
30 |
31 | UTF-8
32 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/press/setenv.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PRG="$0"
3 | PRGDIR=`dirname "$PRG"`
4 | BASE_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
5 |
6 | #server内存配置
7 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -server -Xms4G -Xmx4G -Xmn2G -XX:PermSize=256M -XX:MaxPermSize=512M -Xss1M -XX:SurvivorRatio=8"
8 |
9 | #gc
10 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent -XX:+CMSScavengeBeforeRemark"
11 |
12 | #gc日志
13 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \
14 | -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1"
15 |
16 | #内存溢出
17 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof"
18 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/prod/setenv.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PRG="$0"
3 | PRGDIR=`dirname "$PRG"`
4 | BASE_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
5 |
6 | #server内存配置
7 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -server -Xms4G -Xmx4G -Xmn2G -XX:PermSize=256M -XX:MaxPermSize=512M -Xss1M -XX:SurvivorRatio=8"
8 |
9 | #gc
10 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent -XX:+CMSScavengeBeforeRemark"
11 |
12 | #gc日志
13 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \
14 | -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1"
15 |
16 | #内存溢出
17 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof"
18 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/sql/mysql.sql:
--------------------------------------------------------------------------------
1 | USE chat_bi;
2 | DROP TABLE IF EXISTS `scheam_meta_info`;
3 | CREATE TABLE `scheam_meta_info` (
4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
5 | `meta_name` varchar(64) NOT NULL COMMENT '维度,指标名称',
6 | `meta_zh_name` varchar(128) NOT NULL COMMENT '维度,指标中文名称',
7 | `meta_type` int(1) NOT NULL DEFAULT '1' COMMENT '维度1,指标2',
8 | `meta_expression` varchar(128) DEFAULT NULL COMMENT '维度,指标表达式',
9 | `meta_table_name` varchar(64) DEFAULT NULL COMMENT '维度,指标来源表名称',
10 | `meta_state` int(1) NOT NULL DEFAULT '0' COMMENT '操作类型,0:新增,1:更新,2:删除',
11 | `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
12 | `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
13 | PRIMARY KEY (`id`)
14 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='维度指标元数据信息表';
15 |
--------------------------------------------------------------------------------
/chat_rest/src/main/resources/test/setenv.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PRG="$0"
3 | PRGDIR=`dirname "$PRG"`
4 | BASE_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
5 |
6 | #server内存配置
7 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -d64 -server -Xms4G -Xmx4G -Xmn2G -XX:PermSize=256M -XX:MaxPermSize=512M -Xss1M -XX:SurvivorRatio=8"
8 |
9 | #gc
10 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent -XX:+CMSScavengeBeforeRemark"
11 |
12 | #gc日志
13 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \
14 | -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1"
15 |
16 | #内存溢出
17 | export JAVA_MEM_OPTS="$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof"
18 |
--------------------------------------------------------------------------------
/chat_rest/src/main/shell/comm.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # resolve links - $0 may be a softlink
4 | PRG="$0"
5 |
6 | while [ -h "$PRG" ]; do
7 | ls=`ls -ld "$PRG"`
8 | link=`expr "$ls" : '.*-> \(.*\)$'`
9 | if expr "$link" : '/.*' > /dev/null; then
10 | PRG="$link"
11 | else
12 | PRG=`dirname "$PRG"`/"$link"
13 | fi
14 | done
15 |
16 | COMMAND="$1"
17 |
18 | # Get standard environment variables
19 | PRG_DIR=`dirname "$PRG"`
20 | PLATFORM_HOME=`cd "$PRG_DIR/.." >/dev/null; pwd`
21 | export PLATFORM_HOME
22 |
23 | PLATFORM_CONF_DIR="$PLATFORM_HOME/config"
24 | PLATFORM_LIB_DIR="$PLATFORM_HOME/lib"
25 | export PLATFORM_LIB_DIR
26 |
27 | LIB_JARS=`ls $PLATFORM_LIB_DIR | grep -E '.jar$' | awk '{print "'$PLATFORM_LIB_DIR'/"$0}' | tr "\n" ":"`
28 |
29 | PRO_NAME=${project.artifactId}
30 | PIDFILE="$PLATFORM_HOME/$(basename $PRO_NAME).pid"
31 | PID=0
32 | if [[ -f $PIDFILE ]]; then
33 | PID=`cat $PIDFILE`
34 | fi
35 |
36 | JAVA_OPTS=""
37 | JAVA_MEM_OPTS=""
38 | JAVA_SPRING_OPTS=" --spring.profiles.active=${env}"
39 |
40 | PLATFORM_MAIN_CLASS=${start-class}
41 |
42 |
43 | running() {
44 | if [[ -z $1 || $1 == 0 ]]; then
45 | echo 0
46 | return
47 | fi
48 | if ps -p $1 > /dev/null; then
49 | echo 1
50 | return
51 | fi
52 | echo 0
53 | return
54 | }
55 |
56 | set_env() {
57 | if [ -r "$PLATFORM_HOME/bin/setenv.sh" ]; then
58 | source "$PLATFORM_HOME/bin/setenv.sh"
59 | else
60 | JAVA_MEM_OPTS=" -server -Xms4g -Xmx4g -XX:SurvivorRatio=2 -XX:+UseParallelGC "
61 | fi
62 | }
63 |
64 | start() {
65 | if [[ $(running $PID) != 0 ]]; then
66 | echo "$PRO_NAME is running"
67 | return
68 | fi
69 | echo "### starting $PRO_NAME `date '+%Y-%m-%d %H:%M:%S'` ###" >> /dev/null 2>&1 &
70 | set_env
71 | echo "$JAVA_HOME/bin/java $JAVA_OPTS $JAVA_MEM_OPTS -classpath $PLATFORM_CONF_DIR:$LIB_JARS $PLATFORM_MAIN_CLASS $JAVA_SPRING_OPTS"
72 | START_CMD="$JAVA_HOME/bin/java $JAVA_OPTS $JAVA_MEM_OPTS -classpath $PLATFORM_CONF_DIR:$LIB_JARS $PLATFORM_MAIN_CLASS $JAVA_SPRING_OPTS"
73 | print_env
74 | nohup $START_CMD >> $PLATFORM_HOME/server.log 2>&1 &
75 | if [[ $(running $!) == 0 ]]; then
76 | echo "failed to start $PRO_NAME"
77 | exit 1
78 | fi
79 | PID=$!
80 | echo $! > $PIDFILE
81 | # echo "new pid $!"
82 | }
83 |
84 | stop() {
85 | if [[ $(running $PID) == 0 ]]; then
86 | echo "no $PRO_NAME is running"
87 | return
88 | fi
89 | echo "stopping $PID of $PRO_NAME ..."
90 | kill $PID
91 | }
92 |
93 | restart() {
94 | stop
95 | start
96 | }
97 |
98 | print_env() {
99 | echo "JRE_HOME: $JAVA_HOME"
100 | echo "ENV: ${env}"
101 | echo "JAVA_OPTS: $JAVA_OPTS"
102 | echo "JAVA_MEM_OPTS: $JAVA_MEM_OPTS"
103 | echo "JAVA_SPRING_OPTS: $JAVA_SPRING_OPTS"
104 | echo "START_CMD: $START_CMD"
105 | }
106 |
107 | print_usage() {
108 | echo "Usage: label.sh (start|stop)"
109 | }
110 |
111 | case $COMMAND in
112 |
113 | (start)
114 | start
115 | ;;
116 |
117 | (stop)
118 | stop
119 | ;;
120 |
121 | (*)
122 | print_usage
123 | exit 1
124 | ;;
125 | esac
--------------------------------------------------------------------------------
/chat_rest/src/main/shell/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PRG="$0"
3 | PRGDIR=`dirname "$PRG"`
4 | PLATFORM_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
5 | EXECUTABLE=comm.sh
6 | exec "$PRGDIR"/"$EXECUTABLE" start "$@"
7 |
--------------------------------------------------------------------------------
/chat_rest/src/main/shell/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PRG="$0"
3 | PRGDIR=`dirname "$PRG"`
4 | PLATFORM_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
5 | EXECUTABLE=comm.sh
6 | exec "$PRGDIR"/"$EXECUTABLE" stop "$@"
7 |
--------------------------------------------------------------------------------
/chat_ui/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | chatBI
7 | com.am
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | chat_ui
13 |
14 |
15 |
--------------------------------------------------------------------------------
/doc/photo/模块架构.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ambition119/chatBI/785185c9a6a24d4ba6388b7e05631292f1196d93/doc/photo/模块架构.jpeg
--------------------------------------------------------------------------------
/doc/photo/自动生成图表.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ambition119/chatBI/785185c9a6a24d4ba6388b7e05631292f1196d93/doc/photo/自动生成图表.png
--------------------------------------------------------------------------------
/plugins/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | chatBI
7 | com.am
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | plugins
13 |
14 | plugins
15 |
16 |
17 |
18 | com.google.code.gson
19 | gson
20 |
21 |
22 |
23 | com.alibaba
24 | dashscope-sdk-java
25 |
26 |
27 | ch.qos.logback
28 | logback-classic
29 |
30 |
31 | ch.qos.logback
32 | logback-core
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/plugins/src/main/java/com/am/chat/bi/utils/AliLLMsUtil.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.utils;
2 |
3 |
4 | import com.alibaba.dashscope.aigc.generation.Generation;
5 | import com.alibaba.dashscope.aigc.generation.GenerationResult;
6 | import com.alibaba.dashscope.aigc.generation.models.QwenParam;
7 | import com.alibaba.dashscope.common.ResultCallback;
8 | import com.alibaba.dashscope.utils.Constants;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.util.concurrent.Semaphore;
13 |
14 |
15 | public class AliLLMsUtil {
16 | private static final Logger LOG = LoggerFactory.getLogger(AliLLMsUtil.class);
17 |
18 | static {
19 | Constants.apiKey = "sk-547";
20 | }
21 |
22 | public static String getResult(String prompt) throws Exception {
23 | Generation gen = new Generation();
24 | QwenParam param = QwenParam.builder().model(Generation.Models.QWEN_TURBO).prompt(prompt)
25 | .topP(0.8).build();
26 | Semaphore semaphore = new Semaphore(0);
27 |
28 | final String[] result = {null};
29 | gen.call(param, new ResultCallback() {
30 |
31 | @Override
32 | public void onEvent(GenerationResult message) {
33 | System.out.println(message);
34 |
35 | result[0] = message.getOutput().getText();
36 | LOG.info("阿里大模型返回结果:{}",message);
37 | }
38 | @Override
39 | public void onError(Exception ex){
40 | System.out.println(ex.getMessage());
41 | semaphore.release();
42 | }
43 | @Override
44 | public void onComplete(){
45 | System.out.println("onComplete");
46 | semaphore.release();
47 | }
48 |
49 | });
50 | semaphore.acquire();
51 |
52 | return result[0];
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/plugins/src/main/java/com/am/chat/bi/utils/LLMsResultUtil.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.utils;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import com.google.gson.JsonParser;
6 |
7 | import java.util.regex.Matcher;
8 | import java.util.regex.Pattern;
9 |
10 | public class LLMsResultUtil {
11 |
12 | public static String getIntentionResult(String result){
13 | String intentionResult = null;
14 |
15 | Pattern pattern = Pattern.compile("(\\d+)");
16 | Matcher matcher = pattern.matcher(result);
17 | if (matcher.find()) {
18 | intentionResult = matcher.group();
19 | }
20 |
21 | return intentionResult;
22 | }
23 |
24 | public static JsonElement getJsonValue(String result, String name) {
25 | JsonParser parser = new JsonParser();
26 | JsonObject jsonObject = parser.parse(result).getAsJsonObject();
27 | return jsonObject.get(name);
28 | }
29 |
30 | public static String getDimMetricJson(String result){
31 | String sqlResult = null;
32 | // Pattern pattern = Pattern.compile("```json(.*?)```");
33 | Pattern pattern = Pattern.compile("\\{.*\\}");
34 | Matcher matcher = pattern.matcher(result);
35 | if (matcher.find()) {
36 | sqlResult = matcher.group();
37 | }
38 |
39 | return sqlResult;
40 | }
41 |
42 | public static String getSqlResult(String result){
43 | String sqlResult = null;
44 |
45 | Pattern pattern = Pattern.compile("querySql: \"(.*?)\"}");
46 | Matcher matcher = pattern.matcher(result);
47 | if (matcher.find()) {
48 | sqlResult = matcher.group();
49 | }
50 |
51 | return sqlResult;
52 | }
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/plugins/src/main/java/com/am/chat/bi/utils/PromptUtil.java:
--------------------------------------------------------------------------------
1 | package com.am.chat.bi.utils;
2 |
3 | public class PromptUtil {
4 |
5 | /**
6 | * 查询意图
7 | * @param queryContent
8 | * @return
9 | */
10 | public static String getIntentionPrompt(String queryContent) {
11 | String intentionPrompt = "“" + queryContent + "” 请帮忙判断这句话的意图是需要" +
12 | "知识库还是数据查询。如果意图是知识库的话result返回值是1,是数据查询的话result返回值是2。" +
13 | "最后返回值采用json数据格式,返回值格式为{result:result_$返回值}"
14 | ;
15 |
16 | return intentionPrompt;
17 |
18 | }
19 |
20 | public static String getDimensionMetricPrompt(String queryContent) {
21 | String dimMetricPrompt = "“" + queryContent + "” 请帮忙解析这句话中含有的维度与指标。解析要求:" +
22 | "1,语句中除了指标名词外,默认其他名词为维度。" +
23 | "2,最后的返回结果采用json数据格式,指定返回格式为{dimensions:array[$维度名称],metrics:array[$指标名称]}。";
24 |
25 | return dimMetricPrompt;
26 | }
27 |
28 | public static String getSqlPrompt(String queryContent, String dbType, String schemaInfo, String dbDialect) {
29 | String sqlPrompt = "假设你是"+dbType+"的专家,需要通过问题描述和指令语句两部分内容帮忙生成对应查询SQL语句。第一部分问题说明:\n" +
30 | "“" + queryContent + "” \n" +
31 | "第二部分指令内容:\n" +
32 | "1,不能幻觉出现新的字段,schema字段、表名称、表字段名称必须使用提供的元数据内容信息,元数据信息json格式数据 " + schemaInfo + " \n" +
33 | "2,可能需要关联表的查询SQL才满足问题内容的要求,关联的表和表字段一定存在已经提供的元数据内容。\n" +
34 | "3,生产的sql语句使用json格式返回,返回数据格式要求{querySQL: $生成的结果SQL}。";
35 |
36 | return sqlPrompt;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.am
7 | chatBI
8 | pom
9 | 1.0-SNAPSHOT
10 |
11 |
12 | chat_rest
13 | chat_ui
14 | plugins
15 |
16 |
17 |
18 | UTF-8
19 | 8
20 | 8
21 | 1.5.9.RELEASE
22 | 4.3.13.RELEASE
23 | 1.3.2
24 | 1.1.10
25 | 1.1.1
26 | 3.7
27 | 1.2.47
28 | 2.7.0
29 | 1.2.3
30 | 1.18.0
31 | 2.7.2
32 | 5.1.46
33 |
34 |
35 |
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter
40 | ${spring-boot-starter-parent}
41 |
42 |
43 | logback-classic
44 | ch.qos.logback
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-web
51 | ${spring-boot-starter-parent}
52 |
53 |
54 |
55 | org.springframework
56 | spring-context-support
57 | ${spring-content.version}
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-starter-websocket
63 | ${spring-boot-starter-parent}
64 |
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-configuration-processor
69 | ${spring-boot-starter-parent}
70 | true
71 |
72 |
73 |
74 | org.springframework.boot
75 | spring-boot-starter-test
76 | ${spring-boot-starter-parent}
77 | test
78 |
79 |
80 |
81 | io.springfox
82 | springfox-swagger2
83 | ${swagger.version}
84 |
85 |
86 |
87 | io.springfox
88 | springfox-swagger-ui
89 | ${swagger.version}
90 |
91 |
92 |
93 | com.github.pagehelper
94 | pagehelper-spring-boot-starter
95 | ${pagehelper}
96 |
97 |
98 | mybatis-spring-boot-starter
99 | org.mybatis.spring.boot
100 |
101 |
102 |
103 |
104 |
105 | org.mybatis.spring.boot
106 | mybatis-spring-boot-starter
107 | ${mybatis-spring-boot-starter}
108 |
109 |
110 | org.springframework.boot
111 | spring-boot-starter
112 |
113 |
114 |
115 |
116 |
117 | com.alibaba
118 | druid-spring-boot-starter
119 | ${druid}
120 |
121 |
122 |
123 | mysql
124 | mysql-connector-java
125 | ${mysql.version}
126 |
127 |
128 |
129 | org.mybatis.spring.boot
130 | mybatis-spring-boot-starter-test
131 | ${mybatis-spring-boot-starter}
132 |
133 |
134 |
135 | org.projectlombok
136 | lombok
137 | ${lombok.version}
138 |
139 |
140 |
141 | org.apache.commons
142 | commons-lang3
143 | ${commons-lang3}
144 |
145 |
146 |
147 | ch.qos.logback
148 | logback-classic
149 | ${logback.version}
150 |
151 |
152 | logback-core
153 | ch.qos.logback
154 |
155 |
156 |
157 |
158 | ch.qos.logback
159 | logback-core
160 | ${logback.version}
161 |
162 |
163 |
164 | com.google.code.gson
165 | gson
166 | 2.10.1
167 |
168 |
169 |
170 | com.alibaba
171 | dashscope-sdk-java
172 | 2.6.1
173 |
174 |
175 |
176 | redis.clients
177 | jedis
178 | ${redis.version}
179 |
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------