189 lines
6.1 KiB
Markdown
189 lines
6.1 KiB
Markdown
---
|
||
name: pyspark-sql-pipeline
|
||
description: 当用户希望从业务需求端到端生成一条经过校验和评审的 Spark SQL / PySpark SQL 作业时使用。它编排 requirements-analysis、metadata-validator、logic-planner、sql-context-builder、SQL 生成、pyspark-sql-guardrails、sql-review,并以正式交付格式输出 DRD、元数据校验、逻辑计划、SQL 上下文、最终 SQL、review 和交付清单。
|
||
---
|
||
|
||
# PySpark SQL Pipeline(端到端 SQL 流水线)
|
||
|
||
## 目标
|
||
|
||
把“用户一句业务需求”推进到“可交付、可审查、可追溯的 SQL 和配套审查结果”。它不是单个 SQL 生成器,而是一条带关口的工程流程。
|
||
|
||
本流水线默认不执行 SQL、不提交 Spark 作业。只有用户明确要求执行,并且 SQL 已通过 guardrails 和 review 后,才允许进入 MCP 工具层。
|
||
|
||
## 阶段顺序
|
||
|
||
```text
|
||
1. requirements-analysis
|
||
2. metadata-validator
|
||
3. logic-planner
|
||
4. sql-context-builder
|
||
5. SQL generation
|
||
6. pyspark-sql-guardrails
|
||
7. sql-review
|
||
8. optional MCP execution handoff
|
||
```
|
||
|
||
## 每阶段放行条件
|
||
|
||
```yaml
|
||
requirements-analysis: requirements_output.status == READY_FOR_METADATA
|
||
metadata-validator: validation_result.status == VALIDATED
|
||
logic-planner: logic_plan.status == PLANNED
|
||
sql-context-builder: sql_context.status == CONTEXT_READY
|
||
pyspark-sql-guardrails: sql_guard.status == PASS
|
||
sql-review: sql_review.verdict == PASS 或用户明确接受非 HIGH 风险
|
||
mcp-handoff: user explicitly requested execution
|
||
```
|
||
|
||
任何阶段输出 `NEED_USER_CONFIRMATION` 或 `FAIL`,流水线必须暂停。
|
||
|
||
## SQL 生成规则
|
||
|
||
SQL 生成没有单独 skill。生成 SQL 时只能翻译以下内容:
|
||
|
||
- `requirements_output`
|
||
- `validation_result`
|
||
- `logic_plan.steps`
|
||
- `sql_context.aliases`
|
||
- `sql_context.fields`
|
||
- `sql_context.joins`
|
||
- `sql_context.metrics`
|
||
- `sql_context.filters`
|
||
- `sql_context.time_windows`
|
||
- `sql_context.outputs`
|
||
- `sql_context.write_intent`
|
||
|
||
不能临时新增表、字段、alias、join key 或指标公式。每个 `alias.column` 必须能在 `sql_context.fields` 中找到。
|
||
|
||
## SQL 时间口径硬规则
|
||
|
||
对“近 N 天按 T-1 完整日”,Spark/Hive SQL 必须使用左闭右开窗口:
|
||
|
||
```sql
|
||
event_time >= date_sub(current_date(), N)
|
||
AND event_time < current_date()
|
||
```
|
||
|
||
禁止用下面写法表示 timestamp 完整日窗口:
|
||
|
||
```sql
|
||
event_time BETWEEN date_add(current_date(), -N) AND date_add(current_date(), -1)
|
||
```
|
||
|
||
如果用户指定自然日、滚动到当前时刻、特定日期或特定时区,必须在 DRD 和 SQL 注释里写明。
|
||
|
||
## 转化率 SQL 硬规则
|
||
|
||
漏斗/转化率 SQL 必须保证事件顺序。对“注册后完成付费”,分子应判断存在满足条件的后续付费:
|
||
|
||
```sql
|
||
COUNT(DISTINCT CASE
|
||
WHEN ur.user_id IS NOT NULL
|
||
AND qp.user_id IS NOT NULL
|
||
THEN fl.user_id
|
||
END) AS converted_user_cnt
|
||
```
|
||
|
||
其中 `qualified_payment` 这类 CTE 必须在 join 到注册事件后筛选:
|
||
|
||
```sql
|
||
po.pay_status = 'SUCCESS'
|
||
AND po.pay_time >= ur.register_time
|
||
```
|
||
|
||
不要先对 `pay_order` 按用户取全局最早支付再和 `register_time` 比较;这会漏掉“历史早付费但注册后也完成付费”的用户。
|
||
|
||
## 推荐 CTE 结构
|
||
|
||
对新用户转化率这类需求,优先使用清晰 CTE:
|
||
|
||
```text
|
||
first_login 分母人群:窗口内首次登录用户
|
||
registered 注册事件:按用户保留注册时间
|
||
qualified_payment 合格付费:注册后成功付费
|
||
final_agg 按维度聚合输出
|
||
```
|
||
|
||
## 正式交付格式
|
||
|
||
流水线完成时,最终回答必须包含以下章节,不能只给 SQL:
|
||
|
||
```markdown
|
||
## 需求说明
|
||
## 元数据校验
|
||
## 逻辑计划
|
||
## SQL 上下文
|
||
## 最终 SQL
|
||
## SQL Review
|
||
## 交付清单
|
||
```
|
||
|
||
每章要求:
|
||
|
||
- `需求说明`:业务目标、统计口径、涉及表、表关系、字段清单。
|
||
- `元数据校验`:几张表、多少字段、join key、时间字段是否通过。
|
||
- `逻辑计划`:用表格列出 CTE/步骤、说明和关键条件。
|
||
- `SQL 上下文`:alias、字段来源、join、指标、时间窗口。
|
||
- `最终 SQL`:只在 guardrails PASS 且 review 非 FAIL 后展示。
|
||
- `SQL Review`:verdict、最高风险等级、风险条数、关键建议。
|
||
- `交付清单`:SQL 文件、PySpark 脚本、是否已执行、如何运行。
|
||
|
||
如果生成 PySpark 脚本但当前容器没有 Java/Spark,要明确:
|
||
|
||
```text
|
||
已生成脚本,但当前 opencode 容器不是 Spark 执行环境,未本地执行。可在 Spark 集群中使用 spark-submit 运行。
|
||
```
|
||
|
||
## 关口消息
|
||
|
||
当阶段暂停时,必须用这个格式:
|
||
|
||
```markdown
|
||
## Pipeline paused at: <stage>
|
||
**Status:** NEED_USER_CONFIRMATION
|
||
**Open questions:**
|
||
1. <question>
|
||
**To resume:** answer the questions above, then say "继续".
|
||
```
|
||
|
||
## 输出格式
|
||
|
||
```yaml
|
||
pipeline_result:
|
||
status: COMPLETE | PAUSED | FAILED
|
||
current_stage: requirements-analysis | metadata-validator | logic-planner | sql-context-builder | sql-generation | pyspark-sql-guardrails | sql-review | mcp-handoff
|
||
requirements_output: {}
|
||
validation_result: {}
|
||
logic_plan: {}
|
||
sql_context: {}
|
||
sql: "只在 guardrails PASS 后展示"
|
||
pyspark_code: "只在 SQL 通过校验和评审后生成"
|
||
sql_guard: {}
|
||
sql_review: {}
|
||
mcp_plan:
|
||
should_execute: false
|
||
allowed_tools: []
|
||
pending_questions: []
|
||
blocking_findings: []
|
||
```
|
||
|
||
## 失败处理
|
||
|
||
- 需求变了:回到 requirements-analysis。
|
||
- 缺表缺字段:回到 metadata-validator。
|
||
- 指标公式或 join 粒度错:回到 logic-planner。
|
||
- SQL 引用了 context 没有的字段:回到 sql-context-builder 或更上游。
|
||
- guardrails 失败:重新生成 SQL,不改弱校验器。
|
||
- review 有 HIGH:阻断执行,修根因。
|
||
- MCP 准备失败:只修执行参数或脚本落盘问题,不反向篡改已评审 SQL。
|
||
|
||
## 禁止行为
|
||
|
||
- 不允许跳过 metadata-validator。
|
||
- 不允许 guardrails PASS 后跳过 review。
|
||
- 不允许 review 失败后只做字符串补丁而不检查上游产物。
|
||
- 不允许在用户未确认时继续下一阶段。
|
||
- 不允许把 `prepare_submit_job` 当成真正执行成功。
|
||
- 不允许在未获用户明确确认时调用 `confirm_submit_job`。
|