PROJECT_STRUCTURE.md 14 KB

PROJECT_STRUCTURE — 腾讯广告实时调控模块

目录:examples/tencent_realtime_control/ 定位:独立管理实时投放指标采集、CPM 状态判断和腾讯广告调控,不依赖广告创建或历史调价分析流程。

本目录实际承载 4 个相对独立的子系统,共用同一套基础设施(MySQL / ODPS / 腾讯 API / 飞书):

  1. 实时 CPM 调控(核心)— 按当天整体小时 CPM 阈值,自动提价/恢复/延后自动化广告
  2. 飞书运营命令控制 — 运营人员在指定飞书群 @机器人,用自然语言暂停/恢复/停止/查询广告
  3. 实时收入预测 — 预测当天最终收入,计算建议总成本(只读,不写腾讯接口)
  4. 日级 ROI 逐行审批(消费方)— 代码位于 examples/auto_put_ad_mini/roi_control/,本目录只启动轮询服务

一、子系统总览

┌────────────────────────────────────────────────────────────────┐
│                    run_control_service.py                       │
│                 (组合根 / Docker ad-control-service)            │
│                                                                │
│  ┌─────────────┐ ┌───────────────┐ ┌──────────────────────┐   │
│  │ FeishuCommand│ │RoiSheetApproval│ │ revenue_forecast_service││
│  │   Service    │ │    Service    │ │  (收入预测后台线程)    │   │
│  └──────┬──────┘ └──────┬────────┘ └──────────┬───────────┘   │
│         │              │                      │               │
│         ▼              ▼                      ▼               │
│  ┌────────────────────────────────────────────────────────┐   │
│  │              run_scheduler.py (10分钟调度循环)          │   │
│  │                        │                               │   │
│  │                        ▼                               │   │
│  │              run_once.py::run_cycle()                  │   │
│  │              CPM 读取 → 决策 → 执行 → 通知             │   │
│  └────────────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────────────┘
            ▲                    ▲                    ▲
            │                    │                    │
      ODPS 小时CPM信号     腾讯 Marketing API      MySQL 状态/审计

二、文件清单与职责

1. 入口 / 服务装配

文件 行数 职责
run_control_service.py 85 生产常驻服务入口。初始化 schema 后并行启动:飞书命令 WebSocket、ROI 表格审批轮询、收入预测后台线程、CPM 调度循环 run_forever()。写操作受 RTC_APPLY_ENABLED / --apply 控制
run_scheduler.py 112 CPM 调控的常驻调度循环。默认 12:00–21:00 每 600s 触发一次 run_cycle(),非投放时段休眠到次日 RTC_START_HOUR
run_once.py 798 单次幂等 CPM 调控周期(也是调度循环的核心逻辑所在)。包含决策状态机、执行、写后回读、报告落盘。支持 --apply/--at/--cpm-override/--force-refresh/--test-notification
run_revenue_forecast.py 41 单次收入预测执行入口,默认受运行时间窗约束,--ignore-runtime-window 可越过
init_db.py 18 初始化数据库 schema(读取 schema.sql + 运行迁移)

2. 实时 CPM 调控子系统

文件 行数 职责
realtime_config.py 61 调控参数:投放时段、CPM 高低阈值、提价比例、分区延迟上限、DB 锁名等(全部可环境变量覆盖)
odps_source.py 74 CPM 信号源。从 loghubods.advertiser_data_da_hour 读当天整体小时 真实cpm_总,返回最新分区
tencent_client.py 629 腾讯广告 API 读写封装。写后回读校验(默认 3 次×1s),读回不一致抛 PostWriteVerificationError。区分"未发出/被拒/结果未知"三类写失败
storage.py 1312 MySQL 状态与审计存储(全模块最大)。ad 状态、账户范围、每日状态、操作日志、运营命令、暂停状态、收入预测等全部落库逻辑
feishu_notifier.py 607 飞书在线表格通知。真实调价/延后/状态变更的窗口生成 xlsx + 发群;dry-run 与无动作不通知
fetch_daily_hourly_cpm.py 60 数据检查工具:查看指定日期分时 CPM,落 CSV 并打印

