第 7 部分。首个数据产品的规格说明
本书的第一个数据产品是 customer_360。它应该为分析师提供不含直接 PII 的客户切片。在这一步,重要的是不要编写 SQL。首先需要阐明产品承诺:谁是消费者、输出端口是什么、粒度(grain)是什么、哪些字段是必需的、新鲜度(freshness)是多少以及哪些检查可以证明产品就绪。
制品
specs/customer_360_product.odps.yaml
specs/customer_360_contract.odcs.yaml
specs/models/mart_customer_360.md
specs/validation/customer_360.md
ODPS 描述产品。ODCS 描述技术契约。模型规格说明描述粒度和验收事实。验证说明将规格说明与命令和评审者的检查联系起来。
粒度(Grain)
对于 mart_customer_360 而言,粒度很简单:
每个 `customer_id` 一行
如果再加入 account_id、product_code 或 scope,那就变成了另一个数据集市。这种变更需要确认,因为下游消费者将会得到不同的行单位。
PII 策略
Staging 可以读取 pii_email 以暴露风险。Mart 不应暴露它。该规则必须是可验证的:
models/marts/mart_customer_360.sql 不包含直接的 PII 字段。
dbt singular 测试 assert_customer_360_no_direct_pii 返回 0 行。
SLA 与新鲜度
在教学示例中,新鲜度为 24 小时。在本地我们不构建调度器,因此新鲜度仍作为产品承诺和发布说明保留。在生产环境中,需要通过加载元数据、源新鲜度或编排器来支撑它。
面向 Qwen Code 的请求
请阅读 specs/customer_360_product.odps.yaml、
specs/customer_360_contract.odcs.yaml 和 specs/models/mart_customer_360.md。
阐明粒度、PII 策略、SLA、必需字段以及验收事实。
不要修改文件。
最小输出
本章结束后应有一张表:
| 字段 | 值 |
|---|---|
| 数据产品 | customer_360 |
| Mart | mart_customer_360 |
| 粒度 | 每个 customer_id 一行 |
| PII 策略 | 数据集市中不含直接 PII |
| SLA | 新鲜度 24 小时 |
| 主要检查 | customer_id 的 unique/not_null |
此表将成为第 10–16 部分的参考基准。
读者解读
数据产品的规格说明是技术表格首次转变为承诺的地方。在此之前,mart_customer_360 看起来只是一个模型名称。在此之后,它已成为与消费者的契约:谁需要该数据集市、一行代表什么、哪些字段是必需的、哪些字段被禁止、允许的数据时效是多少。如果这个契约没有被记录下来,SQL 就会开始扮演产品的角色,尽管 SQL 只展示计算方式。
ODPS 和 ODCS 区分了两种不同的对话。ODPS 谈论产品:消费者是谁、数据集市为什么存在、它承诺什么结果。ODCS 谈论技术契约:应保留哪些字段、类型、SLA 以及变更规则。当这些层次混在一起时,评审就会变得模糊。无法判断是产品意义被破坏了,还是仅仅是技术形式被破坏了。
粒度应当在 SQL 之前写好,因为在编写 SQL 之后,作者已经看到了具体的 join、具体的分组和具体方便的列集合。在此阶段,很容易为多余的细化找借口:「它会有用的」、「它不碍事」、「这样更容易验证」。但对消费者而言,这可能是另一个产品。每个客户一行和每个客户-产品一行是两种不同的承诺,即使两张表都叫 Customer 360。
一份好的规格说明并不试图描述未来的所有可能。它固化了第一版所需的最低要求:消费者、粒度、PII 策略、必需字段、SLA 和验收事实。这些足以让智能体能够实现数据集市,并让评审者能够拒绝它。如果评审者说不出拒绝的理由,那么规格说明就过于含糊。
练习
比较 Customer 360 的 ODPS、ODCS 和模型规格说明。分别找出一个属于产品、技术契约以及模型级验收的字段。如果某个字段出现在错误的层次中,请记录为什么这是风险。
常见错误
将「customer 360」作为笼统的口号来记录。对智能体而言这过于宽泛。需要明确指出包含哪些源、粒度是什么、哪些字段被禁止以及什么被视为就绪。
自检问题
- ODPS 与 ODCS 有什么区别?
- 为什么粒度要在 SQL 之前写?
- 如何验证 mart 没有暴露 PII?