DB-GPT,开源的AI数据开发框架,可利用自然语言生成可视化报表
阅读原文
建议阅读原文以获得最佳阅读体验:《DB-GPT,开源的AI数据开发框架,可利用自然语言生成可视化报表》
简介
DB-GPT 是什么?
🤖️ DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。
目的是构建大模型领域的基础设施,通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Multi-Agents框架协作、AWEL(智能体工作流编排)等多种技术能力,让围绕数据库构建大模型应用更简单,更方便。
🚀 数据3.0 时代,基于模型、数据库,企业/开发者可以用更少的代码搭建自己的专属应用。
简单的说,大家可以通过自然语言生成生成报表,支持与excel文件、数据库、知识库对话。
引言
因为工作需要,规范企业电脑软件清单,本人偶尔需要从glpi数据库中导出安装了特定软件的计算机清单(包含使用人),我之前的做法,是写一个SQL语句,然而再利用Powershell调整excel的格式,使其更加直观。具体可以看我之前写的一篇文章https://mp.weixin.qq.com/s/hV70jW7RPZ4vim7pXs_kKQ
自从2022年底AI技术爆发后,将AI技术应用于生成式BI的研究越来越多了,我想能不能利用AI技术,直接用自然语言就能查询数据,或者生成报表呢?于是我找到了DB-GPT,做了一些实验。
类似软件
Vanna.AI Vanna.AI Documentation
部署
用docker compose部署
参考资料:Docker-Compose部署
git clone https://github.com/eosphoros-ai/DB-GPT.git
cd DB-GPT
设置环境变量:
#编辑~/.bashrc文件,在文件末尾加上一行
export DASHSCOPE_API_KEY="<此处替换为你的阿里云百炼上的API KEY>"
#使得配置立即生效
source ~/.bashrc
本文采用阿里云上的大模型,qwen-plus,需要更改一些配置文件
nano configs/dbgpt-proxy-tongyi.toml
[system]
# Load language from environment variable(It is set by the hook)
language = "${env:DBGPT_LANG:-zh}" #这一行的含义是设置DBGPT_LANG的语言,默认为en
api_keys = []
encrypt_key = "your_secret_key"
# Server Configurations
[service.web]
host = "0.0.0.0"
port = 5670
[service.web.database]
type = "sqlite"
path = "pilot/meta_data/dbgpt.db"
[rag.storage]
[rag.storage.vector]
type = "chroma"
persist_path = "pilot/data"
# Model Configurations
[models]
[[models.llms]]
name = "qwen-plus" #此处可以更改大模型
provider = "${env:LLM_MODEL_PROVIDER}" #此处做了调整
api_base = "https://dashscope.aliyuncs.com/compatible-mode/v1"
api_key = "${env:DASHSCOPE_API_KEY}"
[[models.embeddings]]
name = "text-embedding-v3"
provider = "${env:EMBEDDING_MODEL_PROVIDER}" #此处做了调整
api_url = "https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings"
api_key = "${env:DASHSCOPE_API_KEY}"
docker-compose.yml文件也要调整
先创建目录:
sudo mkdir -p /dbgpt-data/models
sudo chown -R ubuntu:docker /dbgpt-data
nano docker-compose.yml
# To run current docker compose file, you should prepare the silliconflow api key in your environment.
# SILICONFLOW_API_KEY=${SILICONFLOW_API_KEY} docker compose up -d
services:
db:
image: mysql/mysql-server
environment:
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'aa123456'
ports:
- 3306:3306
volumes:
- dbgpt-myql-db:/var/lib/mysql
- ./docker/examples/my.cnf:/etc/my.cnf
- ./docker/examples/sqls:/docker-entrypoint-initdb.d
- ./assets/schema/dbgpt.sql:/docker-entrypoint-initdb.d/dbgpt.sql
restart: unless-stopped
networks:
- dbgptnet
webserver:
image: eosphorosai/dbgpt-openai:latest
command: dbgpt start webserver --config /app/configs/dbgpt-proxy-tongyi.toml #此处更换了配置文件,以满足我的需求,使用阿里云上的大模型,此处的默认值是选择硅基流动上的大模型
environment:
- LLM_MODEL_PROVIDER=${LLM_MODEL_PROVIDER:-proxy/tongyi}
- EMBEDDING_MODEL_PROVIDER=${EMBEDDING_MODEL_PROVIDER:-proxy/tongyi}
- DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY}
- MYSQL_PASSWORD=aa123456
- MYSQL_HOST=db
- MYSQL_PORT=3306
- MYSQL_DATABASE=dbgpt
- MYSQL_USER=root
volumes:
- ./configs:/app/configs
- /dbgpt-data:/data #这一行以及下一行做了调整,原来的值是/data:/data,这是因为我的实验环境本来就有了/data这个目录,而且此目录已经没有剩余容量了,所以我自己创建了新的目录/dbgpt-data
# May be you can mount your models to container
- /dbgpt-data/models:/app/models
- dbgpt-data:/app/pilot/data
- dbgpt-message:/app/pilot/message
depends_on:
- db
ports:
- 5670:5670/tcp
# webserver may be failed, it must wait all sqls in /docker-entrypoint-initdb.d execute finish.
restart: unless-stopped
networks:
- dbgptnet
ipc: host
volumes:
dbgpt-myql-db:
dbgpt-data:
dbgpt-message:
dbgpt-alembic-versions:
networks:
dbgptnet:
driver: bridge
name: dbgptnet
运行docker compose
docker compose up -d
查看日志:
docker logs db-gpt-webserver-1 -f
DB-GPT webserver的部分日志:
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO Mount http trigger success, path: /api/v1/awel/trigger/examples/simple_chat
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Include router <fastapi.routing.APIRouter object at 0x720ffc3c1890> to prefix path /api/v1/awel/trigger
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Register trigger HttpTrigger(node_id=8b107f4a-8aa7-403b-b9a7-c2ffe7d09a55)
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO mount router function <function HttpTrigger._create_route_func.<locals>.create_route_function.<locals>.route_function at 0x720fae18a8e0>(AWEL_trigger_route__examples_simple_client_chat_completions), endpoint: /examples/simple_client/chat/completions, methods: ['POST']
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO Mount http trigger success, path: /api/v1/awel/trigger/examples/simple_client/chat/completions
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Include router <fastapi.routing.APIRouter object at 0x720ffc3c1890> to prefix path /api/v1/awel/trigger
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Register trigger HttpTrigger(node_id=d9979d22-f188-47f4-8d76-7c15f45bfa50)
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO mount router function <function HttpTrigger._create_route_func.<locals>.create_route_function.<locals>.route_function at 0x720fae15b4c0>(AWEL_trigger_route__examples_simple_client_count_token), endpoint: /examples/simple_client/count_token, methods: ['POST']
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO Mount http trigger success, path: /api/v1/awel/trigger/examples/simple_client/count_token
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Include router <fastapi.routing.APIRouter object at 0x720ffc3c1890> to prefix path /api/v1/awel/trigger
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Register trigger HttpTrigger(node_id=7cbaebef-31a5-44c0-906c-a08df8167d7e)
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO mount router function <function HttpTrigger._create_route_func.<locals>.create_route_function.<locals>.route_function_get at 0x720fae1d4400>(AWEL_trigger_route__examples_hello), endpoint: /examples/hello, methods: ['GET']
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO Mount http trigger success, path: /api/v1/awel/trigger/examples/hello
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Include router <fastapi.routing.APIRouter object at 0x720ffc3c1890> to prefix path /api/v1/awel/trigger
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Register trigger HttpTrigger(node_id=22e60ffb-3672-4c62-8f0b-17b51d6d76e7)
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO mount router function <function HttpTrigger._create_route_func.<locals>.create_route_function.<locals>.route_function at 0x720fae1d4d60>(AWEL_trigger_route__examples_rag_schema_linking), endpoint: /examples/rag/schema_linking, methods: ['POST']
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO Mount http trigger success, path: /api/v1/awel/trigger/examples/rag/schema_linking
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Include router <fastapi.routing.APIRouter object at 0x720ffc3c1890> to prefix path /api/v1/awel/trigger
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Register trigger HttpTrigger(node_id=0867529d-5ce8-456b-9387-dd341761d5f6)
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO mount router function <function HttpTrigger._create_route_func.<locals>.create_route_function.<locals>.route_function at 0x720fae15a520>(AWEL_trigger_route__examples_rag_rewrite), endpoint: /examples/rag/rewrite, methods: ['POST']
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.http_trigger[1] INFO Mount http trigger success, path: /api/v1/awel/trigger/examples/rag/rewrite
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.core.awel.trigger.trigger_manager[1] INFO Include router <fastapi.routing.APIRouter object at 0x720ffc3c1890> to prefix path /api/v1/awel/trigger
webserver-1 | Libro Server start!
webserver-1 | start libro exception![Errno 2] No such file or directory: 'libro'
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.model.cluster.worker.manager[1] INFO Begin start all worker, apply_req: None
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.model.cluster.worker.manager[1] INFO Apply req: None, apply_func: <function LocalWorkerManager._start_all_worker.<locals>._start_worker at 0x721066e98ea0>
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.model.cluster.worker.manager[1] INFO Apply to all workers
webserver-1 | INFO: Application startup complete.
webserver-1 | INFO: Uvicorn running on http://0.0.0.0:5670 (Press CTRL+C to quit)
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.model.cluster.worker.default_worker[1] INFO Begin load model, model params:
webserver-1 |
webserver-1 | =========================== TongyiDeployModelParameters ===========================
webserver-1 |
webserver-1 | name: qwen-plus
webserver-1 | provider: proxy/tongyi
webserver-1 | verbose: False
webserver-1 | concurrency: 100
webserver-1 | backend: None
webserver-1 | prompt_template: None
webserver-1 | context_length: None
webserver-1 | reasoning_model: None
webserver-1 | api_base: https://dashscope.aliyuncs.com/compatible-mode/v1
webserver-1 | api_key: sk******6a
webserver-1 | api_type: None
webserver-1 | api_version: None
webserver-1 | http_proxy: None
webserver-1 |
webserver-1 | ======================================================================
webserver-1 |
webserver-1 |
webserver-1 | 2025-03-21 03:18:52 6bd8379e0a0c dbgpt.model.adapter.proxy_adapter[1] INFO Load model from params:
webserver-1 |
webserver-1 | =========================== TongyiDeployModelParameters ===========================
webserver-1 |
webserver-1 | name: qwen-plus
webserver-1 | provider: proxy/tongyi
webserver-1 | verbose: False
webserver-1 | concurrency: 100
webserver-1 | backend: None
webserver-1 | prompt_template: None
webserver-1 | context_length: None
webserver-1 | reasoning_model: None
webserver-1 | api_base: https://dashscope.aliyuncs.com/compatible-mode/v1
webserver-1 | api_key: sk******6a
webserver-1 | api_type: None
webserver-1 | api_version: None
webserver-1 | http_proxy: None
webserver-1 |
webserver-1 | ======================================================================
webserver-1 |
webserver-1 | llm client class: <class 'dbgpt.model.proxy.llms.tongyi.TongyiLLMClient'>
webserver-1 | INFO: 127.0.0.1:48844 - "POST /api/controller/models HTTP/1.1" 200 OK
webserver-1 | 2025-03-21 03:18:54 6bd8379e0a0c dbgpt.model.cluster.worker.embedding_worker[1] INFO Load embeddings model: text-embedding-v3
webserver-1 | INFO: 127.0.0.1:48858 - "POST /api/controller/models HTTP/1.1" 200 OK
webserver-1 | INFO: 127.0.0.1:48868 - "POST /api/controller/models HTTP/1.1" 200 OK
webserver-1 | 2025-03-21 03:18:54 6bd8379e0a0c dbgpt.model.cluster.worker.manager[1] INFO There has model storage, start the model from storage
webserver-1 | begin run _add_app_startup_event
webserver-1 | 2025-03-21 03:19:01 6bd8379e0a0c dbgpt.util.code.server[1] INFO Code server is ready
webserver-1 | INFO: 192.168.124.11:49689 - "GET / HTTP/1.1" 304 Not Modified
查看容器状况:
docker compose ps
进入webUI,默认端口是5670
案例一:与数据库对话(GLPI)
GLPI是一个开源的资产管理软件,其同时还支持CMDB、ITIL,单位使用GLPI进行资产管理,其中保存了公司所有电脑的基本信息,如计算机名、序列号、型号、操作系统版本、当前登录用户等等十分丰富信息。
对glpi数据库创建一个新的用户
查询当前有哪些用户:
SELECT user, host FROM mysql.user;
输出如下,从输出可知,glpi这个数据库用户有ip地址限制,只能从10.64.128.116、192.168.124.11和localhost(数据库所在的服务器)访问
创建一个新的glpi数据库用户,因为默认的glpi用户权限太高了,风险很大,遵循最低权限原则,创建一个用户,此用户只需读取数据库即可,无需拥有修改删除权限
-- 1. 创建用户(无IP限制)
CREATE USER 'dbgpt-testuser'@'%' IDENTIFIED BY 'your_strong_password_here';
-- 2. 授予全局只读权限
GRANT SELECT ON *.* TO 'dbgpt-testuser'@'%';
-- 3. 刷新权限使配置生效
FLUSH PRIVILEGES;
/*关键点解析:
用户创建
'dbgpt-testuser'@'%' 中 % 表示允许从任意 IP 地址连接
密码需替换为高强度字符串(建议包含大小写字母、数字、符号组合)
权限控制
SELECT ON *.* 表示允许查询所有数据库和表
未授予 INSERT/UPDATE/DELETE 等写入权限,确保只读特性
安全建议
生产环境建议限制 IP 范围(如 'dbgpt-testuser'@'192.168.1.%')而非使用 %
定期审计权限:通过 SHOW GRANTS FOR 'dbgpt-testuser'@'%' 验证权限*/
添加一个数据库
这里演示如何添加一个mysql数据库,我添加的是glpi的数据库
填写相应的数据库信息
添加其它大模型
如果不想用dbgpt-proxy-tongyi.toml
文件中指定的大模型,还可以添加其它的大模型
创建自定义应用
如果不想用广场中的默认应用,可以单独创建应用,最方便地是直接套用模板,只要更改大模型和数据源就行。
chat DB类型的应用
下图是直接与默认的应用对话
可以看到这种类型的应用,不会直接输出图表,只能得到SQL语句
chat data类型的应用
下面这个是chat data类型的应用,我对大模型进行了自定义,而不是用默认的qwen-plus
输出只有50条,这是因为默认情况下限制了条目,点击SQL即可查看语句
可以看到型号其实不是我们想要的,可以继续提问
可以查看详细的SQL语句
继续提问,让其给出具体的电脑型号,输出满足需求
让AI统计glpi数据库中电脑安装的操作系统版本的比例,总的来说,输出还是可以的,就是没有标注详细的操作系统版本信息,22H2这个版本号,Windows10和Windows11都是有的,从输出中无法区分。
下面这个回答是错误的,说明AI的推理能力还是很弱,不能进行综合分析给出结果。
让AI查询所有安装了SolidWorks这款软件的计算机,很奇怪的是,完全相同的提示词,有时候会报错,有时候没有输出,有时候又可以
询问AI哪些电脑安装了SolidWorks软件,然而输出是空的,这明显也是不对的
查看AI生成的SQL语句:
即使告诉AI具体的软件名称,也还是没有输出
直接就提示“根据现有的表结构信息无法查询哪些电脑安装了QQ,因为缺少与软件安装相关的数据表。”
chat dashboard类型的应用
总结
我发现对于简单的数据分析或者查询,输出的信息还是可以,能直接输出图标,可视化效果好。但是略微复杂一点的问题就不行了,直接就没有输出了,或者报错。
不同的大模型表现也是不同的,需要多尝试。
提升DB-GPT生成效果
如果DB-GPT输出的结果不好,或者有误,我认为以下几点可以考虑:
在提示词中,直接给出示例;
在提示词中,用自然语言详细描述数据库表与表之间的关系,以及表中的字段含义;
使用英语作为提示词,因为数据库中的表字段几乎都是英文的。