ob-db-assistant — 数据库对话式查询与分析助手
Overview
本技能把「用户用中文提的业务问题」转换成「可执行、可核对、可解释的 SQL 查询与结论」。 它面向 OceanBase(兼容 MySQL 协议)、seekdb 与普通 MySQL 实例,覆盖四类典型任务:
- 结构探查:有哪些表、字段类型、主键、索引、行数量级,先摸清地形再写 SQL。
- 自然语言取数:把「上个月华东区销售额 Top5 的商品」这类问题落成 SQL 并执行。
- 多条件数据分析:时间范围 + 类别 + 地区 + 阈值等多维过滤,输出分组汇总与对比。
- 结果解读:把结果集翻译成业务结论,说明口径、注意事项与数据边界。
When to Use
在以下情形加载本技能:
- 用户给出数据库连接信息或表名,要求「查一下」「统计一下」「对比一下」「看趋势」。
- 用户贴出建表语句(DDL)、字段清单、ER 描述,要求据此写查询。
- 用户问「这只表的数据质量怎么样」「为什么这个 SQL 慢」「这个指标怎么算」。
- 用户提到 OceanBase、seekdb、MySQL、SQL、索引、慢查询、分库分表。
不适用:数据仓库全链路建模、离线 ETL 调度、非关系型数据库(MongoDB/Redis)操作。
Core Workflow
严格按下列顺序推进,不要跳过结构探查直接写 SQL。
步骤 1:确认连接状态
python scripts/query.py status
- 输出
READY:环境变量已配置,可直连真实库。 - 输出
DEMO:未配置凭证,进入内置演示数据集(订单/商品/客户三张表)。此时必须明确告知用户"当前为演示数据",不得把演示结果当成真实数据汇报。
步骤 2:探查结构
python scripts/query.py schema # 全部表与字段
python scripts/query.py schema orders # 单表详情
python scripts/query.py sample orders 5 # 采样 5 行看真实取值
写 SQL 前必须知道:字段真实名称(不是用户口语)、时间字段是 date 还是 datetime、金额是否含税、状态字段的枚举值。
步骤 3:把问题拆成可校验的查询
用 scripts/nl2sql.py 组装提示词,或直接按以下模板手工构造:
python scripts/nl2sql.py --question "上个月华东区销售额 Top5 的商品" --schema-out schema.json
生成提示词时必须包含:库表结构、字段含义、时间口径(默认自然月)、聚合函数、排序与限制条数。
若配置了 MODELSCOPE_API_TOKEN,可加 --call 直接调用模型产出 SQL;否则只输出提示词,由当前 Agent 自行推理。
步骤 4:执行并校验
python scripts/query.py run "SELECT ... ;" --limit 200
执行后必须做三项核对:
- 总量核对:分组结果求和是否与不加分组的总额一致。
- 空值核对:过滤条件字段是否有 NULL,是否需要
COALESCE。 - 口径核对:时间边界(
>= 月初 AND < 下月初)、去重(DISTINCT)、退款/取消单是否要剔除。
只允许 SELECT、SHOW、DESCRIBE、EXPLAIN、WITH 开头的语句;写操作需用户显式确认,且技能本身不提供写库能力。
步骤 5:输出结论
按固定三段式回复:
【查询口径】时间/范围/过滤条件一句话说明
【结果】Markdown 表格(列名用中文别名,数值保留合理精度)
【解读】2-3 条业务结论 + 数据边界提示(如样本量小、存在 NULL、演示数据)
Scripts
| 脚本 | 用途 | 关键参数 |
| --- | --- | --- |
| scripts/query.py | 连接状态、结构探查、执行只读 SQL、演示模式 | status / schema [表名] / sample 表名 N / run "SQL" / demo |
| scripts/nl2sql.py | 由自然语言 + 表结构生成 text2sql 提示词,可选调用模型 | --question --schema-out --call |
| scripts/db_client.py | 内部数据访问层,被上面两个脚本复用 | 环境变量驱动,勿直接暴露给用户 |
Examples
例 1:结构探查
python scripts/query.py schema
输出每张表的字段名、类型、是否可空、主键与注释,作为后续写 SQL 的依据。
例 2:多条件分析
用户问:"2024 年第二季度,华东区已完成订单里销售额前 5 的商品是什么?"
python scripts/query.py run "
SELECT p.product_name AS 商品,
SUM(o.amount) AS 销售额,
COUNT(*) AS 订单数
FROM orders o JOIN products p ON o.product_id = p.product_id
WHERE o.order_date >= '2024-04-01' AND o.order_date < '2024-07-01'
AND o.region = '华东' AND o.status = 'completed'
GROUP BY p.product_name
ORDER BY 销售额 DESC
LIMIT 5;"
例 3:无数据库时的自检
python scripts/query.py demo
在 SQLite 内置数据集上跑通全链路,用于验证技能可用性与演示。
Quality Rules
- 绝不编造数据:查询失败就报错并给出修正建议,不得用"大致是"填补结果。
- 绝不猜字段名:字段名一律来自
schema输出。 - 凭证不进文件:连接信息只从环境变量读取;禁止把密码、Token 写进 SQL、日志、示例或任何交付文件。
- 大结果集先聚合:
run默认限制 200 行,需要全量时先COUNT(*)再决定是否分页导出。 - destructive 操作一律拒绝:
DROP、DELETE、UPDATE、TRUNCATE、ALTER需用户明确确认,且建议先SELECT预览影响行数。
Troubleshooting
| 现象 | 原因 | 处理 |
| --- | --- | --- |
| ModuleNotFoundError: pymysql | 未安装驱动 | pip install -r requirements.txt |
| DEMO 但用户以为是真库 | 环境变量缺失 | 明确提示补 OB_* 变量后重跑 status |
| 连接超时 | 白名单/端口/网络 | 检查 OB_HOST、OB_PORT、安全组 |
| 中文乱码 | 字符集不一致 | 连接串固定 charset=utf8mb4 |
| 时间结果差一天 | datetime 与 date 混用 | 统一用 >= 起 AND < 止 半开区间 |
References
references/connect-guide.md:OceanBase / seekdb / MySQL 连接参数与环境变量说明。references/sql-cookbook.md:分组汇总、同环比、TopN、留存、去重计数等常用分析 SQL 模板。
微信扫一扫