豆包威武,不到一天上线智能问数 DEMO
前言
智能问数(自然语言查询)一直是商业智能领域的高成本项目。传统方案往往需要专业团队投入数周甚至数月,进行语义建模、知识库维护等大量定制任务,实施复杂度极高,即使最简单的单宽表场景也很难快速实施。
润乾 NLQ 采用 "规范文本 + LLM" 的两段式架构,将复杂的自然语言理解拆解为 "LLM 转规范文本" 和 "规范文本执行查询" 两个可控环节,无需建设 RAG 知识库,且采用可控可完善的规则引擎,实施成本与复杂度已大幅降低。但即便如此,从零搭建一套可用的 NLQ 智能问数系统,通常仍需数天到数周时间(视数据结构的复杂度)来完成元数据配置、词典编写、提示词调优和联调测试。
那么,能不能借助AI技术来提升实施效率呢?
本文以相对简单的单表场景为试点,全程借助豆包完成从元数据生成、汉语查询词典配置、提示词编写,到 Web 端对话界面上线的全部实施工作。
最终的效果相当显著:不到一天,完整 DEMO 上线:
图:润乾NLQ智能问数Web端对话界面效果
过程中,实施人员只需按常规 BI 任务那样准备好数据结构等基础信息即可,然后按阶段将文中的提示词复制发给豆包,简单确认每步产出,整体工作很轻松。
本次实践的关键突破在于:我们没有让 AI 停留在 "给建议" 的层面,而是使用豆包最新的「工作任务(本地电脑)模式」,让 AI 直接操作实施人员的本地电脑,自动完成文件读写、数据库连接、报错排查等全部实施动作。 这意味着实施人员不再需要把 AI 的建议翻译成手动操作 ——AI 本身就是执行者。
当前 DEMO 已经可以正常对话查询,但因为没有配上用户角色,也就没有涉及数据权限任务,不过这件事在 NLQ 的内核层 DQL 已经有深入考虑,可以将数据权限控制到数据表的每一行和列,甚至可以用关联表作为条件,只要配上用户角色就很容易处理。另外,有了基于单表的 AI 辅助实施经验,更复杂的多表关联场景(这其实是 NLQ 也就是提到的 DQL 内核层更擅长的任务,外键关联,主子表、跨表聚合等都能正确生成 JOIN)也可以在更短的时间内完成实施,后续我们会再介绍相关的实施方案。
本文篇幅较长,但大部分内容是可以直接复制发给豆包的提示词模板,实际操作步骤只有八步。读者可先浏览下方目录了解全貌,再逐阶段操作。
目录
第一阶段:信息准备——收集安装路径、数据库连接、选用表、实例命名
第二阶段:生成元数据文件(lmd)——连接数据库读取表结构,生成DQL元数据
第三阶段:配置DQL数据源并测试——注册直连数据源,运行DQL批量测试验证
第四阶段:生成汉语查询词典(nlq)——基于lmd生成规范文本查询的词法规则
第五阶段:配置NLQ JDBC数据源——注册NLQ数据源,打通规范文本执行链路
第六阶段:编写并运行NLQ批量测试程序——生成30条规范文本用例,批量执行验证
第七阶段:生成自然语言转规范文本提示词(prompt md)——编写LLM提示词,实现自然语言到规范文本的转换
第八阶段:Web端JSP配置——配置对话界面,启动报表中心验证全链路
第一阶段:信息准备
本阶段将实施所需的基础信息一次性发给豆包,为后续生成配置文件做好准备。本阶段不生成任何文件。
实施人员需要准备四类信息:安装路径、数据库连接信息、选用的业务表名、实例命名。其中数据库连接信息包含 URL、驱动类名、用户名、密码四项。驱动 jar 包需提前放入安装根目录下的 common/jdbc 目录中。
本指南以 customer_deposit_detail 表为例,该表为 PostgreSQL 数据库的建表语句和模拟数据。实施所需的参考文件均见附件,以 report 目录结构组织,包含以下内容:
report/
├── customer_deposit_detail.sql # PostgreSQL 建表语句+模拟数据
├── tpch.lmd # 参考元数据文件(第二阶段生成 lmd 的唯一权威参考)
├── dqltest/DQLBatchTest.java # 通用 DQL 批量测试程序
├── nlqtest/NLQBatchTest.java # 通用 NLQ 批量测试程序
├── tpch_data_csv/ # TPC-H 参考数据(含建表SQL和8张表CSV,需自行导入数据库)
│ ├── tpch_ddl.sql # PostgreSQL 建表语句+COPY导入命令
│ ├── TPCH_REGION_5.csv
│ ├── TPCH_NATION_25.csv
│ ├── TPCH_PART_10.csv
│ ├── TPCH_supplier.csv
│ ├── TPCH_customer.csv
│ ├── TPCH_ORDERS_12380.csv
│ ├── TPCH_PARTSUPP_159750.csv
│ └── TPCH_LINEITEM_59206.csv
└── web/webapps/demo/WEB-INF/
├── classes/
│ ├── tpch_nlq_nspl.md # 参考自然语言转规范文本提示词
│ └── nlqConfig.xml # 参考 NLQ 数据源配置
└── files/dql/tpch.nlq # 参考汉语查询词典
实施人员可先将附件中的 customer_deposit_detail.sql(含建表语句和模拟数据)导入 PostgreSQL 数据库,并执行 tpch_data_csv/tpch_ddl.sql 完成 TPC-H 8 张表的建表和数据导入,再按本指南逐步操作。
TPC-H 数据的作用:作为一套完整可运行的参考 demo,与附件中的 tpch.lmd、tpch.nlq、tpch_nlq_nspl.md 等参考配置配套使用。当实施过程中遇到环境、配置、元数据或词典逻辑问题导致报错时,豆包可以对照这套已验证的参考配置进行自检,快速定位问题。
安装根目录结构如下:
安装根目录(如 /raqsoft/)
├── report/
│ ├── bin/ # 启动脚本目录
│ ├── config/ # 全局配置目录(含 raqsoftConfig.xml)
│ ├── services/ # 元数据(lmd)配置目录
│ ├── web/ # Web 应用目录
│ └── doc/ # 产品文档目录
└── common/
├── jdbc/ # 第三方 JDBC 驱动目录
└── jre/ # 产品自带运行环境
以下是发给豆包的内容模板,请将其中的路径、数据库信息替换为实施环境的实际值后发送:
▼ 发给豆包的内容(可直接复制):
帮我做润乾NLQ,单表场景。
{
"安装根目录": "/raqsoft/",
"数据库": {
"url": "jdbc:postgresql://localhost:5432/raqsoft",
"driver": "org.postgresql.Driver",
"user": "raqsoft",
"password": "raqsoft"
},
"选用表": "customer_deposit_detail",
"实例命名": "custdep",
"驱动jar位置": "common/jdbc"
}
本阶段仅做信息检测,不生成文件。请检测:
1. report 路径是否存在;
2. 数据库能否连接,表是否存在;
3. services 目录下是否已有该实例命名,如有需告知,由我决定处理方式。
检测完告诉我结果,等我下一步指示。
豆包收到后会确认信息无误,然后进入第二阶段。
信息确认清单:
安装根目录和 report 目录绝对路径已提供。
数据库 URL、驱动类名、用户名、密码四项完整。
驱动 jar 包已放入安装根目录下的 common/jdbc 目录。
业务表名已提供,与数据库实际一致。
实例命名 custdep,确保不与已有实例重名。
第二阶段:生成元数据文件(lmd)
本阶段的目的:让豆包连接数据库读取表结构,生成元数据文件(lmd)。lmd 定义了表、字段、维等信息,是后续汉语查询词典(nlq)和规范文本查询的基础。
本阶段豆包会生成一个文件:
report/services/custdep/conf/custdep.lmd
豆包需要参考以下资料:
1. 已有示例 lmd(唯一权威参考):report/services/tpch/conf/tpch.lmd,这是 TPC-H 标准业务场景对应的完整示例。注意该示例的数据源是 CSV 导入的 PostgreSQL 数据库表(附件 tpch_data_csv 下提供了 8 张表的 CSV 数据和建表 SQL,需自行导入数据库),生成 lmd 时表和字段的 source 必须写数据库中的实际表名和字段名。
2. 数据库表结构:连接数据库读取表的字段名、字段类型、注释。
生成 lmd 时需要注意:
lmd 中的维分为两类,都需要定义,后续 nlq 中的分组才能基于这些维进行:
第一类是时间维。包括年、季度、月、日、年月、日期、星期、年季度等,参考 tpch.lmd 的写法完全照搬。时间维以假表(type=2)的形式存在于表列表中,同时在维列表(namedDimList)中定义。
第二类是普通字段维。即使是单表,也需要为常用的分组字段创建普通字段维。普通字段维同样以假表(type=2,dimType=0)的形式存在,假表的名称为维的中文名,假表中的字段名必须与物理表中的实际字段名完全一致,并在维列表(namedDimList)中登记。参考 tpch.lmd 中 "行业""订单状态""品牌" 等的写法。
物理表必须通过外键列表(fkList)与上述维假表建立关联,否则维不会生效。所有日期型字段关联到 "日期" 假表,所有普通字段维字段关联到对应的假表。
物理表的主键:仅当多个物理表之间有关联关系时,才需要设置主键,否则不设置主键。
表字段的 name 使用数据库实际字段名,desc 使用字段注释或中文含义,没有注释可留空。
以下是发给豆包的内容模板:
▼ 发给豆包的内容(可直接复制):
现在生成 lmd。
{
"参考lmd": "/raqsoft/report/services/tpch/conf/tpch.lmd",
"输出路径": "/raqsoft/report/services/custdep/conf/custdep.lmd"
}
要求:
1. 连接数据库读取表结构。
2. 参考 tpch.lmd 的 JSON 结构,注意:tpch 示例的数据源是 CSV 导入的数据库表,你生成的也是数据库表的 lmd,表和字段的 source 必须写数据库中的实际名称,不要写文件名。
3. 维分为两类,都必须定义:
a. 时间维:年、季度、月、日、年月、日期、星期、年季度,完全照搬 tpch.lmd(假表 type=2 + namedDimList)。
b. 普通字段维:自动判断哪些字段适合做维(字符串类型,排除主键、大文本、数值型字段),参考 tpch.lmd 中"行业""订单状态""品牌"的写法,创建假表(type=2,dimType=0),假表名称为维的中文名,字段名与物理表实际字段名完全一致,加入 namedDimList。
4. 物理表必须通过外键列表(fkList)与所有维假表建立关联。所有日期型字段关联到"日期"假表,所有普通字段维字段关联到对应假表。
5. 单表场景不设置主键。
6. JSON 格式与示例一致。
7. 只生成 custdep.lmd,完成后告诉我。
豆包生成 custdep.lmd 后,实施人员应检查:
- 文件路径是否正确,JSON 是否合法。
- 时间维假表和 namedDimList 是否完整。
- 普通字段维是否已创建,物理表的外键列表(fkList)是否不为空。
- 单表场景下未设置主键。
可通过 DQL IDE 打开 lmd 文件直观查看。确认无误后进入第三阶段。
第三阶段:配置 DQL 数据源并测试
本阶段的目的:在润乾报表的配置文件中注册 DQL 数据源,然后通过通用测试程序验证 lmd 配置是否可用。DQL 数据源采用直连模式(无需启动 DQL 服务器),在 JDBC URL 中直接指定 lmd 文件路径和底层数据库连接信息。
第一步,配置 DQL 数据源。豆包会修改两个文件:
1. report/web/webapps/demo/WEB-INF/raqsoftConfig.xml(Web 运行时用)
2. report/config/raqsoftConfig.xml(NLQ IDE 用)
直连模式的 URL 格式:jdbc:datalogic://?home=mql_home&lmd=<lmd 路径 >&dct=&db.url=< 数据库 URL>&db.driver=< 驱动 >&db.user=< 用户 >&db.password=< 密码 >&db.type=< 类型编码 >
- lmd 路径相对 report 目录
- db.type:PostgreSQL=15(其他数据库类型可参考产品文档)
- driver=com.datalogic.jdbc.LogicDriver,type=0,user/password 留空
第二步,编写并运行 DQL 测试程序。DQL 驱动执行标准 SQL,但注意:
- 表名用 lmd 中定义的物理表名,不是实例名
- 分组聚合用 BY 关键字,不是 GROUP BY
- 支持 WHERE、ORDER BY、DISTINCT、聚合函数、BY、HAVING,不支持子查询
通用测试程序 report/dqltest/DQLBatchTest.java 已存在,只需生成配置文件 dqltest-config.json。
编译和运行(在 report 目录下执行):
编译:javac -cp "web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" -d dqltest dqltest/DQLBatchTest.java
运行:java -cp "dqltest:web/webapps/demo/WEB-INF:web/webapps/demo/WEB-INF/classes:web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" DQLBatchTest
注意:运行命令的 classpath 中必须包含 web/webapps/demo/WEB-INF/ 目录,这样 LogicDriver 才能从该目录加载 raqsoftConfig.xml 中的 license 配置。
以下是发给豆包的内容模板:
现在配置 DQL 数据源并编写 DQL 测试程序。
{
"配置文件": [
"/raqsoft/report/web/webapps/demo/WEB-INF/raqsoftConfig.xml",
"/raqsoft/report/config/raqsoftConfig.xml"
],
"数据源名": "DQL4CUSTDEP",
"lmd路径": "services/custdep/conf/custdep.lmd",
"数据库": {
"url": "jdbc:postgresql://localhost:5432/raqsoft",
"driver": "org.postgresql.Driver",
"user": "raqsoft",
"password": "raqsoft",
"type": 15
},
"测试配置输出": "/raqsoft/report/dqltest/dqltest-config.json",
"工作目录": "/raqsoft/report"
}
第一步,两个配置文件都添加 DQL 数据源(直连模式,无需 DQL 服务器):
- name=DQL4CUSTDEP
- url=jdbc:datalogic://?home=mql_home&lmd=services/custdep/conf/custdep.lmd&dct=&db.url=jdbc:postgresql://localhost:5432/raqsoft&db.driver=org.postgresql.Driver&db.user=raqsoft&db.password=raqsoft&db.type=15
- driver=com.datalogic.jdbc.LogicDriver,type=0,user/password留空
- batchSize=1000,autoConnect=false,useSchema=false,addTilde=false,caseSentence=false
第二步,生成 dqltest-config.json。通用程序 DQLBatchTest.java 已存在。配置结构如下(tpch 示例,实际用例需连接数据库读取表结构替换为当前表的物理表名和字段名):
{
"jdbc": {
"driver": "com.datalogic.jdbc.LogicDriver",
"url": "jdbc:datalogic://?home=mql_home&lmd=services/tpch/conf/tpch.lmd&dct=&db.url=jdbc:postgresql://localhost:5432/raqsoft&db.driver=org.postgresql.Driver&db.user=raqsoft&db.password=raqsoft&db.type=15",
"user": "",
"password": ""
},
"maxRows": 3,
"testCases": [
{"category": "明细查询", "cases": ["SELECT O_ORDERKEY, O_CUSTKEY, O_TOTALPRICE, O_ORDERDATE FROM ORDERS", "SELECT O_ORDERKEY, O_ORDERSTATUS FROM ORDERS"]},
{"category": "条件查询", "cases": ["SELECT O_ORDERKEY, O_TOTALPRICE FROM ORDERS WHERE O_ORDERSTATUS = 'F'", "SELECT O_ORDERKEY, O_TOTALPRICE FROM ORDERS WHERE O_ORDERPRIORITY = '1-URGENT'"]},
{"category": "聚合查询", "cases": ["SELECT COUNT(*), SUM(O_TOTALPRICE), AVG(O_TOTALPRICE) FROM ORDERS", "SELECT O_ORDERPRIORITY, SUM(O_TOTALPRICE) FROM ORDERS BY O_ORDERPRIORITY", "SELECT O_ORDERPRIORITY, SUM(O_TOTALPRICE) FROM ORDERS BY O_ORDERPRIORITY HAVING SUM(O_TOTALPRICE) > 1000000"]},
{"category": "排序统计", "cases": ["SELECT O_ORDERKEY, O_TOTALPRICE FROM ORDERS ORDER BY O_TOTALPRICE DESC", "SELECT DISTINCT O_ORDERPRIORITY FROM ORDERS"]}
]
}
测试用例覆盖明细、条件、聚合(用 BY)、排序统计四类。
第三步,在工作目录下编译运行:
javac -cp "web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" -d dqltest dqltest/DQLBatchTest.java
java -cp "dqltest:web/webapps/demo/WEB-INF:web/webapps/demo/WEB-INF/classes:web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" DQLBatchTest
约束:无需启动 DQL 服务器。报错先检查编译命令、运行命令、工作目录、URL。
返回完整测试结果,说明情况是否正常。
实施人员检查清单:
- 两个 raqsoftConfig.xml 中是否都新增了 DQL4CUSTDEP,URL 是否为直连模式,db.type 是否为 15。
- dqltest-config.json 中 SQL 表名是否为物理表名,分组是否用 BY。
- 豆包已编译运行,测试结果已返回,大部分查询正常。
确认无误后进入第四阶段。
第四阶段:生成汉语查询词典(nlq)
本阶段的目的:基于已建好的 custdep.lmd,生成汉语查询词典(nlq)。nlq 定义了规范文本查询的词法规则,包括表和字段的中文名称、维词、聚合词、宏词、字段簇、实体等。
本阶段豆包会生成一个文件:
web/webapps/demo/WEB-INF/files/dql/custdep.nlq
豆包需要参考:
1. 已有示例 nlq(最主要):report/web/webapps/demo/WEB-INF/files/dql/tpch.nlq
2. 汉语查询教程:report/doc/zh/ 汉语查询教程 /,第 6 章 "字段簇与实体"(topics/18.html~21.html)是字段簇、动词、簇词、实体的权威依据
3. 已生成的 lmd:report/services/custdep/conf/custdep.lmd,nlq 中使用的维必须与 lmd 完全一致
生成 nlq 时按四类处理:
1. 维词(dimConfigList):维只能用 lmd 中定义的。时间维照搬 tpch.nlq;可枚举维连接数据库查真实值作为常数词,不可枚举的不配置。
2. 通用词法(七项):无效词、存在词、非法词、连词、比较词、聚合词、宏词,全部照搬 tpch.nlq。量纲也照搬。
3. 字段簇、动词、簇词、实体:以汉语查询教程第 6 章为准,参考 tpch.nlq 结构,根据当前表配置,不能照搬。两条铁律:
a. 字段簇(fieldCluster)只能包含维度字段(字符串类型),不能包含数值字段(金额、利率、数量、比例等)。包含数值字段的字段簇会导致维词分组时报 "Dimension cannot find a related field"。
b. 簇词(clusterWord)只能指向包含维度字段的字段簇,不能指向包含数值字段的字段簇。指向数值字段簇的簇词会导致所有含数值字段的查询解析崩溃(query 返回 null)。
数值字段不加入任何字段簇。一个字段簇只能对应一个簇词。
4. 字段视图(fieldView):name 用中文,字段词每个字段一个不重复,dataType 必须设置(数值 =1,日期 =8,字符串 =11),数值字段留空会导致聚合查询全部失败。
以下是发给豆包的内容模板:
▼ 发给豆包的内容(可直接复制):
现在生成汉语查询词典(nlq)。
{
"参考nlq": "/raqsoft/report/web/webapps/demo/WEB-INF/files/dql/tpch.nlq",
"参考文档": "/raqsoft/report/doc/zh/汉语查询教程/",
"基于lmd": "/raqsoft/report/services/custdep/conf/custdep.lmd",
"输出路径": "/raqsoft/report/web/webapps/demo/WEB-INF/files/dql/custdep.nlq"
}
要求:
1. 参考 tpch.nlq 的完整 JSON 结构生成。
2. 维配置列表(dimConfigList)必须与 lmd 的 namedDimList 完全一致。时间维照搬 tpch.nlq;可枚举维连接数据库查真实值作为常数词。
3. 七项通用词法(无效词、存在词、非法词、连词、比较词、聚合词、宏词)和量纲全部照搬 tpch.nlq。
4. tableViewList 中配置字段簇、动词、簇词、实体,含义以汉语查询教程第6章(topics/18~21.html)为准,结构参考 tpch.nlq,根据当前表配置。两条铁律必须遵守:
a. 字段簇(fieldCluster)只能包含维度字段(字符串类型),不能包含数值字段(金额、利率、数量、比例等)。数值字段不加入任何字段簇。
b. 簇词(clusterWord)只能指向包含维度字段的字段簇,不能指向包含数值字段的字段簇。一个字段簇只能对应一个簇词。
5. 字段视图(fieldView):name 用中文,字段词每个字段一个不重复,dataType 必须设置(lmd 数值型→1,日期→8,字符串→11),数值字段必须设为1。
6. 只生成 custdep.nlq,完成后告诉我。
实施人员检查清单:
- 维是否与 lmd 一致,时间维常数词是否与 tpch 一致。
- 通用词法七项和量纲是否完整照搬。
- 字段簇、动词、簇词、实体是否根据业务配置,一个字段簇是否只对应一个簇词。
- 字段簇中是否包含数值字段(不应包含),簇词是否指向了包含数值字段的字段簇(不应指向)。
- 字段词是否有重复,每个字段 dataType 是否正确设置。
确认无误后进入第五阶段。
第五阶段:配置 NLQ JDBC 数据源
本阶段的目的:注册 NLQ 数据源,使得可以通过 JDBC 执行 NLQ 规范文本查询。DQL 数据源已在第三阶段配置完成。
豆包会修改两个文件:
1. report/web/webapps/demo/WEB-INF/raqsoftConfig.xml(添加 NLQ 数据源)
2. report/web/webapps/demo/WEB-INF/classes/nlqConfig.xml(添加 NLQ 配置项)
NLQ 数据源:name=NLQ4CUSTDEP,url=jdbc:datalogic:nlq://?nlq=nlqCustDep(注意:NLQ 直连模式下 URL 中不要加 home=mql_home 参数,否则会导致 query 命令返回 null),driver=com.nlq.datalogic.jdbc.NLQDriver,其余照搬 NLQ4TPCH。
nlqConfig.xml 添加:name=nlqCustDep,DB=DQL4CUSTDEP,MetaData=nlq 文件路径,RaqsoftConfig=raqsoftConfig.xml 路径。
以下是发给豆包的内容模板:
▼ 发给豆包的内容(可直接复制):
现在配置 NLQ JDBC 数据源。
{
"raqsoftConfig": "/raqsoft/report/web/webapps/demo/WEB-INF/raqsoftConfig.xml",
"nlqConfig": "/raqsoft/report/web/webapps/demo/WEB-INF/classes/nlqConfig.xml",
"NLQ数据源名": "NLQ4CUSTDEP",
"NLQ配置名": "nlqCustDep",
"DQL数据源名": "DQL4CUSTDEP",
"nlq文件": "web/webapps/demo/WEB-INF/files/dql/custdep.nlq"
}
第一步,raqsoftConfig.xml 添加 NLQ 数据源(参考 NLQ4TPCH):
- name=NLQ4CUSTDEP
- url=jdbc:datalogic:nlq://?nlq=nlqCustDep(直连模式下不要加 home=mql_home 参数)
- driver=com.nlq.datalogic.jdbc.NLQDriver,type=16,user=root,password=root
- 其余属性照搬 NLQ4TPCH
DQL4CUSTDEP 已在之前配置,不需重复添加。config/raqsoftConfig.xml 不需加 NLQ 数据源。
第二步,nlqConfig.xml 添加(参考 nlqTPCH):
- name=nlqCustDep
- DB=DQL4CUSTDEP
- MetaData=web/webapps/demo/WEB-INF/files/dql/custdep.nlq
- RaqsoftConfig=web/webapps/demo/WEB-INF/raqsoftConfig.xml
只修改这两个文件,完成后告诉我。
实施人员检查清单:
- raqsoftConfig.xml 中是否新增 NLQ4CUSTDEP。
- nlqConfig.xml 中是否新增 nlqCustDep,DB=DQL4CUSTDEP。
- 三处名称对应一致:url 中 nlq=nlqCustDep、nlqConfig 中 name=nlqCustDep、DB=DQL4CUSTDEP。
确认无误后进入第六阶段。
第六阶段:编写并运行 NLQ 批量测试程序
本阶段的目的:通过通用测试程序 NLQBatchTest.java,批量执行规范文本查询,验证从 lmd 到 nlq 到规范文本查询的全链路。测试程序对每条规范文本先解析(query 命令)得到 DQL,再执行 DQL 获取结果集,展示前三条数据。
通用测试程序 report/nlqtest/NLQBatchTest.java 已存在,只需生成配置文件 nlqtest-config.json。
规范文本书写规则:
1. 由空格分隔的词组成,每个词必须是 nlq 中定义的词。
2. 维过滤:维词后跟常数词,不加引号,如 "统计日期 今年"。维过滤可以和实体词同时使用。
3. 非维字段过滤:字段词后跟值,值加单引号,如 "币种'CNY'"。
4. 聚合词位置遵守 nlq 中 ps 属性:ps=1 在左(如 "平均 余额"),ps=2 在右(如 "余额 总和")。
5. 实体词通常放句末,如 "存款明细"。
6. 维词分组(维词 + 聚合词)和实体词不能同时使用。聚合查询中用维词分组时,不要加实体词;明细查询中用实体词时,不要用维词作为选择字段(维过滤除外)。
7. 在字段簇中的数值字段不能和实体词同时使用。明细查询(用实体词)只使用包含维度字段的字段簇中的字段和不在任何字段簇中的数值字段。
编译和运行(在 report 目录下执行):
编译:javac -cp "web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" -d nlqtest nlqtest/NLQBatchTest.java
运行:java -cp "nlqtest:web/webapps/demo/WEB-INF:web/webapps/demo/WEB-INF/classes:web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" NLQBatchTest
注意:运行命令的 classpath 中必须包含 web/webapps/demo/WEB-INF/ 目录,这样 NLQ 驱动才能从该目录加载 raqsoftConfig.xml 中的 license 配置。
以下是发给豆包的内容模板:
▼ 发给豆包的内容(可直接复制):
现在编写并运行 NLQ 批量测试程序。
{
"输出目录": "/raqsoft/report/nlqtest/",
"基于nlq": "/raqsoft/report/web/webapps/demo/WEB-INF/files/dql/custdep.nlq",
"参考示例": "/raqsoft/report/web/webapps/demo/WEB-INF/classes/tpch_nlq_nspl.md",
"NLQ配置名": "nlqCustDep",
"工作目录": "/raqsoft/report"
}
通用程序 NLQBatchTest.java 已存在,只需生成 nlqtest-config.json。
先读取 custdep.nlq 获取所有可用词,参考 tpch_nlq_nspl.md 中的 NLQ 举例格式生成测试用例(仅 NLQ,不涉及 NLC)。
测试用例设计规则(必须遵守):
- 明细查询(含实体词):只使用包含维度字段的字段簇中的字段和不在任何字段簇中的数值字段,不要用其他字段簇的维词作为选择字段。
- 聚合查询(维词分组 + 聚合词):不要加实体词。
- 维过滤查询:维词 + 常数词作为过滤条件,可以和实体词同时使用。
- 宏词查询:时间宏词,可以和实体词或聚合词组合。
- 实体查询:纯实体词或实体词 + 时间过滤。
- 综合查询:多维度聚合,不加实体词。
配置结构如下(tpch 示例,实际用例从 custdep.nlq 取词):
{
"jdbc": {
"driver": "com.nlq.datalogic.jdbc.NLQDriver",
"url": "jdbc:datalogic:nlq://?nlq=nlqTPCH",
"user": "root",
"password": "root"
},
"maxRows": 3,
"testCases": [
{"category": "明细查询", "cases": ["订单日期 订单ID 客户 订单金额 订单", "订单日期 订单ID 订单状态 订单优先级 订单"]},
{"category": "聚合查询", "cases": ["订单日期 今年 订单状态 订单金额 总和 订单", "订单日期 今年 客户 平均 订单金额 订单"]},
{"category": "维过滤查询", "cases": ["订单日期 上半年 订单优先级 订单金额 总和 订单", "订单日期 今年 订单状态 'F' 订单"]},
{"category": "宏词查询", "cases": ["订单日期 前3个月 客户 订单金额 总和 订单", "订单日期 上半年 订单"]},
{"category": "实体查询", "cases": ["订单", "订单日期 今年 订单"]},
{"category": "综合查询", "cases": ["订单日期 今年 订单优先级 订单状态 订单金额 总和 订单", "订单日期 上半年 订单状态 'F' 客户 平均 订单金额 订单"]}
]
}
六大类(明细、聚合、维过滤、宏词、实体、综合),每类5条,共30条。聚合词位置遵守 ps 属性,非维字段过滤加单引号。
jdbc.url=jdbc:datalogic:nlq://?nlq=nlqCustDep(直连模式下不要加 home=mql_home 参数),maxRows=3。
在工作目录下编译运行:
javac -cp "web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" -d nlqtest nlqtest/NLQBatchTest.java
java -cp "nlqtest:web/webapps/demo/WEB-INF:web/webapps/demo/WEB-INF/classes:web/webapps/demo/WEB-INF/lib/*:../common/jdbc/*" NLQBatchTest
约束:无需启动 DQL 服务器。报错先检查编译命令、运行命令、工作目录。
返回完整测试结果:每条通过的用例展示前三条数据,失败的展示错误信息。最后汇总通过/失败数量,说明情况是否正常。
实施人员检查清单:
- nlqtest-config.json 中 jdbc.url 的 nlq 参数是否为 nlqCustDep。
- 测试用例的词是否都在 custdep.nlq 中,聚合词位置是否正确。
- 豆包已编译运行,测试结果已返回。
确认无误后进入第七阶段。
第七阶段:生成自然语言转规范文本提示词(prompt md)
本阶段的目的:基于 custdep.nlq,参考 tpch_nlq_nspl.md,生成针对当前业务场景的 prompt md。该文件用于 LLM 将自然语言转换为 NLQ 规范文本,对于 NLQ 无法实现的功能(排序、排名、环比、同比、占比等),拆成两步:NLQ 查基础数据 + NLC 进一步计算。
本阶段豆包会生成两个文件:
1. report/web/webapps/demo/WEB-INF/classes/custdep_nlq_nspl.md
2. report/ 目录下的用例列表文件(所有自然语言用例和对应的 NLQ+NLC 结果,标序号)
生成要点:
- 通用部分(NLQ 四种范式、NLC 场景、处理七步骤、NLC 语法、输出格式)照搬 tpch_nlq_nspl.md。
- 词典部分(表字段、维词、常数词、筛选条件、分组、聚合运算、查询范式)从 custdep.nlq 提取。
- 举例基于上一阶段 NLQ 批量测试的用例,NLC 部分模仿 tpch 写法。
- 物理表无关联关系时,多表关联和主子表查询内容简化或注明不适用。
以下是发给豆包的内容模板:
▼ 发给豆包的内容(可直接复制):
现在生成自然语言转规范文本的 prompt md。
{
"参考模板": "/raqsoft/report/web/webapps/demo/WEB-INF/classes/tpch_nlq_nspl.md",
"基于nlq": "/raqsoft/report/web/webapps/demo/WEB-INF/files/dql/custdep.nlq",
"输出路径": "/raqsoft/report/web/webapps/demo/WEB-INF/classes/custdep_nlq_nspl.md",
"用例列表输出": "/raqsoft/report/custdep_nlq_examples.txt"
}
要求:
1. 通用部分(NLQ四种范式、NLC进一步计算场景、处理七步骤、NLC语法规范、输出格式)照搬 tpch_nlq_nspl.md。
2. 词典部分从 custdep.nlq 提取,与 nlq 配置完全一致。
3. 举例基于上一阶段 NLQ 批量测试的用例:将每条规范文本对应到自然语言查询。NLC 部分的举例模仿 tpch_nlq_nspl.md 写法。
4. 物理表无关联关系时,多表关联和主子表查询内容简化或注明不适用。
5. 聚合词位置遵守 custdep.nlq 中 ps 属性,非维字段过滤加单引号。
6. 举例至少覆盖上一阶段所有通过的用例。
7. 生成 md 后,将所有自然语言用例和对应的 NLQ+NLC 结果逐条列出标序号,保存为用例列表文件。
8. 只生成这两个文件,完成后告诉我。
实施人员检查清单:
- custdep_nlq_nspl.md 通用部分是否与 tpch 一致,词典部分是否与 custdep.nlq 一致。
- 举例是否基于上一阶段测试用例,NLC 部分是否模仿 tpch 写法。
- 用例列表文件是否已生成,包含所有自然语言用例和对应结果。
确认无误后进入第八阶段。
第八阶段:Web 端 JSP 配置
本阶段的目的:在润乾报表 Web 端(润乾 NLQ 智能查询界面)配置 custdep 实例,使用户可通过浏览器进行自然语言查询。需要修改三个文件:chat.jsp(四处映射)、nlqConfig.xml(路径改为绝对路径)、llm.properties(配置大模型 API key)。
一、chat.jsp 修改(四处映射)
文件路径:report/web/webapps/demo/raqsoft/chatbi/jsp/chat.jsp
1. 默认 dataSource:改为 NLQ4CUSTDEP。
2. mdFile 映射:添加 NLQ4CUSTDEP 分支,指向 custdep_nlq_nspl.md。
3. nlq 词典路径映射:添加 NLQ4CUSTDEP 分支,指向 /WEB-INF/files/dql/custdep.nlq。
4. chatType 映射:添加 NLQ4CUSTDEP 分支,chatType=3(NLQ+NLC)。
二、nlqConfig.xml 路径修正(必须用绝对路径)
文件路径:report/web/webapps/demo/WEB-INF/classes/nlqConfig.xml
nlqCustDep 的 MetaData 和 RaqsoftConfig 必须改为绝对路径,否则 Tomcat 运行时会找不到文件。
三、llm.properties 大模型配置
文件路径:report/web/webapps/demo/WEB-INF/llm.properties
Web 端自然语言查询需要调用大模型将自然语言转为规范文本。该文件为产品自带(report/web/webapps/demo/WEB-INF/llm.properties),已预置 DeepSeek 等常用模型的配置模板,实施人员只需填入自己的 API key 即可。
以下是发给豆包的内容模板:
▼ 发给豆包的内容(可直接复制):
现在配置 Web 端 JSP。
{
"chatJsp": "/raqsoft/report/web/webapps/demo/raqsoft/chatbi/jsp/chat.jsp",
"nlqConfig": "/raqsoft/report/web/webapps/demo/WEB-INF/classes/nlqConfig.xml",
"llmProperties": "/raqsoft/report/web/webapps/demo/WEB-INF/llm.properties",
"NLQ数据源名": "NLQ4CUSTDEP",
"nlq文件": "/raqsoft/report/web/webapps/demo/WEB-INF/files/dql/custdep.nlq",
"raqsoftConfig": "/raqsoft/report/web/webapps/demo/WEB-INF/raqsoftConfig.xml"
}
第一个文件 chat.jsp,参考已有 NLQ4TPCH 配置,为 NLQ4CUSTDEP 添加四处映射(不修改已有配置):
1. 默认 dataSource:if (dataSource == null) dataSource = "NLQ4CUSTDEP";
2. mdFile 映射:} else if ("NLQ4CUSTDEP".equals(dataSource)) { if (qcr) mdFile = "custdep_nlq_nspl_nlr.md"; else mdFile = "custdep_nlq_nspl.md"; }
3. nlq 路径映射:else if ("NLQ4CUSTDEP".equals(dataSource)) nlq = "/WEB-INF/files/dql/custdep.nlq";
4. chatType 映射:else if ('<%=dataSource%>' == 'NLQ4CUSTDEP') { chatType = 3; }
第二个文件 nlqConfig.xml,将 nlqCustDep 的 MetaData 和 RaqsoftConfig 改为绝对路径:
<MetaData>/raqsoft/report/web/webapps/demo/WEB-INF/files/dql/custdep.nlq</MetaData>
<RaqsoftConfig>/raqsoft/report/web/webapps/demo/WEB-INF/raqsoftConfig.xml</RaqsoftConfig>
第三个文件 llm.properties,确认大模型配置存在且 key 已填写(如未填写,告知实施人员需自行填入 API key)。
只修改这三个文件,完成后告诉我。
实施人员检查清单:
- chat.jsp 四处映射已添加。
- nlqConfig.xml 中 nlqCustDep 的 MetaData 和 RaqsoftConfig 为绝对路径。
- llm.properties 中大模型 API key 已填写。
确认无误后,启动报表中心验证:
执行 report/bin/startreportcenter.sh 启动报表中心,访问润乾 NLQ 界面验证全链路。
至此,润乾 NLQ 单表场景的全部集成实施完成。
