update, translate skill.md

This commit is contained in:
tao.chen
2026-06-22 10:08:52 +08:00
parent 71a23d639c
commit f9b03384ab
6 changed files with 565 additions and 541 deletions
+82 -79
View File
@@ -1,97 +1,99 @@
---
name: logic-planner
description: Use when turning a validated data requirement (candidate tables/fields/joins already confirmed) into a step-by-step execution plan that a SQL generator can implement mechanically. Triggers include "拆解逻辑", "执行计划", "logic plan", "SQL 编排", "怎么算", "指标拆解", "join 顺序". Consumes the Validation Result from metadata-validator and produces a Logic Plan in a fixed step taxonomy (Source / Filter / Join / Transform / Aggregate / Output). Does NOT write SQL.
description: 当需要把一份已校验的数据需求(候选表/字段/join 关联已确认)拆解为 SQL 生成器可机械执行的步骤计划时使用。触发词包括"拆解逻辑""执行计划""logic plan""SQL 编排""怎么算""指标拆解""join 顺序"。消费 metadata-validator 的 Validation Result,产出固定步骤分类法(Source / Filter / Join / Transform / Aggregate / Output)的 Logic Plan。**不写 SQL**。
---
# Logic Planner
# Logic Planner(逻辑规划器)
## Overview
## 概述(Overview)
Decompose a validated data requirement into a deterministic pipeline of steps in a fixed taxonomy. The Logic Plan is the *only* input `sql-context-builder` needs to assemble a SQL Context — no further business reasoning is permitted downstream.
将一份已校验的数据需求分解为固定分类法下的确定性步骤流水线。Logic Plan 是 `sql-context-builder` 拼装 SQL Context **唯一**的输入 — 下游不允许再做任何业务推理。
Core principle: **decompose, don't translate.** This skill never writes SQL syntax. It only describes *what* must happen at each step in business/logical terms. The translation to SQL is a separate concern.
核心原则:**只拆分,不翻译。** 本 skill 绝不写 SQL 语法,只在业务/逻辑层面描述每一步要发生什么。SQL 翻译是另一回事。
## When to Use
## 何时使用(When to Use)
Use when:
- `metadata-validator` returned status `VALIDATED` and you need to design how the query will run
- The user asks "how should I compute this", "what's the logic", "step-by-step plan" for a data requirement
- You need to disambiguate grain, metric formulas, deduplication, windowing, or ranking before SQL
**使用场景:**
Do NOT use when:
- `metadata-validator` returned `NEED_USER_CONFIRMATION` — go back and resolve open questions first
- The user has already provided a written execution plan and just needs SQL — go straight to `sql-context-builder`
- `metadata-validator` 返回状态 `VALIDATED`,需要设计查询如何执行
- 用户询问"这个应该怎么算"、"逻辑是啥"、"一步步怎么走"等数据需求问题
- 写 SQL 之前需要先消除粒度、指标公式、去重、窗口、排名的歧义
## Inputs
**不要使用场景:**
1. **Validation Result** from `metadata-validator` (status `VALIDATED`)
2. The original business requirement (often embedded in `requirements-analysis` output)
3. `field_mapping` (mandatory) — every business field must be mapped to a physical `(table, column, type)` before planning starts
- `metadata-validator` 返回 `NEED_USER_CONFIRMATION` — 先回去解决未决问题
- 用户已经提供了书面执行计划,只是要 SQL — 直接进入 `sql-context-builder`
## Step Taxonomy
## 输入(Inputs)
Every Logic Plan is a list of steps. Each step has exactly one `kind` from this set. Reuse the same kind for repeated operations (e.g. multiple joins, multiple filters).
1. 来自 `metadata-validator`**Validation Result**(状态为 `VALIDATED`)
2. 原始业务需求(通常嵌在 `requirements-analysis` 的输出中)
3. `field_mapping`(必备) — 每个业务字段在规划开始前必须先映射到物理 `(table, column, type)`
| Kind | Purpose | Required fields |
## 步骤分类法(Step Taxonomy)
每个 Logic Plan 都是一组步骤。每个步骤有且仅有一个 `kind`,且只能从下表选取。对重复操作(如多次 join、多次 filter)复用同一种 kind。
| Kind | 用途 | 必填字段 |
|---|---|---|
| `source` | Read from a table or subquery | `alias`, `table`, `columns[]` |
| `filter` | Apply predicates to a named alias | `alias`, `predicates[]` |
| `join` | Combine two aliases on keys | `left`, `right`, `keys[]`, `type` (inner/left/right/full/semi/anti) |
| `transform` | Derive new columns (case-when, arithmetic, type cast) | `alias`, `expressions[]` |
| `aggregate` | Group and reduce | `alias`, `group_by[]`, `metrics[]` (each: `expr`, `alias`, `agg`) |
| `dedupe` | DISTINCT or row_number-based dedup | `alias`, `keys[]`, `strategy` |
| `window` | Ranking / running totals / lag-lead | `alias`, `partition_by[]`, `order_by[]`, `window_fn` |
| `output` | Final projection and ordering | `columns[]`, `order_by[]`, `limit?` |
| `source` | 从表或子查询读取 | `alias`, `table`, `columns[]` |
| `filter` | 在指定 alias 上应用谓词 | `alias`, `predicates[]` |
| `join` | 在 key 上合并两个 alias | `left`, `right`, `keys[]`, `type` (inner/left/right/full/semi/anti) |
| `transform` | 派生新列(case-when、算术、类型转换) | `alias`, `expressions[]` |
| `aggregate` | 分组聚合 | `alias`, `group_by[]`, `metrics[]` (每个含 `expr`, `alias`, `agg`) |
| `dedupe` | DISTINCT 或基于 row_number 的去重 | `alias`, `keys[]`, `strategy` |
| `window` | 排名 / 累计 / lag-lead | `alias`, `partition_by[]`, `order_by[]`, `window_fn` |
| `output` | 最终投影和排序 | `columns[]`, `order_by[]`, `limit?` |
Do not invent new kinds. If a transformation does not fit, surface it as `pending_question` and stop.
不要发明新 kind。如果某个变换无法归入上述分类,作为 `pending_question` 暴露并停止。
## Workflow
## 工作流(Workflow)
```dot
digraph logic_planner {
"Read Validation Result + field_mapping" [shape=box];
"Identify fact vs dimension tables & choose primary source" [shape=box];
"List filters (time range, status, business predicates)" [shape=box];
"Plan joins (alias A ON key = alias B.key)" [shape=box];
"Plan transforms (derived columns, type casts)" [shape=box];
"Plan dedupe / window if needed" [shape=box];
"Plan aggregate (grain + metrics)" [shape=box];
"Plan output projection + order" [shape=box];
"Any ambiguity?" [shape=diamond];
"Emit Logic Plan" [shape=box];
"Emit Logic Plan + pending_questions" [shape=box];
"读取 Validation Result + field_mapping" [shape=box];
"区分事实表 / 维度表,选定主源表" [shape=box];
"列出过滤条件(时间区间、状态、业务谓词)" [shape=box];
"规划 join(alias A ON key = alias B.key)" [shape=box];
"规划 transform(派生列、类型转换)" [shape=box];
"如需去重 / 窗口,一并规划" [shape=box];
"规划 aggregate(粒度 + 指标)" [shape=box];
"规划 output 投影 + 排序" [shape=box];
"还有歧义?" [shape=diamond];
"输出 Logic Plan" [shape=box];
"输出 Logic Plan + pending_questions" [shape=box];
"Read Validation Result + field_mapping" -> "Identify fact vs dimension tables & choose primary source";
"Identify fact vs dimension tables & choose primary source" -> "List filters (time range, status, business predicates)";
"List filters (time range, status, business predicates)" -> "Plan joins (alias A ON key = alias B.key)";
"Plan joins (alias A ON key = alias B.key)" -> "Plan transforms (derived columns, type casts)";
"Plan transforms (derived columns, type casts)" -> "Plan dedupe / window if needed";
"Plan dedupe / window if needed" -> "Plan aggregate (grain + group_by)";
"Plan aggregate (grain + group_by)" -> "Plan output projection + order";
"Plan output projection + order" -> "Any ambiguity?";
"Any ambiguity?" -> "Emit Logic Plan" [label="no"];
"Any ambiguity?" -> "Emit Logic Plan + pending_questions" [label="yes"];
"读取 Validation Result + field_mapping" -> "区分事实表 / 维度表,选定主源表";
"区分事实表 / 维度表,选定主源表" -> "列出过滤条件(时间区间、状态、业务谓词)";
"列出过滤条件(时间区间、状态、业务谓词)" -> "规划 join(alias A ON key = alias B.key)";
"规划 join(alias A ON key = alias B.key)" -> "规划 transform(派生列、类型转换)";
"规划 transform(派生列、类型转换)" -> "如需去重 / 窗口,一并规划";
"如需去重 / 窗口,一并规划" -> "规划 aggregate(粒度 + group_by)";
"规划 aggregate(粒度 + group_by)" -> "规划 output 投影 + 排序";
"规划 output 投影 + 排序" -> "还有歧义?";
"还有歧义?" -> "输出 Logic Plan" [label="no"];
"还有歧义?" -> "输出 Logic Plan + pending_questions" [label="yes"];
}
```
## Required Reasoning (do not skip)
## 必须给出的推理(Required Reasoning,不可跳过)
Before emitting the plan, you MUST explicitly state and record:
在输出 plan 之前,你必须显式陈述并记录:
1. **Grain**what does one output row represent? (e.g. one customer, one customer×month, one order)
2. **Metric formula**for every metric, write the exact expression: numerator and denominator defined.
3. **Time grain**confirm the time field and granularity (day, month, hour). State the window inclusively.
4. **Join cardinality**for every join, predict 1:1 / 1:N / N:N. If N:N, mark it and ask the user whether to dedupe before joining.
5. **Dedup position**if a fact table has row multiplicity (e.g. one customer with many addresses), decide *before* the join which side gets deduped and on which key.
6. **Null strategy**for nullable join keys or measures, decide `INNER` vs `LEFT + COALESCE`.
1. **粒度(Grain)**输出一行代表什么?(例如:一个客户、一个客户×月、一笔订单)
2. **指标公式(Metric formula)**对每个指标写出精确表达式:分子与分母都要定义
3. **时间粒度(Time grain)**确认时间字段与粒度(天 / 月 / 小时),用闭/开区间说明窗口
4. **Join 基数(Join cardinality)**对每个 join,预测 1:1 / 1:N / N:N。如果是 N:N,必须标记并询问用户是否在 join 前去重
5. **去重位置(Dedup position)**如果事实表存在行重复(例如一个客户多个地址),在 join 之前决定哪一侧、在哪个 key 上先去重
6. **空值策略(Null strategy)**对可空 join key 或度量,决定用 `INNER` 还是 `LEFT + COALESCE`
If any of the above is unclear, add a `pending_question` and stop. Do not guess.
以上任意一项不清楚时,加入 `pending_question` 并停止。绝不臆测。
## Output Contract
## 输出契约(Output Contract)
```yaml
logic_plan:
grain: "<one sentence describing what one output row represents>"
grain: "<一句话描述输出一行代表什么>"
fact_table: <table_name>
dimension_tables:
- <table_name>
@@ -111,7 +113,7 @@ logic_plan:
right: { alias: c, table: customer_info }
keys: ["o.customer_id = c.customer_id"]
type: left
cardinality_assumption: 1:N # if known; else state "unknown"
cardinality_assumption: 1:N # 已知时填;否则写 "unknown"
- kind: transform
alias: o
expressions:
@@ -132,27 +134,28 @@ logic_plan:
order_by: ["total_loan DESC"]
limit: 100
pending_questions:
- "<ambiguity not yet resolved, blocking SQL generation>"
- "<尚未解决的歧义,会阻塞 SQL 生成>"
status: <PLANNED | NEED_USER_CONFIRMATION>
```
## Forbidden Behaviors
## 禁止行为(Forbidden Behaviors)
| Rationalization | Reality |
| 自我说服 | 现实 |
|---|---|
| "I'll write the SELECT list directly, the user can read SQL" | Logic Plan uses business terms; SQL is downstream. |
| "Aggregation is obvious, skip the formula" | Explicit numerator/denominator avoids silent metric drift. |
| "1:N vs N:N doesn't matter for SELECT" | It matters: it determines dedup and inflation risk. |
| "Time grain is the user's problem" | Pick a grain. Wrong grain ⇒ wrong numbers. |
| "I'll add a HAVING clause at SQL time" | Logic Plan must list all filters, including post-aggregation. |
| "我直接写 SELECT 列表,用户能读懂 SQL" | Logic Plan 用业务术语,SQL 是下游的事。 |
| "聚合太显然,公式就省了" | 显式给出分子/分母才能避免静默的指标漂移。 |
| "1:N 还是 N:N 对 SELECT 来说无所谓" | 它决定了是否要去重以及是否有膨胀风险,影响很大。 |
| "时间粒度是用户的问题" | 必须由规划器选定一个粒度,选错了数字就全错。 |
| "HAVING 我到 SQL 那一步再加" | 所有过滤(含聚合后)都必须在 Logic Plan 中列出。 |
## Completion Criteria
## 完成判定(Completion Criteria)
Status `PLANNED` requires:
- Grain is one sentence, not a paragraph
- Every `field_mapping` entry is referenced by exactly one step
- Every join has a cardinality assumption
- Every metric has an explicit `agg` and an `alias`
- `pending_questions` is empty
要输出状态 `PLANNED`,必须满足:
Otherwise: `NEED_USER_CONFIRMATION` and stop. Do not proceed to `sql-context-builder`.
- 粒度用一句话描述,不是一段话
- 每个 `field_mapping` 条目都被恰好一个 step 引用
- 每个 join 都有 cardinality 假设
- 每个指标都有显式 `agg``alias`
- `pending_questions` 为空
否则:状态为 `NEED_USER_CONFIRMATION` 并停止。**不得**进入 `sql-context-builder`