Skip to content
Charles Shao
Go back

RTA 精讲:竞价前实时 API 过滤——第一方数据不出域地影响出价

Updated:
views

每个程序化团队大概都撞见过这样一幕:广告上线,花费曲线平稳,点击率也说得过去;可三个月后拉真实转化,数字却很难看——预算大把烧在了那些注定不会转化的曝光上。人群是用平台侧的”最佳猜测”模型圈的,而那个模型恰恰不知道对自己用户的那些了解。约翰·沃纳梅克那句”我知道广告费有一半是浪费的,只是不知道浪费在哪一半”,在程序化时代依旧成立——只不过如今我们有了工程手段,能把那”一半”找回来一部分。

RTA(Real-Time API,实时 API)就是这个手段:在不逼任何一方交出数据的前提下,让广告主用自己的第一方数据,实时影响 DSP 的每一次出价决策。 这篇文章从协议层把 RTA 讲透——它到底是什么、在竞价生命周期里站在哪一环、请求在线上长什么样、跑在怎样的工程约束之下,以及在你动手部署之前需要先备齐什么。

范围说明:RTA 是 DSP ↔ 广告主之间的私有契约,紧贴在程序化竞价链路上。链路本身的角色与协议——DSP / SSP / Ad Exchange 全景OpenRTB 与 Header Bidding隐私同意框架——各有专文,这里只在与 RTA 相关处引用。

TL;DR

Table of contents

Open Table of contents

1. 问题:广告主与 DSP 之间那道数据边界

在传统程序化链路里,广告主DSP 分坐在一条跨不过去的边界两侧,各自握着对方拿不到的那一半信息。

把这两侧隔开的,是三重现实:数据隐私法规GDPR、CPRA 及各地类似制度)、商业敏感性,以及把自己的客户名单泄露给第三方的明显风险

在 RTA 之前,弥合这道边界的标准做法是人群上传(audience upload):广告主把用户名单做哈希,经数据洁净室或直连集成发给 DSP,DSP 在上面叠加自己通用的定向模型,广告就以近似黑盒的方式跑起来。问题是——广告主没法实时干预,而 DSP 始终在对着一份过期的广告主状态快照做定向。

结果是一道典型的统计误差问题,两种错误都在悄悄流血、且都不会出现在 DSP 的标准报表里:

关键直觉:人群上传的病根不在”数据不够多”,而在”数据不够新、且方向单向”——广告主只能一次性把状态推过去,之后既改不动、也拿不回控制权。RTA 要解决的正是这个时效性 + 控制权的双重缺口。

2. 破局:去问,而不是去共享

RTA 把这层关系整个反了过来。 与其试图把两份数据集合并,不如让 DSP 在竞价请求发生的那一刻,直接去问广告主:

“我有机会为你的广告,对这个用户出价——要不要出?”

广告主在毫秒级作答,依据是它自己那侧、边界之内的第一方数据,全程不向 DSP 输送任何用户信息。DSP 永远看不到广告主的画像或打分逻辑,广告主也永远看不到 DSP 底层的人群构成。回流的,只有一个决策。

这一”问答”换来了人群上传给不了的三个性质:

一句话:RTA 的精髓是把”共享数据”换成了”共享一个决策”。数据留在产生它的一侧,只有那侧算出来的结论跨过边界——这既是它的隐私优势,也是它整个工程约束(下面几节)的来源。

3. RTA 在竞价生命周期里的位置

RTA 不属于 OpenRTB 规范。它是一道跑在 DSP 内部、在 DSP 落定出价响应之前的竞价前过滤器。把它放进端到端的竞价时序里,位置一目了然:

RTA 在竞价生命周期里的位置时序图:五个参与者(用户·媒体、SSP、DSP、广告主 RTA 服务、拍卖·渲染)上下镜像色块与虚线生命线;步骤为曝光请求 → OpenRTB bid request → DSP 过 RTA 前置过滤旁注 → 询问该不该出价(不透明 user_id,不含 PII)→ RTA 查第一方状态旁注 → 返回 should_bid 加可选档位 → DSP 出/不出决策旁注 → bid response → 拍卖渲染;底部琥珀色注解强调 RTA 是双边 opt-in 契约、去问而非共享 RTA 是嵌在 DSP 内部的一道前置闸门:出价打分之前先问一句广告主,答”不出”就连响应都不发。它不改协议,只在竞价链路上加了一次亚毫秒级的问答。

