DB-GPT 数据分析多智能体应用实战:从 Superstore 数据准备到自动化指标异常分析报告
【免费下载链接】DB-GPTopen-source agentic AI data assistant for the next generation of AI + Data products.项目地址: https://gitcode.com/GitHub_Trending/db/DB-GPT
本文基于 DB-GPT 官方实践文档 data_analysis_agent.md,完整走通"部署 DB-GPT → 准备 Superstore 数据集与指标知识库 → 组装 MetricInfoRetriever / DataScientist / AnomalyDetector / VolatilityAnalyzer / ReportGenerator 五个智能体 → 生成指标分析报告"的端到端流程,并结合仓库源码解释每个智能体的职责边界与协作机制,帮助读者在自己的业务库上复刻一套可复用的数据分析多智能体应用。
1. 方案总览:一条"指标驱动"的分析流水线
DB-GPT 的 Web 端支持"多智能体自动规划模式"(Auto-Plan)应用,用户用自然语言提问后,Planner 会根据各个智能体的 Profile 描述自动编排执行顺序。本案例构建的分析流水线为:
| 智能体(页面显示名) | 源码位置 | 职责 | 所需资源 |
|---|---|---|---|
| MetricInfoRetriever | metric_info_agent.py | 从知识库检索指标元信息(字段、计算规则、建议维度、阈值) | 知识库 |
| DataScientist | data_scientist_agent.py | 基于数据库结构生成并执行分析 SQL | 数据库 |
| AnomalyDetector | anomaly_detection_agent.py | 比较基期值与当期值,判断波动是否超阈值 | 无(依赖上游输出) |
| VolatilityAnalyzer | volatility_analysis_agent.py | 对确认异常的指标按建议维度做归因下钻 | 数据库 |
| ReportGenerator | report_generation_agent.py | 汇总全部结果输出 Markdown 报告 | 无 |
各智能体 Profile 中的desc字段实际承担了"编排契约"的作用,例如 MetricInfoRetriever 的 desc 声明"当用户问题涉及某个业务指标时,必须首先调用此智能体获取指标信息";VolatilityAnalyzer 的 desc 声明"须在 AnomalyDetector 确认异常后调用,并应基于 MetricInfoRetriever 提供的'建议分析维度'进行下钻分析,不得在未检测到异常时主动执行归因"。正是这些描述让 Planner 能自动推导出正确的调用顺序与数据依赖。
2. 项目部署与环境准备
2.1 克隆代码库
git clone https://gitcode.com/GitHub_Trending/db/DB-GPT.git cd DB-GPT2.2 使用 uv 管理依赖
DB-GPT 推荐使用uv管理 Python 环境:
# 安装 uv 工具 curl -LsSf https://astral.sh/uv/install.sh | sh # 验证安装 uv --version2.3 按模型类型安装依赖
根据使用的 LLM 来源选择 extra 组合(项目为多包工作区,--all-packages会同时安装packages/下的 dbgpt-core、dbgpt-serve 等子包):
OpenAI 代理模型:
uv sync --all-packages \ --extra "base" \ --extra "proxy_openai" \ --extra "rag" \ --extra "storage_chromadb" \ --extra "dbgpts"本地模型(以 GLM4 为例,含 CUDA 与 bitsandbytes 量化依赖):
uv sync --all-packages \ --extra "base" \ --extra "cuda121" \ --extra "hf" \ --extra "rag" \ --extra "storage_chromadb" \ --extra "quant_bnb" \ --extra "dbgpts"其中rag与storage_chromadb两个 extra 对应本文案例用到的知识库能力(Chroma 向量存储)。
2.4 配置 LLM 与 Embedding 模型
OpenAI 代理模型配置(仓库自带模板见 configs/dbgpt-proxy-openai.toml,模板中模型名与 API Key 支持${env:...}环境变量占位):
[system] language = "zh" encrypt_key = "your_secret_key" [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" # 模型配置 [models] [[models.llms]] name = "gpt-3.5-turbo" provider = "proxy/openai" api_key = "your-openai-api-key" [[models.embeddings]] name = "text-embedding-ada-002" provider = "proxy/openai" api_key = "your-openai-api-key"本地模型配置(对应 configs/dbgpt-local-glm.toml):
[system] language = "zh" encrypt_key = "your_secret_key" [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" # 模型配置 [models] [[models.llms]] name = "THUDM/glm-4-9b-chat-hf" provider = "hf" # 如果未提供,模型将从 Hugging Face 模型中心下载 # 取消注释以下行以指定本地文件系统中的模型路径 # path = "the-model-path-in-the-local-file-system" [[models.embeddings]] name = "BAAI/bge-large-zh-v1.5" provider = "hf" # 如果未提供,模型将从 Hugging Face 模型中心下载 # 取消注释以下行以指定本地文件系统中的模型路径 # path = "the-model-path-in-the-local-file-system"关键点说明:
[service.web.database]:DB-GPT 自身的元数据库(会话、应用定义等),案例用 SQLite,落在pilot/meta_data/dbgpt.db;[rag.storage.vector]:知识库向量存储,案例使用本地 Chroma,数据目录pilot/data;- 本地模型配置中若不提供
path,权重将从 Hugging Face 模型中心自动下载,有本地权重时可取消注释path指定路径。
3. 数据集与数据库准备
本案例使用Superstore 数据集(Kaggle 上的j2ngb/superstore-data,可自行下载)并导入 MySQL。步骤:
- 确保已安装并启动 MySQL 服务;
- 创建数据库:
CREATE DATABASE superstore; USE superstore;- 创建
superstore_dataset表(表结构中每列均带 COMMENT 注释,这对后续 LLM 理解表结构、生成准确 SQL 很有帮助):
CREATE TABLE `superstore_dataset` ( `row_id` int NOT NULL COMMENT 'Unique ID for each row', `order_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Unique Order ID for each Customer.', `order_date` date NULL DEFAULT NULL COMMENT 'Order Date of the product.', `ship_date` date NULL DEFAULT NULL COMMENT 'Shipping Date of the Product.', `ship_mode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Shipping Mode specified by the Customer.', `customer_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Unique ID to identify each Customer.', `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Name of the Customer.', `segment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'The segment where the Customer belongs.', `country` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT ' Country of residence of the Customer.', `city` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'city where the customer lives.', `state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'State of residence of the Customer.', `postal_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Postal Code of every Customer.', `region` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Region where the Customer belong.', `market` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'market name', `product_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Unique ID of the Product.', `category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Category of the product ordered.', `sub_category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Sub-Category of the product ordered.', `product_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'Name of the Product', `sales` float(10, 2) NULL DEFAULT NULL COMMENT 'Product sales price', `quantity` int NULL DEFAULT NULL COMMENT 'Quantity of the Product.', `discount` float(10, 3) NULL DEFAULT NULL COMMENT 'Discount provided.', `profit` float(10, 4) NULL DEFAULT NULL COMMENT 'Profit/Loss incurred.', `shipping_cost` float(10, 2) NULL DEFAULT NULL COMMENT 'shipping cost', `order_priority` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'order priority', PRIMARY KEY (`row_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;- 将下载的数据文件导入
superstore_dataset表(可按 CSV/JSON 格式使用LOAD DATA或客户端导入工具)。
4. 知识库准备:让智能体"认识"你的业务指标
数据分析多智能体应用需要一份业务知识文件来描述数据集的指标口径,包括指标名、字段、计算规则、建议分析维度和异常阈值。创建指标.txt,不同指标之间用###分隔,便于按分隔符分片(本案例定义两个指标):
### 指标名称:订单数量 字段:quantity 计算规则:无 建议计算维度:地区(region) 阈值:0.01 ### 指标名称:订单占比 字段:quantity 计算规则:SUM(quantity) / TOTAL(SUM(quantity)) OVER() 建议计算维度:地区(region) 阈值:0.05这份文件的设计与源码中的智能体职责是一一对应的:
- "指标名称/字段/计算规则/建议计算维度/阈值" 五要素,正是 MetricInfoAgent Profile 中 goal 声明的"返回结构化信息,包括指标名、字段、计算规则、建议维度与阈值";
- "阈值" 会被传递给 AnomalyDetectionAction,其输入模型
AnomalyDetectionInput要求metric_name、baseline_value、current_value、threshold四个字段,内部按(current - baseline) / baseline计算波动率并与阈值比较(threshold = 0.01即 1% 波动率); - "建议计算维度:地区(region)" 会被 VolatilityAnalyzer 用作归因下钻的维度选择依据。
因此,将业务口径沉淀为这种"结构化指标卡片",是这套方案能从通用问答升级为确定性业务分析的关键。
5. 启动服务与资源接入
5.1 启动 Web 服务
# 使用 OpenAI 代理模型配置启动 uv run dbgpt start webserver --config configs/dbgpt-proxy-openai.toml # 或使用本地模型配置启动 uv run dbgpt start webserver --config configs/dbgpt-local-glm.toml启动后浏览器访问http://localhost:5670。
5.2 接入知识库
- 点击"应用管理",选择"知识库";
- 创建知识库;
- 填写相关配置信息(名称、描述等);
- 知识库类型选择"文档";
- 上传提前准备好的
指标.txt; - 分片策略选择
separator,分隔符设置为###—— 这与 4 节中文件的设计相呼应,保证每个分片恰好是一个完整指标卡片,检索时不会把不同指标的口径混在同一个 chunk 里; - 完成创建,知识库出现在列表中。
5.3 接入数据库
- 进入"数据库/数据源"管理页面;
- 点击"添加数据源";
- 填写 3 节准备好的 MySQL 连接信息(主机、端口、
superstore库、账号密码,MySQL 方言); - 测试连接通过后保存,数据源添加成功。
6. 创建数据分析应用
进入"应用管理",点击"创建应用":
- 基础配置中选择**"多智能体自动规划模式"**,填写应用名称与描述;
- 依次添加五个智能体并配置资源:
| 步骤 | 操作 |
|---|---|
| 加入 MetricInfoRetriever | 选取该智能体,配置知识库资源(第 5.2 节创建的知识库) |
| 加入 DataScientist | 选取该智能体,配置数据库资源(第 5.3 节的数据源) |
| 加入 AnomalyDetector | 选取该智能体,无需额外资源 |
| 加入 VolatilityAnalyzer | 选取该智能体,配置数据库资源 |
| 加入 ReportGenerator | 选取该智能体,无需额外资源 |
- 点击"保存"完成应用创建。
注意:从当前源码看,VolatilityAnalysisAgent 的注册行 被注释(源码注释说明该智能体在页面上"temp hidden")。若你的界面上看不到 VolatilityAnalyzer,可跳过该步骤,流水线仍可完成"取指标信息 → 查数 → 判异常 → 出报告"的主流程。
7. 智能体内部机制:源码级解读
7.1 DataScientist:带自检与重试的 SQL 分析器
DataScientistAgent 是流水线中唯一直接"碰"数据库的智能体,其设计要点:
- 方言感知:
_init_reply_message会把self.database.dialect(数据库方言)与支持的可视化展示类型(ChartAction.render_prompt())注入提示词上下文,约束 LLM 生成当前数据库方言的 SQL; - SQL 正确性自检:
correctness_check方法会把模型给出的 SQL 真正在数据库上执行一遍——执行失败、未生成 SQL、查不到数据,都会返回失败原因要求重写,配合max_retry_count = 5实现"生成-执行-纠错"的自修正循环; - 防幻觉约束:constraints 中明确"禁止使用不存在的字段"、"禁止自行构造查询条件,只能使用输入中给出的数据值",从提示词层面抑制 SQL 幻觉。
7.2 AnomalyDetector:确定性的阈值判断
AnomalyDetectionAction 的输入是强类型 Pydantic 模型,LLM 只负责从上游对话中提取参数,计算本身是确定性代码:波动率 =(当期值 − 基期值) / 基期值,并与指标卡片中的阈值比较,基期为 0 时按特殊规则处理(当期值大于 0 视为无穷大波动)。该动作还绑定VisAnomalyDetection渲染协议,可在前端输出可视化组件。这种"LLM 提参 + 代码计算"的模式,避免了让 LLM 心算比率带来的数值不可靠问题。
7.3 ReportGenerator:流式输出与长文本配额
ReportGenerationAgent 有两个值得注意的实现细节:stream_out = True,报告以流式方式逐字输出;build方法中显式把agent_context.max_new_tokens提升到4096,为长报告预留输出配额。其 constraints 还要求报告必须是结构化 Markdown,包含关键指标、波动分析与根因定位三个部分。
8. 运行分析:从提问到报告
进入应用点击"开始对话",在输入框中提问:
请帮我分析订单数量 2012 年 年环比增长情况
执行过程大致为:Planner 依据各智能体 Profile 的 desc 编排任务 → MetricInfoRetriever 从知识库检索"订单数量"指标卡片(字段quantity、阈值 0.01、建议维度 region)→ DataScientist 生成并执行 2011/2012 年SUM(quantity)查询 → AnomalyDetector 计算环比波动率并与阈值比对 →(确认异常时)VolatilityAnalyzer 按 region 维度归因 → ReportGenerator 汇总输出分析报告。
9. 小结与适用说明
本实践文档给出了一个可复制的方法论:把"指标口径"沉淀为知识库、把"取数"交给带自检的 DataScientist、把"判断"交给确定性代码、把"表达"交给报告智能体。适用前提与限制:
- 需要可用的 LLM(代理或本地)与向量模型服务,模型配置见 2.4 节,仓库中 configs/ 目录下还有 Ollama、SiliconFlow、GLM 等多种现成配置模板可参考;
- 数据库方言不限 MySQL,替换为 SQLite、PostgreSQL 等数据源即可,DataScientist 会通过
dialect自适应生成 SQL; - 知识库分片必须与
指标.txt的###分隔约定保持一致,否则指标卡片会被拆碎,影响 MetricInfoRetriever 的结构化抽取; - 从当前源码看 VolatilityAnalyzer 的页面注册暂时被注释,界面未显示时可跳过归因步骤,不影响主链路运行。
【免费下载链接】DB-GPTopen-source agentic AI data assistant for the next generation of AI + Data products.项目地址: https://gitcode.com/GitHub_Trending/db/DB-GPT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考