Files
Neo-ZQYY/docs/ai/app2_finance_multi_app_design.md
Neo d269ee6401 docs(ai): app2a v1.2 system prompt + 多 APP 派生设计 v2 + 审计 + A/B 脚本
1. docs/ai/app2a_finance_area_system_prompt_20260422_v1.md (新建 · v1.2 生产版):
   - 基于 app2_finance V5.1 派生
   - 板块 C 改"业态收入结构" · 板块 E 改"业态定位与对比"
   - 新增 H7 硬约束:业态特征引用必须紧跟 payload 真实数据
   - H6 扩展区域级 6 类字段缺失降级(储值卡/分渠道现金流/现金流出/会员占比/按星期/日异常)
   - 经 3 次修正:v1"稀疏" → v1.1 纠正为业务真实 0/非 0 → v1.2 纠正为字段存在/整块缺失
   - 已同步百炼控制台 APP ID 0ae965029bc54706bcff44f511ac716b

2. docs/ai/app2_finance_multi_app_design.md (新建 · v2 定稿):
   - 6 章 + 3 附录 · Q1-Q7 全部决策 · 6 阶段 28 项 checklist
   - 72 组合数据源支持度三档梳理(必须 / 业务级全店 / 字段存在 vs 整块缺失)
   - 2 套 prompt 拼接方案 · 2 个派生百炼 APP 策略

3. docs/audit/changes/2026-04-23__app2a_finance_area_integrated.md (新建):
   - 完整审计记录 · 13 高风险文件逐项注解
   - 数据库变更 + 风险与回滚 + 验证方式 + 合规检查

4. docs/audit/audit_dashboard.md (刷新 · 135 条记录)

5. scripts/ab_test_app2a_area.py (新建):
   - 8 业态 × 3 轮 = 24 次采样评估含金量
   - 自动检测 H1/H2/H3/H7 硬约束通过率 + seq11 三色灯分布

6. scripts/ab_to_cache.py (新建):
   - 复用 A/B 结果直接写 ai_cache · 绕开百炼预算验证 UI 端到端

A/B 实测 24/24 成功 · 12 条齐整率 100% · H1/H3/H7 100% · 达生产级。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 21:56:46 +08:00

19 KiB
Raw Blame History

App2 财务洞察 72 组合 · 多 APP 派生与 Prompt 拼接方案设计 v2(决策已定 · 实施中)

文档状态:v2 定稿 · 实施中2026-04-22 用户已确认全部 7 个决策点 · 已进入整包实施阶段) 前置版本v1 草案2026-04-22 初稿) 作者Claude + Neo 适用范围:apps/backend/app/ai/prompts/ · apps/backend/app/ai/dispatcher.py · apps/etl/connectors/feiqiu/loaders/ · db/etl_feiqiu/migrations/ · 小程序 board-finance · admin-web 3 页 · 百炼控制台新建 APP 前置背景:this_month / all 组合已通过 V5.1 system prompt 达到生产级(综合分 92.3);本次针对其他 64 个区域组合8 时间 × 8 业态)派生新 APP app2a_finance_area


· TL;DR整包实施总览

