# 预算决策框架

> 最后更新：2026-04-09
> 适用系统：自动化投放 Agent（auto_put_ad）
> 核心文件：`tools/budget_calc.py`、`skills/budget_strategy.md`

---

## 一、整体架构

```
运营输入今日预算
        ↓
① 拉昨日数据 → 算 scale_ratio → 确定全局策略
        ↓
② 筛有效广告（open_count ≥ 100）
        ↓
③ 计算分位数阈值（ROI P70/P30 + 消耗 P50）
        ↓
④ 冷启动保护判定（优先于矩阵）
        ↓
⑤ ROI × 跑量 二维矩阵 → 输出动作
        ↓
⑥ 关停保护检查（赔付门槛）
        ↓
⑦ 出价边界约束 → 写入 Excel
```

---

## 二、全局策略判定（scale_ratio）

```
scale_ratio = 今日预算 ÷ 昨日实际消耗
```

| scale_ratio 区间 | 策略名称 | 含义 |
|---|---|---|
| < 0.70 | `aggressive_scale_down` | 大幅缩量（>30%） |
| 0.70 ~ 0.95 | `moderate_scale_down` | 温和缩量 |
| 0.95 ~ 1.05 | `maintain` | 基本持平 |
| 1.05 ~ 1.30 | `moderate_scale_up` | 温和扩量 |
| > 1.30 | `aggressive_scale_up` | 大幅扩量（>30%） |

---

## 三、广告分类（二维象限）

**ROI 维度**（效率分 = 裂变0层回流数 / 昨日消耗）

- **High**：效率分 ≥ P70（头部 30%）
- **Mid**：P30 ~ P70（腰部 40%）
- **Low**：< P30（尾部 30%）

**跑量维度**（昨日消耗绝对值）

- **High**：消耗 ≥ P50（中位数以上）
- **Low**：消耗 < P50

> 阈值基于当日有效广告池（open_count ≥ 100）动态计算，无固定值。

---

## 四、决策矩阵（三套）

### 缩量矩阵（scale_ratio < 0.95）

| | 高跑量（≥ P50） | 低跑量（< P50） |
|---|---|---|
| **高 ROI（≥ P70）** | keep | keep |
| **中 ROI（P30~P70）** | decrease **-10%**（大幅） / **-5%**（温和） | observe |
| **低 ROI（< P30）** | decrease **-15%**（大幅） / **-10%**（温和） | close |

### 扩量矩阵（scale_ratio > 1.05）

| | 高跑量（≥ P50） | 低跑量（< P50） |
|---|---|---|
| **高 ROI（≥ P70）** | keep | increase **+15%**（大幅） / **+10%**（温和） |
| **中 ROI（P30~P70）** | keep | increase **+5%** |
| **低 ROI（< P30）** | decrease -10% | close |

### 持平矩阵（0.95 ≤ scale_ratio ≤ 1.05）

- 低 ROI + 低跑量 → `close`
- 其余全部 → `keep`

---

## 五、5 种动作说明

| 动作 | 含义 | 出价变化 |
|------|------|---------|
| `keep` | 保持不动 | 不调整 |
| `increase` | 提价放量 | +5% ~ +15% |
| `decrease` | 降价控量 | -5% ~ -15% |
| `close` | 建议关停 | 不调整（标记，需人工确认） |
| `observe` | 观察不动 | 不调整 |

---

## 六、保护机制

### 6.1 冷启动保护（最高优先级，覆盖矩阵结果）

| 判定条件 | 处理方式 |
|---|---|
| 广告 `create_time` 距今 < 48h | 强制 `observe`，不调价 |
| 累计 `conversions_count` < 6 次 | 强制 `observe`，不调价不关停 |

> ⚠️ 冷启动判定**优先于** ROI × 跑量矩阵。即使 ROI=Low，只要满足冷启动条件，一律 observe。

### 6.2 赔付门槛保护（关停前检查）

腾讯广告赔付规则：转化 ≥ 6 且 CPA 偏离目标 ≥ 20%/30% 时，可申请赔付。

| 转化数 | 处理 |
|---|---|
| < 3 | 可正常执行 close |
| 3 ~ 5 | 改为 `observe`，等积累到 6 次 |
| ≥ 6 且 CPA 偏离 ≥ 20% | 改为 `observe`，先申请赔付再关停 |
| ≥ 6 且 CPA 正常 | 可正常执行 close |

---

## 七、出价执行约束

| 约束 | 规则 |
|---|---|
| 出价范围 | 10分（0.10元）~ 10000分（100元） |
| `keep / observe / close` | **不改出价** |
| `increase / decrease` | 按矩阵比例计算新出价，截断到边界 |
| 单次调整幅度 | ≤ 10%（超过需拆阶梯执行，间隔 ≥ 2h） |
| 调整间隔 | ≥ 2 小时（oCPM 模型重学习需要时间） |
| 每天调整次数 | 2 ~ 3 次 |

**阶梯式调价原则**：
- 单次降幅超过 10%：拆分为多次执行，每次间隔 2h
- 单次提幅超过 15%：建议拆分为 2 次执行

---

## 八、广告样本过滤

```
open_count < 100  →  样本不足，本次跳过，不进入矩阵决策
```

---

## 九、出价与消耗的非线性关系

oCPM 模式下，出价调整与消耗变化是**非线性**关系：

```
eCPM = bid × pCTR × pCVR × 1000
```

- **降价效果放大**：降 10% 出价 ≈ 降 15~25% 消耗
- **掉量悬崖**：eCPM 低于竞争水位时，展示量骤降至接近 0（断崖，非线性）
- **提价天花板**：提价 10% 不一定多消耗 10%，存在边际递减

> ⚠️ 降价操作比提价风险更高，应更谨慎；接近 MIN_BID 时调幅控制在 3% 以内。

---

## 十、核心设计哲学

> 用**出价（bid）**而非**预算上限（day_amount）**控制消耗。
>
> oCPM 下：出价 → eCPM → 竞价胜率 → 消耗量，是一个连续但非线性的链路，比设 day_amount 上限更精细灵活。

---

## 十一、待实现（预留接口）

| 功能 | 状态 |
|---|---|
| 日内 PID 控制（实时消耗 vs 节奏对比，动态微调出价） | 待实现 |
| 时段差异化出价（早间/晚间流量差异） | 待实现 |
| 调价后验强化（实际消耗/ROI 变化反馈） | 待实现 |
| 公众号渠道独立预算分配（GT/GW + 即转 ROI） | 待实现 |