一步步拆开:

  1. 曝光事件:用户打开一个 App 或网页,媒体的 SDK / 广告标签向它的 SSP 发出一个具备曝光资格的请求。
  2. OpenRTB 扇出:SSP 打包一个 OpenRTB 竞价请求,扇出给它对接的各个 DSP。
  3. RTA 前置过滤(在 DSP 内部):在出价打分之前,请求先打到 RTA 过滤层——DSP 取出用户标识(GAID、IDFA、哈希邮箱、设备指纹等),去问广告主的 RTA 端点:“这个用户、这条广告,我该不该出价?“广告主基于自己的第一方状态作答。
  4. 丢弃或打分:若答案是”不出”(或没及时拿到答案、且兜底解析为”不出”),DSP 直接退出——不发出价响应;若是”出”(可带档位提示),DSP 走它正常的打分与定价逻辑,必要时按档位调整出价,再向 SSP 发出价响应。
  5. 拍卖与渲染:SSP 跑它的拍卖,竞胜 DSP 的素材在媒体版面上渲染。

RTA 契约是双边、opt-in 的:每个想用 RTA 的广告主都要单独对接 DSP 的 RTA 平台,各有自己的 schema、延迟预算、兜底策略与缓存配置。它不是一个”全网开关”,而是一条条一对一拉起来的私有通道。

4. 解剖一个 RTA 请求

大多数生产级 RTA 实现长得都差不多——小载荷、确定性响应。具体 schema 因 DSP 而异,但关键字段是一致的。一对有代表性的请求 / 响应长这样:

// DSP → 广告主
POST /rta/v1/bid-eligibility HTTP/1.1
Content-Type: application/json

{
  "request_id": "abc-7f3e9a",
  "user_id": "GAID:8f4e2c1a...",
  "campaign_id": "summer_promo_2026",
  "ad_slot": {
    "media_type": "video",
    "placement": "feed",
    "size": "1080x1920"
  },
  "context": {
    "app_id": "com.example.shopping",
    "geo": "SG",
    "device_os": "Android"
  },
  "timestamp_ms": 1747400000123
}
// 广告主 → DSP
{
  "request_id": "abc-7f3e9a",
  "should_bid": true,
  "tier": "high_value",
  "bid_multiplier": 1.5,
  "ttl_seconds": 3600,
  "reason_code": "RECENT_CART_ABANDON"
}

值得注意的是请求里没有什么:没有用户属性、没有人群 ID、没有行为历史。DSP 只给广告主一个不透明的用户标识和一个竞价上下文,问一个问题。广告主做它需要的查询——通常是对逐用户状态的一次亚毫秒级 KV 命中——然后作答。

响应里那几个可选字段,正是 RTA 从”硬开关”升级成”软信号”的关键:

关键直觉:请求方向是”DSP 问、广告主答”,但信息只单向减少不单向增加——DSP 给出的是它本就有的标识与上下文,广告主给回的是一个结论。整条链路上没有任何一比特的用户画像跨过边界,这正是 §2 那句”共享决策而非共享数据”在协议层的样子。

5. RTA 到底能做什么

5.1 智能出价:硬过滤 + 软打分

RTA 给广告主两个截然不同、却常常合用的杠杆:

两种情况下的经济学论证是同一个:别再为永远不会转化的曝光花钱,把预算集中到会转化的曝光上。 bidder 这侧也一并受益——不再把竞胜浪费在注定无果的曝光上,“竞胜 → 转化”的比率全面改善。

5.2 个性化素材:广告层真正的 1:1

把 RTA 和 DPA(Dynamic Product Ads,动态商品广告)结合,就得到了商品级的个性化。DSP 同时查询广告主的商品目录和 RTA 端点,再为每个用户渲染不同的素材——由真实的行为信号驱动:近期看过的商品、被遗弃的购物车、相似品的亲和度。

RTA + DPA 架构图:左侧蓝色虚线框「广告主(边界之内 · 第一方)」含商品目录 API 与逐用户 opt-in 信号(RTA 接口,不外泄 PII);两者箭头指向中间琥珀色虚线框「DSP」内的推荐 / 选品系统,再向下到动态素材合成(同 100ms 出价预算内);最后绿色箭头指向右侧「App 内渲染千人千面的 DPA 素材」。底部琥珀色注解说明目录与 RTA 各司其职、PII 不过界,超时按兜底接管 商品目录 + 逐用户信号 → DSP 推荐选品 → 动态素材合成 → 端上渲染。广告主只交出”该给这个人看什么”的信号,具体画像仍留在自己边界内。

这里的转化提升可以相当可观,但工程代价不小:你现在是在和一次普通出价同样的、低于 100ms 的预算之下,做逐请求的素材合成。

6. 工程落地:把 RTA 做到生产可用

RTA 纸上看着简单,到了生产里,它变成一连串延迟预算的取舍,每一个都有可量化的收入后果。这一节的三张旋钮——延迟预算、兜底策略、缓存分级——可以先用一张图串起来:

RTA 延迟预算与兜底决策三层面板:① 蓝色「先查缓存」——竞价请求进入 RTA 过滤层 → 缓存命中则约 5ms 用缓存,未命中则实时调 RTA(软超时 ≤50ms);② 琥珀色「硬超时内有答复?」——是则用实时 should_bid 加档位,否则走兜底分出 default-allow(怕丢量 → true)与 default-deny(怕白花钱 → false);③ 绿色「最终闸门 should_bid」——true 进打分定价,false 则 DSP 直接退出。底部琥珀色注解强调缓存命中率与 TTL、两种兜底的取舍 一次竞价请求进 RTA 过滤层后的全部分支:先查缓存(~5ms),未命中才实时调用(软超时 50ms / 硬超时 100ms),超时落兜底,最后统一汇到”出还是不出”。

6.1 延迟预算

DSP 侧一份典型的 RTA 契约会把时间切成几档:

阶段预算行为
缓存命中~5 ms返回缓存决策,整段跳过实时 RTA 调用
实时 RTA 调用(软超时)≤ 50 ms常态下广告主的 RTA 服务必须在这里作答
硬超时100 ms再晚一律丢弃,兜底策略接管

如果 RTA 服务在硬超时内答不上来,响应就被丢掉——越过那条边界之后发生的一切,都不属于这次拍卖。

这把广告主的 RTA 服务直接放进了和 bidder 本身同一个延迟等级。RTA 的峰值 QPS ≈ DSP 对该广告主各广告的峰值竞价请求 QPS——对一个认真投放的广告主,轻松就是几十万 QPS,上面还叠着日内波动与事件驱动的尖峰。

一句话:从第一天起就把 RTA 端点当作 tier-zero 服务对待——它的可用性和尾延迟,直接等价于实时的花费与丢量。

6.2 兜底策略:default-allow vs default-deny

当 RTA 服务超时或报错,DSP 套用一个事先约定的兜底。业内对同样的两个选择有好几种叫法:

模式RTA 失败时的行为适合谁
YES 模式(default-allow / fail-open)把缺失的答案当作 should_bid: true最怕丢量的广告主
NO 模式(default-deny / fail-closed)把缺失的答案当作 should_bid: false最怕白花钱的广告主

这个选择不是理论问题。它直接决定了你的 RTA 服务在 p99 上需要多宽容——以及你这侧 1% 的错误率,究竟是个小毛刺,还是一处大的花费泄漏。

在广告与隐私系统里,fail-closed 通常是更安全的默认:宁可少投一点,也不要在系统抖动时对本该屏蔽的人群放量。这与冷启动里”信号缺失时该保守还是激进”是同一类取舍。

6.3 缓存策略

对那些在短窗口内产生大量竞价请求的用户(重度移动 App 用户是最典型的一类),每个请求都跑一次全新的 RTA 调用,会同时浪费两侧的容量。DSP 通常支持分级缓存

TTL用例
不缓存(实时)时效敏感的决策——“这个用户刚弃购,接下来 30 分钟激进出价”
1 小时最常见的默认——在新鲜度和成本之间平衡
24 小时稳定的人群级决策——“这个用户今天已经转化了,当天别再出价”

广告主按广告或按信号挑 TTL,响应本身也可带一个 ttl_seconds 提示,动态驱动缓存寿命。这一分级配错,是 RTA 部署悄悄跑不出效果的最常见方式——典型表现是:给几小时前就已转化的用户,继续命中那条过期的”yes”缓存决策,一路超花。

算一笔账:缓存命中率如何决定你的容量与成本

缓存不是”锦上添花”,它直接定了 RTA 服务的容量需求和这次部署的单位经济。设某广告主峰值 200k QPS 的竞价请求打到 RTA 过滤层,每次实时 RTA 调用的全成本(计算 + 下游特征查询)约 $0.02 / 千次

缓存命中率实时调用 QPS需要扛的实时容量实时调用日成本
0%(不缓存)200k200k~$345k
50%100k100k~$173k
90%(1h TTL 常见档)20k20k~$35k
99%(24h TTL 稳定人群)2k2k~$3.5k

从 90% 提到 99% 命中率,把实时容量需求砍掉 10 倍——这就是为什么”缓存分级”是 RTA 的第一性设计,而不是事后优化。

但命中率不能无脑往上推:TTL 越长,决策越陈旧、错误出价越多。把两侧成本放进同一个式子,最优 TTL 就是让”省下的调用成本”与”陈旧决策的花费泄漏”边际相等的那一点:

TTL=argminT[CcallQ1+λTcall cost+Cstalepflip(T)Qstale leak]\text{TTL}^{*} = \arg\min_{T}\Big[\underbrace{C_{\text{call}}\cdot \frac{Q}{1+\lambda T}}_{\text{call cost}} + \underbrace{C_{\text{stale}}\cdot p_{\text{flip}}(T)\cdot Q}_{\text{stale leak}}\Big]