维度 定案
Prompt 拼接方案 2 套(全域全量 app2_finance 不动 · 区域派生 app2a_finance_area 新建)
百炼 APP 数量 2 个(新建 app2a_finance_areaenv: DASHSCOPE_APP_ID_2A_FINANCE_AREA
System Prompt app2a v1 已产出 · 基于 V5.1 派生 · 12 条 · 板块 C/E 重分工 · 新增 H7 业态特征硬约束
DWS 改造 必做 · dws_finance_area_dailymember_order_count 列 + ETL loader 改造 + RLS 视图更新(会员订单占比覆盖)
前端 seq 精确匹配 必做 · 保留 seq 字段,按 find(i => i.seq === 11) 定位,降级保留"末两条"启发式
灰度开关 不加(用户指示作为正式模块上线)
admin-web 改动 一起做 · AIPrewarm 分两段 + AIDashboard/AIOperations app_type 选择器扩展
DB DDL 改动 1 处 · db/etl_feiqiu/migrations/YYYYMMDD__app2a_member_order_count.sql

一 · 用户确认的决策点Q1-Q7

问题 决策
Q1 · app2a system prompt 条数 方案 α · 12 条板块重分工(前端 seq 11/12 兼容)
Q2 · 板块 C/E 替代方向 同意 · C = 业态收入结构 / E = 业态定位与对比
Q3 · DWS 改造 · 区域级单位经济 + 按星期聚合纳入 payload
Q4 · seq 精确匹配时机 现在做 · 与 app2a 一起上
Q5 · 灰度开关 不加 · 作为正式模块上线,要通过测试验收
Q6 · 百炼建 APP 节奏 用户拿 v1 system prompt 去百炼建 APP → 拿到 APP ID → 写 .env → Claude 实施后端
Q7 · admin-web 改动 一起做 · 整包交付

二 · 区域粒度字段处理三档(用户已认同)

档 1 · 业务本质为"全店级",区域下无需补齐(维持现状隐藏)

字段 业务理由
预收资产 / 储值卡余额变化 储值卡是会员账户级资产,与消费区域无关
现金流入来源(纸币/线上/团购 分渠道) 支付渠道是收银台级属性,区域级无法自然拆分
现金流出 4 类 全店级成本(房租/水电/平台手续费),无法按区域归属

档 2 · 区域下有业务价值且技术上可补齐(本期做)

字段 实施方式
单位经济 · 客单价(按成交收入 / 按发生额) app.v_dws_finance_area_daily 现有字段 gross_amount / confirmed_income / order_count 可直接算
单位经济 · 日均订单数 order_count 聚合
单位经济 · 会员订单占比 需新增 member_order_count 列 + ETL loader 改造(本次 DDL
按星期聚合(区域级 7 天日均) gross_amount / order_count 聚合(不含 cash_inflow_total,区域级不适用)
日粒度异常(同周基线 / 区域级) gross_amount 做异常检测(不含现金流入)

档 3 · 助教分析(区域下"字段存在 vs 字段整块缺失"两态,非"稀疏"也非"值 = 0"

  • 数据链路真相ODS 助教服务日志每条带 table_id / room_id → DWD 层按物理位置→区域映射 → DWS dws_coach_area_hours(assistant_id, area_code, stat_month) 精确分桶聚合
  • ETL 写入逻辑(见 coach_area_hours_task.py:L134只在发生过服务时才 INSERT 记录。没有服务 = 没有聚合键 = 不写入
  • 查询结果只有两种状态
    • 查到记录且 effective_hours > 0 = 业务真实:本期该区域发生了 N 小时助教服务、M 元薪酬
    • 查不到记录(空集) = 业务真实:本期该区域零助教服务发生(不是数据问题,不是"稀疏"
  • 不存在"单条记录值 = 0"(除非边角极端:全部服务被标废单 · 概率极低)
  • UI 处置
    • 后端返回助教字段 → 正常展示助教板块
    • 后端不返回助教字段(空集) → 不展示助教板块 展示中性提示"本期本区域无助教服务"用"数据稀疏"字眼)
  • AI 处置v1.2 system prompt 板块 D 已改):按助教字段"存在 vs 整块缺失" + 业态合理性区分
    • 麻将/KTV 业态缺失:业态正常,简述一笔带过,不作为隐患
    • 大厅/VIP/斯诺克 业态缺失:业态异常,提示店长核查(排班未录入/停招/ETL 流水完整性),作为 seq 11 健康度"数据/运营完整性"维度扣分

三 · DWS 改造详细设计

3.1 DDL 改动1 处)

文件db/etl_feiqiu/migrations/20260423__app2a_member_order_count.sql(即将产出)

内容

BEGIN;

-- 1. 给区域级 DWS 表加 member_order_count 列
ALTER TABLE dws.dws_finance_area_daily
  ADD COLUMN IF NOT EXISTS member_order_count integer DEFAULT 0 NOT NULL;

COMMENT ON COLUMN dws.dws_finance_area_daily.member_order_count IS '会员订单数区域粒度DWD 聚合)';

-- 2. 重建 RLS 视图app schema
CREATE OR REPLACE VIEW app.v_dws_finance_area_daily AS
SELECT id, site_id, tenant_id, stat_date, area_code,
       table_fee_amount, goods_amount, assistant_pd_amount, assistant_cx_amount,
       gross_amount,
       discount_groupbuy, discount_vip, discount_manual, discount_gift_card,
       discount_rounding, discount_other, discount_total,
       confirmed_income,
       cash_pay_amount, cash_paper_amount, scan_pay_amount, groupbuy_pay_amount,
       recharge_cash_inflow, cash_inflow_total, cash_outflow_total, cash_balance_change,
       card_consume_total, recharge_card_consume, gift_card_consume,
       recharge_cash, first_recharge_cash, renewal_cash,
       order_count,
       member_order_count,  -- 新增
       created_at, updated_at
  FROM dws.dws_finance_area_daily
 WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);

-- 3. dws schema 视图同步(如存在)
-- 按 CLAUDE.md "RLS 视图双 Schema 规则",若 dws.v_dws_finance_area_daily 存在需同步创建

COMMIT;

3.2 ETL loader 改造(飞球 Connector

文件apps/etl/connectors/feiqiu/loaders/dws_finance_area_daily.py(或对应文件,需确认)

改动:聚合 DWD 层订单数据时,按 area_code + stat_date + is_member_order 分组,将 is_member_order = true 的订单数合并到 member_order_count 列。

验证 SQL

-- 全店总数应等于区域总和
SELECT s.site_id, s.stat_date, s.member_order_count AS full_store,
       COALESCE(SUM(a.member_order_count), 0) AS sum_areas
  FROM dws.dws_finance_daily_summary s
  LEFT JOIN dws.dws_finance_area_daily a
    ON s.site_id = a.site_id AND s.stat_date = a.stat_date
 WHERE s.stat_date >= current_date - interval '7 days'
 GROUP BY s.site_id, s.stat_date, s.member_order_count
HAVING s.member_order_count <> COALESCE(SUM(a.member_order_count), 0);
-- 期望0 行

3.3 回填策略

  • 新列 DEFAULT 0 → 历史数据 member_order_count = 0(区域历史会员占比暂全为 0
  • 用户可选择:① 接受新数据生效即可P2 上线后生成的数据正确);② 写回填脚本 scripts/ops/backfill_area_member_order.py 从 DWD 重算历史(工作量 1 天)
  • 建议当期不回填,待运行 7 天观察新数据正确后再视需要回填

四 · 后端实施清单

4.1 新建 app2a_finance_area_prompt.py

文件apps/backend/app/ai/prompts/app2a_finance_area_prompt.py

关键设计

  • 复用 app2_finance_prompt.py 的:DIMENSION_MAP / AREA_LABELS / KEY_TRANSLATIONS / _slim / _pct / _build_discount_kpi / _build_coach_kpi / _translate_keys / _calc_date_range / _calc_prev_range
  • 新增 _fetch_area_daily_series(site_id, start_date, end_date, area_code) -> list[tuple]:查 app.v_dws_finance_area_daily 区域级日粒度
  • 新增 _build_area_unit_economics(series, prev_series):区域级单位经济(客单价、日均订单数、会员占比 含环比)
  • 新增 _aggregate_by_weekday_area(series):区域级按星期聚合(无现金流入)
  • 新增 _detect_anomaly_days_area(site_id, start, end, area_code, series):区域级日粒度异常(仅 gross_amount
  • 新增 AREA_INDUSTRY_TRAITS:业态特征字典,按 area_code 映射文字描述
  • 新增 _fetch_area_share(site_id, time_dimension, area_code) -> dict:查本区域成交收入占全店比(对比区域 total vs 全店 total

payload 结构

payload = {
    "当前时间": now,
    "门店编号": site_id,
    "时间维度": time_label,
    "区域": area_label,
    "对比口径": compare_caliber,  # H1 依赖
    "业态说明": {"区域编码": area, "区域名称": label, "业态特征": trait, "典型对比项": peer},  # 新增
    "区域占比": {"本区域成交收入": ..., "占全店成交收入": ..., "占比环比": ...},  # 新增
    "核心KPI": {...},
    "派生比率": {"人力成本占成交收入比": ..., "优惠侵蚀率": ...},  # 仅 2 项,其他区域级不可用
    "优惠构成": {...},
    "助教成本": {...},  # 可能为空
    "单位经济": {...},   # 新增(区域级,不含会员占比直到 DWS 改造后)
    "按星期聚合": {...}, # 新增(区域级,当期 ≥ 14 天)
    "日粒度异常": [...], # 新增(区域级,当期 ≥ 7 天)
    "行业基线": {"周中客流规律": ...},
    "原始指标": raw_cn,
}

4.2 dispatcher.py 改动

  • 常量拆分:
    _ALL_AREA = "all"
    _SUB_AREAS = ("hall", "hallA", "hallB", "hallC", "vip", "snooker", "mahjong", "ktv")
    
  • _handle_dws_completed() 的 72 循环拆分:
    for td in _TIME_DIMENSIONS:
        await self._run_step("app2_finance", td, "all", ...)
        for area in _SUB_AREAS:
            await self._run_step("app2a_finance_area", td, area, ...)
    
  • run_single_app() 新增分支:
    elif app_type == "app2a_finance_area":
        prompt_str = await build_app2a_area_prompt(context)
        ...
    

4.3 配置与注册

  • config.pyapp_id_2a_finance_area: str env DASHSCOPE_APP_ID_2A_FINANCE_AREA
  • prompts/__init__.pyfrom .app2a_finance_area_prompt import build_prompt as build_app2a_area_prompt
  • cache_service.py CacheTypeEnum:新增 APP2A_FINANCE_AREA = "app2a_finance_area"TTL 0 · 当日过期)
  • admin_ai.py _SUPPORTED_APP_TYPES:加 "app2a_finance_area"
  • schemas/admin_ai.py RunAppRequestapp_type 枚举加入新值

4.4 环境变量

.env 追加

DASHSCOPE_APP_ID_2A_FINANCE_AREA=<用户从百炼控制台粘贴>

config.py 启动期校验:缺失立即 raiseAIConfig.from_env() 现有机制)


五 · 前端实施清单

5.1 小程序 seq 精确匹配 + 双 cache key

文件apps/miniprogram/miniprogram/pages/board-finance/board-finance.ts

改动 1 · _loadAIInsights:按 area 选 cache_type

const cacheType = areaKey === 'all' ? 'app2_finance' : 'app2a_finance_area'
const cache = await fetchAICache(cacheType, targetId)

改动 2 · map 阶段保留 seq 字段:

const insights = Array.isArray(rj.insights)
  ? rj.insights.map((item: any, idx: number) => ({
      seq: Number(item.seq) || (idx + 1),  // 保留 seq兼容无 seq 的旧缓存
      title: ...,
      body: ...,
      titleSegs: ...,
      bodySegs: ...,
    }))
  : []

改动 3 · _extractSummary 按 seq 精确匹配:

const evaluation = insights.find(i => i.seq === 11) || insights[insights.length - 2]
const tracking = insights.find(i => i.seq === 12) || insights[insights.length - 1]
const details = insights.filter(i => i.seq !== 11 && i.seq !== 12)

5.2 admin-web 改动

AIPrewarm.tsx

  • 72 组合列表分两段渲染:
    • 段 18 个全域组合cache_type: app2_finance
    • 段 264 个区域组合cache_type: app2a_finance_area
  • 每组合显示 app_type 标签(蓝=全域,绿=区域)

AIDashboard.tsx + AIOperations.tsx

  • app_type 下拉选择器增加 app2a_finance_area
  • 运行日志筛选器支持新 app_type

api/adminAI.ts

  • AppType 类型增加 'app2a_finance_area'

六 · 整包实施 Checklist按依赖顺序

Phase A · 用户侧准备(独立于 Claude

  • A1 · 用户将 app2a_finance_area_system_prompt_20260422_v1.md 的 ``` 代码块内全文粘贴到百炼控制台新建 APP
  • A2 · 获取 APP ID类似 1dcdb5f39c3040b6af8ef79215b9b051
  • A3 · 在根 .env 追加 DASHSCOPE_APP_ID_2A_FINANCE_AREA=<APP ID>
  • A4 · 告知 Claude APP ID 已配置完成

Phase B · DWS 改造Claude 实施)

  • B1 · 产出 db/etl_feiqiu/migrations/20260423__app2a_member_order_count.sqlDDL 迁移)
  • B2 · 改 ETL loader 增加 member_order_count 聚合(apps/etl/connectors/feiqiu/loaders/ 对应 loader
  • B3 · 执行 migration + 运行一次区域级 ETL 回放 7 天验证
  • B4 · 校验 SQL 确认全店 = 区域和

Phase C · 后端实施Claude 实施 · 依赖 A4

  • C1 · 新建 app2a_finance_area_prompt.py(含业态特征字典 + 5 个区域级辅助函数)
  • C2 · 改 prompts/__init__.py / config.py / cache_service.py / admin_ai.py / schemas/admin_ai.py
  • C3 · 改 dispatcher.py 72 循环拆分 + run_single_app 新分支
  • C4 · 单元测试:build_app2a_area_prompt 对 hall/vip/mahjong/ktv 4 个代表业态拼接验证
  • C5 · 集成测试admin-web 手动触发任一区域组合,验证 ai_run_logs.app_type = 'app2a_finance_area' 有记录

Phase D · 前端实施Claude 实施 · 独立于 B/C

  • D1 · 小程序 board-finance.ts_loadAIInsights 按 area 切 cache_type + 保留 seq 字段
  • D2 · 小程序 _extractSummary 按 seq 精确匹配(含回退启发式)
  • D3 · admin-web AIPrewarm.tsx 分两段渲染 72 组合
  • D4 · admin-web AIDashboard.tsx / AIOperations.tsx / api/adminAI.ts app_type 扩展

Phase E · 端到端验证(全部完成后)

  • E1 · 百炼 APP 端到端实调:单个区域组合(如 this_month__vip触发AI 返回 12 条完整
  • E2 · 72 组合预热实调:手动触发 ai_dws_completed,全链路走完 ~20 min
  • E3 · 小程序切换区域 → AI 洞察区正确展示 app2a 结果 · 总结卡片 seq 11/12 精确匹配
  • E4 · admin-web AIPrewarm 两段正确展示 · AIDashboard 筛选 app2a 可见
  • E5 · A/B 测试采样 16 组8 时间 × 2 业态 hall/vip人工评估 ≥ 12/16 组达标
  • E6 · 更新 docs/ai/app2_finance_prompt_version_history.md 增加 app2a v1 生产版记录

Phase F · 审计收尾

  • F1 · /audit 生成 docs/audit/changes/2026-0X-XX__app2a_finance_area_integrated.md
  • F2 · 数据库文档同步:docs/database/ 记录 member_order_count 列新增
  • F3 · 本设计文档切换为 v2 完成

七 · 分阶段时间估算(整包交付)

Phase 工作量 负责 依赖
A · 百炼 APP 建立 10 min Neo 无(可立即开始)
B · DWS 改造 2-3 h Claude A1 完成
C · 后端实施 3-4 h Claude A4拿 APP ID + B4DWS 新列生效)
D · 前端实施 2-3 h Claude 无(与 B/C 并行)
E · 端到端验证 2-3 h Neo + Claude C/D 全部完成
F · 审计 30 min Claude E 全部通过

总耗时估算10-14 小时1.5 工作日)


八 · 风险与回滚

风险 影响 缓解
app2a system prompt v1 质量不达预期 64 组合低质 E5 人工评估 · 未通过则迭代 v2 系统 prompt
DWS member_order_count 历史值 = 0未回填 区域级会员占比环比在上线首周失真 接受首周降级 · system prompt H2 已定"样本不足后缀"降权引用
ETL loader 改造引入数据错算 区域级订单数异常 全店 = 区域和校验 SQL · E2 跑完立即验证
百炼 APP ID 配置错误 64 组合全失败 config.py 启动期校验缺失即报错
dispatcher 72 循环拆分 bug 预热超时 保留原熔断/限流机制 · C3 单测覆盖拆分

回滚(若整包实施后发现重大问题):

  1. 百炼侧:将 app2a APP 暂停控制台操作dispatcher 自动回退(但需代码改动支持)
  2. 代码侧git revert 整包 commit
  3. DWS 侧ALTER TABLE DROP COLUMN member_order_countCASCADE 视图)

由于用户指示"作为正式模块上线、不加灰度",回滚复杂度较高 · 要求 E5 人工评估严格把关。


九 · 验证清单Definition of Done

B · DWS

  • SELECT column_name FROM information_schema.columns WHERE table_schema='dws' AND table_name='dws_finance_area_daily' AND column_name='member_order_count'; 返回 1 行
  • 全店 vs 区域和 校验 SQL 返回 0 行
  • app.v_dws_finance_area_daily 新视图 SELECT 正常返回带 member_order_count 列

C · 后端

  • AIConfig.from_env() 加载通过(新 env 变量识别)
  • 对 hall/vip/mahjong/ktv 4 个代表业态调 build_app2a_area_prompt 本地返回 prompt 字符串,"对比口径"/"业态说明"/"区域占比" 三字段齐
  • ai_run_logs.app_type = 'app2a_finance_area' 出现
  • 单次预热总耗时 < 25 min

D · 前端

  • 小程序切换到 VIP/大厅/斯诺克 3 个区域AI 洞察区能正确加载 app2a 缓存结果
  • 本期总结卡片三色灯 + seq 11/12 精确匹配
  • admin-web AIPrewarm 两段分区正常显示 72 组合
  • admin-web AIDashboard 可按 app2a_finance_area 筛选日志

E · 端到端

  • 16 组采样人工评估 ≥ 75% 达标12/16 组)
  • 7 天成功率 ≥ 95%
  • insights 数组长度 = 12 占比 ≥ 90%

变更记录

日期 版本 变更 作者
2026-04-22 v1草案 初版 · 基于 this_month/all 调优结论 + 72 组合数据源调研 Claude + Neo
2026-04-22 v2定稿 用户已确认 Q1-Q7 决策 · 纳入 DWS 改造 + seq 精确匹配 · 产出整包 checklist · 删除灰度开关 Claude + Neo