Skip to content

分析类CLI

定位:让 AI 现场「拼」查询,不调死端点——模型填结构化 DSL JSON,引擎编译成 SQL 直查语义层(宽表 + 本体),口径护栏自动注入。支持多维聚合、Top-N、下钻归因。对应风险等级 R0(读),但能力远超查询类。

📎 案例参考:实战 B sales-query find/aggregate/rank · Cube 语义层(measures/dimensions 一次定义、编译成 SQL)。理论底座见 设计指南/本体设计/TBox设计指南/本体设计/ABox


  • 任意维度聚合(GROUP BY)、排名(Top-N)、时间分桶、计算度量(去化率)
  • 下钻归因:沿共振/替代关系追根因(L3/L4)
  • ✅ 加新维度不想改代码——换 DSL 参数即可
  • ❌ 只取一条固定数据 → 用更轻的 设计指南/CLI设计/查询类CLI

命令形态:窄到只有 3 个一级指令

Section titled “命令形态:窄到只有 3 个一级指令”

接口窄 = 错不了。模型只填 JSON,不写 SQL:

指令用途关键字段SQL 语义
find行级查询cube · dimensions · filters · order · limitSELECT … WHERE … LIMIT
aggregate聚合分组cube · dimensions · measures · filters · havingSELECT … GROUP BY … HAVING
rankTop-N 排名cube · rankBy · dimensions · measures · limitSELECT … ORDER BY … LIMIT N
Terminal window
sales-query aggregate --dsl '{
"cube":"OrderDetail",
"dimensions":["zygw"],
"measures":[{"member":"cjTotal","agg":"sum"}]
}'
# 引擎自动加 WHERE Status=激活 AND OrderType=认购

为什么是 DSL 而不是「让模型写 SQL」

Section titled “为什么是 DSL 而不是「让模型写 SQL」”

业界语义层(Cube 等)的共识:AI 生成查询前,先读语义层的概念上下文,避免幻觉列名、错 JOIN、错 filter。DSL 把这点强制化:

  1. 每个 cube/measure/filter 必须在 TBox 里有定义(TBox = DSL 的词典),模型不能凭空造字段。
  2. 口径护栏 defaultFilters 默认过滤 + 规则放开:模型不传也补——这是 设计指南/本体设计/TBox 货值三倍 bug 的解法(AI 写裸 SQL 错 3 倍,DSL 引擎默认补 Level=3 就对);但用户「按科目」展开查询时引擎自动放开这条兜底(unless 字段出现在 filter / dimension),不把”看各级科目”焊死成只看末级。机制见 场景指南/问数/04-DSL编译层 §4.4.2。
  3. routed measure / friendlyAlias:同名多口径路由、中文短名,语义层统一处理。
  1. 窄接口:一级指令越少越好(3 个够覆盖 90%);复杂度沉到 schema,不沉到命令面。
  2. 护栏写在本体不在命令:业务铁律进 schema.yaml,模型再厉害也绕不过。
  3. 计算度量声明式:{"alias":"去化率","calc":"${已成交}/${全盘}"},不让模型手算。
  4. 下钻沿 ABox 关系:归因不是背科目,是沿 resonance/substitute 边走(见 设计指南/本体设计/ABox)。
  5. JSON 填空 > 自由发挥:模型只填结构化字段,引擎负责 SQL 正确性与口径安全。

stdout 纯 JSON(含命中行、自动注入的 WHERE 作为 evidence);对业务暴露结论+依据,不暴露 schema/cube/DSL/SQL/字段路由等实现细节。

分析类的转换特征:问话里出现”按…分组 / 排名 / 比率 / 为什么”等聚合意图,落成 find/aggregate/rank 三选一,模型只填 DSL JSON。

▸ find「列出 5 月成交额超过 500 万的订单明细」

Terminal window
sales-query find --dsl '{
"cube":"OrderDetail",
"dimensions":["fanghao","zygw","cjTotal"],
"filters":[{"member":"month","op":"=","val":"2026-05"},
{"member":"cjTotal","op":">","val":5000000}],
"order":[{"member":"cjTotal","dir":"desc"}], "limit":50
}'

行级明细 + 条件过滤 = find;引擎仍自动注入 Status=激活 等口径护栏。

▸ aggregate「各置业顾问 5 月成交额合计」

Terminal window
sales-query aggregate --dsl '{
"cube":"OrderDetail", "dimensions":["zygw"],
"measures":[{"member":"cjTotal","agg":"sum"}],
"filters":[{"member":"month","op":"=","val":"2026-05"}]
}'

「各 X 的 Y 合计」= GROUP BY zygw + SUM;典型聚合句式。

▸ rank「成交额前 5 的楼盘」

Terminal window
sales-query rank --dsl '{
"cube":"OrderDetail",
"rankBy":{"member":"cjTotal","agg":"sum"},
"dimensions":["loupan"], "limit":5
}'

「前 N / 排个名 / 谁最高」→ rank,本质是 aggregate + ORDER BY + LIMIT 的窄化封装。

▸ 计算度量「各业态的去化率」

Terminal window
sales-query aggregate --dsl '{
"cube":"Inventory", "dimensions":["yetai"],
"measures":[{"alias":"去化率","calc":"${已成交}/${全盘}"}]
}'

比率类声明式交给引擎,不让模型手算分子分母;去化率/含量/单方造价同理。

▸ 下钻归因「为什么 A 业态卖得这么差?」

Terminal window
sales-query find --dsl '{
"cube":"Inventory", "dimensions":["A业态"],
"drilldown":{"along":"substitute", "depth":2}
}'

归因不是背科目,是沿 ABox 的 resonance/substitute 关系边走(见 设计指南/本体设计/ABox);三个一级指令够覆盖 90% 分析意图。

  • 一级指令膨胀到十几个 → 退化成「DSL 版 API wrapper」
  • 护栏写进 SKILL.md 而非 schema → 长链路下漏一条就错口径
  • 让模型直接写 SQL「更灵活」→ 幻觉列名 + 口径裸奔(货值 bug 即此)

分析类 CLI 胜在灵活、新维度即问即答、口径由本体兜底;它是「垂直 Agent = Skill + 本体 + CLI」的核心。工程化全流程见 场景指南/问数