Target 如何用 LLM 给营销预测找到“相似历史战役”

2026-06-29 34 预计阅读时间: 1 分钟
来源: infoq.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

营销活动预测最难的部分,往往不是建模本身,而是找到足够相似的历史案例:同样的品类、渠道、季节、促销力度和受众,过去表现如何?Target 的做法是把这一步从规则驱动的人工流程,升级为一个结合 embeddings、向量检索和 LLM 排序的语义匹配系统,用来支撑营销 campaign forecast pipeline。

这类系统的价值不只在“搜索更聪明”。它把经验判断变成可复用、可评估、可反馈优化的流程:先召回相似历史活动,再让 LLM 对候选项排序,最后把结果用于预测和人工审核。

从规则匹配到语义匹配

传统营销预测流程通常会写很多规则:

  • 同一业务线优先
  • 同一渠道优先
  • 时间窗口接近优先
  • 折扣、预算、受众规模相近优先
  • 文案或活动目标包含特定关键词

这些规则好维护吗?一开始还行,但营销活动越多,边界情况越多:一个“返校季电子产品组合促销”和一个“学生折扣笔记本电脑 campaign”可能语义接近,但关键词和字段值并不完全相同。

Target 的系统用 embeddings 把 campaign 描述、元数据和历史表现变成向量,再通过 vector search 找到候选历史 campaign。随后,LLM 不只是看关键词,而是根据业务上下文判断“这个历史活动是否真的适合作为预测参考”。

可以把它理解成两级漏斗:

  1. 向量检索负责快:从大量历史 campaign 中召回 top-k 候选。
  2. LLM 排序负责准:在候选集中做语义比较和业务相关性排序。

来源摘要中提到,系统评估达到了 75% top-1 coverage100% top-3 coverage。这说明正确或可接受的相似 campaign 经常能出现在首位,至少能稳定落在前三个候选中。对预测工作流来说,这已经足以显著减少人工翻找和反复校验。

为什么 LLM 排序比单纯向量搜索更适合营销场景

单纯 embeddings 检索适合“语义相近”的粗筛,但营销预测里的“相似”并不等于文本相似。

例如两个活动描述都提到“holiday promotion”,但一个面向高客单家电,一个面向低价日用品;它们在文案上相近,在预测参考价值上可能相差很大。LLM 排序可以把更多字段纳入判断:

  • 活动目标:拉新、复购、清库存、提升客单价
  • 渠道:email、app push、paid media、店内促销
  • 品类:食品、服饰、家电、母婴等
  • 时间:节假日、开学季、季末清仓
  • 激励方式:折扣、满减、会员权益、礼包
  • 历史结果:转化率、销售额提升、ROI、客群响应

这里的关键不是“让 LLM 直接预测结果”,而是让它承担更适合的任务:解释候选项之间的相似度,并给出排序依据。预测模型或人工计划团队再使用这些候选历史结果。

可以这样实践:一个最小语义匹配原型

下面是一个可复制改造的 Python 原型。它用 sentence-transformers 生成 embeddings,用 faiss-cpu 做向量检索,并预留了 LLM rerank 的位置。你可以先运行本地语义召回,再接入自己的 LLM API 做排序。

安装依赖:

python -m venv .venv
source .venv/bin/activate
pip install sentence-transformers faiss-cpu numpy

创建 campaign_matcher.py

from sentence_transformers import SentenceTransformer
import faiss
import numpy as np

campaigns = [
    {
        "id": "C001",
        "text": "Back-to-school laptop discount campaign for students, app push and email, 15% off.",
        "outcome": "High conversion among loyalty members, strong electronics sales lift."
    },
    {
        "id": "C002",
        "text": "Holiday home appliance promotion with paid media and store signage, bundle discount.",
        "outcome": "Moderate ROI, high average order value."
    },
    {
        "id": "C003",
        "text": "Weekly grocery coupon campaign for families, email only, buy-one-get-one offers.",
        "outcome": "High redemption rate, low incremental margin."
    },
    {
        "id": "C004",
        "text": "Student tech essentials campaign featuring tablets, headphones, and laptops before school season.",
        "outcome": "Strong click-through rate and above-plan electronics revenue."
    }
]

