Skip to content
Charles Shao
Go back

媒体 Ad Server 深挖:它如何拍板每一次曝光

Updated:
views

程序化广告生态全景交易模式Header Bidding 三篇里,媒体 Ad Server 反复作为”那个做最终决策的角色”出现,却一直没被单独讲透。这篇补上——它是卖方侧真正”拍板这次曝光归谁”的调度总控,也是 Google Ad Manager(GAM)/ decisioning 这类岗位的高频考点。

我们从它的本质(分配,不是竞价)讲起,拆开 line item 与优先级一次曝光的决策流水线dynamic allocation 与统一竞价Header Bidding 怎么落进来,再划清它和广告主 Ad Server、SSP/ADX 的边界,最后看它作为一个高 QPS 决策系统的工程内核。

TL;DR

Table of contents

Open Table of contents

1. 定位:卖方侧的”调度总控”

媒体 Ad Server(publisher ad server,典型是 Google Ad Manager / GAM,前身 DoubleClick for Publishers / DFP)是媒体一侧的广告调度总控。 一家媒体的同一个广告位,有好几种卖法在抢同一次曝光:

媒体 Ad Server 的活儿,就是当一次广告请求进来时,在这些来源之间排出优先级、挑出”既满足合约、收益又最高”的那一个。这个动作叫 ad decisioning(决策 / 分配)

理解它的钥匙:媒体 Ad Server 解决的是”分配(allocation)“问题,不是”竞价(auction)“问题。 它决定”这个广告位走直采还是走程序化”;一旦决定走程序化,真正的”卖”(实时竞价撮合)才交给 SSP / ADX。把这两件事分开,是看懂整章的前提。

打个比方:它像电视台的排播总控——手里有黄金时段(保量给签约品牌)和零碎时段(临时来竞价的客户),要在每个时间点决定”这一秒播谁的广告最划算、又不违约”。只不过媒体 Ad Server 每秒要做成千上万次这样的决定。

什么算”一次广告请求”

它由真实用户的行为触发,而非定时任务。下面这张图把它从”用户行为触发”走到”到达 Ad Server 决策”,并标出 Header Bidding 何时介入:

一次广告请求是怎么产生并到达媒体 Ad Server 的流程图。① 用户行为触发(不是定时任务,平铺四种):打开/刷新页面、刷到信息流卡片、视频播到插播点、广告位进入视口;② Header Bidding 先跑(页面/App 加载时):客户端 Prebid.js 或服务端 Prebid Server → 并行向多个 SSP/bidder 询价 → 选出最高价 hb_pb=6.20、hb_bidder=sspB;③ 页面广告标签(GPT)或 App 广告 SDK 发出一个 HTTP 请求;④ 请求携带决策上下文:谁(用户标识/地理/设备)、哪儿(ad unit/尺寸/页面·版位)、候选价(hb_pb,由第②步的 Header Bidding 捎上);⑤ 请求到达媒体 Ad Server,成为一个『已带候选价』的曝光机会;⑥ Ad Server 做 decisioning,拍板这一次曝光给谁。旁注:每个请求是决策的最小单位、各自独立——同一广告位,用户 A 这次可能给保量直采,一秒后用户 B 那次可能给竞价,结果可以不同 一次广告请求 = 一个真实用户在某一刻触发了某个广告位;此前 Header Bidding 已在客户端 / 服务端先跑完,把胜价(hb_pb)连同上下文打包进这个 HTTP 请求,送到 Ad Server 等它拍板。所以它是决策的最小单位:同位的两次请求各自独立、结果可不同。

“② HB 先跑”跑的是哪些位?取决于广告位的加载策略,不是非此即彼:

加载策略何时跑拍卖覆盖范围
首屏批量(最常见)页面加载时,一次 requestBids 同时询价首屏 / 已定义的多个位
懒加载 / 信息流该位接近视口时才跑(图中①的触发)单个或一批将露出的位
自动刷新按时为自己重跑、刷新 hb_pb开了 refresh 的单个位

