**摘要:**传统广告系统围绕一次搜索、一次浏览或一次点击工作,但对话式产品里的商业意图会在多轮交流中逐渐形成。OpenAI 为 ChatGPT 重新设计了一套广告技术栈:用有状态广告会话持续理解目标,用独立服务保证广告不影响自然回答,再让经过后训练的 LLM 以工具调用方式编排语义召回、资格过滤、质量评分、拍卖和最终交付。本文基于 OpenAI 官方工程文章与广告政策,拆解这套架构为什么成立、每个阶段如何落地,以及普通团队可以复用哪些工程原则。
一、为什么对话广告不能照搬搜索广告
搜索广告天然拥有一个明确事件:用户提交查询,系统立刻获得关键词和展示机会。对话产品却更像一段逐步收敛的需求分析。用户可能先问旅行路线,随后讨论天气,最后才提到鞋、酒店或租车。最初的消息并不等于最终意图,较早出现的商品词也可能只是举例。
如果把每条消息都当成独立广告请求,会同时产生四个问题:过早判断意图、重复运行昂贵链路、把已经失效的上下文当成当前目标,以及在不合适的时机打断用户。ChatGPT 的解法不是让模型"猜一个关键词",而是把广告决策建模为一个随对话更新的有状态过程。
| 维度 | 传统搜索/信息流广告 | 对话式广告 |
|---|---|---|
| 意图单位 | 查询、页面或事件 | 多轮目标与约束的演进 |
| 请求状态 | 通常可无状态处理 | 需要记忆当前广告会话 |
| 召回输入 | 关键词、页面标签、用户画像 | 对话摘要、语义查询、当前轮约束 |
| 成功结果 | 通常需要返回候选 | "不展示广告"也是正常成功 |
| 时延边界 | 由广告位请求决定 | 不能拖慢自然回答,晚到即放弃 |
二、总体架构:回答链路与广告链路并行、隔离
整套系统最重要的设计,不是用了哪个向量库或排序模型,而是边界。自然回答由 ChatGPT 核心服务生成;广告服务消费一份受控的对话上下文,在独立模型、独立代码和独立服务中判断是否存在合适机会。两条链路并行运行,广告系统慢、超时或不可用时,自然回答仍然继续。
用户消息
├─> ChatGPT 回答链路 ───────────────> 自然回答
│
└─> 广告资格检查 ─> 广告会话 ─> LLM 编排器
├─> 语义查询生成
├─> ANN 候选召回
├─> 资格与安全过滤
├─> 相关性/质量评分
└─> 拍卖与最终复核
│
在回答完成前到达?
├─ 是:前端标记并展示
└─ 否:丢弃,不阻塞回答
这个隔离同时解决可靠性和信任问题。广告不参与回答生成,因此不能改变回答的中立立场;自然回答也不依赖广告系统,因此广告服务不会成为 ChatGPT 可用性的单点风险。对于任何"推荐、赞助、增值"并存的产品,这都是比单纯调高排序准确率更优先的架构约束。
三、有状态广告会话:把意图当作动态对象
广告会话并不是把全部历史原样堆进提示词,而是维护当前目标、硬约束、待确认条件、过期意图和已尝试结果。每个新回合到来后,系统判断哪些信息需要保留、哪些需要替换、是否值得重新召回。
json
{
"goal": "为两天徒步旅行挑选装备",
"active_constraints": ["低温", "轻量", "防水"],
"stale_context": ["最初讨论的城市观光"],
"commercial_intent": "exploring",
"last_retrieval": {
"queries": ["轻量防水徒步鞋", "寒冷天气徒步装备"],
"candidate_count": 42,
"refresh_after_turn": true
}
}
上面只是可复用的工程化示例,并非 OpenAI 内部字段。关键在于:状态必须能解释"为什么本轮重跑",还要能防止旧目标污染新目标。一个稳健实现通常会同时设置时间、轮次和语义变化阈值,只有意图显著变化时才重新运行完整链路。
四、LLM 编排器:不直接选广告,只决定调用哪些工具
OpenAI 将一个经过后训练的 LLM 作为 orchestrator。它不是直接从所有广告中凭语言感觉选出赢家,而是在受约束的工具循环中工作:生成商业意图查询、发起召回、请求过滤、调用相关性与质量评分,再把合格候选提交给拍卖工具。
这种设计保留了两类系统各自的长处。LLM 擅长理解指代、省略、假设和多轮目标变化;传统广告基础设施擅长预算、节奏控制、合规、去重、计价和可审计执行。把所有逻辑塞进一个提示词,会让金额计算、预算扣减和政策判断都变得难以复现。
python
def run_ads_turn(session, message, deadline):
state = update_intent_state(session, message)
if not placement_is_eligible(state):
return NoAd("turn_ineligible")
queries = orchestrator.create_retrieval_queries(state)
candidates = retrieve_ann(queries)
candidates = hydrate_and_filter(candidates, state)
candidates = score_relevance_quality(candidates, state)
nominees = orchestrator.nominate(candidates, state)
winner = auction(nominees)
winner = final_context_check(winner, state)
if winner is None or now() > deadline:
return NoAd("no_fit_or_late")
return deliver(winner)
这段伪代码刻意把拍卖留在确定性工具里:模型可以提名,但不能自行决定价格。工程上还应为每个工具设置结构化输入、最大候选数、调用次数、超时和失败回退,避免编排器无限探索。
五、召回:一个会话可以生成多条语义查询
对话往往包含多个同时成立的需求。把整段历史压缩成单个向量,容易让不同目标相互稀释。官方文章举出的思路是让编排器产生一条或多条查询,再转为语义嵌入,送入不同的近似最近邻索引。
例如一次旅行规划可能同时存在交通、住宿和活动需求。多查询召回可以保留这些分支,并让不同索引按自己的约束优化:商品广告索引可以考虑评价信息,本地服务索引可以更重视地理位置,而数字产品索引可能更关注兼容性和订阅周期。
ANN 的目标不是一次找到唯一正确答案,而是在很短时间内获得一个高召回候选池。随后才由资格过滤和质量评分收窄范围。这个"先宽后严"的漏斗,比让大模型扫描完整广告库更便宜、更稳定,也更容易水平扩展。
六、过滤与评分:相关不等于可以展示
召回只证明"语义上可能相关",不代表候选具备展示资格。候选通常还要通过素材与活动状态、地区定向、政策、预算、投放节奏、版位兼容、广告主去重等检查。任何一个条件失败,都应在进入拍卖前被移除。
| 阶段 | 核心问题 | 建议输出 |
|---|---|---|
| 召回 | 哪些广告可能相关? | 候选 ID、召回来源、相似度 |
| 资格过滤 | 现在能否参与竞争? | 通过/拒绝及原因码 |
| 相关性与质量 | 是否真正帮助当前目标? | 多维分数与置信度 |
| 拍卖 | 价值、质量、预算如何平衡? | 赢家、价格、排名证据 |
| 最终复核 | 放在此刻是否合适且及时? | 展示、拦截或超时 |
相关性阶段可结合语义匹配、预测互动、历史表现和安全模型,但不要把这些分数直接混成一个无法解释的黑盒。保留每个阶段的独立指标,才能区分"没召回到""预算不足""质量太低"和"系统太慢"。
七、拍卖:让模型提名,让规则决定计价
编排器在理解对话后提名可能有价值的候选,最终拍卖仍负责准入阈值、预算节奏、出价特征、质量校正排序、价格和赢家选择。这一职责划分很重要:语言理解可以是概率性的,涉及资金和账务的执行必须可重放、可核对、可审计。
"用户价值优先"不能只是一句产品口号,应转成可执行门槛。例如先设置相关性、安全和体验下限,再允许合格候选按质量校正后的商业价值竞争。这样高出价也无法越过最基本的用户价值要求。
八、交付:服务端选中不等于用户看见
对话广告还有一个传统报表很容易混淆的边界:拍卖选出赢家,只代表服务端完成选择;只有广告在自然回答结束前及时到达、通过最终复核并被前端确认渲染,才能计为真正展示。
OpenAI 的架构把广告放在回答下方,并返回独立的广告素材与模型生成的中性引导语。若广告来晚了,本轮直接不展示,不让回答等待。这意味着系统要分别记录 winner、delivery、render acknowledgement 和 impression,不能用"拍卖成功"代替"用户实际看见"。
selected --> delivered --> frontend_accepted --> rendered --> impression
| | |
| | └─ 页面状态变化或用户离开
| └─ 超过回答完成的截止时间
└─ 最终语境复核不通过
任何分支失败都记录原因码,但不阻塞自然回答。
九、可观测性:先回答"漏斗在哪一层掉了"
一套可运营的广告系统不能只统计点击率。官方文章强调细粒度日志,例如:本轮不具备广告资格、创建了广告会话但没有触发召回、召回为空、候选在补全或资格检查中失败、已交付后发生互动等。
推荐用统一 trace_id 串联完整链路,并保留受控的阶段事件:
- **机会层:**eligible_turn_rate、session_start_rate、no_ad_success_rate。
- **召回层:**query_count、candidate_count、index_latency、recall_source。
- **过滤层:**policy_reject、budget_reject、pacing_reject、dedupe_reject。
- **质量层:**relevance_distribution、quality_threshold_pass_rate。
- **交付层:**auction_win、delivery_latency、late_drop、frontend_ack、impression。
- **反馈层:**click、conversion、hide、report、survey 与负反馈率。
日志应优先记录枚举化原因和统计特征,避免把原始敏感对话复制到每个下游系统。数据保留、访问控制和用于训练的处理范围,需要与隐私政策和用户设置保持一致。
十、自我改进闭环:强模型评估,小模型在线执行
OpenAI 描述了一条分层反馈路线:高能力模型评估广告交付质量,为更小、更快的编排或召回模型提供训练信号;同时结合点击、隐藏、调查和广告主反馈持续调整系统。强模型不一定承担每次在线请求,但可以作为离线教师和质量审查者。
落地时应把反馈按阶段归因。隐藏广告可能意味着时机不对、素材不好或语义误判;点击低也可能来自前端未正确展示。只有结合召回、过滤、拍卖和渲染日志,才能避免把错误信号训练回模型。
十一、安全与隐私:必须在架构里,而不是上线前补丁
OpenAI 的公开原则包括回答独立、对话隐私、用户选择与控制,以及优先长期信任。广告政策还明确限制敏感或高风险语境。对工程团队而言,这些原则应落成独立服务、资格闸门、政策模型、可解释原因码、个性化开关和数据删除流程。
- 广告主只能获得汇总、非识别性效果信息,不应访问用户聊天、历史、记忆或个人细节。
- 关闭个性化后,只能依据当前对话允许使用的上下文工作。
- 安全、脆弱或高风险场景要在召回前做机会拦截,并在交付前再次复核。
- 广告必须清晰标记,与自然回答在视觉和数据链路上分离。
- 预算扣减、计费和展示确认都需要幂等键,防止重试导致重复计费。
十二、普通团队如何复用这套方法
这套架构并不只适用于广告。电商推荐、企业知识推荐、客服增值服务、对话式表单和 Agent 工具选择,都面临"意图跨多轮变化、推荐不能污染主回答、晚到结果不应阻塞用户"的共同问题。
- **先切断依赖:**把主回答与推荐链路做成并行服务,定义明确超时。
- **再建状态:**维护当前目标和约束,不要每轮重放全部历史。
- **模型只做理解与编排:**预算、权限、政策和计价放在确定性工具中。
- **召回先宽后严:**用多查询和多索引保证覆盖,再逐层过滤。
- **允许 No Result:**没有高质量候选时,空结果就是正确结果。
- **以阶段事件观测:**能够精确回答每个候选在哪一步退出。
- **建立双层反馈:**在线轻量模型负责速度,离线强模型与人工反馈负责方向。
十三、结语
ChatGPT 广告技术栈真正值得学习的,不是"用 LLM 做广告"这句概括,而是它把概率性的意图理解嵌入了一个边界清晰的工程系统:会话状态承载多轮目标,LLM 负责编排,ANN 负责高速召回,规则系统守住资格与资金,拍卖完成确定性选择,前端以超时和确认定义真实展示,细粒度日志再驱动下一轮改进。
对话式产品越智能,就越不能让一个模型包办所有决策。把模型放在它擅长的位置,把信任、可靠性和可审计性固化在架构中,才是这套系统最有价值的经验。
参考资料
- OpenAI Engineering:How we built ChatGPT's novel ad stack for user trust and relevance
- OpenAI:Our approach to advertising and expanding access to ChatGPT
- OpenAI Help Center:Ads in ChatGPT
- OpenAI:Ad policies
说明:文中的架构解读和伪代码用于工程教学,基于公开资料抽象整理,不代表 OpenAI 未公开的内部实现。