跳转至

第 9 章 Semantic Plane:语义治理

本章学习目标 - 深入理解三层语义治理模型(Layer 1/2/3)与 9 类资产的设计动机 - 掌握语义资产的 Git 版本控制 + 本地 hooks + CI/CD + PR review + S3 发布 + 后台自动同步的完整端到端管道 - 理解语义治理资产如何被 R/V/G/D 四引擎运行时消费 - 掌握资产编写的快速上手与校验发布流程 - 对比 YAML 治理与 dbt 语义层 / Cube 的选型取舍 - 认清当前治理设计的工程权衡与改进方向

前置知识第 5 章 RAG 检索(资产如何被消费)、第 2 章 整体架构(离线发布链路) 关联代码semantic-plane/scripts/(CI 校验)、backend/app/agents/semantic_plane/(导入管道)、backend/app/services/semantic_sync.py(后台同步)


9.1 背景与动机

9.1.1 为什么需要语义治理

第 1 章 所述,NL2SQL 失败常因"同一个业务问题在不同上下文有不同答案"。语义治理就是把企业知识结构化为机器可读、可校验、可版本控制的资产,在生成 SQL 前约束 LLM。

9.1.2 治理 vs 元数据

普通元数据(如 information_schema)只描述"表结构是什么";语义治理还描述"这个字段在业务上意味着什么、应该怎么用、和别的字段什么关系"。后者是 LLM 无法从世界知识补全的企业特有知识——这是 TTD 把治理称为"一等公民"的原因。

9.1.3 为什么用 Git + YAML

语义治理资产选择 Git + YAML 而非数据库驱动,是经过权衡的决策:

维度 Git + YAML(TTD) DB-driven 元数据
版本控制 Git 原生(每次变更有 commit、可 diff、可 revert) 需自建审计表
协作审查 PR Review(人类把关变更质量) 在线编辑,审查弱
可编程性 高(CI 脚本自动化校验) 中(应用层校验)
冷启动 慢(手写 YAML) 快(UI 编辑)
离线可编辑 是(任何编辑器) 否(需在线)

TTD 选择 Git + YAML 是因为语义治理资产是高价值、低频变更、需严格审查的——这与代码的变更模式一致,适合用代码工程的方法管理(Git + CI + PR)。


9.2 设计原理

9.2.1 三层治理模型

层级 名称 内容 目录 解决的问题
Layer 1 Metadata Contracts 表/列/指标定义、关联规则、Few-shot 示例 domains/, few_shots/, join_rules/ "表结构是什么、指标怎么算、表之间怎么 join"
Layer 2 Terminology Governance 术语生命周期、消歧矩阵、同义词网络、术语关系 terms/, term_relationships/ "GMV 到底指什么、和哪些词同义"
Layer 3 Business Rules & Context 业务规则表达式、上下文假设、约束条件 business_rules/, business_contexts/ "同比的时间口径、华东区包含哪些省"

这三层对应 ADR-12。层次清晰、职责分离,各层可独立演进。

9.2.2 9 类资产

资产类型 层级 用途 运行时消费
table_asset L1 表定义(含业务描述、域归属、PII 策略) Engine V 向量检索
column_asset L1 列定义(含别名、数据类型、暴露策略) Engine R+ 别名匹配、V 向量检索
metric_asset L1 指标定义(含 SQL 公式、源表) Engine V 检索、规划器源表推导
join_rule L1 表间 join 规则 规划器 Steiner 树建图
few_shot_example L1 few-shot 示例(问题→SQL) Engine D 检索、Prompt 注入
business_term L1+2 术语定义(含 mapped_asset_id 绑定) Engine R 精确匹配、术语绑定
term_relationship L2 术语关系(同义/反义/上下位) Engine G 图遍历
business_rule L3 业务规则表达式 Prompt 注入、护栏校验
business_context L3 业务上下文假设 Prompt 注入

9.2.3 资产如何被运行时消费

