智能BI(后端) -- 智能分析业务

文章目录

业务流程

  1. 用户输入

a. 分析目标

b. 上传原始数据

c. 更精细话地控制图表,比如图表类型,图表名称等

  1. 后端校验

    a. 校验用户的输入是否合法

    b. 成本控制(次数统计和校验,鉴权等)

  2. 把处理后的数据输入给AI模型(调用AI接口),让AI模型给我们提供图表信息,结论文本

  3. 图表信息(是一段json配置,是一段代码),结论文本在前端进行展示

开发接口

easyExcel从excel读取数据,数据过滤并进行数据压缩

不要想复杂啦,读取数据很正常,数据过滤就是过滤掉null的数据,数据压缩转化为csv,其实就是转换格式,用英文逗号分割,节省空间,给个预设语句,可以使得AI回答地更准确

java 复制代码
package com.yupi.springbootinit.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * excel相关工具类
 */
@Slf4j
public class ExcelUtils {
    /**
     * 数据压缩为csv,返回字符串
     */
    public static String excelToCsv(MultipartFile multipartFile){
        //读取数据
        List<Map<Integer, String>> list = null;
        try {
            list = EasyExcel.read(multipartFile.getInputStream())
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet()
                    .headRowNumber(0)
                    .doReadSync();
        } catch (IOException e) {
            log.error("表格处理错误");
        }
        System.out.println(list);
        //如果数据为空
        if(CollUtil.isEmpty(list)){
            return "";
        }
        //转换为csv (数据压缩)
        StrBuilder strBuilder = new StrBuilder();
        //过滤表头数据
        //todo 问为什么要用LinkedHashMap呢?
        LinkedHashMap<Integer, String> headMap = (LinkedHashMap<Integer, String>) list.get(0);
        List<String> headValueList = headMap.values().stream().filter(item -> ObjectUtil.isNotEmpty(item)).collect(Collectors.toList());
        String head = StringUtils.join(headValueList, ",");
        System.out.println(head);
        strBuilder.append(head).append("\n");
        //过滤表数据
        for (int i = 1; i < list.size(); i ++){
            LinkedHashMap<Integer, String> dataListMap = (LinkedHashMap)list.get(i);
            List<String> dataList = dataListMap.values().stream().filter(item -> ObjectUtil.isNotEmpty(item)).collect(Collectors.toList());
            String data = StringUtils.join(dataList, ",");
            System.out.println(data);
            strBuilder.append(data).append("\n");
        }
        return strBuilder.toString();
    }

    /**
     * test
     * @param args
     */
    public static void main(String[] args) {
        excelToCsv(null);
    }
}

分析接口

java 复制代码
    /**
     * 上传文件,返回数据
     *
     * @param multipartFile
     * @param genChartByAiRequest
     * @param request
     * @return
     */
    @PostMapping("/gen")
    public BaseResponse<String> genChartByAi(@RequestPart("file") MultipartFile multipartFile,
                                           GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
        String name = genChartByAiRequest.getName();
        String goal = genChartByAiRequest.getGoal();
        String chartType = genChartByAiRequest.getChartType();
        //分析目标为空抛出异常
        ThrowUtils.throwIf(StringUtils.isBlank(goal),ErrorCode.PARAMS_ERROR,"分析目标为空");
        //名称不为空并且名称>100 提示名称过长
        ThrowUtils.throwIf(StringUtils.isNotBlank(name) && name.length() > 100,ErrorCode.PARAMS_ERROR,"图表名称过长");
        StrBuilder userInput = new StrBuilder();
        userInput.append("你是一个数据分析师,接下来我会给你我的分析目标和原始数据,请告诉我分析结论:").append("\n");
        userInput.append("分析目标:").append(goal).append("\n");
        String result = ExcelUtils.excelToCsv(multipartFile);
        userInput.append("数据:").append(result).append("\n");
        return ResultUtils.success(userInput.toString());
    }

利用AI生成结论和图表

生成结论

生成图表:

AI无法直接生成现成的图表,但是AI可以生成图表代码,可以把代码利用前端组件库(Echarts)在网页进行展示

预期生成的图表代码

AI提问技巧

如果想让AI更好的理解我们的输入,给我们预期的,精确格式的输出,我们就需要严格控制咱们的提问词

0)使用系统预设

1)控制输入格式(便于AI精确地理解我们的需求和提问)

2)控制输出格式(便于AI返回的内容能够更加方便的为我们所用)

3)指定一个示例问答

调用AI

直接调用AI大模型官网的接口

官方文档:https://platform.openai.com/docs/api-reference

优点:不经封装,最灵活,最原始

缺点:要钱,要魔法

本质上openAI就是提供了Http接口,我们可以用任何语言去调用

1)在请求头中指定OPENAI_API_KEY

2)找到你要使用的接口,比如AI对话接口

3)按照接口文档的示例,构造Http请求,比如用Hutool工具类,或者HttpClient

java 复制代码
/**
 * AI 对话(需要自己创建请求响应对象)
 *
 * @param request
 * @param openAiApiKey
 * @return
 */
public CreateChatCompletionResponse createChatCompletion(CreateChatCompletionRequest request, String openAiApiKey) {
    if (StringUtils.isBlank(openAiApiKey)) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "未传 openAiApiKey");
    }
    String url = "https://api.openai.com/v1/chat/completions";
    String json = JSONUtil.toJsonStr(request);
    String result = HttpRequest.post(url)
    .header("Authorization", "Bearer " + openAiApiKey)
    .body(json)
    .execute()
    .body();
    return JSONUtil.toBean(result, CreateChatCompletionResponse.class);
}

使用云服务商提供的,封装后的AI接口

比如:Azure云

优点:不用魔法

缺点:依然要钱,可能比直接调用原始的接口更贵

利用鱼聪明AI提供的开放SDK

优点:有很多现成的模型,可以预设
https://github.com/liyupi/yucongming-java-sdk

智能接口实现

echarts在线调试:https://echarts.apache.org/examples/zh/editor.html?c=line-simple

  1. 构造用户请求(用户消息,csv,图表类型)
  2. 调用鱼聪明sdk,得到AI响应结果
  3. 从AI响应结果中,取出需要的信息
  4. 保存图表到数据库
相关推荐
网安墨雨5 分钟前
常用网络协议
网络·网络协议
Tlzns8 分钟前
Linux网络——UDP的运用
linux·网络·udp
微服务 spring cloud21 分钟前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡23 分钟前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷25 分钟前
Redis
数据库·redis·缓存
黑客老陈28 分钟前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
wm104339 分钟前
java web springboot
java·spring boot·后端
smile-yan41 分钟前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风42 分钟前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java