摘要:通过上图的实现完成了下面的效果,能够回答数据元模型相关的关于业务域、应用系统、数据实体相关的问题,同时也能够根据查询、统计问题从元模型获得数据库表定义从而生成对应的查询SQL。
问答执行
通过上图的实现完成了下面的效果,能够回答数据元模型相关的关于业务域、应用系统、数据实体相关的问题,同时也能够根据查询、统计问题从元模型获得数据库表定义从而生成对应的查询SQL。
演示视频:下一步,迈向ChatBI ... 吗?
作为知识图谱的基础构建了一个关于业务域、应用、数据实体、物理表、字段的元模型。这边部的编制是通过一个高阶的数据架构图实现的。
数架构
将架构图转化为图数据库中的节点和边进行存储,并通过为大模型提供恰当的提示词,便可取得较理想的效果,使大模型能够有效提取元模型的数据架构信息。
Agent执行过程如下:
08:27:23.067 graph run start=PlanGen08:27:23.069 run node PlanGen08:27:23.103 plan_agent run prompt=统计本月'资金账户收入流水'的总金额08:27:23.135 preparing model requestparams run_step=108:27:23.139 model request08:27:41.471 handle model response08:27:41.477 run node StepRunner08:27:41.479 run node MetaCypherGen08:27:41.480 age_agent run prompt=查找与'资金账户收入流水'相关的数据实体、对应的物理表名称以及所有相关列(尤其是涉及金额和日期的列)08:27:41.481 preparing model request params run_step=108:27:41.482 model request08:28:19.876 handle model response08:28:19.882 Validate Age query08:28:19.971 run node AgeCypherQuery08:28:20.052 Age Query08:28:20.056 query: 这个查询用于查找名称为'资金账户收入流水'的数据实体(Entity),其定义的物理表(Table),以及该 表中所有列名包含'金额'或'日期'关键词的相关列(Column)。这里假设了存在一种`HAS_COLUMN`关系连接物理表和列,并且`Column`节点具有`name`属性来存储列名。如果图数据库模式有所不同,可能需要调整这部分以匹配实际的关系类型和属性。- `MATCH (e:Entity {name: '资金账户收入流水'})-[:DEFINE]->(t:Table)`:首先定位到指定的数据实体及其关联的物理表。- `OPTIONAL MATCH (t)-[:HAS_COLUMN]->(c:Column)`:然后尝试找到这些物理表所拥有的列。使用`OPTIONAL MATCH`确保即使没有相关列时也能返回实体和表的信息。- `WHERE c.name =~ '.*金额|.*日期'`:筛选出列名中含有'金额'或'日期'字样的列。- `RETURN e, t, COLLECT(c) AS related_columns`:最终返回数据实体、物理表及符合条件的列集合。08:28:20.056 query: SELECT * FROM cypher('fsg_model', $$MATCH (e:Entity {name: '资金账户收入流水'})-[:DEFINE]->(t:Table)OPTIONAL MATCH (t)-[:HAS_COLUMN]->(c:Column)WHERE c.name =~ '.*金额|.*日期'RETURN e, t, COLLECT(c) AS related_columns$$) AS (e agtype, t agtype, related_columns agtype);08:28:20.310 result rows: 108:28:20.315 run node StepRunner08:28:20.318 run node SqlGen08:28:20.321 sql_agent run prompt=问题:基于上一步提供的物理表和列信息,生成一个SQL查询来计算本月'资金账户收入流水' 的总金额参考物理表:[{"id": ...har(32)"}, {"name": "update_time", "dtype": "timestamp(0)"}]}]08:28:20.323 preparing model request params run_step=108:28:20.326 model request08:28:24.401 handle model response08:28:24.402 preparing model request params run_step=208:28:24.403 model request08:28:28.310 handle model response08:28:28.318 run node StepRunner至此我们能够通过用户问问题获得SQL进行数据库查询。关于复杂数据表关系,我们可以在数据实体关系上预先做好定义然后就能够得到一些比较复杂关系的SQL生成了。
q = "本月按结算客户的账单收款匹配金额"06:53:36.348 sql_agent run prompt=问题:本月按结算客户的账单收款匹配金额参考物理表:[{"id": 2814749767106693, "name": "\...= t_bank_refund_statement.revenue_account`\u8fdb\u884cJOIN\n"]06:53:36.357 preparing model request params run_step=106:53:36.358 model request06:54:11.324 handle model response06:54:11.325 preparing model request params run_step=206:54:11.326 model request06:54:19.469 handle model response生成SQL
SELECT t_bill.settle_cust_no AS "结算客户编号",t_bill.settle_cust_name AS "结算客户名称",SUM(t_collect_arrange_record.match_amount) AS "匹配金额"FROM cdps_orcl.cdps_user.t_bill t_billJOIN cdps_orcl.cdps_user.t_acct_subtotal t_acct_subtotal ON t_bill.bill_no = t_acct_subtotal.bill_noJOIN cdps_orcl.cdps_user.t_collect_arrange_record t_collect_arrange_record ON t_acct_subtotal.bill_no = t_collect_arrange_record.biz_noAND t_acct_subtotal.id = t_collect_arrange_record.subtotal_idAND t_collect_arrange_record.match_type = 'CW-SKPP-01'WHERE DATE_TRUNC('month', t_bill.create_time) = DATE_TRUNC('month', now)GROUP BY t_bill.settle_cust_no,t_bill.settle_cust_namePS:这是没有经过提示词优化或者微调的结果。
下一步呢?通过元模型的知识图谱支持能够生成SQL并执行数据查询,有了这些支持是否能够达到ChatBI这一目标?
实现ChatBI是一个分阶段的复杂工程,现有的图数据库元模型查询与SQL生成能力是重要基础,但要达到真正可用、用户友好的产品化阶段,还需系统性解决以下关键问题:
技术架构分层实现(以二层架构为例,不用中间DSL层是因为我们有统一跨数据库访问层)
语义理解层 采用混合模型(如BERT+规则引擎)处理歧义性问题 构建领域知识图谱增强实体识别(如将"GMV"映射到orders.total_amount) 示例:用户问"华北区门店的月流水",需识别"华北区"=region_id IN ('BJ','TJ'),"月流水"=SUM(amount) GROUP BY MONTH(date) 是否有必要生成一段中间的DSL的查询定义再转换为SQL?执行优化层 SQL重写优化(如将CORRELATED SUBQUERY改为JOIN) 查询结果缓存策略(TTL设置、缓存失效机制) 分页处理:将LIMIT 1000改为ROW_NUMBER窗口函数模糊查询处理,"卖得最好的产品"背后被隐含的意义指标智能推导,"客户活跃度"具体是什么多表关联路径选择,可以通过3张表join和4张表join的怎么选可以看到走的了这里出现的线头也越来越多了,当前技术栈已能支撑ChatBI的基础实现,但真正的挑战在于:如何将准确率从70%提升到95%(最后5%需处理大量长尾问题),以及如何设计符合认知心理学的交互流程。而且,ChatBI是未来吗?目前我还没有找到答案。
来源:immortal17