消费方式 使用资产 引擎 说明
RAG 检索 table/column/metric/term/few-shot Engine R/V/G 四引擎并行检索相关资产
图遍历 join_rule、term_relationship Engine G Cypher 遍历关系网
精确查找 business_term (mapped_asset_id) Engine R 术语绑定强路由
规则注入 business_rule Prompt 直接注入 SQL 生成 prompt
Few-shot 选择 few_shot_example + 动态 few-shot Engine D + Prompt 历史成功案例复用

9.3 实现详解

9.3.1 目录结构

semantic-plane/
├── domains/              # Layer 1: table_asset(含 metrics/ 子目录)
├── terms/                # Layer 1+2: business_term
├── term_relationships/   # Layer 2: 术语关系
├── few_shots/            # Layer 1: few-shot 示例
├── join_rules/           # Layer 1: JOIN 规则
├── business_rules/       # Layer 3
├── business_contexts/    # Layer 3
└── schemas/              # 8 个 JSON Schema(资产结构定义)

9.3.2 ID 命名规范

资产 ID 用正则约束,确保全局唯一与可追溯:

  • table_asset: tbl_<domain>_<name>(如 tbl_hm_fact_transaction
  • column_asset: col_<table>_<column>(如 col_fact_txn_price
  • metric_asset: metric_<name>(如 metric_gmv
  • business_term: term_<name>(如 term_gmv

9.3.3 SemVer 版本化

每条资产有 SemVer 版本号,CI 强制检查(check_version_bump.py):

  • MAJOR:破坏性变更(如改了指标 SQL 定义)→ 触发全量重向量化
  • MINOR:新增字段 → 增量更新
  • PATCH:描述修正 → 不触发重向量化

9.3.4 端到端发布管道(Git → Hooks → CI → PR → S3 → 自动同步)

这是语义治理的核心工程链路——从业务开发编辑 YAML 到线上 RAG 索引生效的完整管道:

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#e8f0fe','primaryTextColor':'#202124','primaryBorderColor':'#1a73e8','lineColor':'#5f6368','secondaryColor':'#e0f2f1','tertiaryColor':'#f8f9fa'}}}%%
flowchart TB
    subgraph Local["本地开发阶段"]
        direction LR
        EDIT["业务开发编辑 YAML<br/>semantic-plane/"]
        HOOK["pre-commit hooks<br/>schema · sqlglot 快速校验"]
        COMMIT["git commit"]
        EDIT --> HOOK --> COMMIT
    end

    subgraph GitHub["GitHub 协作阶段"]
        direction LR
        PUSH["git push → 创建 PR"]
        CI["GitHub Actions CI/CD<br/>4 个校验脚本自动运行"]
        REVIEW["PR Review<br/>Governance Lead 审查"]
        MERGE["合并到 main"]
        PUSH --> CI --> REVIEW --> MERGE
    end

    subgraph Publish["发布阶段"]
        direction LR
        BUILD["build_changeset.py<br/>构建增量变更集"]
        S3["自动发布到 S3<br/>语义资产快照 + manifest"]
        BUILD --> S3
    end

    subgraph Sync["TTD 后台自动同步"]
        POLL["Backend 语义层知识库<br/>定时轮询 S3 manifest hash"]
        DETECT["检测到变更"]
        PIPELINE["semantic_plane agent<br/>R+V+G pipeline"]
    end
    PIPELINE --> R["Upsert 关系表<br/>semlayer.* (Engine R)"]
    PIPELINE --> G["MERGE AGE 图<br/>ttd_governance (Engine G)"]
    PIPELINE --> V["生成 embedding<br/>pgvector (Engine V)"]

    COMMIT --> PUSH
    MERGE --> BUILD
    S3 --> POLL --> DETECT --> PIPELINE

    classDef bpProcess  fill:#e8f0fe,stroke:#1a73e8,stroke-width:2px,color:#202124
    classDef bpData     fill:#e0f2f1,stroke:#0d7377,stroke-width:2px,color:#202124
    classDef bpDecision fill:#fef7e0,stroke:#f9ab00,stroke-width:2px,color:#202124
    classDef bpSuccess  fill:#e6f4ea,stroke:#1e8e3e,stroke-width:2px,color:#202124
    classDef bpInfo     fill:#f3e8fd,stroke:#9334e6,stroke-width:2px,color:#202124

    class EDIT,HOOK,COMMIT bpProcess
    class PUSH,CI,REVIEW,MERGE bpDecision
    class BUILD,S3 bpSuccess
    class POLL,DETECT bpInfo
    class PIPELINE bpProcess
    class R,G,V bpData

阶段一:本地开发(Git 版本控制 + pre-commit hooks)

业务开发者在 semantic-plane/ 目录编辑 YAML 资产,使用任意 IDE。提交时触发 pre-commit hooks 做本地快速校验:

# .pre-commit-config.yaml 配置的钩子
# 1. YAML 格式校验
# 2. JSON Schema 基础校验(validate_all_yaml.py 子集)
# 3. ruff/ty 代码检查(若改了脚本)

本地 hooks 的目标是快速反馈——让开发者在提交前就发现明显错误,避免推到 CI 才失败。hooks 只跑快速校验子集,完整校验留给 CI。

阶段二:GitHub 协作(CI/CD + PR Review)

git push 后创建 PR,触发 GitHub Actions CI/CD 自动运行 4 个校验脚本:

CI 脚本 作用 失败处理
validate_all_yaml.py JSON Schema 校验所有 YAML(结构完整性) 阻断 PR merge
validate_sql_definitions.py metric_asset 的 SQL 语法验证(用 sqlglot 解析) 阻断 PR merge
validate_cross_layer_refs.py 跨层引用完整性(如 term 的 mapped_asset_id 是否存在) 阻断 PR merge
check_version_bump.py 版本号递增检查(变更必须 bump version) 强制 bump

CI 通过后进入 PR Review——由 Governance Lead 审查变更质量。MAJOR 变更(如改指标定义)必须人工审批,MINOR/PATCH 可常规合并。这是人类把关语义质量的最后一道关卡。

阶段三:发布(S3)

PR 合并到 main 后,build_changeset.py 构建增量变更集(基于 git diff,只含变更的资产),发布到 S3:

  • S3 存储语义资产快照 + manifest(含 hash、版本、时间戳)
  • 增量发布减少传输量与处理时间
  • 首次发布或 MAJOR 变更时用 build_full_changeset.py 全量发布

阶段四:TTD 后台自动同步(S3 → RAG 索引)

这是"治理态到执行态"的最后一步,由 Backend 的 semantic_sync.py 服务自动完成:

  1. 轮询检测:Backend 后台服务定时轮询 S3 manifest hash,与本地记录对比,检测是否有变更
  2. 触发同步:检测到 hash 变化后,触发 semantic_plane agent(一个独立的 LangGraph 工作流)
  3. R/V/G pipeline 执行
    • Engine R(关系表):Upsert 变更资产到 semlayer.* 表(table_asset/column_asset/metric_asset 等)
    • Engine G(图):MERGE 变更资产到 Apache AGE ttd_governance 图(节点 + 边)
    • Engine V(向量):调用 DashScope text-embedding-v4 生成 embedding,写入 pgvector *_embedding
  4. 软删除:S3 快照中缺失的资产被标记 deleted_at,不再参与检索(而非物理删除,保留可追溯)
  5. change_log:记录同步状态(pending → processing → completed/failed),失败自动重试
manifest hash 变化 → semantic_plane agent
                      ├── scan_yaml(扫描变更)
                      ├── validate(校验)
                      ├── relational_upsert(Engine R)
                      ├── graph_sync(Engine G)
                      ├── generate_embeddings(Engine V)
                      ├── record_changelog
                      └── cleanup_stale(软删除)

整个管道实现了"业务开发只管写 YAML,其余全自动"的体验——Git 版本控制 + hooks + CI + PR 保证质量,S3 + 后台同步保证自动生效,开发者无需手动操作数据库或重启服务。

9.3.5 快速上手(维护手册)

# 1. 安装依赖
uv sync

# 2. 编写/修改 YAML 资产(参考 schemas/ 下的 JSON Schema)

# 3. 本地校验(等价于 pre-commit hooks)
task sp:validate

# 4. 提交 + 推送 → 创建 PR
git add . && git commit -m "feat: add GMV metric"
git push origin feature/add-gmv

# 5. CI 自动校验 → PR Review → 合并 → 自动发布到 S3 → Backend 自动同步

资产编写 5 条约束

  1. 双语必备:_zh/_en 成对(ADR-13
  2. PII 标注:llm_exposure_policy: visible/masked/hiddenADR-14
  3. 版本递增:任何变更必须 bump version
  4. 跨层引用完整:mapped_asset_id 必须指向真实存在的资产
  5. 质量评分:新资产需标注 quality_score,进入认证生命周期(draft → reviewed → certified → deprecated)

9.4 资产编写实战:新增"退货率"指标

本节以一个真实业务场景——"新增退货率指标"——展示从零编写语义资产的完整产出。假设数据团队需要支持"各品类退货率"查询。

9.4.1 业务理解

退货率 = 退货交易数 / 总交易数。在 H&M 数据集中,退货通过 price < 0 识别(业务规则:退货金额为负)。

9.4.2 编写资产(5 个文件)

1. business_rule(业务规则)

# file: business_rules/hm_return_rule.yaml
business_rule:
  rule_id: "rule_hm_return_negative_price"
  rule_name: "退货金额为负"
  rule_type: "data_constraint"
  description_zh: "退货交易的 price 字段为负值,正常购买为正值。"
  description_en: "Return transactions have negative price; purchases have positive."
  bound_assets:
    - "gold_hm.fact_transaction.price"
  sql_expression: "price < 0"
  certification_status: "certified"
  version: "1.0.0"

2. metric_asset(指标定义)

# file: metrics/return_rate.yaml
metric_asset:
  metric_id: "met_hm_return_rate"
  metric_name: "Return Rate"
  business_definition_zh: >
    退货率 = 退货交易数 / 总交易数。退货交易通过 price < 0 识别。
    按品类分解可定位退货率上升的具体品类。
  business_definition_en: >
    Return rate = return count / total count. Returns identified by price < 0.
  sql_definition: >
    SELECT
      ROUND(COUNT(*) FILTER (WHERE price < 0)::NUMERIC
            / NULLIF(COUNT(*), 0) * 100, 2) AS return_rate_pct
    FROM gold_hm.fact_transaction
  default_grain: "monthly"
  allowed_dimensions: ["t_dat", "sales_channel_id"]
  owner: "data-team@hm.com"
  certification_status: "draft"
  version: "1.0.0"
  similar_metrics:
    - metric_id: "met_hm_transaction_count"
      difference: "退货率是比例指标,交易次数是绝对计数"
  counter_examples:
    - "退货率  退货金额占比,前者按笔数算,后者按金额算"
  common_questions:
    - "各品类退货率是多少?"
    - "退货率趋势如何?"

3. business_term(术语映射)

# file: terms/hm_return_term.yaml
business_term:
  term_id: "term_hm_return_rate"
  canonical_term: "退货率"
  aliases: ["return rate", "退货比例", "退单率"]
  term_type: "metric"
  mapped_asset_id: "met_hm_return_rate"
  mapped_asset_type: "metric"
  confidence: 0.95
  disambiguation_context: "若用户问'退货金额'则映射到 SUM(price) WHERE price < 0,非退货率"

4. join_rule(关联规则,复用已有)

退货率查询需 join fact_transactiondim_article(按品类分解),复用已有 join_rule hm_fashion_joins.yaml 中的 fact_transaction ⟕ dim_article

5. few_shot_example(参考示例)

# file: few_shots/hm_return_example.yaml
few_shot_example:
  example_id: "fs_hm_return_by_category"
  question: "各品类退货率是多少?"
  expected_sql: >
    SELECT a.index_group_name AS category,
           ROUND(COUNT(*) FILTER (WHERE f.price < 0)::NUMERIC
                 / NULLIF(COUNT(*), 0) * 100, 2) AS return_rate_pct
    FROM gold_hm.fact_transaction f
    JOIN gold_hm.dim_article a ON f.article_id = a.article_id
    GROUP BY a.index_group_name
    ORDER BY return_rate_pct DESC
  route: "nl2sql_query"
  certification_status: "approved"

9.4.3 验证与发布

# 1. 本地校验
ttd-publish-sp --dry-run          # JSON Schema 校验 + 跨层引用检查

# 2. Git 提交
git add semantic-plane/
git commit -m "feat: add return_rate metric and term"

# 3. PR 审查 → 合并 → CI 自动发布到 S3
# 4. Backend 轮询检测到 manifest 变更 → 自动导入
# 5. 验证:提问"各品类退货率"应正确路由并生成 SQL

9.4.4 产出总结

新增一个业务指标需要产出 4-5 个资产文件(metric + term + rule + few_shot,join_rule 通常复用)。这体现了语义治理的前期投入——编写成本固定,但一旦发布,所有后续查询都受益(术语绑定自动路由、业务规则自动注入、few-shot 自动参考)。


9.5 方案选型对比

9.4.1 语义治理方案对比

维度 TTD YAML 治理 dbt 语义层 Cube DB-driven 元数据
存储 Git YAML dbt 项目(YAML+SQL) Cube 配置 数据库表
版本控制 Git 原生 Git 原生 Git 需自建
校验 pre-commit + CI 4 脚本 dbt parse Cube validator 应用层
运行时消费 R/V/G 检索 编译为 SQL 语义层 API 应用查询
冷启动成本 高(手写 YAML)
发布方式 Git+CI+PR+S3+自动同步 dbt build Cube refresh 应用更新
TTD 选择理由 Git 版本控制 + 多引擎检索 + 全自动同步最契合治理诉求

9.4.2 Git-as-SSOT vs DB-driven

维度 Git-as-SSOT(TTD) DB-driven
版本控制 强(Git commit/diff/revert) 弱(需自建审计)
协作 PR Review 在线编辑
冷启动 慢(写 YAML) 快(UI 编辑)
可编程性 高(CI 自动化)
适合 高价值、低频变更、需审查 低价值、高频变更、快速迭代

当前实现可改进之处

  1. 资产类型冗余(9 类):对新手偏多,冷启动成本高。生产中数百张表时,手写 YAML 不可持续。改进:提供 CLI 脚手架 + LLM 辅助补全(从 schema 自动生成候选资产 + 业务描述候选,人工只校验),合并使用频率低的资产类型。
  2. 缺在线编辑:所有资产必须 Git 编辑 + PR,对非技术 Data Steward 不友好。改进:Admin Panel 增加资产在线编辑 + 提交 PR 的能力,降低协作门槛。
  3. 版本治理靠 CI 较重:每次变更需过 4 个 CI 校验脚本,开发反馈慢。改进:本地 task sp:validate 快速反馈,CI 只做最终门控;增量校验只跑变更相关的子集。
  4. 同步是轮询式非事件驱动:Backend 定时轮询 S3 manifest hash,有延迟。改进:S3 事件通知 → webhook → Backend 立即同步,将一致性窗口压缩到秒级。

改进方向

语义治理的演进方向是降低冷启动成本 + 提升协作效率 + 实时同步。短期:CLI 脚手架 + LLM 辅助生成候选资产、S3 事件驱动同步。长期:在线编辑 + 自动认证(LLM 评估资产质量,高分自动认证,低分人工审核),让治理资产像代码一样可协作但更易上手。


9.6 小结与延伸阅读

本章要点

  1. 三层治理模型:L1 元数据契约 / L2 术语治理 / L3 业务规则,9 类资产。
  2. 端到端发布管道:Git 版本控制 → pre-commit hooks 本地校验 → GitHub Actions CI/CD 4 脚本 → PR Review 审批 → 合并后自动发布到 S3 → Backend 后台轮询检测变更 → 自动执行 R/V/G pipeline 同步索引到各 RAG 存储。
  3. 资产经 R/V/G/D 四引擎检索消费,术语绑定贯穿全管道。
  4. SemVer 版本化 + 双语必备 + PII 分级是核心规范。
  5. "业务开发只管写 YAML,其余全自动"——Git+CI+PR 保证质量,S3+后台同步保证自动生效。

延伸阅读

下一章第 10 章 Data Plane:数据执行环境——PG Supernode、pg_mooncake、MinIO 与 H&M 测试数据集。