不管哪种,一场拍卖可覆盖多个位,但 hb_pb 始终按”位”产出(每个广告位决出各自的最高价),再跟着各自那次广告请求去 Ad Server。一句话:广告请求按位(per ad slot)走,HB 既可按位、也可首屏批量地为这些请求预先备好 hb_pb

2. line item:决策的基本单位与优先级

媒体 Ad Server 用 line item(订单行) 表达每一笔需求——一个直采合同是一个 line item,一档 Header Bidding 价格桶也是一个 line item。每个 line item 带一个优先级,Ad Server 大体按优先级从高到低分配。以 GAM 的类型为例:

line item 类型优先级性质谁落在这
Sponsorship(冠名)最高保量、按比例占量旗舰品牌包断、首页冠名
Standard(标准)保量、按目标量投满多数直采 / PG 程序化保量
Network / Bulk不保量广告网络联盟、批量剩余
Price Priority(价格优先)较低纯按价比拼Header Bidding 的 hb_pb + 公开竞价
House(自有)最低兜底媒体自家推广

这里只记相对档位(高 / 中 / 低)即可——GAM 内部确有数字优先级(如 1–16),但具体数值随版本与配置变动,背数字意义不大;真正要钉死的是”保量在上、价格优先在下”这个相对关系。

两个关键认知:

顺带一个工程坑:每一个价格档位(如每 $0.10 一档)都要在 GAM 里建一个对应的 price priority line item。粒度细 → line item 数量爆炸(成百上千),维护与延迟都受影响;粒度粗 → 价格被”向下取整”漏收。hb_pb 的分桶(price granularity)必须和这批 line item 严格对齐。

3. decisioning:一次曝光在 Ad Server 内部怎么被选中

把一次曝光请求进来后的内部处理拆成一条流水线(pipeline)——这正是 decisioning 的核心:

媒体 Ad Server 决策流水线示意图。一次曝光请求进入后:第一步候选筛选,按定向(地域/设备/受众/版位)和排期(flight dates)筛出所有能投的 line item;第二步过滤,应用竞争性排除(competitive exclusion,同行业不同框)、频次控制(frequency cap)、投放节奏(pacing)等约束,淘汰不合规的候选;第三步选胜者,先按 line item 优先级分层(保量在上),同层或价格层内按 eCPM / 出价价高者得,并通过 dynamic allocation 让实时竞价与保量预估 eCPM 同台;第四步选 creative(按尺寸/格式/创意轮播规则);第五步返回并计数(impression/click)。旁注:全流程毫秒级完成,每秒上万次 decisioning 不是”挑价最高的”这么简单——它是一条带定向、合约、排除、频次、节奏多重约束的流水线,最后才轮到”比价”。

逐步拆:

  1. 候选筛选(targeting + 排期):按地域、设备、受众、版位等定向,以及 flight dates(投放档期),筛出所有”有资格投这次曝光”的 line item。
  2. 过滤(约束校验)
    • competitive exclusion(竞争性排除):同一页面 / 同一广告主类目不能同框(如两家车企不相邻);
    • frequency cap(频次控制):同一用户在某时间窗内看某广告不超过 N 次;
    • pacing(投放节奏):保量单要把量均匀投满整个档期,避免一次烧完——这和出价引擎的预算节奏是同一类问题,只是约束反过来(不是”别超支”,而是”必须投够”)。
  3. 选胜者:在通过过滤的候选里,先按 line item 优先级分层(保量在上),再在价格层内 / 通过 dynamic allocation 按 eCPM / 实时出价价高者得(见第 4 节)。
  4. 选 creative:胜出 line item 可能挂了多个素材,按尺寸 / 格式匹配、creative rotation(轮播)规则选一个。
  5. 返回 + 计数:把 creative(或其 ad markup)返回客户端,并记录 impression / click 等。

这条流水线每秒要跑成千上万次,且必须在毫秒级返回——这是它工程难度的来源(第 8 节)。

