通过配置业务上下文,SQLBot开源智能问数系统可以实现智能问数“越问越准”的目标。SQLBot的最佳应用实践是通过表管理、表关联关系管理、术语配置、示例SQL和自定义提示词五大配置项,让AI生成的查询更贴合库表结构、更符合业务语义与查询逻辑,进而更懂业务,实现从“能生成SQL”到“一问就准、稳定可靠、可复用、可维护”的企业级Text2SQL能力升级。
SQLBot在社区版本中提供了表管理、表关联关系管理、术语配置、示例SQL的配置能力。在SQLBot专业版中,还提供了自定义提示词的配置能力。企业用户可以通过合理使用这五大配置项能力,让SQLBot更懂业务,更熟悉上下文,问数更精准。
本文通过电商CRM系统相关的多个业务场景,为您介绍SQLBot的具体配置方法和调试技巧。
一、五大配置项能力对比
SQLBot所提供的五个配置项分别从表和字段描述(即表管理)、表关系管理(即表关联关系管理)、术语配置(即自定义术语)、SQL示例库(即示例SQL)和自定义提示词这五个维度对齐业务意图,各自承担明确作用,又可相互配合、层层增强,最终能够大幅提升自然语言转SQL语句的准确率、召回率与可用性。
这五大配置项之间不是孤立的,而是层层递进、相互补充的关系:
1. 表和字段描述+表关系管理=基础能力(必须配置)
前者告诉模型“字段含义”,后者告诉模型“如何关联”,缺少任何一个,多表查询都会出错;
2. 术语配置=沟通桥梁(高频使用)
解决“业务语言”与“数据库语言”的鸿沟,让模型理解“大客户就是A级”、“制造业包含哪些行业”等问题的清晰准则;
3. SQL示例库=标准答案(针对性强)
解决特定、复杂、高频的查询问题,模型可以举一反三,将SQL示例应用到其他类似场景;
4. 自定义提示词=全局规则(补充约束)
定义适用于所有查询的通用规则,例如“销售额必须用actual_amount字段”、“日期查询默认查询最近30天”等。
配置路径建议:
第一步: 表和字段描述(地基),让模型知道每个字段是什么;
第二步: 表关系管理(桥梁),让模型知道表与表之间怎么连;
第三步: 术语配置(翻译器),让模型理解业务人员怎么说;
第四步: SQL示例库(教科书),给模型提供复杂查询的标准答案;
第五步: 自定义提示词(规则手册),告诉模型必须遵守的业务规则。
二、电商CRM系统智能问数配置案例
在本文中,我们将模拟一套电商CRM系统数据为例,将这套数据作为电商CRM系统数据源接入SQLBot。通过对电商CRM系统数据源及其中的数据进行SQLBot配置,展示在不同的使用场景中如何通过系统配置让AI更理解业务。
电商CRM系统数据源中包含的客户、订单、销售团队等核心表如下:
-- 1. 部门表(树形结构)
CREATE TABLE crm_departments (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(100) NOT NULL COMMENT '部门名称',
parent_id BIGINT NULL COMMENT '上级部门ID,NULL表示顶级部门',
dept_level INT NOT NULL COMMENT '部门层级:1-一级, 2-二级, 3-三级',
region VARCHAR(50) COMMENT '所属区域',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_parent_id (parent_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表';
-- 2. 销售人员表
CREATE TABLE crm_salespeople (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL COMMENT '姓名',
department_id BIGINT NOT NULL COMMENT '部门ID',
region VARCHAR(50) COMMENT '负责区域',
hire_date DATE COMMENT '入职日期',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES crm_departments(id),
INDEX idx_department_id (department_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='销售人员表';
-- 3. 客户表
CREATE TABLE crm_customers (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
customer_name VARCHAR(100) NOT NULL COMMENT '客户名称',
industry VARCHAR(50) COMMENT '所属行业',
customer_level VARCHAR(10) COMMENT '客户等级:A/B/C',
total_purchase DECIMAL(12,2) DEFAULT 0.00 COMMENT '累计采购金额',
last_order_date DATE COMMENT '最后下单日期',
contact_person VARCHAR(50) COMMENT '联系人',
contact_phone VARCHAR(20) COMMENT '联系电话',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_customer_level (customer_level),
INDEX idx_industry (industry),
INDEX idx_last_order_date (last_order_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户表';
-- 4. 商品表
CREATE TABLE crm_products (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(200) NOT NULL COMMENT '商品名称',
category VARCHAR(50) COMMENT '商品类别',
price DECIMAL(10,2) NOT NULL COMMENT '价格',
stock INT DEFAULT 0 COMMENT '库存',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_category (category)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
-- 5. 订单表
CREATE TABLE crm_orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(50) UNIQUE NOT NULL COMMENT '订单号',
customer_id BIGINT NOT NULL COMMENT '客户ID',
order_amount DECIMAL(10,2) NOT NULL COMMENT '订单总金额',
discount_amount DECIMAL(10,2) DEFAULT 0.00 COMMENT '优惠金额',
actual_amount DECIMAL(10,2) NOT NULL COMMENT '实际支付金额',
order_status VARCHAR(20) NOT NULL COMMENT '订单状态:UNPAID-未支付, PAID-已支付, CANCELLED-已取消, REFUNDED-已退款',
order_type VARCHAR(20) COMMENT '订单类型:NORMAL-普通, PRESALE-预售, GROUPON-团购',
salesperson_id BIGINT COMMENT '销售人员ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',
paid_at TIMESTAMP NULL COMMENT '支付时间',
FOREIGN KEY (customer_id) REFERENCES crm_customers(id),
FOREIGN KEY (salesperson_id) REFERENCES crm_salespeople(id),
INDEX idx_customer_id (customer_id),
INDEX idx_salesperson_id (salesperson_id),
INDEX idx_order_status (order_status),
INDEX idx_created_at (created_at),
INDEX idx_paid_at (paid_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
-- 6. 订单明细表
CREATE TABLE crm_order_items (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT NOT NULL COMMENT '订单ID',
product_id BIGINT NOT NULL COMMENT '商品ID',
quantity INT NOT NULL COMMENT '数量',
unit_price DECIMAL(10,2) NOT NULL COMMENT '单价',
subtotal DECIMAL(10,2) NOT NULL COMMENT '小计',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES crm_orders(id),
FOREIGN KEY (product_id) REFERENCES crm_products(id),
INDEX idx_order_id (order_id),
INDEX idx_product_id (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单明细表';
场景1:规范大模型对客户等级和行业范围的认知
在SQLBot未经配置的状态下,当用户对模拟电商CRM系统数据源进行智能问数,提出“统计制造业大客户的数量?”的问题时,大模型生成的SQL语句如下:
SELECT COUNT(`id`) AS `manufacturing_major_customer_count`
FROM `south`.`crm_customers` `c`
WHERE `c`.`industry` = '制造业'
AND `c`.`customer_level` IN ('A','B')
SQLBot使用以上SQL语句,在模拟电商CRM系统数据源进行查数后,对提问作出的回答如下,未能如实反映原数据中的“制造业大客户数量”。
在此场景中,智能问数回答有误,主要是由以下原因导致的:
■ 大模型不理解“大客户”在数据库中对应的评级标准(准确评级为A级客户),无法精准查询;
■ 大模型不能匹配到“制造业”这一关键词在数据库中所属的具体字段数据,无法精准查询。
对于大模型不能如实反映“制造业大客户数量”这一问题的解决方案如下:
第一步:添加表和字段描述。 让大模型理解在客户表crm_customers中,字段customer_level的数值对应客户等级的评级标准,以及字段industry包含对应客户所属行业的关键词范围。
【表描述 - customers】
客户表,存储所有已签约的企业客户信息,包括客户基本信息、等级评定和历史交易数据。
【字段描述 - customer_level】
客户等级,根据年采购金额评定:
A级:年采购额 >= 100万
B级:年采购额 50-100万
C级:年采购额 < 50万
【字段描述 - industry】
客户所属行业,包括但不限于:制造、IT、金融、零售、教育、医疗等。
部分客户会填写详细行业,如"电子制造"、"汽车制造"等。
第二步:术语配置。 建立用户口语与数据库标准值的映射关系,让大模型可以将电商CRM系统数据源中满足“customer_level = 'A'”条件的客户识别为“大客户”,并可以通过模糊匹配“LIKE'%制造%'”识别出所属行业为“制造业”的用户。
【术语名称】大客户/重点客户/优质客户/VIP客户
【术语描述】这些都指 customer_level = 'A' 的客户,即年采购额达到100万以上的企业客户。查询时使用条件:WHERE customer_level = 'A'
【术语名称】制造业/制造/生产企业/工厂
【术语描述】指所属行业为制造相关的客户,包括:
industry = '制造'
industry LIKE '%制造%'(匹配"电子制造"、"汽车制造"等)
industry LIKE '%生产%'
查询时建议使用模糊匹配:WHERE industry LIKE '%制造%'
完成表管理配置和术语配置后,再一次向SQLBot智能问数提问“统计制造业大客户的数量”,大模型就可以生成正确的SQL语句:
SELECT COUNT(`t1`.`id`) AS `manufacturing_vip_customer_count`
FROM `south`.`crm_customers` `t1`
WHERE `t1`.`industry` LIKE '%制造%' # 正确识别"制造业"
AND `t1`.`customer_level` = 'A' # 正确识别"大客户"
使用正确的SQL语句,SQLBot可以从数据源中查询出问题的正确结果,即制造业大客户的实际数量:
场景2:客户订单金额的细节理解偏差
在SQLBot未经配置的状态下,当用户对模拟电商CRM系统数据源进行智能问数,提出问题“每个客户的订单总金额是多少?”时,大模型生成的SQL语句如下:
SELECT `c`.`customer_name` AS `customer_name`,
SUM(`o`.`order_amount`) AS `total_order_amount`
FROM `south`.`crm_customers` `c`
JOIN `south`.`crm_orders` `o` ON `c`.`industry` = `o`.`salesperson_id`
GROUP BY `c`.`id`
ORDER BY `total_order_amount` DESC
SQLBot使用以上SQL语句,在模拟电商CRM系统数据源进行查数后,对提问作出回答。我们看到,回答未能如实反映用户想要查询的“客户订单总金额”(实际订单金额,不包括未支付和已退款订单)。
▲图5 未经配置的SQLBot对订单金额计算问题不能正确回答
在此场景中,智能问数回答有误主要是由以下原因导致的:
■ 大模型不能理解字段的实际含义,使用了错误的关联字段(c.industry= o.salesperson_id),大模型错误地把industry(行业)字段和salesperson_id(销售员ID)关联起来了。
注意:本次测试一共只有六张表,由于数据库表结构创建了对应索引,基本上多表关联查询的相关问题产生的SQL都比较准确。
■ 大模型写出的SQL语句中,查询的字段为order_amount(订单总金额)而非actual_amount(实际支付金额),大模型用了order_amount(订单原价)字段,而非actual_amount(实际支付)字段,导致统计金额包含了已优惠部分,虚增了收入。
■ 大模型写出的SQL语句没有筛选订单状态,包含了未支付和已退款的订单。
对于大模型不能如实回答用户想要查询的“客户订单总金额”这一问题的解决方案如下:
第一步:进行表关系管理。 明确告诉模型,将表crm_customers和表crm_orders通过customers.id(客户表ID)和orders.customer_id(订单表中的客户表ID)字段进行关联,避免使用错误的字段进行JOIN,确保多表查询的关联逻辑正确。
▲图6 设置表客户表crm_customers和订单表crm_orders的关联关系
第二步: 添加字段描述。说明customer_id字段表示客户ID,外键关联字段为customers表中的crm_customers.id;明确actual_amount字段为实际支付金额,是统计销售额使用的标准字段;order_status字段为订单状态,需要从中筛选出“PAID”(已支付)状态,便于模型选择正确的字段和条件。
【表描述 - crm_orders】
订单表,存储所有订单信息。
通过 customer_id 关联客户,通过 salesperson_id 关联销售人员。
【字段描述 - customer_id】
客户ID,外键关联 crm_customers.id,用于查询订单所属客户。
【字段描述 - order_amount】
订单总金额,未扣除优惠金额,仅用于记录原始金额,不用于销售额统计。
【字段描述 - actual_amount】
实际支付金额,已扣除优惠后的最终支付金额,是统计销售额的标准字段。
【字段描述 - order_status】
订单状态,枚举值:
UNPAID:待支付
PAID:已支付
CANCELLED:已取消
REFUNDED:已退款
统计销售额时,只统计 PAID 状态的订单。
▲图7 设置订单表crm_orders的表备注和字段备注信息
添加表关联关系和字段描述后,再一次向SQLBot提问“每个客户的订单总金额是多少?”,大模型就可以生成正确的SQL语句:
SELECT `c`.`customer_name` AS `customer_name`,
SUM(`o`.`actual_amount`) AS `total_order_amount`
FROM `crm_orders` `o`
JOIN `crm_customers` `c` ON `o`.`customer_id` = `c`.`id`
WHERE `o`.`order_status` = 'PAID'
GROUP BY `c`.`customer_name`
ORDER BY `total_order_amount` DESC
LIMIT 1000
使用正确的SQL语句,SQLBot可以从数据源中查询出问题的正确结果,即每个客户已正常支付的订单总金额:
场景3:理清销售额的计算逻辑
在SQLBot未经配置的状态下,当用户对模拟电商CRM系统数据源进行智能问数,提出问题“本月销售额是多少?”时,大模型生成的SQL语句如下:
SELECT SUM(`o`.`order_amount`) AS `total_sales`
FROM `south`.`crm_orders` `o`
WHERE DATE_FORMAT(`o`.`created_at`, '%Y-%m') = '2026-02'
LIMIT 1000
SQLBot使用以上SQL语句,在模拟电商CRM系统数据源进行查数后,作出的回答未能正常反映“本月销售额”数值。
▲图9 未经配置的SQLBot对销售额类计算问题不能正确回答
在此场景中,智能问数回答有误,主要是由以下原因导致的:
■ 大模型进行销售额查数时,错误使用了字段order_amount(订单总金额),而不是真正反映销售额数据的字段actual_amount(实际支付金额);
■ 大模型进行销售额查数时,没有筛选排除未支付或已退款的订单;
■ 大模型会将“本月”这种定义模糊的时间范围理解为一个自然月时长,而非当月至今。
对于大模型不能正常反映“本月销售额”数值这一问题的解决方案如下:
第一步:添加字段描述。 让大模型明确在crm_orders表中,理解到actual_amount(实际支付金额)字段才是统计销售额的标准字段,且能够在order_status(订单状态)字段中筛选出“PAID”(已支付)状态下的金额数据。
【字段描述 - order_amount】
订单总金额,未扣除优惠金额,仅用于记录原始金额,不用于销售额统计。
【字段描述 - actual_amount】
实际支付金额,已扣除优惠后的最终支付金额,是统计销售额的标准字段。
【字段描述 - order_status】
订单状态,枚举值:
UNPAID:待支付
PAID:已支付
CANCELLED:已取消
REFUNDED:已退款
统计销售额时,只统计 PAID 状态的订单。
第二步:自定义提示词。 定义“销售额”的标准计算规则,确保每次查询销售额数据都能够遵循业务口径。
【提示词内容】
销售额的计算标准:
必须使用 actual_amount 字段(实际支付金额)
不要使用 order_amount(订单总金额)
必须筛选 order_status = 'PAID'(已支付)
必须排除已退款订单(order_status != 'REFUNDED')
时间维度的理解:
"本月":当月1号到当前日期(使用 created_at 字段)
"上月":上个自然月的完整月份
"最近":默认最近30天
"今天":当天0点到当前时刻
- 标准查询模板:
SELECT SUM(actual_amount) as total_sales
FROM orders
WHERE order_status = 'PAID'
AND DATE_FORMAT(created_at, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m');
注意事项:
如果用户未明确时间范围,默认查询最近30天
统计时使用 created_at(下单时间),而非 paid_at(支付时间)
添加字段描述并自定义提示词后,再一次向SQLBot提问“本月销售额是多少?”,大模型就可以生成正确的SQL语句:
SELECT SUM(`t1`.`actual_amount`) AS `total_sales`
FROM `south`.`crm_orders` `t1`
WHERE `t1`.`order_status` = 'PAID'
AND `t1`.`order_status` != 'REFUNDED'
AND DATE_FORMAT(`t1`.`created_at`, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m')
使用正确的SQL语句,SQLBot可以从数据源中查询出问题的正确结果,即正确的“本月销售额”数据:
场景4:理清部门层级查询的复杂逻辑
在SQLBot未经配置的状态下,当用户对模拟电商CRM系统数据源进行智能问数,提出问题“华南大区本月的销售业绩”时,大模型生成的SQL语句如下:
SELECT SUM(`o`.`actual_amount`) AS `total_sales`
FROM `south`.`crm_orders` `o`
JOIN `south`.`crm_salespeople` `s` ON `o`.`salesperson_id` = `s`.`id`
WHERE `s`.`region` = '华南'
AND DATE_FORMAT(`o`.`paid_at`, '%Y-%m') = '2026-02'
LIMIT 1000
SQLBot使用以上SQL语句,在模拟电商CRM系统数据源进行查数后,作出的回答未能正确反映“华南大区本月的销售业绩”的正确数值。
▲图11 未经配置的SQLBot对多层级查询类问题不能正确回答
在此场景中,智能问数回答有误,主要是由以下原因导致的:
■ 大模型生成的SQL语句只查询了“华南大区”这个部门中的销售数据,没有查询“华南大区”下属的广州、深圳、厦门三个下级分公司的销售数据;
■ 对于树形结构的部门表,查数时需要递归查询所有下级部门。
对于大模型不能正确反映“华南大区本月的销售业绩”数值这一问题的解决方案如下:
第一步:表关系管理。 定义部门表crm_departments的自关联关系(id = parent_id),让模型理解表的树形结构;同时配置“crm_departments→crm_salespeople→crm_orders”的三表关联路径,为递归查询提供基础。
▲图12 在客户表和订单表的基础上再额外补充部门表和销售人员表的关联关系
第二步:添加字段描述。 说明部门表crm_departments中的parent_id字段用于表示部门的上下级关系,提示模型查询大区业绩时需要递归查询所有下级部门的业绩数据,而不是只查询大区本身。
【表描述 - departments】
部门表,采用树形结构存储组织架构,通过 parent_id 字段关联上级部门。
一级部门:销售总部(parent_id = NULL)
二级部门:华东大区、华北大区、华南大区等
三级部门:上海分公司、北京分公司等
【字段描述 - parent_id】
上级部门ID,NULL 表示顶级部门,其他值表示该部门的上级部门。
查询某个大区的业绩时,需要递归查询所有下级部门。
▲图13 设置部门表crm_departments的表备注和字段描述
第三步,添加SQL示例库。为大模型提供递归查询的标准模板,让大模型能够参考这个示例,用同样的逻辑处理其他大区的业绩查询。
【问题描述】
华南大区本月的销售业绩
【示例 SQL】
WITH RECURSIVE dept_tree AS (
-- 锚点:找到华南大区
SELECT id, dept_name, parent_id
FROM departments
WHERE dept_name = '华南大区'
UNION ALL
-- 递归:找到所有子部门
SELECT d.id, d.dept_name, d.parent_id
FROM departments d
INNER JOIN dept_tree dt ON d.parent_id = dt.id
)
SELECT
SUM(o.actual_amount) as total_sales,
COUNT(o.id) as order_count
FROM orders o
JOIN salespeople s ON o.salesperson_id = s.id
WHERE s.department_id IN (SELECT id FROM dept_tree)
AND o.order_status = 'PAID'
AND DATE_FORMAT(o.created_at, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m');
注意: 查数的递归深度一般不超过5层,如果部门层级过深,建议在应用层做好数据的预处理,避免影响查询效率。
第四步,自定义提示词。 目的是无论用户问“华南大区”、“XX分公司”还是其他任何部门,模型都会自动使用递归查询包含所有下级部门的数据。
【提示词名称】部门层级查询规则
【提示词内容】
- 部门查询的递归规则:
当查询某个部门的业绩时,必须包含该部门及其所有下级部门的数据。
- 实现方式:
使用 WITH RECURSIVE 递归 CTE(公共表表达式):
锚点成员:找到目标部门本身
递归成员:通过 parent_id 关联找到所有子部门
部门匹配规则:
"华东大区"、"华北大区":包含所有下级分公司
"上海分公司":仅统计该城市的数据(无需递归)
"销售总部":包含所有部门的数据
在配置好表关联关系、添加字段描述与示例SQL,并设置自定义提示词后,再一次向SQLBot提问“华南大区本月的销售业绩?”,大模型就可以生成正确的SQL语句:
WITH RECURSIVE dept_tree AS
(SELECT id
FROM crm_departments
WHERE dept_name = '华南大区'
UNION ALL SELECT d.id
FROM crm_departments d
INNER JOIN dept_tree dt ON d.parent_id = dt.id)
SELECT SUM(`o`.`actual_amount`) AS `total_sales`,
COUNT(`o`.`id`) AS `order_count`
FROM `crm_orders` `o`
JOIN `crm_salespeople` `s` ON `o`.`salesperson_id` = `s`.`id`
WHERE `s`.`department_id` IN
(SELECT id
FROM dept_tree)
AND `o`.`order_status` = 'PAID'
AND `o`.`created_at` >= DATE_FORMAT(NOW(), '%Y-%m-01')
AND `o`.`created_at` < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH)
LIMIT 1000
使用正确的SQL语句,SQLBot可以从数据源中查询出问题的正确结果,即正确的“华南大区本月销售业绩”数据:
场景5:高频复杂查询的标准化
在SQLBot未经配置的状态下,当用户对模拟电商CRM系统数据源进行智能问数,提出问题“IT行业大客户在华南大区的第一季度平均客单价是多少?”时,大模型生成的SQL语句如下:
SELECT AVG(`o`.`actual_amount`) AS `average_order_amount`
FROM `south`.`crm_orders` `o`
JOIN `south`.`crm_customers` `c` ON `o`.`customer_id` = `c`.`id`
JOIN `south`.`crm_salespeople` `s` ON `o`.`salesperson_id` = `s`.`id`
WHERE `c`.`industry` = 'IT'
AND `c`.`customer_level` = 'A'
AND `s`.`region` = '华南'
AND DATE_FORMAT(`o`.`paid_at`, '%Y-%m') BETWEEN '2026-01' AND '2026-03'
LIMIT 1000
SQLBot使用以上SQL语句,在模拟电商CRM系统数据源进行查数后,作出的回答未能正确反映“IT行业大客户在华南大区的第一季度平均客单价是多少?”这一复杂查询的结果。
▲图15 未经配置的SQLBot对复杂查询类问题不能正确回答
在此场景中,智能问数回答有误,主要原因如下,是前文中四个场景遇到问题的综合体现:
■ 术语理解问题(客户筛选):大模型无法精准实现对“IT行业”与“大客户”这两种模糊条件下的客户筛选;
■ 层级查询问题(区域筛选):大模型生成的SQL语句未能对树形结构的部门表进行递归查询;
■ 时间理解问题(时间筛选):大模型未能理解“季度”所代表的准确时间范围;
■ 关联问题(多表关联):大模型未能精准定位关联字段,建立起“客户→订单→销售人员→部门“所在不同表之间正确的关联关系;
■ 计算规则问题(业务指标计算):大模型未能明确一些业务指标计算的标准公式,影响数据的处理与查询效果。
对于大模型不能正确回答“IT行业大客户在华南大区的第一季度平均客单价是多少?”这一复杂问题,我们可以综合运用前面四个场景提到的配置方法,构建一套更加全面的解决方案:
第一步:字段描述(场景1+场景2) ,让大模型理解各字段的业务含义;
第二步:术语配置(场景1) , 为大模型翻译“大客户”、“IT行业”等业务术语;
第三步:表关系管理(场景2+场景4) ,定义4个表的正确关联路径和递归关系;
第四步:SQL示例库(场景4) ,为大模型提供递归查询模板;
第五步:自定义提示词(场景3) ,设定销售额和客单价的计算规则;
第六步:自定义提示词(额外补充) ,设定季度时间范围的规则。
【提示词名称】时间范围理解规则(补充)
【提示词内容】
季度时间范围:
"第一季度/Q1":1月1日 - 3月31日
"第二季度/Q2":4月1日 - 6月30日
"第三季度/Q3":7月1日 - 9月30日
"第四季度/Q4":10月1日 - 12月31日
标准SQL写法:
-- 今年第一季度
WHERE created_at >= STR_TO_DATE(CONCAT(YEAR(NOW()), '-01-01'), '%Y-%m-%d')
AND created_at < STR_TO_DATE(CONCAT(YEAR(NOW()), '-04-01'), '%Y-%m-%d')
在完成上述所有配置后,再一次向SQLBot提问“IT行业大客户在华南大区的第一季度平均客单价是多少?”,大模型就可以明确用户的提问意图,生成正确的SQL语句:
WITH RECURSIVE dept_tree AS
(SELECT id
FROM `crm_departments`
WHERE `dept_name` = '华南大区'
UNION ALL SELECT d.id
FROM `crm_departments` d
INNER JOIN dept_tree dt ON d.parent_id = dt.id)
SELECT AVG(`o`.`actual_amount`) AS `average_order_amount`
FROM `crm_orders` `o`
JOIN `crm_salespeople` `s` ON `o`.`salesperson_id` = `s`.`id`
JOIN `crm_customers` `c` ON `o`.`customer_id` = `c`.`id`
WHERE `s`.`department_id` IN
(SELECT id
FROM dept_tree)
AND `o`.`order_status` = 'PAID'
AND `c`.`customer_level` = 'A'
AND `c`.`industry` LIKE '%IT%'
AND `o`.`created_at` >= STR_TO_DATE(CONCAT(YEAR(NOW()), '-01-01'), '%Y-%m-%d')
AND `o`.`created_at` < STR_TO_DATE(CONCAT(YEAR(NOW()), '-04-01'), '%Y-%m-%d')
LIMIT 1000
使用正确的SQL语句,SQLBot可以从数据源中查询出问题的正确结果,即正确回答“IT行业大客户在华南大区的第一季度平均客单价”这样的复杂问题:
三、场景配置误区与避坑指南
在SQLBot的配置过程中,容易遇到一些误区,可能会影响配置效果,需要通过改变填写的习惯来优化配置内容。
错误做法1:把所有信息都写在字段描述里
【字段描述 - customer_level】
客户等级,A表示大客户也叫VIP客户,是年采购额超过100万的客户。
B是中等客户,C是小客户。
统计大客户时用customer_level='A',
有时候也说重点客户或者优质客户。
正确的做法:让不同的配置各司其职,字段描述说明字段本身,术语配置负责名称映射。
【字段描述 - customer_level】
客户等级,根据年采购金额评定:
A级:>= 100万
B级:50-100万
C级:< 50万
【术语配置】
术语名称:大客户/VIP客户/重点客户/优质客户
术语描述:指 customer_level = 'A' 的客户
错误做法2:SQL示例库配置过于具体
问题:2024年1月重庆地区的销售额
SQL: SELECT ... WHERE region = '重庆' AND created_at >= '2024-01-01' ...
正确的做法:配置有通用性的示例,让大模型举一反三。
问题:某月某地区的销售额
(示例:本月重庆销售额、上月成都销售额等)
SQL:
SELECT SUM(actual_amount) as total_sales
FROM orders o
JOIN salespeople s ON o.salesperson_id = s.id
WHERE o.order_status = 'PAID'
AND s.region = '目标区域'
AND DATE_FORMAT(o.created_at, '%Y-%m') = '目标月份';
错误做法3:自定义提示词过于啰嗦
在我们公司,销售额是一个非常重要的指标,它代表了我们的业务收入情况。计算销售额的时候,我们需要注意很多事项,首先要确保订单是已支付的,其次要使用实际支付金额而不是订单总金额,因为订单总金额包含了优惠...
正确的做法:提示词要简洁明确,用列表和示例代替长篇描述。
销售额统计规则:
使用字段:actual_amount(实际支付金额)
筛选条件:order_status = 'PAID'
排除条件:order_status != 'REFUNDED'
标准SQL:SELECT SUM(actual_amount) FROM orders WHERE order_status = 'PAID';