分析类CLI
分析类 CLI
Section titled “分析类 CLI”定位:让 AI 现场「拼」查询,不调死端点——模型填结构化 DSL JSON,引擎编译成 SQL 直查语义层(宽表 + 本体),口径护栏自动注入。支持多维聚合、Top-N、下钻归因。对应风险等级 R0(读),但能力远超查询类。
📎 案例参考:实战 B
sales-queryfind/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 · limit | SELECT … WHERE … LIMIT |
aggregate | 聚合分组 | cube · dimensions · measures · filters · having | SELECT … GROUP BY … HAVING |
rank | Top-N 排名 | cube · rankBy · dimensions · measures · limit | SELECT … ORDER BY … LIMIT N |
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 把这点强制化:
- 每个 cube/measure/filter 必须在 TBox 里有定义(TBox = DSL 的词典),模型不能凭空造字段。
- 口径护栏
defaultFilters默认过滤 + 规则放开:模型不传也补——这是 设计指南/本体设计/TBox 货值三倍 bug 的解法(AI 写裸 SQL 错 3 倍,DSL 引擎默认补Level=3就对);但用户「按科目」展开查询时引擎自动放开这条兜底(unless字段出现在 filter / dimension),不把”看各级科目”焊死成只看末级。机制见 场景指南/问数/04-DSL编译层 §4.4.2。 - routed measure / friendlyAlias:同名多口径路由、中文短名,语义层统一处理。
- 窄接口:一级指令越少越好(3 个够覆盖 90%);复杂度沉到 schema,不沉到命令面。
- 护栏写在本体不在命令:业务铁律进
schema.yaml,模型再厉害也绕不过。 - 计算度量声明式:
{"alias":"去化率","calc":"${已成交}/${全盘}"},不让模型手算。 - 下钻沿 ABox 关系:归因不是背科目,是沿
resonance/substitute边走(见 设计指南/本体设计/ABox)。 - JSON 填空 > 自由发挥:模型只填结构化字段,引擎负责 SQL 正确性与口径安全。
stdout 纯 JSON(含命中行、自动注入的 WHERE 作为 evidence);对业务暴露结论+依据,不暴露 schema/cube/DSL/SQL/字段路由等实现细节。
案例:用户问题 → CLI
Section titled “案例:用户问题 → CLI”分析类的转换特征:问话里出现”按…分组 / 排名 / 比率 / 为什么”等聚合意图,落成 find/aggregate/rank 三选一,模型只填 DSL JSON。
▸ find「列出 5 月成交额超过 500 万的订单明细」
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 月成交额合计」
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 的楼盘」
sales-query rank --dsl '{ "cube":"OrderDetail", "rankBy":{"member":"cjTotal","agg":"sum"}, "dimensions":["loupan"], "limit":5}'「前 N / 排个名 / 谁最高」→ rank,本质是 aggregate + ORDER BY + LIMIT 的窄化封装。
▸ 计算度量「各业态的去化率」
sales-query aggregate --dsl '{ "cube":"Inventory", "dimensions":["yetai"], "measures":[{"alias":"去化率","calc":"${已成交}/${全盘}"}]}'比率类声明式交给引擎,不让模型手算分子分母;去化率/含量/单方造价同理。
▸ 下钻归因「为什么 A 业态卖得这么差?」
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」的核心。工程化全流程见 场景指南/问数。