4. dynamic allocation 与统一竞价:竞价价怎么和直采同台

纯按”优先级层级”分配有个老问题:一个愿出 $20 的 price-priority 竞价,会输给一个只值 $8 的低价保量单——媒体把钱漏了

GAM 早期用 dynamic allocation(动态分配) 缓解:让 AdX 用实时出价去和保量单的预估 eCPM 比,价高就能”插队”,赢走本来要给保量的曝光(同时保证保量单仍能按节奏投满)。这让”价格”第一次能局部地凌驾于”优先级”。

和上一节的流水线图分工不同:§3 的流水线图回答”一次决策分哪几步走”,下面这张”两个世界”图回答的是另一个问题——胜者最终从哪两层里产生、以及价格怎么跨层比。 上层是按优先级的保量世界,下层是按价高者得的竞价世界:

媒体 Ad Server 决策的两个世界示意图。上层是按优先级的保量世界(直采):先 Sponsorship 冠名(保量、最高优先),未满足则下沉到 Standard 标准(保量/PG、高优先)。若上层已投满或不匹配定向,则下沉到下层按价高者得的竞价世界(统一竞价):Header Bidding 传入的 hb_pb(price priority line item)与 AdX / Open Bidding 的实时出价在此同台比价、价高者得;若都没有则兜底 House 自有广告;胜者返回 creative。旁注:保量按优先级在上层享有结构性优先,价格层内部纯价高者得;现代统一竞价(unified pricing rules)尽量把两层放到同一把价格尺子上比,减少'高价竞价输给低价保量'的漏损 上层是”按合约优先级”的保量世界,下层是”按价高者得”的竞价世界;Header Bidding 的价和 AdX 一起活在下层。

但 dynamic allocation 有个偏心——历史上只有 Google 自家 AdX 能这样实时插队,而且跑在最后一棒,能看着其他需求报出的价再决定自己出多少。这正是 last look 的温床,也是 Header Bidding 出现的核心动机之一:把别的需求也搬到能和直采、AdX 公平竞争的位置。

行业(含 GAM 2019 年的改造)的方向是 unified pricing rules / 统一竞价:把 AdX、Open Bidding、price-priority line item(含 Header Bidding)尽量放进同一把价格尺子上比,保量单仍按优先级在上层享有结构性优先,但价格层内部做到透明、价高者得、赢家付自己的价(一价)。

一个算例:同一次曝光,三种机制三种结局

设这次曝光有三个候选——一张已开但还没投满的 Standard 保量单(预估 eCPM $8、优先级高)、一笔 Header Bidding 竞价hb_pb = $20)、一笔 AdX 实时出价(真实价值 $22)。同一次机会,机制不同,结局和媒体到手的钱差很多:

机制谁赢这次曝光媒体到手 eCPM问题
纯优先级瀑布保量单(优先级高,直接吃掉)~$8$20 / $22 的高价需求被白白挡在门外
dynamic allocation + AdX last lookAdX(看到 HB 的 $20,报 $20.01)~$20.01AdX 靠”最后一眼”压价捡漏,HB 真实需求落败
统一竞价(HB / AdX 同台、无 last look)AdX($22 公平胜出)~$22媒体拿到真实最高价,保量单顺延到别的曝光投

读这张表的三个要点:

顺带一提:二价 → 一价的整体迁移

2019 年前后,AdX / GAM 把拍卖从二价整体切到一价(first-price)。动因有二:一是 Header Bidding 普遍用一价,二价和一价混在一场里没法公平比;二是一价削弱了 last look 的获利空间——你看不到别人的价、也没法”刚好高一点”。代价是把复杂度推回买方:DSP 得自己做 bid shading(出价压扁),在”出太高怕赢家诅咒、出太低怕拿不到”之间估一个最优落点。换句话说,媒体侧拍卖规则一变,买方的竞价引擎就得跟着改算法——这也是为什么这套机制值得卖方工程师也懂买方那一端。

5. Header Bidding 怎么落进来

