指标很多,口径很少
读到卷三最后一章,团队手里通常已经有一堆指标:流水、ARPU、ARPPU、付费率、eCPM、CPI、ROI、订单量、退款率、掉单率。
问题不是指标不够,而是这些指标很少被放在同一张表里检查。收入看增长、买量看 ROI、订单看客服工单,三个报表各自成立,合起来却可能互相矛盾:流水涨了,净收入没涨;ROI 达标,退款后回收周期变长;订单量正常,掉单率已经翻倍。
收口章要做的第一件事,是把它们收成一张矩阵。
五组指标
矩阵按商业化的五个环节分组:
| 组 | 回答的问题 | 典型指标 |
|---|---|---|
| 收入 | 这个月到底赚了多少 | 净收入 |
| 付费 | 谁在付、付多少 | 付费率、ARPPU |
| 广告 | 流量变现效率如何 | eCPM |
| 买量 | 获客是否划算 | CPI、D30 ROI |
| 订单 | 收款过程是否健康 | 掉单率、退款率 |
五组不是并列的 KPI,而是一条因果链:买量带来用户,付费与广告产生收入,订单决定收入能不能落袋。任何一组失真,上下游都会跟着错。
判定规则
每个指标需要三个属性:方向、预算、当前值。
- 方向:越高越好,还是越低越好。付费率越高越好,掉单率越低越好。
- 预算:这条指标的红线。它不是目标值,而是「低于/高于它就要停下来看」的阈值。
- 当前值:按产品分别记录,消消与方舟不共用一套预算。
判定分三档:
| 档位 | 条件 | 处理 |
|---|---|---|
| ok | 在预算内 | 保持 |
| watch | 超出预算 10% 以内 | 记录并观察 |
| fail | 超出预算 10% 以上 | 阻塞发布,先修复 |
10% 的容差不是精确科学,而是给波动留出空间。真正的价值在于:它强迫团队为每条指标写下一个数字,而不是在评审会上说「大概还行」。
把矩阵写成代码
// file: src/lab/biz-matrix.ts
// tier: L1
// verify: node --test test/lab/biz-matrix.test.ts
export type ProductId = "match3" | "ark";
export type Direction = "lower" | "higher";
export interface BizMetric {
readonly id: string;
readonly group: string;
readonly unit: string;
readonly match3: number;
readonly ark: number;
readonly direction: Direction;
readonly budget: number;
}
export const BIZ_GROUPS = ["收入", "付费", "广告", "买量", "订单"] as const;
export const BIZ_METRICS: readonly BizMetric[] = [
{ id: "net_revenue", group: "收入", unit: "万元/月", match3: 987, ark: 2820, direction: "higher", budget: 800 },
{ id: "pay_rate", group: "付费", unit: "%", match3: 2.8, ark: 6.5, direction: "higher", budget: 2.5 },
{ id: "arppu", group: "付费", unit: "元", match3: 68, ark: 420, direction: "higher", budget: 60 },
{ id: "ad_ecpm", group: "广告", unit: "元", match3: 45, ark: 80, direction: "higher", budget: 40 },
{ id: "roi_d30", group: "买量", unit: "%", match3: 82, ark: 62, direction: "higher", budget: 65 },
{ id: "cpi", group: "买量", unit: "元", match3: 3.5, ark: 28, direction: "lower", budget: 35 },
{ id: "order_drop", group: "订单", unit: "%", match3: 0.35, ark: 0.2, direction: "lower", budget: 0.5 },
{ id: "refund_rate", group: "订单", unit: "%", match3: 1.2, ark: 0.8, direction: "lower", budget: 1.5 },
];
export type Verdict = "ok" | "watch" | "fail";
export function judge(row: BizMetric, value: number): Verdict {
const ratio = row.direction === "lower" ? value / row.budget : row.budget / value;
if (ratio <= 1) {
return "ok";
}
if (ratio <= 1.1) {
return "watch";
}
return "fail";
}
export function evaluateProduct(metrics: readonly BizMetric[], product: ProductId): readonly string[] {
const problems: string[] = [];
for (const row of metrics) {
const value = row[product];
const verdict = judge(row, value);
if (verdict === "fail") {
problems.push(
`${product}:${row.id}=${value}${row.unit} misses budget ${row.budget}${row.unit}`,
);
}
}
return problems;
}
export function matrixGaps(metrics: readonly BizMetric[]): readonly string[] {
const covered = new Set(metrics.map((row) => row.group));
return BIZ_GROUPS.filter((group) => !covered.has(group));
}
export function watchRows(metrics: readonly BizMetric[], product: ProductId): readonly string[] {
return metrics
.filter((row) => judge(row, row[product]) === "watch")
.map((row) => row.id);
}
export function netRevenue(gross: number, refundRate: number, channelShare: number): number {
const afterRefund = gross * (1 - refundRate / 100);
return afterRefund * (1 - channelShare / 100);
}
export function formatMatrix(metrics: readonly BizMetric[]): string {
const header = "id\tgroup\tunit\tmatch3\tark\tbudget\tdirection";
const rows = metrics.map(
(row) =>
`${row.id}\t${row.group}\t${row.unit}\t${row.match3}\t${row.ark}\t${row.budget}\t${row.direction}`,
);
return [header, ...rows].join("\n");
}
代码里有三个关键选择。
第一,judge 用比值而不是差值。收入类指标差 10 万元可能无关紧要,掉单率差 0.1 个百分点却可能意味着几千笔订单。比值让不同量纲的指标可以用同一套阈值。
第二,evaluateProduct 只返回 fail,不返回 watch。watch 是观察项,不应该阻塞发布;把它混进失败列表,会让团队对告警麻木。
第三,matrixGaps 检查组覆盖。矩阵最常见的错误不是某个数不好,而是整组指标没人负责。少了「广告」组,广告变现出问题也不会有人发现。
净收入为什么单独成函数
矩阵里的 net_revenue 是净收入,不是流水。很多团队把它当流水填,导致买量 ROI 被系统性高估。
正确的计算顺序是:
- 先扣退款:
gross × (1 − refundRate); - 再扣渠道分成:
afterRefund × (1 − channelShare)。
顺序不能反。先扣分成再扣退款,结果会偏高,因为退款退的是用户支付的金额,不是渠道分成后的金额。
以消消为例:月流水 987 万元,退款率 1.2%,平均分成 40%。
afterRefund = 987 × (1 − 0.012) = 975.2 万元
netRevenue = 975.2 × (1 − 0.40) = 585.1 万元
如果只报流水 987 万,会高估 68%。这不是小数点误差,而是商业判断的根本偏差。
双案例矩阵
把两款产品的当前值放进同一张表:
| 指标 | 消消 | 方舟 | 预算 | 判定(消消 / 方舟) |
|---|---|---|---|---|
| 净收入(万元/月) | 987 | 2,820 | ≥800 | ok / ok |
| 付费率 | 2.8% | 6.5% | ≥2.5% | ok / ok |
| ARPPU | ¥68 | ¥420 | ≥¥60 | ok / ok |
| 激励 eCPM | ¥45 | ¥80 | ≥¥40 | ok / ok |
| D30 ROI | 82% | 62% | ≥65% | ok / watch |
| CPI | ¥3.5 | ¥28 | ≤¥35 | ok / ok |
| 掉单率 | 0.35% | 0.20% | ≤0.5% | ok / ok |
| 退款率 | 1.2% | 0.8% | ≤1.5% | ok / ok |
方舟的 D30 ROI 62% 对预算 65%,比值是 65 / 62 ≈ 1.048,落在 watch 区间。它不阻塞发布,但需要记录:方舟的回收周期比消消长,这是中重度产品的常态,不是异常;真正需要警惕的是它从 watch 滑到 fail。
消消的广告收入占比高,eCPM 是它的生命线;方舟的订单少、客单价高,退款率与掉单率的绝对波动更值得关注。同一张矩阵,两款产品的敏感指标不同。
指标从哪来
矩阵里的每个数字都必须有明确来源,否则它只是一排看起来专业的数。
| 指标 | 来源 | 更新频率 |
|---|---|---|
| 净收入 | 财务月结,扣退款与分成后 | 每月 |
| 付费率 | 账号中台的付费用户表 | 每日 |
| ARPPU | 内购订单与付费用户表联表 | 每月 |
| eCPM | 广告平台账单,按展示数计算 | 每日 |
| D30 ROI | 买量成本与归因后累计净收入 | 每日滚动 |
| CPI | 投放平台消耗除以归因安装数 | 每日 |
| 掉单率 | 渠道成功支付与内部已发货订单的差集 | 每日 |
| 退款率 | 渠道退款账单除以当月订单 | 每月 |
三条规则:
- 一个指标只有一个来源。 净收入只认财务月结,不认运营自己算的表。
- 来源要能追溯到原始账单。 报表可以二次加工,但必须能回到渠道或财务的原始记录。
- 口径变更要留版本。 改了退款口径,就要能区分新旧两段数据,不能直接拼在一起。
来源不清的指标,宁可先不放进矩阵,也不要放一个「大概对」的数。
矩阵不是 KPI 表
把矩阵做成 KPI 表,会立刻出现两个问题。
一是平均分掩盖空白组。 五组里四组很好、一组没人管,平均分仍然很高。矩阵按组检查,matrixGaps 专门抓「整组缺失」。
二是目标值替代预算。 预算是红线,不是目标。把预算当目标,团队会刚好做到红线附近,然后在下一次波动中集体越线。
矩阵的正确用法是发布前检查:所有组都有指标、所有指标都有预算、所有 fail 都有处理记录。它不负责激励,负责兜底。
与第 13.2 节的关系
本节给出「看什么数」,下一节给出「按什么顺序放行」。指标矩阵回答产品是否健康,发行门禁回答这次发布是否安全。
两者不能互相替代:指标全绿但门禁缺失,可能把一个健康的版本发到错误的渠道;门禁齐全但指标失真,可能把一个有问题的版本顺利放出去。
小结
- 商业化指标收成五组:收入、付费、广告、买量、订单。
- 每条指标需要方向、预算、当前值三要素,判定分 ok/watch/fail。
- 比值判定让不同量纲的指标共用一套阈值;10% 容差用于区分观察与阻塞。
- 净收入先扣退款再扣分成,顺序不能反。
matrixGaps抓整组缺失,watchRows抓接近红线的指标。- 矩阵是发布前的兜底检查,不是 KPI 打分表。
阅读导航:上一节:12.3 商店审核材料与驳回应对 · 下一节:13.2 发行清单与上线门禁 。
常见错误与边界
- 把流水当净收入。 少扣退款与分成,ROI 与回收周期全部失真。
- 先扣分成再扣退款。 计算顺序错误会让净收入偏高。
- 所有指标用同一套绝对值阈值。 量纲不同,应该用比值。
- 把 watch 当 fail。 观察项也阻塞,团队会对告警麻木。
- 只看单指标。 收入涨、退款也涨,净收入可能没变。
- 矩阵长期不更新预算。 业务阶段变了,红线不变,判定失去意义。
- 让一个团队负责所有组。 组对应不同职责,必须有明确 owner。
- 用平均数掩盖空白组。 整组缺失比单点失败更危险。
- 把矩阵当对外汇报材料。 对外口径需要财务确认,矩阵是内部检查工具。
- 忽略单位。 万元与元混用,等于没有矩阵。
- 预算写成目标值。 目标可以超额,红线不能。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。