跳到主要内容

如何搭建一个可用的 ChatBI

本文以零售行业为例介绍如何搭建一个可用的 ChatBI。

1. 概述

1.1. 业务调研

1.2. 通过ChatBI能实现的效果

  1. 通过前台问数即问即答获取数据结果
  2. 当提问涉及具体指标时,可自动判断指标是否发生异动、异动原因是什么,并进一步呈现数据背后发生的商业行为
  3. 当系统输出数据分析结论时,同步输出可执行的策略建议

2. 主题建设

2.1. 准备数据

在创建 ChatBI 主题之前需要准备好接入的数据集,数据集接入可参考 数据准备。数据集要求如下:

  • 单个主题建议使用 同一种类型 的数据集,例如都是 Spark 或 MySQL 或 StarRocks 数据集
  • 数据集表名、字段名 避免使用英文、数字 等难以理解业务含义的描述,数据集表名 避免使用空格和特殊符号,数据集表名和字段名 避免重名
  • 不同数据集 避免使用相似 难以区分差异的名称
  • 时间/日期字段尽量 避免使用 字符串格式

接入哪些数据集可根据需要满足的问题倒推。

例如:查看2025年1月以来杭州店每日的客单量,此时我们需要接入门店的销售日表。

2.2. 开通权限

  1. 在 BI 平台开通ChatBI相关权限,详细操作可参考权限配置

  1. 在ChatBI运营管理后台为不同用户赋予所有者/访问者权限,详细操作可参考 权限赋予
    • 所有者权限:该用户能在运营管理后台看到当前主题,并对主题名称、基础配置、知识库配置及权限配置进行修改;同时,用户能在问数前台对该主题进行提问。
    • 使用者权限:该用户能在问数前台对该主题进行提问。

2.3. 创建主题

支持创建多个主题,如何创建主题可参考新建主题

说明

首次创建主题时建议基于单表创建,在单表问答准确率达到80%后,再扩展其他表进行问答。

主题创建主要包含基础信息、关联数据集与知识库三部分内容。

2.3.1. 主题基础信息

主题基础信息包含主题名称、主题描述、问答头像以及欢迎语,在前台问数时展示效果如下。

基础信息配置可参考基础配置

2.3.2. 主题数据

数据集描述、数据集结构和字段注释会作为模型学习知识,如未维护将影响模型回答准确性。

支持关联多个数据集,数据集相关操作详见数据集配置

2.3.3. 主题知识库

主题知识库包含「业务知识库」和「错题集」。

  • 业务知识库

    • 通用知识:每次提问都会参考的知识信息
    • 业务知识:当与提问内容相似/关联,才会参考的知识信息
  • 错题集:当与提问内容相似/关联,才会参考的SQL逻辑

  • 是否需要添加知识,取决于问答效果,而不是按照以下要求刻板地维护。
  • 知识维护优先级:「业务知识库」>「错题集」。

2.3.3.1. 业务知识库

业务知识库相关配置可参考业务知识库

