Files
Commercialization.topon/IAA广告架构重构实施指南.md
2026-04-22 17:44:49 +08:00

614 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IAA广告架构重构实施指南
## 1. 目标
本文档的目标不是讨论“架构是否优雅”,而是以 **IAA 收益最大化** 为第一原则,对当前广告接入架构进行诊断、排序和重构规划。
核心目标:
1. 提高激励视频和插屏的首播成功率、Ready Rate、Show Rate、Reward Rate。
2. 将当前旧版 `load/show/listener` 心智升级为新版 Taku/TopOn 的 **生命周期 + 自动加载 + 场景统计 + 状态查询 + 策略化调度**
3. 保留业务层统一入口 `ADManager`,但重做中下层能力和策略层。
4. 把当前“联调环境”和“实际发布包依赖”统一起来,避免版本漂移导致的收益判断失真。
---
## 2. 当前架构快照
### 2.1 运行时主链路
```mermaid
flowchart LR
A["业务层\nADManager.AsyncPlayAD"] --> B["商业化抽象层\nADPlayer / AsyncAdPlayer"]
B --> C["平台实现层\nToponAdController / AwardVideoPlayer / InteractionPlayer"]
C --> D["Unity桥\nATSDKAPI / Rewarded / Interstitial"]
D --> E["原生桥\nSDKInitHelper / VideoHelper / VideoAutoAdHelper"]
E --> F["Taku/TopOn 原生 SDK\n微信 / 抖音 / 小程序 / 下载链路"]
```
### 2.2 当前仓库角色
- 抽象层本地源码:`Packages/CC-Framework.Commercialization`
- 当前平台实现层:`Assets/Topon_Adapter`
- 当前官方 Unity 插件:`Assets/AnyThinkPlugin`
- 当前 Android 额外插件与资源:`Assets/Plugins/Android`
### 2.3 当前已知版本状态
- 本地抽象层版本:`1.0.12`
- 文件:[Packages/CC-Framework.Commercialization/Assets/package.json](F:/UnityWork/Commercialization.topon/Packages/CC-Framework.Commercialization/Assets/package.json)
- 当前 Topon 包版本:`1.4.7`
- 文件:[Assets/package.json](F:/UnityWork/Commercialization.topon/Assets/package.json)
- 当前 Topon 包对抽象层的发布依赖是:`1.0.12`
- 文件同上
- 当前联调工程和发布依赖已对齐到同一抽象层版本,版本漂移问题已收敛。
- Android 接入侧需注意:
- 当前中国区 Gromore/CSJ 组合要求 `minSdkVersion >= 24`
---
## 3. 术语速查
### 3.1 Placement广告位
- 一个 placement 就是一个固定广告机会点的唯一 ID。
- 例如:
- 复活激励
- 双倍奖励激励
- 关卡结尾插屏
### 3.2 Scenario广告场景
- placement 是固定广告位scenario 是这次广告触发的业务上下文。
- 例如:
- `revive`
- `double_coin`
- `level_fail_exit`
- 它主要用于:
- 漏斗分析
- 场景收益对比
- 定位具体场景的展示问题
### 3.3 load / ready / show
- `load`:发起请求并缓存广告
- `ready`:当前已有可展示广告缓存
- `show`:真正展示广告
### 3.4 Auto Load自动加载
- SDK 自动维护某个 placement 的缓存和补量
- 更适合高频高价值激励位
### 3.5 Waterfall瀑布流
- 按优先级依次请求广告源
- 优先级和广告源配置主要在后台控制
### 3.6 Bidding竞价
- 广告源实时回传价格
- 平台再选择最优广告展示
### 3.7 eCPM
- 每千次展示收益
- 是重要指标,但不能脱离:
- Ready Rate
- Show Rate
- Fill Rate
- Reward Completion
单独看
### 3.8 Fill Rate填充率
- 发起请求后,最终拿到可展示广告的比例
### 3.9 Show Rate展示率
- 已到达广告场景或已请求后,最终真正展示成功的比例
### 3.10 Impression展示
- 广告真正展示给用户一次
- 收益通常基于展示结算,而不是基于请求结算
### 3.11 Report API
- 广告平台收益与展示数据接口
- 用于自动价格、收益归因、Waterfall 对账和优化
### 3.12 Local Extra / Custom Map
- `local extra`:请求级参数,通常带用户透传、业务信息
- `custom map`:初始化级参数,通常带渠道、用户分组、实验标记
### 3.13 为什么“预加载影响 eCPM”是旧命题
- 旧时代常说“不要太早 load会伤 eCPM”
- 现在更准确的说法是:
- 问题不在预加载本身
- 问题在于是否 **策略化预热**
- 真正影响收益的是:
- 预热时机不对
- placement 太多
- 长时间不展示
- 后台策略和客户端行为脱节
---
## 4. 官方推荐生命周期
### 4.1 推荐调用顺序
```mermaid
sequenceDiagram
participant App as App启动
participant Privacy as 隐私同意
participant SDK as Taku SDK
participant Policy as 客户端策略层
participant Game as 广告业务逻辑
App->>Privacy: 展示隐私协议
Privacy-->>App: 用户同意
App->>SDK: ATSDK.init(...)
App->>SDK: ATSDK.start()(中国区)
App->>Policy: 注册核心placement自动加载/预热
Game->>Policy: 到达广告场景 entryScenario
Policy->>SDK: ready/status 检查
alt 已ready
Policy->>SDK: show
else 未ready但在容错窗口
Policy->>SDK: 短等待 / 补偿重试
else 超时
Policy-->>Game: 播放失败
end
```
### 4.2 推荐自动调用的动作
这些动作建议由底层 provider 自动做掉,而不是依赖业务层自己记忆:
1. 中国区 `ATSDK.start()`
2. 核心激励位注册 auto load
3. 启动后预热高价值 placement
4. 核心 placement 的诊断日志与状态快照
5. `show start` 后安排下一轮预热
6. 首轮失败进入短重试窗口
### 4.3 业务层不应该感知的内容
以下内容应由策略层 / 平台层封装:
1. placement 是否自动加载
2. 何时预热
3. 是否可以等待更高价缓存
4. 冷启动是否容许重试
5. 微信/抖音/小程序/下载的具体差异
---
## 5.1 当前已接入的策略 Key第二阶段
目前已在 `ToponControllerOptions` 中接入的高收益策略 key
- `topon.rewarded_auto_load`
- 是否开启激励自动加载
- 当前建议默认:`true`
- `topon.rewarded_prewarm_on_init`
- 初始化后是否自动预热激励位
- 当前建议默认:`true`
- `topon.rewarded_max_load_attempts`
- 单次播放请求允许的最大加载尝试次数
- 当前建议默认:`3`
- `topon.rewarded_load_retry_delay_ms`
- 激励首次失败后的短补偿等待时间
- 当前建议默认:`1000`
- `topon.interstitial_auto_load`
- 是否开启插屏自动加载
- 当前建议默认:`true`
- `topon.interstitial_prewarm_on_init`
- 初始化后是否自动预热插屏位
- 当前建议默认:`true`
- `topon.interstitial_max_load_attempts`
- 单次插屏播放请求允许的最大加载尝试次数
- 当前建议默认:`2`
- `topon.interstitial_load_retry_delay_ms`
- 插屏首轮失败后的短补偿等待时间
- 当前建议默认:`500`
- `topon.local_strategy_asset_path`
- Android 本地策略资源路径
- `topon.auto_open_debugger_ui`
- 是否在初始化后自动打开官方 DebugUI
- 当前建议默认:`false`
适用方式:
- 通过 `ADConfig.CommonKeyValues`
- 或通过 `ToponControllerOptions`
- 或额外传入 `IDictionary`
推荐默认示例:
```text
topon.rewarded_auto_load=true
topon.rewarded_prewarm_on_init=true
topon.rewarded_max_load_attempts=3
topon.rewarded_load_retry_delay_ms=1000
topon.interstitial_auto_load=true
topon.interstitial_prewarm_on_init=true
topon.interstitial_max_load_attempts=2
topon.interstitial_load_retry_delay_ms=500
topon.auto_open_debugger_ui=false
```
调试说明:
- `topon.debug=true`
- 当前只用于开启 SDK 调试日志
- 不再默认自动弹出官方 DebugUI
- 官方 DebugUI 建议在真机样例或专用调试入口中手动打开
---
## 5. 官方最新 SDK 能力,与当前项目的差距
结合官方文档和当前插件/反编译结果,当前 Taku/TopOn 体系已经具备以下关键能力,但当前项目没有充分利用:
### 3.1 `ATSDK.start()`
- 官方中国区 SDK 初始化文档要求 `ATSDK.init(...)` 后建议调用 `ATSDK.start()`
- 反编译验证:`ATSDK.start()` 在当前 `anythink_core` 中真实存在,且是无参静态方法。
- 当前缺陷:
- `ToponAdController` 只调了 `ATSDKAPI.initSDK(...)`
- Unity 壳 `ATSDKAPI.cs` 没有暴露 `start`
### 3.2 自动加载能力
- 已有能力:
- `ATRewardedAutoVideo`
- `ATInterstitialAutoAd`
- 当前缺陷:
- 当前 `AwardVideoPlayer` / `InteractionPlayer` 仍是手工状态机模式
- 没有利用自动加载做高频 placement 的持续预热
### 3.3 状态查询能力
- 已有能力:
- `hasAdReady`
- `checkAdStatus`
- `getValidAdCaches`
- 当前缺陷:
- 未接入策略层
- 无法做“软等待”“缓存质量判断”“首轮失败补偿”
### 3.4 广告场景统计能力
- 官方推荐使用 `entryAdScenario` 做漏斗分析
- 当前缺陷:
- `adScene` 只在 `show` 阶段透传
- 没有将“用户到达广告机会点”单独建模
### 3.5 本地策略能力
- 官方原生 SDK 有 `ATSDK.setLocalStrategyAssetPath(...)`
- 当前缺陷:
- Unity 壳没暴露
- 客户端无法加载本地预置策略
### 3.6 流量分组 / 规则能力
- 当前已接的弱能力:
- `channel / sub_channel`
- `custom_map`
- `placement custom data`
- 当前缺陷:
- 只是透传,不是可运营的“收益策略层”
---
## 6. 现有问题,按收入影响从大到小排序
### P0. 首播请求容错太差,直接损失收入
表现:
- 激励视频第一次点击经常失败
- 冷启动期首轮加载不稳定
根因:
- `AsyncAdPlayer` 仍是“单次播放只给一次首轮 load 机会”
- 首次 `load` 比后续 `load` 多做了一层 `VideoHelper / ATRewardVideoAd` 初始化
- 冷启动期没有任何“延迟补偿 / 软等待 / 重试窗口”
影响:
- 直接损失首播展示
- 高价值激励点收益打折
- 拉低用户广告可接受度和视频完成率
### P1. 高价值 placement 没有自动加载Ready Rate 偏低
表现:
- 核心激励位依赖点击时加载
- 就绪完全由手工 load 时机决定
影响:
- 展示机会点到来时,经常没 ready
- 收入天花板偏低
### P2. 没有完整接入场景统计,无法做精细化收益调优
影响:
- 无法准确判断问题在“场景设计”还是“缓存策略”
- 客户端和后台漏斗对不上
### P3. 生命周期抽象过粗,不适配新版 SDK
表现:
- `init` 被调用 != 广告系统真正 ready
- 当前实现无法表达 `start`、本地策略、自动加载启动等生命周期
### P4. 插屏回调链本身存在缺陷
表现:
- `InteractionPlayer.ShowAD(...)` 没接 `onClose/onVideoComplete`
- `onInterstitialAdFailedToShow` 等回调是空实现
影响:
- 插屏统计、重试、展示完成事件不可靠
### P5. 版本漂移导致实验结果不可信
表现:
- 本地抽象层、联调工程、发布依赖三个版本不统一
影响:
- 本地验证表现无法可信映射到业务项目
---
## 7. 对“预加载影响 eCPM”的判断
这是一个 **旧时代常见结论,但今天已经不能直接这么说**
更准确的说法是:
- **无脑预加载本身不是收益最优策略**
- 但“预加载会直接伤 eCPM”这个说法过于粗暴已经过时
当前更合理的理解:
1. 预加载是 IAA 的基础能力,不做高价值位预热,收入上限一定低。
2. 问题不在“要不要预加载”,而在“何时预加载、预加载多少、多久不展示视为无效”。
3. 真正会伤收益的不是“有预加载”,而是:
- 预热过早
- 长时间不展示
- placement 太多导致缓存浪费
- 高价值场景没有拿到新鲜缓存
- 客户端策略和后台 Waterfall 配置脱节
最优结论:
- **高价值高频位**:必须预热,甚至自动加载
- **中频位**:场景前置预热
- **低频位**Just-in-time load + 短等待容错
- **插屏**:策略化预热,不建议全局常驻缓存所有位
---
## 8. 最优指南:面向 IAA 的广告策略
### 6.1 激励视频
推荐策略:
1. 核心激励位默认使用自动加载
2. 启动后预热
3. 用户进入关键广告场景时调用 `entryAdScenario`
4. 播放前先读 `ready/status`
5. 首次失败给短重试窗口,不要直接判死
6. `onRewardedVideoAdPlayStart` 后立即安排下一轮预热
### 6.2 插屏
推荐策略:
1. 重要插屏位可使用自动加载
2. 低频插屏采用场景前置预热
3. 插屏失败要完整上报 show fail 和 close 结果
4. 插屏不应该沿用激励的奖励回调模型
### 6.3 后台协同
推荐策略:
1. 开启报表 API
2. 配置自动价格
3. 做流量分组
4. 用 A/B 测试验证:
- 自动加载 vs 手工加载
- 启动预热 vs 场景预热
- 软等待 0/300/800ms
### 8.4 常见产品策略方式
#### 策略 A核心激励常驻预热
- 适用:
- 复活激励
- 双倍奖励激励
- 特点:
- 就绪率高
- 收入稳定
#### 策略 B场景前置预热
- 适用:
- 结算页激励
- 阶段性插屏
- 特点:
- 更省请求
- 更接近真实展示时机
#### 策略 C点击兜底加载 + 软等待
- 适用:
- 低频长尾位
- 特点:
- 节省资源
- 不适合核心高价值激励位
#### 策略 D自动加载 + 场景感知展示
- 适用:
- 高频核心激励
- 特点:
- 是当前推荐的主流 IAA 策略
- 平衡 ready rate 和展示体验
#### 策略 E更高价广告软等待
- 适用:
- 激励价值极高的场景
- 特点:
- 可能提高单次展示收益
- 风险:
- 等待过久伤转化
- 必须通过 A/B 测试验证
---
## 9. 推荐的新架构
```mermaid
flowchart LR
A["业务层\nADManager.AsyncPlayAD"] --> B["策略层\nPlacementPolicy / RevenuePolicy"]
B --> C["Provider Runtime\nRewardedRuntime / InterstitialRuntime"]
C --> D["Platform Adapter\nTopOn/Taku"]
D --> E["Unity SDK Bridge"]
E --> F["Native SDK"]
```
### 7.1 抽象层职责
- 保留 `ADManager` 作为统一入口
- 去掉“只懂 0/1/2 状态”的单薄模型
- 引入 placement 级策略
### 7.2 平台层职责
- 管理 SDK 生命周期
- 管理自动加载/手工加载
- 管理状态查询和场景统计
- 处理微信/抖音/小程序/下载相关链路
### 7.3 策略层职责
- placement 是否自动加载
- 预热时机
- soft wait 时长
- load fail 重试策略
- show 冷却和频控
---
## 10. 实施计划
### 阶段 1P0 止血
目标:解决首播失败和关键回调缺陷
实施项:
1. 将工程切换到本地 `CC-Framework.Commercialization`
2. 扩展 Unity 层,补 `ATSDK.start()`
3. `ToponAdController` 中接入 `start` 生命周期
4. 激励首播增加冷启动补偿和短重试窗口
5. 插屏回调链修正
### 阶段 2P1 收益增强
目标:提高 Ready Rate 和 Show Rate
实施项:
1. 核心激励位切自动加载
2. 插屏支持自动加载或策略化预热
3.`entryAdScenario`
4. 接状态查询、缓存查询
### 阶段 3P2 架构升级
目标:建立长期可运营体系
实施项:
1. 新增策略层
2. placement 级配置
3. 本地策略 / 后端策略下发
4. 数据埋点和 BI 打通
---
## 11. 第一阶段具体改动清单
### 9.1 必改
- `Packages/manifest.json`
- 切本地包依赖
- `Packages/CC-Framework.Commercialization/Assets/Runtime/ADAggregator/*`
- 升级 `AsyncAdPlayer`
- `Assets/Topon_Adapter/Runtime/Scripts/ToponAdController.cs`
-`start`
- `Assets/Topon_Adapter/Runtime/Scripts/AwardVideoPlayer.cs`
- 首播容错、场景统计
- `Assets/Topon_Adapter/Runtime/Scripts/InteractionPlayer.cs`
- 回调完整化
### 9.2 推荐
- 增加 `ToponSdkLifecycle``ToponStrategyConfig`
- 增加 `RewardedPlacementPolicy`
- 为激励和插屏补统一诊断日志
---
## 12. 产品 / 运营 / 后端建议
### 10.1 产品侧
- 明确每个激励位的触发场景和价值等级
- 区分“高价值激励位”和“长尾激励位”
- 插屏不要用“一刀切”频率
### 10.2 运营侧
- 配合场景统计做 placement 漏斗
- 按渠道分组优化 Waterfall
- 做自动价格和 A/B 实验
### 10.3 后端侧
- 下发 placement 策略
- 拉通报表 API
- 统一客户端和平台收益口径
- 对激励奖励做服务端幂等和风控
---
## 13. 一句话结论
当前最优方案不是继续修补旧版手工状态机,而是:
**保留 `ADManager` 统一入口,重做中下层为“策略层 + 平台能力层”,把新版 Taku/TopOn 的 `start / 自动加载 / 场景统计 / 状态查询 / 本地策略` 真正接进来。**