update, translate skill.md
This commit is contained in:
@@ -1,28 +1,30 @@
|
||||
---
|
||||
name: pyspark-sql-pipeline
|
||||
description: Use when orchestrating the full PySpark SQL pipeline from a business requirement to a reviewed, ready-to-execute SQL string. Triggers include "完整跑一遍取数流程", "生成 SQL 并 review", "end-to-end 取数", "full pipeline", "从头到尾", "数据需求到 SQL". Coordinates requirements-analysis → metadata-validator → logic-planner → sql-context-builder → pyspark-sql-guardrails → sql-review as a single deterministic flow with explicit user-confirmation gates between stages. Does NOT execute SQL — it drives the pipeline to a reviewed SQL string.
|
||||
description: 当需要把业务需求一路编排到"已被评审过、可执行的 SQL 字符串"时使用。触发词包括"完整跑一遍取数流程"、"生成 SQL 并 review"、"end-to-end 取数"、"full pipeline"、"从头到尾"、"数据需求到 SQL"。把 requirements-analysis → metadata-validator → logic-planner → sql-context-builder → pyspark-sql-guardrails → sql-review 串成一条确定性流水线,阶段之间用显式的用户确认关口隔开。**不执行 SQL** — 只把流水线驱动到一条被评审过的 SQL 字符串。
|
||||
---
|
||||
|
||||
# PySpark SQL Pipeline
|
||||
# PySpark SQL Pipeline(PySpark SQL 流水线)
|
||||
|
||||
## Overview
|
||||
## 概述(Overview)
|
||||
|
||||
End-to-end orchestrator for turning a business data requirement into a reviewed SQL string. Each stage has a fixed input/output contract; between any two stages there is a **user-confirmation gate** when the upstream status is not green.
|
||||
把一份业务数据需求一路编排到"已评审"SQL 字符串的端到端协调器。每个阶段有固定的输入/输出契约;任意两阶段之间,当上游状态不是绿色时,都设有**用户确认关口**。
|
||||
|
||||
Core principle: **never skip a stage, never let a stage quietly proceed past its own `NEED_USER_CONFIRMATION`.** The pipeline is a sequence of hand-offs, not a single agent's internal monologue.
|
||||
核心原则:**绝不跳阶段,也绝不让任何阶段悄无声息地越过它自己的 `NEED_USER_CONFIRMATION`。** 流水线是一连串交接,不是某个 agent 的内心独白。
|
||||
|
||||
## When to Use
|
||||
## 何时使用(When to Use)
|
||||
|
||||
Use when:
|
||||
- The user gives a data requirement and wants SQL produced end-to-end (e.g. "统计近 30 天各城市贷款总额及客户数")
|
||||
- The user asks to "run the full pipeline" or "从需求到 SQL 一条龙"
|
||||
- A non-trivial SQL change touches multiple skills' contracts
|
||||
**使用场景:**
|
||||
|
||||
Do NOT use when:
|
||||
- The user only needs one stage (e.g. "review this SQL" → use `sql-review` directly)
|
||||
- The user explicitly says "skip validation" or "just give me SQL fast" — surface the risk and ask once; if they confirm, you may collapse stages but you MUST still apply `pyspark-sql-guardrails` and `sql-review`
|
||||
- 用户给出一个数据需求,希望端到端生成 SQL(例如"统计近 30 天各城市贷款总额及客户数")
|
||||
- 用户要求"跑完整流水线"或"从需求到 SQL 一条龙"
|
||||
- 一个非平凡的 SQL 改动会同时触碰多个 skill 的契约
|
||||
|
||||
## The Pipeline
|
||||
**不要使用场景:**
|
||||
|
||||
- 用户只需要其中一个阶段(例如"评审这条 SQL" → 直接用 `sql-review`)
|
||||
- 用户明确说"跳过校验"或"快点给我 SQL"— 主动说明风险并确认一次;若用户确认,可以合并阶段,但**仍必须**应用 `pyspark-sql-guardrails` 和 `sql-review`
|
||||
|
||||
## 流水线(The Pipeline)
|
||||
|
||||
```dot
|
||||
digraph pipeline {
|
||||
@@ -30,92 +32,93 @@ digraph pipeline {
|
||||
"2. metadata-validator" [shape=box];
|
||||
"3. logic-planner" [shape=box];
|
||||
"4. sql-context-builder" [shape=box];
|
||||
"5. SQL generation" [shape=box];
|
||||
"5. SQL 生成" [shape=box];
|
||||
"6. pyspark-sql-guardrails" [shape=box];
|
||||
"7. sql-review" [shape=box];
|
||||
|
||||
"1. requirements-analysis" -> "2. metadata-validator" [label="status=READY_FOR_VALIDATION"];
|
||||
"2. metadata-validator" -> "3. logic-planner" [label="status=VALIDATED"];
|
||||
"3. logic-planner" -> "4. sql-context-builder" [label="status=PLANNED"];
|
||||
"4. sql-context-builder" -> "5. SQL generation" [label="status=READY"];
|
||||
"5. SQL generation" -> "6. pyspark-sql-guardrails" [label="SQL string"];
|
||||
"4. sql-context-builder" -> "5. SQL 生成" [label="status=READY"];
|
||||
"5. SQL 生成" -> "6. pyspark-sql-guardrails" [label="SQL 字符串"];
|
||||
"6. pyspark-sql-guardrails" -> "7. sql-review" [label="guardrail pass"];
|
||||
}
|
||||
```
|
||||
|
||||
Every arrow is a **contract boundary**. Do not let a stage start before its predecessor has produced the expected status.
|
||||
每条箭头都是**契约边界**。前序阶段没产出预期状态时,绝不允许下游阶段启动。
|
||||
|
||||
## Stage Contracts
|
||||
## 阶段契约(Stage Contracts)
|
||||
|
||||
| # | Stage | Skill | Input | Output Status (green) | Output Status (stop) |
|
||||
| # | 阶段 | Skill | 输入 | 绿色输出状态 | 停止状态 |
|
||||
|---|---|---|---|---|---|
|
||||
| 1 | Requirements | `requirements-analysis` | user message | `READY_FOR_VALIDATION` | `NEED_USER_CONFIRMATION` |
|
||||
| 2 | Metadata | `metadata-validator` | requirements_output + workspace | `VALIDATED` | `NEED_USER_CONFIRMATION` |
|
||||
| 3 | Logic | `logic-planner` | validation_result | `PLANNED` | `NEED_USER_CONFIRMATION` |
|
||||
| 4 | Context | `sql-context-builder` | logic_plan + field_mapping | `READY` | `NEED_USER_CONFIRMATION` |
|
||||
| 5 | Generate | (no skill — see "SQL Generation" below) | sql_context | SQL string | n/a |
|
||||
| 6 | Guardrail | `pyspark-sql-guardrails` | SQL string | `pass` | `fail` (raise) |
|
||||
| 7 | Review | `sql-review` | SQL string + sql_context | `verdict: PASS` | `verdict: FAIL` |
|
||||
| 1 | 需求 | `requirements-analysis` | 用户消息 | `READY_FOR_VALIDATION` | `NEED_USER_CONFIRMATION` |
|
||||
| 2 | 元数据 | `metadata-validator` | requirements_output + 工作区 | `VALIDATED` | `NEED_USER_CONFIRMATION` |
|
||||
| 3 | 逻辑 | `logic-planner` | validation_result | `PLANNED` | `NEED_USER_CONFIRMATION` |
|
||||
| 4 | 上下文 | `sql-context-builder` | logic_plan + field_mapping | `READY` | `NEED_USER_CONFIRMATION` |
|
||||
| 5 | 生成 | (无独立 skill — 见下文"SQL 生成") | sql_context | SQL 字符串 | n/a |
|
||||
| 6 | 防护栏 | `pyspark-sql-guardrails` | SQL 字符串 | `pass` | `fail`(抛错) |
|
||||
| 7 | 评审 | `sql-review` | SQL 字符串 + sql_context | `verdict: PASS` | `verdict: FAIL` |
|
||||
|
||||
## Gate Rules (READ THESE CAREFULLY)
|
||||
## 关口规则(Gate Rules,务必细读)
|
||||
|
||||
A stage that returns a stop status **must not** be followed by the next stage. Instead:
|
||||
返回停止状态的阶段**不能**被下一阶段跟随。要做的:
|
||||
|
||||
1. Surface the `pending_questions` from that stage to the user.
|
||||
2. Stop the pipeline.
|
||||
3. After the user answers, re-run from the same stage (not from the beginning) using the user's answers as additional input.
|
||||
4. Once the stage produces its green status, advance to the next stage.
|
||||
1. 把该阶段的 `pending_questions` 暴露给用户
|
||||
2. 停下流水线
|
||||
3. 等用户回答后,从**同一个阶段**重跑(不是从头跑),把用户的新回答作为额外输入
|
||||
4. 一旦该阶段产出绿色状态,推进到下一阶段
|
||||
|
||||
Stages are idempotent. Re-running a stage with the same inputs must produce the same output; with new inputs, it must produce a new output that supersedes the old one. Carry forward all prior `field_mapping`, `validation_result`, `logic_plan`, and `sql_context` as the durable artifacts of the pipeline.
|
||||
阶段是幂等的。同一份输入重跑必须产出同样的输出;新输入则必须产出能覆盖旧输出的新输出。所有前置的 `field_mapping`、`validation_result`、`logic_plan`、`sql_context` 必须作为流水线的持久化产物一路带下来。
|
||||
|
||||
## SQL Generation (Stage 5)
|
||||
## SQL 生成(阶段 5)
|
||||
|
||||
There is no dedicated skill for generating SQL. The pipeline performs this step directly, with these constraints:
|
||||
本步没有独立的 skill。流水线直接执行,约束如下:
|
||||
|
||||
- Use the `sql_context` as the **only** source of field names, aliases, and join keys.
|
||||
- Compose the SQL from the `logic_plan.steps` in order: `source` → `filter` → `join` → `transform` → `dedupe` → `window` → `aggregate` → `output`.
|
||||
- Every `<alias>.<column>` in the output must appear in `sql_context.fields`.
|
||||
- The generated SQL must be runnable through `pyspark-sql-guardrails.safe_spark_sql` without further edits.
|
||||
- `sql_context` 是字段名、alias、join key 的**唯一**来源
|
||||
- 按 `logic_plan.steps` 的顺序组装 SQL:`source` → `filter` → `join` → `transform` → `dedupe` → `window` → `aggregate` → `output`
|
||||
- 输出中每个 `<alias>.<column>` 都必须出现在 `sql_context.fields` 中
|
||||
- 生成的 SQL 必须能在 `pyspark-sql-guardrails.safe_spark_sql` 中不修改地跑过
|
||||
|
||||
## User-Confirmation Messages
|
||||
## 用户确认消息(User-Confirmation Messages)
|
||||
|
||||
Each gate should produce a single, structured message in this shape:
|
||||
每个关口应产出一条结构化消息,格式如下:
|
||||
|
||||
```markdown
|
||||
## Pipeline paused at: <stage name>
|
||||
## Pipeline paused at: <阶段名>
|
||||
**Status:** NEED_USER_CONFIRMATION
|
||||
**Open questions:**
|
||||
1. <question 1>
|
||||
2. <question 2>
|
||||
1. <问题 1>
|
||||
2. <问题 2>
|
||||
**Pending options:** A / B / C / other
|
||||
**To resume:** answer the questions above, then say "继续" (continue).
|
||||
**To resume:** 回答以上问题后,说"继续"。
|
||||
```
|
||||
|
||||
Do not present a stage's output as final when its status is a stop status. Do not bury the `pending_questions` inside a longer narrative.
|
||||
不要把某个阶段的输出当作最终结果,如果它的状态是停止状态。不要把 `pending_questions` 埋在冗长叙述里。
|
||||
|
||||
## Failure Handling
|
||||
## 失败处理(Failure Handling)
|
||||
|
||||
- **Guardrail failure (`pyspark-sql-guardrails`)** — do not retry the same SQL. Return to Stage 5 and regenerate, this time respecting the guardrail.
|
||||
- **Review verdict FAIL with HIGH findings** — return to Stage 5 (or earlier if a finding is about context, in which case return to Stage 4). Do not "patch" the SQL to silence a finding; address the root cause.
|
||||
- **Review verdict FAIL with only MEDIUM/LOW** — surface the findings to the user. They decide whether to ship or fix.
|
||||
- **Inconsistency between stages** (e.g. SQL references a column not in `sql_context`) — treat as a Stage 5 bug; the SQL was generated without honoring the context. Regenerate, do not amend.
|
||||
- **防护栏失败(`pyspark-sql-guardrails`)** — 不要用同一条 SQL 重试。回到阶段 5 重新生成,这一次遵守防护栏
|
||||
- **评审结论为 FAIL 且有 HIGH 风险** — 回到阶段 5(或更早,如果是 context 类的发现,就回到阶段 4)。**不要**"打个补丁"让发现项闭嘴;要解决根因
|
||||
- **评审结论为 FAIL 但只有 MEDIUM/LOW** — 把发现项暴露给用户,由用户决定上线还是改
|
||||
- **阶段间不一致**(例如 SQL 引用了 `sql_context` 里没有的列) — 视为阶段 5 的 bug;SQL 在生成时没遵守 context。**重新生成,不要修补**。
|
||||
|
||||
## Forbidden Behaviors
|
||||
## 禁止行为(Forbidden Behaviors)
|
||||
|
||||
| Rationalization | Reality |
|
||||
| 自我说服 | 现实 |
|
||||
|---|---|
|
||||
| "User asked for SQL fast, skip the gates" | Gates exist because skipping them produces wrong numbers. Ask the user once; if they confirm, you may collapse only adjacent non-validation stages. Never skip guardrail or review. |
|
||||
| "Just one stage failed, no need to ask" | Every stop status is a question to the user. Always ask. |
|
||||
| "I'll inline the validation into SQL generation" | Stages are separate so they can be re-run independently. Inlining couples them. |
|
||||
| "Review found MEDIUM, ship it" | Surface the findings. The user — not the agent — decides. |
|
||||
| "Field mapping is obvious, skip the validator" | Field mapping is the validator's job. Bypassing it is the #1 cause of hallucinated column names. |
|
||||
| "Same status, just continue" | Status names are fixed strings. Re-check the actual status text, do not pattern-match on memory. |
|
||||
| "用户要 SQL 快点,关口跳过" | 关口存在的原因就是跳过它们会让数字变错。先问一次;如果用户确认,可以只合并相邻的非校验阶段。**永远不能**跳过防护栏或评审。 |
|
||||
| "只一个阶段失败,不必问" | 每一个停止状态都是要问用户的问题。永远要问。 |
|
||||
| "我把校验内联到 SQL 生成里" | 阶段分开是为了能独立重跑,内联会把它们耦合死。 |
|
||||
| "评审只发现 MEDIUM,直接上线" | 把发现项暴露给用户,决定权在用户,不在 agent。 |
|
||||
| "字段映射太显然,跳过校验器" | 字段映射就是校验器的工作。绕过它就是幻觉字段名的头号原因。 |
|
||||
| "状态一样,直接继续" | 状态名是固定字符串。重读实际状态文本,不要凭记忆做模式匹配。 |
|
||||
|
||||
## Completion Criteria
|
||||
## 完成判定(Completion Criteria)
|
||||
|
||||
The pipeline is complete only when:
|
||||
- All 7 stages have run in order
|
||||
- `sql-review.verdict` is `PASS` (or the user has explicitly accepted remaining MEDIUM/LOW findings)
|
||||
- The final SQL string, the `sql_context`, the `logic_plan`, the `validation_result`, and the `requirements_output` are all available to the user in the same response
|
||||
流水线完成需要**全部**满足:
|
||||
|
||||
If the user later changes the requirement, restart at Stage 1 — do not patch downstream artifacts.
|
||||
- 7 个阶段按序都跑过
|
||||
- `sql-review.verdict` 为 `PASS`(或用户已显式接受剩余的 MEDIUM/LOW 发现)
|
||||
- 同一份回复里同时向用户交付:最终 SQL 字符串、`sql_context`、`logic_plan`、`validation_result`、`requirements_output`
|
||||
|
||||
如果用户后续修改了需求,从阶段 1 重新开始 — **不要**打补丁修下游产物。
|
||||
|
||||
Reference in New Issue
Block a user