2.3.3.1.1. 添加「通用知识」

  • 针对 数据集 的知识

    • 说明【主键】:“<xxx资产明细表>的主键是月份客户编号。”
    • 说明【字段含义】:“<商品维表>中的商品状态用于判断是否在售。”
    • 说明【关联关系】:“<订单明细表>用货号关联<商品维表>,<订单明细表>用店铺编码关联<门店维表>。”
    • 说明【业务场景】:“<xxx资产明细表>的数据包含了客户信息(开户日期、所属营业部/分公司、客户类型等)以及客户在该月份的资产、创收情况。”
    • 说明【表选择、查询优先级】当表名接近容易歧义时,可以添加知识:“涉及商品相关问题时,查询<门店_商品销售日表>,否则都查询<门店销售日表>。”
  • 针对 时间条件 的知识

    • 【字段选择】当存在多个时间字段容易引发歧义时,可以添加知识:“月份是业务发生所在的月份(YYYYMM的STRING类型)。开户日期是用户的开户时间,是该客户的用户属性,仅用于统计新开户、当月开户指标。”

    • 【周/月的定义】当周的统计口径需要统一定义时,可以添加知识:“数据库的dayofweek默认周日是1,但在中国,默认每周的开始是周一。计算本周起始的方法是通过DATE_SUB(CURRENT_DATE, INTERVAL(DAYOFWEEK(CURRENT_DATE) + 5) % 7 DAY)来找到本周一,计算上周起始的方法是先找到本周的起始,再减7天。”

    • 【语义匹配】当需要定义模糊时间条件时,可以添加知识:

      • “当提问涉及<最近>作为时间条件时,默认查询最近3个月的数据。”
      • “当提问涉及<近一个月>作为时间条件时,默认查询过去30天的数据。”
      • “本周:业务日期大于等于本周起始,小于等于今日。上周:业务日期大于等于上周起始,小于等于上周末。最近7天、最近一周:业务日期小于等于昨日,大于等于当前日期减7天。”
    • 【业务常识】当业务上有时间统计口径需要统一定义时,可以添加知识:“每个月 6 号是门店的会员日。”

    • 【默认时间条件】当需要默认时间条件时_(不推荐)_,可以添加知识:“如果提问里没有明确时间,默认都要筛选业务日期是昨天,不要直接统计累计值,除非提问中指定了具体时间条件(日/周/月)。”

  • 针对 几乎所有提问都适用 的知识,或者说是 数据集【全局筛选条件】

    • 当需要剔除不可用数据时,可以添加知识:“<销售表>的所有查询都要限制销售金额不为空。”
    • 当仅使用符合业务逻辑的数据时,可以添加知识:“<销售表>的所有查询都要限制门店状态为“正常营业”。”
  • 针对 自定义回复 的知识,添加至_「通用知识」_,例如:“当提问涉及美团、人效、抖音、库存、采购、配送、订货、周转、仓库、保质期时,回复用户:目前尚未包含这些业务数据,等待后续数据更新。”

