过去聊起“人工智能怎么做广告”,很多人的第一反应是程序化广告投放,也就是那个在后台自动出价的系统。但如果只盯住这一层,很容易把 AI 在广告里的作用想窄了。AI 不仅能帮我们决定“这个广告要不要投给这个人”,还能写文案、自动切尺寸、预测用户流失、优化预算分配,甚至判断某一波素材什么时候该下线。这篇文章想从一个工程开发者的视角,把“人工智能怎么做广告”这个问题拆开,讲清楚 AI 在广告系统中的每一步在解决什么真实问题,以及作为工程师你可以从哪里开始动手实践。
先说一个判断:AI 做广告不是把几个人工智能模型堆在一起,而是一套围绕“投放决策”展开的工程系统。CTR 预估、创意生成、竞价策略、归因分析,每一环都有明确的输入输出,也都有现成工具可以做最小实现。本文会结合三个可直接运行的代码示例,覆盖广告点击率预测、广告创意文案生成、智能出价策略模拟,帮助你快速理解 AI 广告的完整链路和落地节奏。
1. 这篇文章真正要解决的问题
1.1 为什么“人工智能做广告”值得关注
广告行业是数据规模最大、决策延迟要求最高的业务场景之一。一个普通信息流广告系统,每天需要处理的数据量级是数亿到数十亿次曝光请求,每一次曝光都要在几十毫秒内决定“是否竞价”“出多少钱”。这种规模下,纯人工规则完全无法覆盖高维度的用户行为和环境上下文。AI 的价值就在于从海量历史数据中学习用户偏好、内容特征和转化规律,然后把这些规律嵌入到线上决策链路里。
从工程角度看,AI 做广告有两个明显收益:一是把“人工经验”变成“可量化模型”,二是把“统一流量分配”升级成“个性化决策”。过去优化师调整出价主要靠经验曲线,现在模型可以直接预估每次曝光的转化概率,再结合预算约束输出最优出价。这并不意味着优化师会失业,而是优化师的工作从“调整出价”变成了“定义目标、清洗数据、监控模型、处理异常”。
1.2 很多人的误区在哪
我见过不少刚接触 AI 广告的团队,以为只要导入一个推荐模型,点击率就自动上去了。结果模型离线指标很好,在线跑了一个月,成本飙升,转化却下降。问题往往不在模型结构,而在数据流、特征一致性、样本标签和线上服务延迟。
另一个误区是“创意生成”等于“随机写文案”。通过大模型批量生成文案确实可行,但如果不加约束条件,生成结果会偏离品牌调性,甚至出现合规风险。所以 AI 创意生成不是“让模型自由发挥”,而是要设计好 prompt 模板、风格约束、关键词白名单和人工审核流程。
1.3 读者能从这里获得什么
如果你希望进入智能广告或增长算法方向,这篇文章能帮你建立从模型到工程的整体认知。如果你已经在做广告投放相关开发,文中的三个示例可以当作你的第一版最小实践。本文不会展开深入的凸优化理论,也不会贴出一整份工业级系统架构,但会把最关键的步骤讲清楚:数据怎么准备,模型怎么训练,预测结果怎么用,以及线上部署会踩哪些坑。
2. AI 广告系统的核心链路与架构
2.1 一条广告请求的完整旅程
要理解 AI 在广告中的作用,先看一条广告请求是怎么走的。假设一个用户正在打开某个 App,客户端向广告平台发起一次广告请求,服务端会把这个请求转化成一次“曝光机会”,然后经过以下步骤:
- 请求解析:获取用户 ID、设备类型、网络环境、当前页面、时间戳等信息。
- 召回:从海量广告库中选出可能相关的数百条候选广告。这一步通常会用到倒排索引、向量检索或协同过滤。
- 粗排:用轻量模型对候选广告做一次快速打分,筛掉明显不合适的,保留几十条。
- 精排:用更复杂的 CTR/CVR 模型对候选集做精确预估,输出点击概率和转化概率。
- 出价决策:结合预估概率、预算消耗、广告主出价和平台约束,计算出价金额。
- 广告展示:最终选出一条或几条广告返回给客户端,用户看到并产生点击/转化。
- 日志回收与归因:把曝光、点击、转化数据落库,用于后续模型训练和效果分析。
AI 并不是只在“精排”阶段出现。召回阶段的向量化、出价阶段的强化学习、创意阶段的生成模型,都是 AI 能力在广告系统中的落地场景。所以谈论“AI 做广告”时,需要先明确我们讨论的是哪一环。
2.2 典型的 AI 广告系统模块
从开发视角,一个可扩展的 AI 广告系统通常会拆成以下模块:
| 模块 | 主要职责 | 典型 AI 技术 |
|---|---|---|
| 数据接入 | 收集曝光、点击、转化、用户行为日志 | 消息队列、流式处理 |
| 特征平台 | 加工用户画像、内容标签、上下文特征 | 特征工程、Embedding |
| 召回系统 | 从海量广告中找候选 | 向量检索、多路召回 |
| 排序模型 | 预估点击率/转化率 | LR、GBDT、DeepFM |
| 出价策略 | 在预算约束下优化投放效果 | 强化学习、PID控制 |
| 创意生产 | 生成/优化广告文案和素材 | 语言模型、图像生成 |
| 归因分析 | 把转化归到正确的广告触点 | 规则归因、Shapley值 |
这不是一个必须一步到位的架构。个人开发者和中小团队完全可以从“排序模型”和“创意生成”这两个点切入,因为它们的输入输出清晰,验证成本低。
3. 广告 AI 中的关键概念:CTR、CVR、出价与归因
3.1 CTR 和 CVR 是什么,为什么是 AI 广告的核心
CTR(Click-Through Rate,点击率)是“广告展示后被点击的概率”。CVR(Conversion Rate,转化率)是“点击后完成目标行为(注册、下单、安装)的概率”。在广告系统中,CTR 和 CVR 往往是两个模型分别建模,也可以做成多任务模型一起输出。
CTR 预估的输入是“用户特征 + 广告特征 + 上下文特征”,输出是 0 到 1 之间的概率。举例来说,一个 28 岁的男性用户在晚上 10 点浏览科技资讯,看到某手机品牌的新品广告,模型预测他点击的概率是 0.037。这个数字看起来很小,但在广告竞价场景里,只要比竞争对手的概率高一点,就可能赢得这次曝光。
CVR 的建模逻辑类似,但标签通常是“是否完成转化”,正样本更稀疏。很多团队会用“点击后转化”的数据训练 CVR 模型,并使用 ESMM(Entire Space Multi-Task Model)这类方法解决样本选择偏差。
3.2 出价策略:AI 如何决定花多少钱
广告系统是典型的“预算约束下的优化问题”。广告主每天预算有限,平台会根据 eCPM(千次曝光收益)= 预估 CTR × 预估 CVR × 广告主出价,来决定广告排序。广告平台自身的智能出价策略,比如 oCPM、oCPC、tCPA,本质上都是在预估概率的基础上,为广告主自动调整出价,以完成“成本控制”和“量级获取”的平衡。
对于工程师来说,最简单的智能出价实现是:根据实时预算消耗速度动态调整出价系数。如果预算消耗过快,就适当降低出价;如果消耗太慢,就提高出价。更高级的方法会用到强化学习,让智能体在“剩余预算、剩余时间、当前成本”的状态下学习最优出价动作。
3.3 归因模型:广告效果到底算谁的
用户从看到广告到完成转化,中间可能经历了多次曝光、多个渠道。归因模型解决的是“把转化功劳分配给哪些触达点”。常见的归因规则包括:末次点击归因、首次点击归因、时间衰减归因、位置归因。AI 在归因中的价值主要是基于数据驱动的方式学习每个触点的重要度,比如用 Shapley 值计算各渠道的边际贡献,但工业界部署时仍以可解释的规则归因为主。
4. 环境准备与前置条件
4.1 本机环境要求
本文示例使用 Python 3.8+,建议准备一个干净的虚拟环境。操作系统不限,Windows、macOS、Linux 都可以。如果你在本地没有 GPU,也不用担心,文中所有代码都能在 CPU 上运行,只是训练时间稍长。
建议安装以下 Python 库:
- numpy:数值计算
- pandas:数据处理
- scikit-learn:机器学习模型和评估
- transformers:预训练语言模型(可选,用于创意生成)
- torch 或 tensorflow:transformers 的底层框架
4.2 创建虚拟环境
使用 conda 或 venv 都可以,以 venv 为例:
python3 -m venv ai_ad_env source ai_ad_env/bin/activate # Windows 下使用 ai_ad_env\Scripts\activate安装依赖:
pip install numpy pandas scikit-learn transformers torch版本请以实际安装时的官方最新稳定版为准,本文重点演示的是通用思路,不绑定某个具体版本。
5. 实操一:构建广告点击率(CTR)预测模型
5.1 数据准备
为了演示,我们构造一份简化广告点击日志。真实系统中字段会更多,但核心结构类似:用户特征、广告特征、上下文特征、标签(是否点击)。
以下代码生成一份示例 DataFrame,包含 1 万条记录。我们只用几个关键字段做演示,不追求真实分布。
import pandas as pd import numpy as np np.random.seed(42) n = 10000 data = { "user_age": np.random.randint(18, 60, n), "user_gender": np.random.choice([0, 1], n), # 0 女 1 男 "ad_id": np.random.randint(1000, 2000, n), "ad_category": np.random.randint(1, 10, n), # 广告品类 ID "device_type": np.random.choice([0, 1, 2], n), # 0 手机 1 平板 2 桌面 "hour": np.random.randint(0, 24, n), "is_click": np.random.binomial(1, 0.05, n) # 基础点击率 5% } df = pd.DataFrame(data) df.head()这段代码中,is_click是我们要预测的标签,正样本占比通过np.random.binomial控制在 5% 左右。真实广告场景的点击率通常远低于 5%,尤其是品牌广告,可能只有千分之几。这里为了演示方便,没有刻意做严重不均衡处理。
5.2 特征工程与数据集划分
我们将用户年龄、广告 ID、品类、设备、小时作为特征。其中ad_id、ad_category、device_type是离散特征,可以直接用数值 ID 喂给树模型;如果使用逻辑回归,通常需要做 one-hot 或者 embedding。这里为了演示流程,先直接保留数值,并添加一个简单的交叉特征:用户年龄是否大于 30。
df["age_gt30"] = (df["user_age"] > 30).astype(int) feature_cols = ["user_age", "user_gender", "ad_id", "ad_category", "device_type", "hour", "age_gt30"] X = df[feature_cols] y = df["is_click"] from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y )注意这里使用了stratify=y,保证训练集和测试集的正负样本比例一致,避免切分后分布漂移。
5.3 训练逻辑回归模型
逻辑回归是广告 CTR 预估的经典 baseline。它可解释性强,训练快,适合作为第一版模型上线。
from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_auc_score, accuracy_score lr = LogisticRegression(max_iter=1000, random_state=42) lr.fit(X_train, y_train) y_pred_proba = lr.predict_proba(X_test)[:, 1] y_pred = lr.predict(X_test) auc = roc_auc_score(y_test, y_pred_proba) acc = accuracy_score(y_test, y_pred) print(f"Logistic Regression AUC: {auc:.4f}") print(f"Accuracy: {acc:.4f}")在示例数据上,AUC 会接近 0.5,因为特征是随机生成的,与点击标签没有真实关联。这恰好提醒我们一个关键点:模型的预测能力上限取决于特征与标签之间的真实相关性。在真实项目里,特征工程的重要性往往高于模型选型。
5.4 训练梯度提升树模型
接下来用 LightGBM 或 XGBoost 训练一个稍强的模型。这里以 scikit-learn 的HistGradientBoostingClassifier为例,避免引入额外依赖(实际生产更推荐 LightGBM,训练更快)。
from sklearn.ensemble import HistGradientBoostingClassifier hgb = HistGradientBoostingClassifier(max_iter=100, random_state=42) hgb.fit(X_train, y_train) y_pred_proba_hgb = hgb.predict_proba(X_test)[:, 1] auc_hgb = roc_auc_score(y_test, y_pred_proba_hgb) print(f"HistGradientBoosting AUC: {auc_hgb:.4f}")通过对比 LR 和 GBDT 的 AUC,可以判断特征非线性关系是否显著。如果 GBDT 明显优于 LR,说明特征之间存在高维交互,后续可以考虑 Feature Embedding 或深度模型。
5.5 如何把模型应用到广告投放决策
训练好的 CTR 模型,在线上通常会以接口形式暴露出来,输入一次请求的用户特征和广告特征,输出预测点击概率。最简单的部署方式是使用 Flask 构建一个 HTTP 服务:
# 文件路径:ctr_server.py from flask import Flask, request, jsonify import joblib app = Flask(__name__) model = joblib.load("ctr_model.joblib") @app.route("/predict", methods=["POST"]) def predict(): data = request.get_json() # 假设 data 是 {"user_age": 28, ...} feature_values = [ data["user_age"], data["user_gender"], data["ad_id"], data["ad_category"], data["device_type"], data["hour"], int(data["user_age"] > 30) ] proba = model.predict_proba([feature_values])[0][1] return jsonify({"ctr": proba}) if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)保存模型:
import joblib joblib.dump(hgb, "ctr_model.joblib")这里的重点是理解“预测概率如何影响竞价”:平台通常会把 CTR 乘以广告出价得到 eCPM,然后按 eCPM 排序竞价。因此 CTR 模型的一个微小提升,可能带来收入或广告效果的明显变化。
6. 实操二:使用语言模型批量生成广告创意文案
6.1 为什么需要 AI 生成广告创意
广告创意的需求量极大。一个商品可能同时需要 10 套标题、30 条卖点描述、上百个不同尺寸的图文组合。传统人工写文案成本高、周期长。大语言模型出现后,批量生成广告文案成了低成本选项。
但 AI 生成文案不是“点一下生成”那么简单。你需要定义清晰的生成目标,比如:目标用户是谁、广告位是信息流还是搜索、品牌语调是活泼还是稳重、需不需要包含促销词。同时还要通过多路生成 + 人工审核来控制质量。
6.2 使用 transformers 生成广告文案
我们使用一个通用中文生成模型,比如uer/gpt2-chinese-cluecorpussmall或Langboat/bloom-1b4-zh,具体选择以你本机资源和网络条件为准。这里以加载小模型的方式演示生成流程。
# 文件路径:ad_copy_generator.py from transformers import AutoTokenizer, AutoModelForCausalLM import torch model_name = "uer/gpt2-chinese-cluecorpussmall" # 仅作示例,可换成其他中文模型 tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained(model_name) prompt = "【限时特惠】这款智能手环支持心率监测和血氧检测," inputs = tokenizer(prompt, return_tensors="pt") output = model.generate( inputs.input_ids, max_new_tokens=50, do_sample=True, temperature=0.8, top_p=0.9 ) generated_text = tokenizer.decode(output[0], skip_special_tokens=True) print(generated_text)这个代码的输入是一个prompt,输出是模型续写的完整文案。temperature控制随机性:值越低越保守,值越高越多样。批量生成时,可以准备一组模板和一组关键词,然后循环生成多版文案。
6.3 用模板约束生成方向
单纯给模型一两个词,生成结果不可控。更合理的做法是设计带槽位的 prompt,把产品名称、卖点、促销政策、号召语拆成变量:
def generate_ad_copy(product_name, selling_point, discount): prompt = ( f"请为产品“{product_name}”写一段信息流广告文案。\n" f"核心卖点:{selling_point}\n" f"促销信息:{discount}\n" "要求:20字以内,简洁有吸引力,不要夸大宣传。\n" "文案:" ) inputs = tokenizer(prompt, return_tensors="pt") output = model.generate( inputs.input_ids, max_new_tokens=80, do_sample=True, temperature=0.7, top_p=0.9 ) return tokenizer.decode(output[0], skip_special_tokens=True) copy1 = generate_ad_copy( "无线降噪耳机", "主动降噪,续航30小时", "下单立减100元" ) print(copy1)这种模板化方式比让模型自由写作更容易产出符合要求的文案。在真实业务中,还会额外加一层“违规词过滤”和“人工抽检”,避免生成涉及极限词、虚假宣传或不符合平台政策的内容。
6.4 生成效果的评估
广告文案很难单靠模型指标评估,最终要看 A/B 测试的点击率和转化率。但在上线前,可以通过几个简单标准做粗筛:
- 是否包含产品名和核心卖点。
- 是否出现不必要的负面词或歧义。
- 字数是否在广告位限制内。
- 是否包含过度承诺(如“绝对”“第一”“最便宜”)。
7. 实操三:简化的智能出价策略模拟
7.1 出价问题的建模抽象
假设我们有一个广告计划,每天预算 B 元,一天有 N 次曝光机会,每次曝光 i 都有一个预估点击率 p_i 和广告主设定的基础出价 bid_i。我们需要决定每次曝光是否参与竞价,以及出价多少,最终在预算约束下最大化点击数。
这是一个经典的在线优化问题。为了快速演示,我们用一个简化策略:当剩余预算还充足时,按“预估 CTR × 基础出价 × 动态系数”出价;当消耗速度过快时,降低动态系数。
7.2 代码实现
import random import numpy as np def smart_bid_simulation(impressions, daily_budget, base_bid): """ impressions: list of (ctr, base_bid) daily_budget: 今日总预算 base_bid: 初始出价系数 返回: 总花费、总点击数、消耗率 """ budget_left = daily_budget total_clicks = 0 total_cost = 0 spend_history = [] dynamic_coef = 1.0 for idx, (ctr, base) in enumerate(impressions): if budget_left <= 0: break # 简单动态调价:最近100次曝光花费比例过高则降价 if len(spend_history) >= 100: recent_spend = sum(spend_history[-100:]) if recent_spend > 50: dynamic_coef = max(0.5, dynamic_coef - 0.05) else: dynamic_coef = min(1.5, dynamic_coef + 0.02) # 出价 = 预估ctr * 基础出价 * 动态系数 final_bid = ctr * base * dynamic_coef # 模拟平台竞价结果:随机判断是否竞价成功 win_prob = min(1.0, final_bid / (final_bid + 100)) if random.random() < win_prob: cost = final_bid if cost > budget_left: cost = budget_left budget_left -= cost total_cost += cost # 是否点击,按ctr概率 if random.random() < ctr: total_clicks += 1 spend_history.append(cost) return total_cost, total_clicks, (daily_budget - budget_left) / daily_budget7.3 运行模拟
random.seed(2026) impressions = [(random.uniform(0.001, 0.05), random.uniform(10, 50)) for _ in range(1000)] cost, clicks, spend_ratio = smart_bid_simulation(impressions, daily_budget=500, base_bid=30) print(f"总花费: {cost:.2f}") print(f"总点击数: {clicks}") print(f"预算消耗率: {spend_ratio:.2%}")这个示例展示了智能出价的核心理念:不是每个流量都出同样的价格,而是根据预估概率动态调整。真实系统里,出价模型要考虑预算消耗速率、流量质量分布、广告主成本约束和平台竞价环境,代码复杂度会更高,但底层思路是一致的。
8. 运行结果与效果验证
8.1 CTR 模型验证
运行前面的训练代码后,你会看到类似输出:
Logistic Regression AUC: 0.5012 HistGradientBoosting AUC: 0.5033因为示例数据是随机生成的,AUC 接近随机水平,这是正常现象。真实项目中,如果你用一份有业务含义的数据进行训练,AUC 通常能达到 0.7 以上才算有可用性。如果 AUC 太低,建议按以下顺序检查:
- 标签是否有噪声:比如把“误点”也算作正样本。
- 特征是否泄漏:训练集中的特征是否包含了未来信息。
- 样本分布是否和线上一致。
8.2 创意生成验证
运行ad_copy_generator.py后,会打印模型生成的文案。你可以用不同的prompt和temperature多次尝试。如果生成结果不完整,可以增加max_new_tokens;如果文案偏离主题,可以调整 prompt 中产品描述的词序。
8.3 出价模拟验证
运行出价模拟后,会输出总花费、点击数、预算消耗率。你可以在保持预算不变的情况下,调整dynamic_coef的增减步长,观察预算消耗率和点击量的变化。这个模拟不是真实竞价环境,但能帮你理解策略参数对投放节奏的影响。
9. 常见问题与排查思路
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| CTR 模型 AUC 接近 0.5 | 特征与标签无关或标签噪声大 | 查看特征的分布和相关性,检查正样本定义 | 重新做特征工程,清洗标签 |
| 模型训练时特征维度爆炸 | 对高基数离散特征直接 one-hot | 查看特征列数量和内存占用 | 改用 embedding 或 hash 技巧 |
| 线上预测耗时太高 | 模型复杂或特征拼接过于耗时 | 压测接口 p99 延迟 | 模型剪枝、特征缓存、使用模型服务框架 |
| 创意生成文案包含违规词 | prompt 约束不足 | 检查生成输出中的具体词 | 增加违规词过滤和白名单提示 |
| 出价策略导致预算过早花完 | 动态系数下降太慢 | 查看分时消耗曲线 | 提高降价幅度,增加实时消耗监控 |
| AB 测试效果不一致 | 分流不均匀或假设检验时间不足 | 检查分组样本量,计算置信区间 | 使用 AA 测试预检验,延长实验周期 |
10. AI 广告开发的最佳实践与工程建议
10.1 从一个小闭环开始
不要一开始就追求完整的 DMP、特征平台、模型训练平台。先选一个业务痛点,比如“某个广告位的点击率低于预期”,然后搭建一个离线数据管道,训练 CTR 模型,再通过一个简单的线上服务返回预测分数,最后用 A/B 测试验证效果。这个闭环跑通后,再逐步复制到其他广告位。
10.2 定义清楚样本标签
广告模型的标签并不是简单的 0/1,而是深度绑定业务目标。点击率模型的标签是“用户是否点击”,转化率模型的标签是“用户是否完成目标动作”。如果你的业务目标不是直接转化,而是一个长期价值指标,还需要考虑延迟反馈问题,比如用户第二天才激活。工程上通常会对样本设置观察窗口,比如“点击后 24 小时内完成转化”算作正样本。
10.3 重视特征一致性
训练时用的特征和线上实时拿到的特征必须有一致的定义。很多模型上线后掉点的原因就是训练时用了“用户未来 7 天的行为数”,但这个特征在线上是无法实时获取的。建议在特征平台中维护一份特征字典,训练和预测共用一个特征逻辑。
10.4 把模型当作服务而非黑盒
CTR 模型不只是输出一个概率,它还需要支持监控、回滚和解释。每次模型版本更新,都应该评估新模型与当前线上模型在核心指标上的差异,并使用灰度流量逐步放量。一旦发现成本异常,要能快速回退到上一个版本。
10.5 关注合规和用户隐私
广告系统使用的数据涉及用户行为和个人信息,必须遵循最小必要原则。不要为了提升模型效果而滥用敏感字段。对用户特征做脱敏处理,并在数据存储和传输环节加密。相关法律法规要求可能随地区和平台变化,上线前要经过合规评审。
10.6 建立可观测性
广告链路很长,任何一个模块失败都可能造成投放事故。建议对以下指标做实时监控:
- 请求量、曝光量、点击量、转化量。
- CTR、CVR、平均出价、预算消耗率。
- 模型预估分发的分布变化。
- 创意生成接口的成功率和延迟。
11. 总结与后续学习方向
“人工智能怎么做广告”不是一个单一问题的答案,而是一条完整的技术链路。本文从广告请求的旅程讲起,解释了 CTR、CVR、出价、归因这些核心概念,并用三个最小示例展示了 CTR 预测、文案生成和智能出价的实现路径。你可以把这三个示例当作入门的底稿,在它们之上替换成真实数据、真实模型和真实业务目标。
下一步,如果你对算法层感兴趣,可以深入研究 DeepFM、DIN 这类广告排序模型,以及强化学习在自动出价中的应用。如果你更偏向工程层,可以关注特征平台、模型服务和 A/B 实验系统的搭建。无论选择哪个方向,建议都先把手里的数据跑通,再用小流量实验验证效果。AI 广告没有银弹,但每一步可衡量的优化,都会直接反映在投放成本和效果上。