Files
SBrainCO/docs/智脑实施方法论/06-步骤五-AI协同本体层构建.md
T

6.5 KiB
Raw Blame History

06 · 步骤五:AI协同本体层构建

目标:AI参与数据层代码编写——物化视图SQL、导入脚本、数据质量校验,并逐项验证。 [Delta主导,AI为主]

FDE角色:这一步是Delta层的核心工作。AI承担80%的代码生成(SQL、脚本),人聚焦审查和验证。本体层的沉淀质量直接决定下一个同类客户的交付速度。

1. AI协同模式

1.1 工作流程

1. 人工提供:数据现状(表结构、样本数据、数据量)
2. AI生成:物化视图SQL草案
3. 人工审查:业务逻辑是否正确
4. AI执行:在数据库上创建视图 + 验证数据
5. 人工确认:抽查数据准确性
6. 迭代:发现问题→AI修复→再验证

1.2 AI Prompt模式

"请基于以下原始表设计物化视图:
- 原始表:bill_records(字段:c003门店, c009消费, c068优惠, c114实收, c175下单时间, c176结账时间, c191收银员)
- 需求:按月×门店×小时聚合账单数、消费、优惠、实收
- 注意:c114可能为空字符串,需COALESCE处理
输出:CREATE MATERIALIZED VIEW SQL + 索引SQL"

2. 物化视图构建

2.1 构建顺序

1. 基础视图(不依赖其他视图)
   ├── mv_bill_hourly(账单小时聚合)
   ├── mv_overview_daily(日度概览)
   └── mv_overview_monthly(月度概览)

2. 门店评级视图(依赖基础视图)
   ├── mv_store_risk_rating_monthly(门店风险评级)
   └── mv_store_benchmark_composite_monthly(门店对标)

3. 费用视图(依赖外部费用数据)
   └── mv_store_operating_expense_monthly(门店费用)

4. 风险明细视图(依赖原始表)
   ├── mv_risk_anomaly(异常账单)
   ├── mv_risk_zero(零实收)
   └── mv_risk_cashier(收银员风险)

5. 平台视图
   └── mv_store_platform_economics_monthly(平台经济性)

2.2 AI协同编写物化视图

典型交互

人:bill_records中c003是门店名,c114是实收金额,但有些是空字符串
AI:生成SQL
    CREATE MATERIALIZED VIEW mv_bill_hourly AS
    SELECT 
      c003 AS store_name,
      EXTRACT(HOUR FROM c176::timestamp) AS hour,
      to_char(c176::timestamp, 'YYYY-MM') AS month,
      count(*) AS bills,
      sum(COALESCE(NULLIF(c009,'')::numeric, 0)) AS consumption,
      sum(COALESCE(NULLIF(c114,'')::numeric, 0)) AS received
    FROM bill_records
    WHERE c176 IS NOT NULL
    GROUP BY 1, 2, 3;

人:门店名需要和费用表对齐,有些名字不一样
AI:补充映射逻辑,使用store_name_mapping

2.3 异常账单视图设计

-- AI协同设计的异常判断逻辑
CASE
  WHEN consumption > 0 AND received = 0 THEN '有消费无实收'
  WHEN discount > consumption THEN '优惠大于消费'
  WHEN abs(consumption - discount - received) > 1 THEN '消费-优惠与实收不平'
  ELSE NULL
END

关键教训:阈值0.05元太严格,会将浮点舍入差异标为异常。AI建议初始阈值设为1元,后续根据数据分布调整。

3. 数据导入脚本

3.1 AI协同编写导入脚本

人:这是4月的薪资Excel,列名是中文,需要导入salary_detail_records
AI:生成Python/SQL导入脚本,包含:
    - 列名映射(中文→英文字段名)
    - 数据类型转换
    - 空值处理
    - 去重逻辑
    - 进度输出

3.2 导入关键点

数据源 关键问题 解决方案
bill_records c001~c200列名无含义 建立字段映射文档
salary_detail_records salary_period格式"2026年4月" 查询时用to_char中文格式
attendance_records department是路径字符串 extractStore从后往前找"店"
费用数据 门店名与账单系统不一致 store_name_mapping映射表

4. 数据质量校验

4.1 AI协同校验

AI Prompt:
"请对以下物化视图进行数据质量校验:
1. 记录数是否合理(与原始表对比)
2. 金额加总是否一致(物化视图 vs 原始表)
3. 是否有NULL或异常值
4. 门店数是否完整
输出:校验SQL + 预期结果 + 实际结果"

4.2 校验清单

校验项 SQL 预期
门店数 SELECT count(DISTINCT store_name) FROM mv_bill_hourly WHERE month='2026-04' ~94家
实收总额 SELECT sum(received) FROM mv_bill_hourly WHERE month='2026-04' ~6369万
账单总数 SELECT sum(bills) FROM mv_bill_hourly WHERE month='2026-04' ~168万
异常账单占比 SELECT count(*) FROM mv_risk_anomaly / SELECT count(*) FROM bill_records <5%
物化视图新鲜度 对比物化视图和原始表的count 一致

5. 门店名映射

5.1 映射表构建

CREATE TABLE public.store_name_mapping (
  salary_name TEXT,  -- 薪资/考勤系统中的名称
  bill_name   TEXT   -- 账单系统中的名称
);

5.2 AI协同发现映射

AI Prompt:
"请对比以下两个数据源的门店名,找出不一致的:
- 账单系统:SELECT DISTINCT store_name FROM mv_bill_hourly
- 考勤系统:SELECT DISTINCT extractStore(department) FROM attendance_records
输出:需要映射的对照表"

5.3 代码中的映射查找模式

// 构建查找表:同时用原名和映射名
const staffLookup: Record<string, any> = {}
for (const [store, data] of Object.entries(staffSummary)) {
  staffLookup[store] = data           // 原名
  const mapped = nameMap[store]
  if (mapped && mapped !== store) {
    staffLookup[mapped] = data        // 映射名
  }
}

6. 输出物

输出物 说明 验证方式
物化视图SQL 所有视图的CREATE语句 psql执行成功
索引SQL 每个视图的索引 查询性能达标
导入脚本 各数据源的导入脚本 导入后数据量正确
映射表 store_name_mapping 所有门店能匹配
数据质量报告 校验结果汇总 人工抽查确认
刷新脚本 物化视图刷新流程 执行后数据更新

7. 关键注意事项

  1. 先查数据再写SQL:AI生成SQL前,先让它查实际表结构和样本数据
  2. 物化视图必须建索引:无索引的物化视图查询比原始表还慢
  3. 刷新脚本要完整:遗漏任何一个视图的刷新都会导致数据不一致
  4. 映射表要持续维护:新开门店时需要补充映射
  5. AI生成的SQL必须人工审查:AI可能忽略业务约束(如空值处理、日期格式)