2.3.3.1.2. 添加「业务知识」

  • 针对 名词映射 的知识

    • 【字段选择】当专有名词指代特定字段,或特定场景使用特定字段时,可以添加知识:

      • “产品类型、产品业务类型、 产品来源、产品类别都是相同概念,指的是产品业务类型(产品来源类别)字段(包含otc、公募、私募)。”
      • “品牌:<销售表>中的销售品牌,<目标表>的品牌名称。”
      • “督导指OFC,区经指DM,战区负责人指ZM。”
      • “提问涉及商品具体的规格时,例如:克/千克/g/kg/毫升/升/ml/L/片/条/支/只,都使用商品全称进行过滤,只有不包含具体规格时使用商品名称进行过滤。”
    • 【局部筛选条件】当专有名词指代特定筛选条件时,可以添加知识:

      • “核心会员: 人群资产类型 IN ("一单会员", "多单会员")。”
      • “在售商品:商品状态 = "正常",百货商品:一级品类名称 = "非休闲食品",低温商品:一级品类名称 = "冷冻冷藏"。”
      • “呆滞资产/呆滞用户资产/呆滞用户/呆滞人群/呆滞会员都是相同概念:人群资产类型 IN ("休眠会员", "流失会员")。”
      • “植物面膜:(sku IN ('50269','99802') OR 商品名称 LIKE '%植物%' AND 商品名称 LIKE '%面膜%')。”
      • “批发店、批发超市、百货店都是相同概念:门店版本 LIKE '%百货店%'。”
  • 针对 计算逻辑 的知识

    • 说明【指标公式】可以添加知识:

      • “转化率 = 转化人数 / 跟进人数,跟进率 = 跟进人数 / 触发人数。”
      • “购买件数:SUM(销售数量) ,购买人数:COUNT(DISTINCT 消费者唯一标识),客件数: 购买件数 / 购买人数。”
      • “门店数量 = COUNT(DISTINCT 门店ID),毛利率 = SUM(销售毛利)/SUM(销售金额),客单价 = SUM(销售金额)/SUM(销售订单个数)。”
      • ““亏损”、“损益”都是指代相同指标:亏损金额 = SUM(门店总成本)-SUM(毛利额),净利润 = SUM(毛利额)-SUM(门店总成本)。”
    • 说明【单/多步骤查询逻辑】可以添加知识:

      • “长尾商品:将商品按销售金额升序排序,计算这些商品的累计销售金额,累计销售金额达到总金额20%时,已经统计的商品属于长尾商品;头部商品:将商品按销售金额降序排序,计算这些商品的累计销售金额,累计销售金额达到总金额80%时,已经统计的商品属于头部商品”
      • “【同环比】提问涉及周的同环比、月的同环比,周之间的对比、月之间的对比,都要限制相同的统计天数,例如:在周五提问“本周销售额及环比上周表现”,计算的是本周一到周四的销售额,环比上周一到周四的销售额;例如:在某月20日提问“本月销售额及环比上月表现”,计算的是本月1日到昨天的销售额,环比上个月1日到相同天数的销售额。”
      • “【关于预测】提问涉及”预测“、“预估”、“估算”时,默认先计算最近7日的日均数据,再根据最近7日的日均值预测未来数据。预测本周,指的是从本周起始到本周末;预测本月,指的是完整月份,需要按完整月份天数进行统计。”
  • 针对 可视化展示 的知识

    • 当需要默认展示某些字段时,可以添加知识:

      • “查询涉及门店详情、门店列表时默认都显示门店名称,但不显示门店编码,除非提问中明确需要显示门店编码。”
      • “提问涉及ofc、dm、zm、督导、战区负责人中任意一个时,所有查询必须显示对应的大战区小战区。”
    • 当特定场景需要包含指定字段时,可以添加知识:

      • “提问涉及“亏损”、“损益”,或“成本”、“利润”时,除了统计相关指标,还要同时统计成本明细项供用户参考:房租成本人工成本水电成本购物袋费成本渠道手续成本杂项成本物流成本等。”
      • “提问涉及“销售情况”时计算以下指标:销售金额、销售数量、毛利、毛利率。”
  • 针对 语义澄清 的知识

    • 当提问可能指代多个字段或筛选条件,或存在歧义时,可以添加知识:

      • “当用户提到<城市名>时,请让用户明确提问中的城市名,具体是指城市仓库还是大区。”
  • 针对 临时解决方案 的知识

    • 【枚举值匹配】当提问涉及具体字段的枚举值,但与枚举值又不完全一致,需要通过模糊匹配查询时,可以参考知识:

      • “涉及门店、商品名称时,根据对应字段已检索到的value examples,进行分词和模糊匹配,如提问”泸定成武路店“,示例值有“泸定县成武路店”,则条件为like '%泸定%' and like '%成武路%',这样才能确保匹配到当前已检索到的值。如果没有较匹配的示例值,如用户查询”银泰城南湖国际门店“,示例值只有”天府新区南湖国际社区店“,没有“银泰城”相关门店,则直接反问用户进行澄清。如果存在数字含义的词(阿拉伯数字/汉字),必须同时匹配两种形态,如 like '%24%' or like '%二十四%'。另外,门店指标如果使用了模糊匹配,需按门店分组聚合统计”
      • “【英文大小写匹配】提问涉及英文字符时,需要先将条件统一转为大写后再进行匹配。例如:abc的销售额是多少,需要筛选UPPER(品牌名称) = UPPER("abc")。娃哈哈ad钙奶销售额是多少,需要筛选UPPER(商品名称) LIKE "%UPPER("娃哈哈ad钙奶")%"”
    • 【错误处理】当移动端语音转文字准确率不高,需要将错误文本转化为可理解的业务名词时,可以参考知识:

      • 【错字、同音字转义】用户提问都是和连锁零食批发销售相关的场景,会有很多门店、商品、店均销、日均销,相关零食维度指标问题出现;针对输入错误的文字比如 ‘电均销‘对应'店均销',字大概率是
2.3.3.2. 错题集

错题集相关配置可参考错题集

  • 针对 极小范围、特殊或唯一 的情况,添加至「错题集

    除「业务知识库」中指定情况以外的更特殊情况

  • 针对 逻辑复杂、条件繁多(业务知识难以清晰维护) 的提问情况,添加至「错题集

    • 当根据“长尾商品”定义进行查询涉及窗口函数等复杂逻辑时,可以添加错题集:
WITH `store_goods` AS (
SELECT `商品编码`, `商品名称`, SUM(`销售金额`) AS `销售额`
FROM `@CHatBI_全国门店商品销售数据_按天`
WHERE `业务日期` >= '2025-04-01'
AND `业务日期` <= '2025-04-30'
AND `门店名称` LIKE '%德昌%'
AND `门店名称` LIKE '%育才%'
AND `门店名称` LIKE '%路%'
AND NOT `销售金额` IS NULL
GROUP BY `商品编码`, `商品名称`
),
`total_sales` AS (
SELECT SUM(`销售额`) AS `总销售额`
FROM `store_goods`
),
`ranked_goods` AS (
SELECT `商品编码`, `商品名称`, `销售额`
, SUM(`销售额`) OVER (ORDER BY `销售额` ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS `累计销售额`
FROM `store_goods`
)
SELECT `商品编码`, `商品名称`, `销售额`
, ROUND(`累计销售额` / `总销售额`, 4) AS `累计占比`
FROM `ranked_goods`, `total_sales`
WHERE `累计销售额` / `总销售额` <= 0.2
ORDER BY `销售额` ASC
    • 当本周的周度环比,需要限制上周相同天数时,可以添加错题集:
WITH `date_ref` AS (
SELECT DATE_SUB(CURRENT_DATE, INTERVAL (DAYOFWEEK(CURRENT_DATE) + 5) % 7 DAY) AS `本周起始`
, DATE_SUB(DATE_SUB(CURRENT_DATE, INTERVAL (DAYOFWEEK(CURRENT_DATE) + 5) % 7 DAY), INTERVAL '7' DAY) AS `上周起始`
),
`cur` AS (
SELECT SUM(`销售金额`) AS `本周销售额`
FROM `@CHatBI_全国门店销售数据_按天`, `date_ref`
WHERE `大战区` LIKE '%川东南%'
AND `业务日期` >= `date_ref`.`本周起始`
AND `业务日期` <= DATE_SUB(CURRENT_DATE, INTERVAL '1' DAY)
AND NOT `销售金额` IS NULL
),
`pre` AS (
SELECT SUM(`销售金额`) AS `上周销售额`
FROM `@CHatBI_全国门店销售数据_按天`, `date_ref`
WHERE `大战区` LIKE '%川东南%'
AND `业务日期` >= `date_ref`.`上周起始`
AND `业务日期` < DATE_ADD(`date_ref`.`上周起始`, INTERVAL DATE_DIFF('DAY', DATE_SUB(CURRENT_DATE, INTERVAL '1' DAY), `date_ref`.`本周起始`) DAY)
AND NOT `销售金额` IS NULL
)
SELECT `cur`.`本周销售额`, `pre`.`上周销售额`, `cur`.`本周销售额` - `pre`.`上周销售额` AS `环比变化`
, CASE
WHEN `pre`.`上周销售额` = 0
OR `pre`.`上周销售额` IS NULL
THEN NULL
ELSE ROUND((`cur`.`本周销售额` - `pre`.`上周销售额`) / `pre`.`上周销售额`, 4)
END AS `环比变化率`
FROM `cur`, `pre`
    • 当本月的月度同环比,即MTD业务指标同环比的上月同期、去年同期也需要限制相同天数时,可以添加错题集:
WITH `cur_month` AS (
SELECT SUM(`销售金额`) AS `本月销售额`
FROM `@CHatBI_全国门店销售数据_按天`
WHERE `城市` LIKE '%成都%'
AND `业务日期` >= DATE_FORMAT(CURRENT_DATE, '%Y-%m-01')
AND `业务日期` <= DATE_SUB(CURRENT_DATE, INTERVAL '1' DAY)
AND NOT `销售金额` IS NULL
),
`last_month` AS (
SELECT SUM(`销售金额`) AS `上月同期销售额`
FROM `@CHatBI_全国门店销售数据_按天`
WHERE `城市` LIKE '%成都%'
AND `业务日期` >= DATE_SUB(DATE_FORMAT(CURRENT_DATE, '%Y-%m-01'), INTERVAL '1' MONTH)
AND `业务日期` <= DATE_SUB(DATE_SUB(CURRENT_DATE, INTERVAL '1' DAY), INTERVAL '1' MONTH)
AND NOT `销售金额` IS NULL
),
`last_year` AS (
SELECT SUM(`销售金额`) AS `去年同期销售额`
FROM `@CHatBI_全国门店销售数据_按天`
WHERE `城市` LIKE '%成都%'
AND `业务日期` >= DATE_SUB(DATE_FORMAT(CURRENT_DATE, '%Y-%m-01'), INTERVAL '1' YEAR)
AND `业务日期` <= DATE_SUB(DATE_SUB(CURRENT_DATE, INTERVAL '1' DAY), INTERVAL '1' YEAR)
AND NOT `销售金额` IS NULL
)
SELECT `c`.`本月销售额`, `l`.`上月同期销售额`, `y`.`去年同期销售额`, `c`.`本月销售额` - `l`.`上月同期销售额` AS `环比变化`
, CASE
WHEN `l`.`上月同期销售额` = 0
OR `l`.`上月同期销售额` IS NULL
THEN NULL
ELSE ROUND((`c`.`本月销售额` - `l`.`上月同期销售额`) / `l`.`上月同期销售额`, 4)
END AS `环比变化率`, `c`.`本月销售额` - `y`.`去年同期销售额` AS `同比变化`
, CASE
WHEN `y`.`去年同期销售额` = 0
OR `y`.`去年同期销售额` IS NULL
THEN NULL
ELSE ROUND((`c`.`本月销售额` - `y`.`去年同期销售额`) / `y`.`去年同期销售额`, 4)
END AS `同比变化率`
FROM `cur_month` `c`, `last_month` `l`, `last_year` `y`

避免添加过于简单或非长期有效的「错题集」

  • 【过于简单】可以通过业务知识库高效维护,例如:【提问】2025年2月xxx商品的销售金额是多少?
  • 【非长期有效】提问是相对日期,SQL条件是绝对日期,例如:【提问】昨天的销售金额是多少?【错题集SQL】的条件日期= "2025-03-01"

2.4. 测试主题

用于批量测试问答效果,评估问答准确性(准确率计算仅针对测试中的提问)。

建议主题测试准确率90%及以上后再投入生产。若准确率较低,可通过对数据集添加数据集描述和字段注释、增加更多的错题集、增加更多的业务知识来提升问答准确性。

2.4.1. 测试步骤

①添加问题/批量导入 → ②判断数据结果是否正确 → ③判断SQL是否正确 → ④新增/修改知识 → ⑤重新测试

2.4.2. 注意事项

问数原则:符合有效提问的基本结构([时间范围] + [条件(如果有)] + [数据指标]),时间/条件/指标清晰明确、避免歧义

2.4.3. 报错的原因和处理

可参考故障排除进行处理。

  • 有数据,但与业务常识不符或与BI有出入(SQL条件错误) 新增/修改知识后再次测试

  • 暂无数据(SQL条件错误/数据源缺失/无数据权限) 确保数据源未缺失、数据权限开通的情况下,新增/修改知识后再次测试

  • 数据查询失败(SQL语法错误/接口异常) 检查SQL语法是否正确,包括表名/字段名的引号、函数使用规范等。如频繁出现该问题需联系观远进行排查。

  • SQL有效性不通过
    建议勾选后重新测试,如频繁出现该问题需联系观远进行排查。

2.5. 上线主题

当主题测试准确率达90%以上可正式启用该主题,启用后的主题可在前台问数时进行切换选择。

3. 主题运维

3.1. 使用追踪

用于追踪历史对话,排查问答效果,包括知识在每个对话中的应用情况。

3.1.1. 前台问答

3.1.1.1. 有效提问

基本结构:[时间范围] + [条件(如果有)] + [数据指标],例如:

  • 2024年xxx公司xxx客户的净资产和总创收是多少?
  • 2024年客户数最多的10个员工来自哪些营业部?这些营业部对应的年度创收和同比情况如何?
  • 3月xxx商品有多少订单量和期末库存?其中多少是散单订单,散单占比多少?
  • 三季度xxx地区xxx门店xxx商品的销售额、毛利、毛利率是多少?
  • 2024年下半年月销售额持续下降的门店有哪些?
说明

提问是否符合以上基本结构,直接影响问答准确率、知识库维护的难度。

3.1.1.2. 前台问答步骤
  • ①前台问数 → ②判断数据结果是否正确 → ③判断SQL是否正确 → ④查看运维日志定位原因 → ⑤新增/修改知识 → ⑥再次问数测试
3.1.1.3. 注意事项
  • 问数原则:符合有效提问的基本结构([时间范围] + [条件(如果有)] + [数据指标]),时间/条件/指标清晰明确、避免歧义

  • 提问出错并新增/修改知识后,再次问数测试需 避免与原问题完全一致(问答生成SQL存在缓存机制)

3.1.2. 故障排除

3.1.2.1. 排查流程&案例

3.1.2.2. 问答错误分类

除SQL错误以外,其余问题排查参考常见问题排查指南

3.1.2.3. 运维日志

运维日志包含以下信息,用于判断哪些影响了当前问答效果

  • 相关表信息(数据集结构、字段枚举值 Value examples)
  • 相关业务知识( 「业务知识」中与当前提问有关的条目)
  • 相关训练样本( 「错题集」中与当前提问有关的条目)

3.2. 知识迭代

在前台问答的过程中不断新增/修改知识,完善知识库建设

文档AI助手
观远AI助手关闭