model = SentenceTransformer("all-MiniLM-L6-v2")

texts = [f"{c['text']} Historical outcome: {c['outcome']}" for c in campaigns]
embeddings = model.encode(texts, normalize_embeddings=True)

index = faiss.IndexFlatIP(embeddings.shape[1])
index.add(np.array(embeddings, dtype="float32"))

new_campaign = "App and email campaign for back-to-school student laptop deals with a 10% discount."
query_embedding = model.encode([new_campaign], normalize_embeddings=True)

scores, indices = index.search(np.array(query_embedding, dtype="float32"), k=3)

print("New campaign:", new_campaign)
print("\nTop candidates:")
for rank, idx in enumerate(indices[0], start=1):
    campaign = campaigns[idx]
    print(f"{rank}. {campaign['id']} score={scores[0][rank-1]:.3f}")
    print("   text:", campaign["text"])
    print("   outcome:", campaign["outcome"])

运行:

python campaign_matcher.py

这段代码只完成了第一层:向量召回。实际生产系统里,下一步可以把 top-3 或 top-10 候选交给 LLM 重新排序。一个可改造的 prompt 可以这样写:

You are ranking historical marketing campaigns for forecast reference.

New campaign:
{new_campaign}

Candidate campaigns:
{candidates}

Rank the candidates by forecasting relevance. Consider audience, category, timing,
channel, offer mechanics, and historical outcome. Return JSON with campaign_id,
rank, score from 1 to 5, and a short reason.

注意这里要求 LLM 输出结构化 JSON,而不是自由文本。这样后续 pipeline 可以稳定消费排序结果,并把排序理由展示给营销或预测团队审核。

反馈循环才是系统变聪明的地方

来源摘要中特别提到,Target 使用 campaign outcomes 形成反馈循环,持续优化检索。这个设计很重要。

如果系统只在上线时做一次 embeddings 和 prompt 调优,很快就会老化。营销环境会变化:渠道效率变了,用户偏好变了,季节性变了,折扣敏感度也会变化。反馈循环可以把这些变化重新注入系统:

  • 记录 LLM 排序候选是否被业务人员采纳
  • 记录最终预测误差和真实 campaign outcome
  • 分析哪些相似特征真正提升了预测准确性
  • 调整 embedding 输入字段、召回数量和 rerank prompt
  • 将高质量匹配样本沉淀为评估集

一个简单的数据表可以这样设计:

CREATE TABLE campaign_match_feedback (
    new_campaign_id TEXT NOT NULL,
    matched_campaign_id TEXT NOT NULL,
    rank_position INTEGER NOT NULL,
    accepted_by_planner BOOLEAN NOT NULL,
    forecast_error_pct NUMERIC,
    actual_revenue_lift NUMERIC,
    planner_note TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

有了这张表,团队就能定期回答一个很实际的问题:系统推荐的“相似历史活动”,到底有没有让预测更准?

落地建议:别让 LLM 变成黑盒魔法

这类系统适合逐步上线,而不是一次性替换全部预测流程。

可以从低风险环节开始:先让系统推荐相似 campaign,并显示相似原因;人工仍然保留最终选择权。等 top-1、top-3 命中率和预测误差都稳定后,再把结果更深地接入自动化 forecast pipeline。

落地时建议检查这些点:

  • 输入质量:campaign 描述、渠道、品类、预算、受众和历史 outcome 是否完整。
  • 评估口径:top-1/top-3 coverage 之外,还要看预测误差是否下降。
  • 可解释性:LLM 排序必须给出可读理由,方便业务团队质疑和修正。
  • 漂移监控:节假日、渠道策略、宏观消费变化都会让历史相似性失效。
  • 人工反馈:业务人员的采纳、拒绝和备注应该进入训练或调优闭环。

Target 的案例说明,LLM 在企业预测系统里的实用位置,未必是“直接给答案”,而是把过去散落在人工经验和规则表里的判断,转成一个可检索、可排序、可评估的语义层。对营销预测来说,这往往比炫技式生成更有价值。


相关推荐