Header Bidding 那篇的下半段接上:Header Bidding(无论客户端 Prebid.js 还是服务端 Prebid Server)跑完,得到一个最高价,它不直接投广告,而是把结果编码成一组 targeting key:

hb_pb     = 6.20      # 价格分桶
hb_bidder = sspB      # 中标 bidder
hb_adid   = a1b2c3    # 对应 creative

GPT 携带这些 key-value 调用 GAM;GAM 用 hb_pb匹配预先建好的 price priority line item(每个价格档一个),从而让 Header Bidding 的价以”价格优先”line item 的身份,进入第 3、4 节的决策流水线,和直采、AdX 同台。

这解释了 Header Bidding 的设计哲学:不绕开媒体 Ad Server,而是把自己”翻译”成它听得懂的语言(line item + key-value),复用它的 decisioning。代价就是第 2 节那个”line item 爆炸”的运维负担,以及 hb_pb 分桶必须和 line item 严格对齐。

6. 别和广告主 Ad Server 混(最常见的坑)

“Ad Server”这个词有两个,同名不同命,是新人最大的混淆点:

媒体 Ad Server广告主 Ad Server
服务谁媒体 / Publisher广告主
核心职责库存排期、流量分配、decisioning集中存素材、跨渠道下发 creative、统一计数与归因
解决的问题”这个广告位给谁""我的广告被看了多少次、带来多少转化”
代表产品Google Ad Manager(GAM)Campaign Manager 360(CM360)

一句话:媒体 Ad Server 管”我的库存怎么分配”,广告主 Ad Server 管”我的广告效果怎么记账”。 本篇讲的始终是前者。

7. 边界:Ad Server vs SSP/ADX vs 竞价引擎

三者最容易糊在一起,用”它回答什么问题”来切:

角色回答的问题一句话
媒体 Ad Server这次曝光给谁(分配)在直采 / 程序化 / 兜底之间排序选一个
SSP / ADX程序化这部分卖多少钱(撮合)向众多 DSP 询价、跑实时拍卖
竞价引擎(DSP 侧)这次曝光值不值得买、出多少(出价)在 ~100ms 内决策买方出价

Ad Server 决定”走不走程序化”,走了之后才轮到 SSP/ADX 去”卖”,而买方的 DSP 竞价引擎在另一端”买”。三者各管一段,别混。

8. 工程视角:它是个高 QPS 决策系统

别被”配置后台”的外表骗了。媒体 Ad Server 在线上是一个每秒做成千上万次决策、ms 级返回的系统,工程上和竞价引擎、Prebid Server 同属”高并发 + 低延迟 + 复杂决策”一类。

先给点量级感:头部媒体 Ad Server 日均处理可达数十亿至数百亿次广告请求;单次 decisioning 的时间预算通常只有几十毫秒——因为它前面排着 Header Bidding 的超时窗、后面还要留时间给素材加载与可见性测量,整条广告链路对用户的总耗时窗口很窄。几个值得拆的点:

一句话给工程师:媒体 Ad Server 把”卖方变现”抽象成了一个’带约束的高 QPS 实时分配’问题——召回(候选)、过滤(约束)、排序(优先级 + 价格)三段式,和推荐 / 搜索排序、竞价引擎在骨架上惊人地一致。

8.1 深挖:库存预测(forecasting)为什么是 Ad Server 最难的离线题

前面讲的 decisioning 是实时的”这次曝光给谁”。但 Ad Server 还背着一道离线的硬题,难度一点不输实时——avails(可用库存)预测:销售要签一笔保量单(“未来 30 天,美国 × iOS × 体育版块,投 1000 万次,CPM $15”)之前,系统必须先回答一个对未来的反事实问题

“在这个定向下,未来 30 天总共会有多少次曝光?其中又有多少还没被已签的保量单占住、真的可卖?”