决策逻辑(在 run_once.py

decide(cpm, low, high):
    cpm > high(250)   → BOOST   # 基础出价 ×1.05 上调,每天至多一次
    low(190) ≤ cpm ≤ high → RESTORE  # 恢复基础出价 + 恢复策略暂停的广告
    cpm < low(190)    → PAUSE   # 恢复基础价,begin_date 延后到次日(不 SUSPEND)

3. 飞书运营命令子系统

文件 行数 职责
feishu_command_service.py 395 飞书 WebSocket 入口。校验群/发送人/@机器人后串行处理消息;多轮补问草稿、命令预览、确认/取消
operator_commands.py 198 确定性命令解析ParsedCommand / CommandIntent 数据类,暂停/停止/恢复/状态/今日消耗等动作的规则解析
command_intent_parser.py 218 受限 NLU。标准命令走确定性解析;RTC_NL_COMMAND_ENABLED=1 时模型只返回动作+范围 JSON,不可读库/调接口
operator_control.py 899 命令预览与执行。预览冻结广告快照 + 冲突检测;确认后按账户/广告执行暂停/恢复/停止,含写后回读、状态机流转
account_status_query.py - 从 ODPS 账号表读取全部当前账号,校验 token 后按投放起止日期和广告开关判断广告投放状态,生成飞书三 Sheet 报表与按钮卡片
today_spend_query.py 79 只读的今日消耗汇总查询(全部/自动化/指定账户),逐账户调腾讯报表聚合

命令生命周期解析 → 预览(冻结明细) → 10分钟内确认 → 执行 → 回读校验 → 审计落库

4. 实时收入预测子系统

文件 行数 职责
revenue_forecast.py 57 领域数据类:RevenueObservationRevenueTrendWindowRevenueForecast
revenue_forecast_config.py 115 预测配置:运行时段、15分钟窗口数、目标成本比例、参数版本、DB 锁名
revenue_forecast_source.py 250 ODPS 取数:ads_ad_own_package_detail_15min 15分钟收入序列、opengid_base_data 渠道成本、当日快照
revenue_speed_forecast.py 243 加权速度预测算法build_speed_samplesaggregate_speed_parameters(发布 P10/P50/P90)→ calculate_speed_forecast
revenue_forecast_repository.py 370 预测结果/观测/速度样本/已发布参数的 MySQL 持久化;参数版本发布后不可覆盖
revenue_forecast_job.py 212 单轮预测周期:取数 → 质量校验(VALID/STALE/CORRECTED) → 载入参数 → 计算 → 落库
revenue_forecast_service.py 77 后台调度线程(默认关闭,REVENUE_FORECAST_ENABLED=1 启用)
build_revenue_speed_parameters.py 118 从完整历史日构建并发布速度参数版本--start-date/--end-date/--parameter-version
backtest_revenue_speed_forecast.py 284 严格走步回测:每个预测日只用此前日期训练,只读 ODPS,不写 MySQL

5. 实验 / 测试 / 配置

文件 行数 职责
adjust_bid_experiment_20260729.py 284 一次性八广告分组调价实验(2026-07-29),默认只预览,带 bid_hold 释放与账户范围注册
test_feishu_natural_commands.py 439 飞书命令链路单测:确定性解析、NLU 兜底、预览、调度器唤醒、暂停执行
test_revenue_forecast.py 158 收入预测算法单测:速度样本构建、参数聚合、预测计算、异常分支
schema.sql 420 全部表结构(见下)
requirements.txt 7 pandas / openpyxl / pyodps / pymysql / python-dotenv / requests
.env.example 76 环境变量样例(本地开发兼容;生产以仓库根 runtime.env.example 为准)
__init__.py 1 模块标记

6. 外部依赖(不在本目录)

路径 用途
examples/auto_put_ad_mini/roi_control/ 日级 ROI 指标计算与审批表发布,run_control_service.py 启动其 RoiSheetApprovalService
agent.tools.builtin.feishu.feishu_client 框架内置飞书客户端(WebSocket / 发消息)

三、数据库表(schema.sql

用途
realtime_control_daily_state 每日 CPM 调控状态(最后分区/决策/刷新时间)
realtime_control_ad_state 广告基准与状态:base_bid_fen、boosted_date、bid_hold、paused_by_strategy、operatorpause*
realtime_control_account_scope 实时调控显式账户范围(control_mode:FULL / PAUSE_ONLY)
realtime_control_action_log 每次真实动作的审计日志
operator_command / operator_command_item / operator_command_draft 飞书运营命令、冻结明细、多轮草稿
roi_metric_run / roi_fission_parameter_* / roi_entity_snapshot / roi_action_item / roi_agency_delivery 日级 ROI 指标运行与审批动作(ROI 子系统表,由 auto_put_ad_mini 写入)
revenue_forecast_observation / result / speed_sample / speed_parameter 收入预测的原始快照、版本化结果、历史速度样本、已发布参数

storage.py::initialize_schema() 会在建表后额外执行 realtime_control_ad_state 的增量列迁移。


四、关键数据流

CPM 调控(每 10 分钟)

ODPS 小时CPM (odps_source)
   │ fetch_latest_cpm()
   ▼
run_cycle() ── 校验分区延迟 ≤2h / 时段 12–21 点
   │ decide() → BOOST / RESTORE / PAUSE / CUTOFF / WAIT_DATA / OFF_HOURS
   ▼
execute_inventory_action()
   ├─ load_ad_states() 取每账户广告状态(MySQL)
   ├─ tencent.get_ads() 拉实时广告
   ├─ target_for_ad() 计算目标出价/状态/begin_date
   └─ tencent.update_ad()/update_ad_begin_dates() 写腾讯(含回读校验)
   ▼
feishu_notifier.send_action_notification() ── 真实变更才发飞书在线表格
   ▼
upsert_ad_state() / insert_action_log() ── 状态与审计落库

飞书命令(消息触发)

飞书群 @机器人
   ▼ FeishuCommandService._authorized() 校验群/人/@
   ▼ understand():确定性解析 → (可选)LLM 兜底
   ▼ preview_write_command():冻结广告快照 + 冲突检测 → 回复预览
   ▼ 用户「确认 cmd_xxx」(10分钟内)
   ▼ execute_confirmed_command():锁内执行 → 写后回读 → 审计

五、配置要点(.env.example / realtime_config.py

变量 默认 含义
RTC_START_HOUR / RTC_STOP_HOUR 12 / 21 CPM 调控投放时段
RTC_POLL_SECONDS 600 调控轮询间隔
RTC_HIGH_CPM / RTC_LOW_CPM 250 / 190 提价 / 延后阈值
RTC_BID_UP_RATIO 1.05 提价比例
RTC_APPLY_ENABLED 0 总闸:所有入口默认 dry-run,为 1 才写腾讯
RTC_COMMAND_ENABLED / RTC_COMMAND_CHAT_ID / RTC_COMMAND_ALLOWED_OPEN_IDS - 飞书命令开关与白名单
RTC_NL_COMMAND_ENABLED 0 启用 LLM 兜底解析
REVENUE_FORECAST_ENABLED 0 收入预测后台服务开关
REVENUE_SPEED_PARAMETER_VERSION revenue_speed_params_v1 已发布速度参数版本(只读)

⚠️ 所有执行入口默认 dry-run,只有 --applyRTC_APPLY_ENABLED=1 才调用腾讯写接口;--at / --cpm-override 仅限 dry-run(run_once.py 会校验)。


六、常用运行命令

# 初始化数据库
.venv/bin/python examples/tencent_realtime_control/init_db.py

# 单次 CPM 调控(dry-run)
.venv/bin/python examples/tencent_realtime_control/run_once.py
# 验证指定 CPM 分支
.venv/bin/python examples/tencent_realtime_control/run_once.py --at 2026-07-24T15:00:00 --cpm-override 260
# 真实执行
.venv/bin/python examples/tencent_realtime_control/run_once.py --apply

# 生产常驻服务(含飞书命令 + ROI 审批 + 收入预测 + CPM 循环)
RTC_APPLY_ENABLED=0 .venv/bin/python examples/tencent_realtime_control/run_control_service.py

# 收入预测:发布参数 / 单次执行 / 走步回测
.venv/bin/python examples/tencent_realtime_control/build_revenue_speed_parameters.py --start-date 20260727 --end-date 20260805 --parameter-version revenue_speed_params_v1
.venv/bin/python examples/tencent_realtime_control/run_revenue_forecast.py
.venv/bin/python examples/tencent_realtime_control/backtest_revenue_speed_forecast.py --history-start 20260727 --start-date 20260728 --end-date 20260805

# 查看当天分时 CPM
.venv/bin/python examples/tencent_realtime_control/fetch_daily_hourly_cpm.py

七、扩展指引

  • 调整 CPM 阈值/时段 → 改 realtime_config.py 或环境变量,无需动业务代码
  • 新增决策分支 → 在 run_once.py::decide()target_for_ad() 中扩展,并补充 feishu_notifier._action_text() 的动作文案
  • 新增飞书命令operator_commands.py 定义动作常量与解析 → operator_control.py 实现预览/执行 → feishu_command_service.py 接入消息分发
  • 训练新预测参数 → 用 build_revenue_speed_parameters.py 发布新版本号(发布后不可覆盖)
  • 任何涉及腾讯写操作的新功能 → 复用 tencent_client.py 的写后回读校验与失败分类,不要裸调 API