最优 TTL 成本权衡示意:横轴为 TTL,蓝色实线调用成本随 T 下降,红色实线陈旧泄漏随 T 上升,紫色虚线为总成本,其最低点标出 TTL*;右侧图例对应三条曲线。底部琥珀色注解点明铁律:状态翻转越快,TTL 必须越短 调用成本随 TTL 下降,陈旧泄漏随 TTL 上升;最优 TTL 就在总成本曲线的最低点——实务上不必真去解方程,但方向铁定:翻转越快的信号,TTL 越短。

其中 pflip(T)p_{\text{flip}}(T) 是”用户状态在 TTL 窗口内翻转”(如已转化、已流失)的概率,随 TT 单调上升。实务上没人去解析地解它——但这个式子点明了那条铁律:状态变得越快的信号,TTL 必须越短。“刚弃购”这类分钟级翻转的信号就该走不缓存;“今天已转化”这类按天稳定的信号才配 24h TTL。把高翻转信号配上长 TTL,正是上一段那条”过期 yes 缓存”花费泄漏的数学根源。

6.4 多租户隔离

一套生产级 RTA 部署,很少是”每个广告主一个端点”。不同产品线、广告、业务单元通常在隔离的子账户上跑各自独立的 RTA 策略,每个都有自己的:

DSP 侧的路由必须足够细粒度,好让一个产品团队的糟糕发布不会毒到另一个团队的流量。这通常把广告主这侧推向一个更像内部 RTA 平台而非单一服务的东西:路由层、逐租户限流、冷热策略之间的隔离,以及一个让产品团队自助配置的控制面。

6.5 可观测性与失效模式

生产里至少要盯的指标:

几个值得在它们发生之前就知道的常见失效模式:

7. 什么场景下 RTA 最发光:垂直行业用例

只要广告主握着 DSP 根本拿不到的状态,这个模式就发光:

这些场景的共同形状是:广告主维护着一台逐用户的状态机(匿名 → 试用 → 付费 → 流失 → 召回),DSP 对它零可见,而它几乎决定了此刻”正确的营销动作”的一切。RTA 做的,就是让这台状态机在不暴露自身的前提下,实时驱动 DSP 的每一次出价。

8. 上线 RTA 前的前提清单

RTA 不是一个一拨就开的开关。动手之前,至少要备齐这几样:

9. 走向何处:以第一方数据为默认的程序化栈

宏观图景很清楚:第三方 cookie 正在死去,IDFA 覆盖在 ATT 后早已坍塌,隐私监管(GDPR、CPRA 及跟在后面的一波)持续收紧。那个粗粒度、靠”信任平台”的程序化定向时代,正在关上门。

接下来的,是一个以第一方数据为默认搭建起来的程序化栈——而 RTA 是我们手上最干净的工程模式:让那份数据在永不跨越边界的前提下,去影响平台侧的出价。广告主留住决策逻辑,DSP 留住曝光,用户的数据待在它该待的地方。

不是每个广告主明天就需要 RTA。但每个程序化工程师都该理解这个模式——因为接下来十年的 AdTech,会建在它的各种变体之上。

10. 常见误解 ↔ 正解

这一节专治 RTA 最容易被想歪的地方——也是面试和对接时最常翻车的点:

常见误解正解
RTA 是 OpenRTB 的一部分不是。它是 DSP ↔ 广告主的私有契约,跑在 OpenRTB 出价响应落定之前
RTA 要把用户数据发给 DSP恰恰相反:请求里不含 PII,广告主只回一个决策——“共享决策而非共享数据”
RTA 只能”出 / 不出”还能带 tier / bid_multiplier,从硬过滤升级成软打分、做差异化出价
只要缓存命中率越高越好命中率高省成本,但 TTL 越长决策越陈旧;高翻转信号配长 TTL 会持续超花
fail-open 更安全广告与隐私系统里 fail-closed 通常更安全——宁可少投,别在抖动时对屏蔽人群放量
RTA 服务是个后台旁路,挂了没关系它是 tier-zero:峰值 QPS ≈ 竞价峰值 QPS,降级每一秒都在实时超花或丢量
上了 RTA 就能省钱部署与运维要花真钱,只有在媒体花费足够大时才回本,小预算不值得
一套 RTA 端点服务所有广告生产里是多租户平台:逐子账户的定向 / TTL / 兜底 / 限流都要隔离

11. 速查表

把全篇压成随手可查的几条:


延伸阅读

先看同系列里和本篇相邻的几篇:

再是一手资料:

附录:术语表


views
Share this post on:

Previous Post
广告出海地区分层:T1 / T2 / T3 市场分析与打法
Next Post
供应链透明度(下):OpenRTB schain 用运行时逐跳记录做供应链核验