这题难在三个地方,每一个都不是实时检索能解决的:

  1. 它是 what-if,不是查历史:你要预测的是”如果接下这单,它能不能投满”,依赖对未来流量的投影 + 与现有所有保量单的争抢模拟。
  2. 定向是高维谓词geo × device × OS × 版块 × 受众 × 时段 × 频次,组合爆炸,不可能给每种组合预存一个计数。
  3. 要快到能交互:销售在下单界面上等这个数,几秒内要出——可它背后是一次对海量未来曝光的模拟。

业界的主流解法是基于抽样的预测(sample-based forecasting),本质是一次蒙特卡洛:

1. 蓄水池抽样:把过去 N 天的真实广告请求留一个有代表性的样本(如 1%),
   每条带全部定向维度(geo/device/受众/时段…)。
2. 流量投影:按季节性 / 趋势 / 星期几,把这个历史样本投影成"未来 30 天"
   的预期请求流(乘上增长系数、节假日系数)。
3. 回放 + 扣减:把候选保量单的定向谓词,连同所有【已存在的、优先级更高或同级的】
   保量单,一起在这个投影样本上回放一遍——
   先让已有合约按优先级和 pacing 扣掉它们该拿的量,
   剩下的、且匹配新单定向的,才是"可卖 avails"。
4. 放大回真实量级:样本是 1%,结果 ×100 得到绝对预测值,并给出置信区间。

这套设计解释了几个反直觉的现象:

一句话:实时 decisioning 是”召回 → 过滤 → 排序”的检索题,离线 forecasting 是”抽样 → 投影 → 争抢模拟”的预测题。 同一个 Ad Server,一边在毫秒级拍板单次曝光,一边在用蒙特卡洛回答”这单敢不敢接”——后者错一次,赔的是真金白银的违约金。

9. 工程实战:几个绕不开的坑

一个典型的”钱漏了”事故:某媒体发现一批高价 Header Bidding 竞价始终拿不到量。排查发现,问题不在竞价,而在 Ad Server——有几个优先级设成 Standard 的”保量”line item 其实没真正卖出去(目标量虚高),却按高优先级把曝光截走了,把本该价高者得的 HB 竞价压在了下面。把这些僵尸保量单降级 / 清理后,price priority 层的真实竞价才浮上来,eCPM 立刻回升。在 Ad Server 里,优先级配置错一格,比竞价逻辑错更隐蔽、更费钱。

其余高频坑:

10. 常见误解 ↔ 正解

这一节专治”听起来对、其实差一点”的高频误区——也是面试里最容易露馅的地方:

常见误解正解
媒体 Ad Server 在”竞价”它在分配;竞价是 SSP / ADX 的事
HB 出价最高就一定拿到曝光不一定——保量单按优先级压在 price priority 之上
媒体 Ad Server = 广告主 Ad Server两回事:GAM 管库存分配,CM360 管效果记账
保量单优先级高 = 媒体收益最高未必,纯瀑布会漏掉更高价竞价(见 §4 算例)
last look 让 AdX “抢走”曝光它更多是”压价”——AdX 仍赢,但少付了钱
dynamic allocation 对所有需求公平历史上偏向自家 AdX(跑最后一棒 + last look)
line item 优先级数值要背相对档位即可,数值随版本变
price priority 分桶越细越好太细会 line item 爆炸、拖慢决策

11. 速查表

把它记成一句话:媒体 Ad Server 是卖方侧的”总决策点”——所有卖法(直采、各种程序化、Header Bidding)最终都汇到它这里,由它拍板这次曝光归谁。 理解了它,程序化广告生态全景里卖方那半张图就活了。


延伸阅读

这篇是程序化系列的一块拼图,按”全局 → 交易 → 卖方机制”的顺序串起来读最顺:

再是规范与一手资料:

附录:术语表


views
Share this post on:

Previous Post
程序化策展(Curation / Marketplace 2.0):一个把「数据 + 库存」在卖方侧打包成 deal 的新中间层
Next Post
拍卖机制与 Bid Shading:一次竞价的漏斗、底价、结算,与一价时代为什么要「主动少出一点」