解耦架构 · 调控 + 新建 双子系统

新建广告 · 新建创意 · 架构设计

项目代号 auto_put_ad_mini
plan v2 · 2026-06-05

现有"调控子系统"做减法 — 关停 / 调价 / 扩量;新增"新建子系统"做加法 — 建广告 / 挂创意。两者共享数据 + 平台 API + 基础知识,但各自的脑子 (skill + prompt)独立,避免互相污染。

本文档展示 6 张图:① 三层架构(共享 infra · 双子系统 · 关联点) · ② 数据契约流向 · ③ 关联点放大图 · ④ 模块 A/B 内部流水线 · ⑤ 决策框架 L1/L2/L3 · ⑥ 实施甘特图。配色:cream 为共享 infra,navy 既有调控,terracotta 新建子系统,gold 跨系统关联点。

关键约束 · 一账一人群包(2026-06-05 锁定)
一个账户固定一个 custom_audience(人群包),即使有多个广告也不变。这意味着 audience 不参与广告差异化,跨 tier 测试通过跨账户实现。单账户内唯一性差异化维度退化为 site_set × age × geo 三维,可建 4×4×4 = 64 种 unique 组合,起步 5-15 条远未饱和。账户与人群包映射由 ACCOUNT_AUDIENCE_PACK_MAPPING[account_id] 在配置中预设,LLM 不参与选择。

图一 · 三层架构总览

Layer 1 · Shared Infra 共享基础设施 两个子系统都依赖的"地基"— 数据 · 能力 · 知识 · 配置 DATA 数据层 data_query · roi_calculator creative_metrics · portfolio_metrics → metrics_{date}.csv · portfolio_summary.json CAPABILITY 能力层 ad_api (腾讯 v3.0) im_approval (飞书基类) · execution_engine QPS · retry · audit log 公共部分 KNOWLEDGE 知识层 skills/ad_domain.md skills/platform_rules.md 两个 Agent 系统 prompt 都注入 CONFIG 配置层 config.py [SHARED] 段 账户白名单 · QPS · 时区 · 数据窗口 基础阈值 · 冷启动天数 · 最低统计门槛 Layer 2a · 调控子系统(现有) 调控子系统 "做减法 + 微调"— 完全保留,本期几乎不动 ENTRYPOINT execute_once.py 每日 02:00 UTC (K8s cronjob) BRAIN · CODE tools/ad_decision.py · execution_engine 现有 dispatch VALID_ACTIONS = pause / bid_down / bid_up / scale_up / observe / hold / creative_adjust BRAIN · KNOWLEDGE prompts/system.prompt skills/decision_strategy.md · posterior_wisdom.md OUTPUT · APPROVAL · EXECUTION → outputs/reports/llm_decisions_{date}.csv → outputs/reports/decision_{date}.xlsx · FEISHU_OPERATOR_CHAT_ID → outputs/execution_log/exec_{date}.jsonl(审计) Layer 2b · 新建子系统(新增) 新建子系统 "做加法"— 全新独立 entrypoint,与调控并行 ENTRYPOINT execute_creation_once.py 每日 02:30 UTC (新 cronjob) BRAIN · CODE(全新 8 个模块) creation_decision · ad_creation · creative_creation material_recall · material_recall_sources · dedup_check (stub) · uniqueness_check · audience_demand BRAIN · KNOWLEDGE(独立 prompt + skill) prompts/system_creation.prompt skills/creation_strategy.md(新增) OUTPUT · APPROVAL · EXECUTION → outputs/reports/creation_decisions_{date}.csv → outputs/reports/creation_{date}.xlsx · FEISHU_CREATION_CHAT_ID → outputs/execution_log/creation_exec_{date}.jsonl(独立审计) Layer 3 · Minimal Coupling 关联点(本期实现:单向) 新建子系统启动时只读调控的 llm_decisions_{LATEST}.csv, 提取 {ad_id where action=='pause'} 加入 excluded_ad_ids 黑名单 add_creative 候选标记阶段硬过滤 · 不给"即将被关停的广告"补创意 · 反向耦合(调控读新建)留下期 latest_decisions excluded_ad_ids
共享 infra(数据 / API / 基础 skill)
调控子系统(现有 · 不动)
新建子系统(全新)
跨系统关联点(单向 · 最小)
数据流(共享 → 子系统)
关联流(单向只读)

图二 · 数据契约 — 文件级数据流

两个子系统通过文件系统通信,**互不调用对方 API**。所有产物文件都在 outputs/ 下,可单独审计。共享只读输入由调控子系统在 02:00 写出 → 新建子系统在 02:30 读入。

SHARED READ-ONLY INPUTS · 共享只读输入(由调控产 / 新建读) metrics_{date}.csv 广告级 + 创意级 ROI 候选标记(roi_low / decay_signal / ...) 由 roi_calculator.py 产 portfolio_summary_{date}.json tier 基线 channel_p50 / tier_fission_mean 渠道 P25/50/75 分位 由 portfolio_metrics.py 产 ad_status_{date}.csv 广告状态快照(活跃 / pause / 删除) 出价 · 预算 · 定向 由 data_query.py 产 creative_pause_history.json adjustment_history.json 操作级频次(7 日窗口) 两子系统都读以避免频次违规 ADJUSTMENT SUBSYSTEM OUTPUTS 调控产物(现有) outputs/reports/llm_decisions_{date}.csv 每行一条决策(7 种 action) outputs/reports/decision_{date}.xlsx 飞书审批表(调控群) outputs/execution_log/exec_{date}.jsonl API 调用审计 CREATION SUBSYSTEM OUTPUTS 新建产物(全新) outputs/reports/creation_decisions_{date}.csv action ∈ {create_ad, add_creative} outputs/reports/creation_{date}.xlsx 飞书审批表(新建群) outputs/execution_log/creation_exec_{date}.jsonl 独立审计 outputs/data/ad_fingerprint_cache.json 营销内容指纹(唯一性预校验) 每次新建广告前先比对此缓存 + 调 ads_get 同步 creative_add_history.json ad_creation_history.json 7 日累计护栏数据源 类比现有 creative_pause_history read pause ad_id 反向耦合(调控读新建)留下期 LAYER 3 · COUPLING DETAIL 新建子系统 Step 1: excluded_ad_ids = read_pause_ad_ids(latest_llm_decisions) → 传给 LLM prompt + 候选标记代码(creation_decision.mark_add_creative_candidates) 空盘场景(常态): 如果调控 latest 无 pause 决策 → excluded_ad_ids = ∅ 新建子系统照常按自己的候选 + LLM 决策跑

图三 · 模块 A 广告新建 · 内部流水线

STEP 1 · 候选标记(L1 代码层 · 每 tier 硬算 6 信号) tools/creation_decision.py::mark_create_ad_candidates(portfolio_summary, ads_snapshot, history) tier_active_low tier_pause_burst tier_creative_refresh_failed tier_uniqueness_slots_available tier_roi_healthy account_quota_remaining 任 4 项命中 → 候选 STEP 2 · LLM 综合判断(L2 · skill 启发式) skills/creation_strategy.md 看 6 个候选 + tier 趋势 + 7 日累计配额,综合决定 "create_ad(tier_X, N 条)" + reason 5 元组 + confidence STEP 3 · 唯一性枚举搜索(避免 1901634)· 约束:一账一包,audience 账户级固定 tools/ad_creation.py::enumerate_new_ad_candidates(account_id, N) 笛卡尔积 site_set × age × geo(3 维,共 4×4×4=64 组合) → 过滤已有 fingerprint → 取前 N site_set: 知乎信息流 · 朋友圈 微信公众号 · 优量汇 ...(4) age 离散段: 18-25 / 26-35 / 36-45 / 46-55(4) geo 离散段: 全国 / 一线 / 二线 / 三四线(4) audience 已由 ACCOUNT_AUDIENCE_PACK_MAPPING 固定 + fingerprint_cache + ads_get(account_id) → 单账户 64 组合中取 N 个 unique STEP 4 · 出价基准三层降级 + 预算 + 命名 tools/ad_creation.py::compute_target_bid(tier, site_set, age, geo) ① combo_median (≥3 历史)→ factor 1.20 ② tier_history_median → factor 1.30 ③ channel_p50(兜底)→ factor 1.50 budget = combo_median × 0.5 → 写一行到 creation_decisions_{date}.csv · action_type='create_ad' · 等飞书审批 · 通过则调 ad_api.ad_create()

图四 · 模块 B 创意新建 · 内部流水线

STEP 1 · 候选标记(L1 代码层 · 每广告硬算 7 信号) tools/creation_decision.py::mark_add_creative_candidates(metrics, excluded_ad_ids, history, tier_summary) decay_signal (复用现有) creative_count_low < 15 creative_age_old 中位 ≥ 7 天 not_recently_added 7 天未补过 ad_alive_and_healthy ROI ≥ P50 × 0.90 tier_not_declining tier 趋势护栏(深度补) not_in_excluded 关联点过滤 任 4 项命中 → 候选 STEP 2 · LLM 综合判断(L2 · skill 启发式) skills/creation_strategy.md 综合候选 + tier 趋势 + 频次 + 配额 → 决定 "add_creative(ad_X, ≤ 5 条)" + 三路素材配比 + reason + confidence STEP 3 · 三路素材召回(黑盒 API + 排序加权) tools/material_recall.py::recall_materials(audience_demand, top_k=50, sources, weights) 50% ① 历史投放素材 HistorySource score = 0.3×cost + 0.4×CTR + 0.3×ROI(标准化) 30% ② 合作方即转卡片 PartnerSource score = 卡片点击率 20% ③ AI 改写 (取 ① top 5) RewriteSource · uses LLM light:同义改写 · medium:句式重组 STEP 4 · 4+M 判重(本期 STUB) tools/dedup_check.py::check_material_duplicate(...) DEDUP_ENABLED=False · always returns not_duplicate 本地预筛:同广告下 md5(image_id+title+desc) 去重 → 后续接 4+M 云服务,只改本函数实现,接口不变 STEP 5 · AI 改写命中重复时升档 light 改写 → 命中重复 → medium → skip 最多尝试 2 次(AI_REWRITE_MAX_ATTEMPTS_PER_MATERIAL=2) 改写后再走判重 → 才上传 / 挂载 heavy 级(图像重新生成)留下期 渐进式控制 · 单次 ≤ 5 · 单广告 7 日累计 ≤ 8 · 已有 ≥ 30 不触发 → 写 creation_decisions / 飞书审批 / creative_create()

图五 · 决策框架:代码 vs 知识 三层分工

两个子系统都遵循同一套三层分工 — L1 候选标记代码(确定性 · 可单测)/ L2 LLM skill(启发式 · 灰色地带)/ L3 兜底护栏代码(确定性 · 边界)。这是分离架构的核心:**skill 不是简单等于一段话,是 LLM 的推理框架,各子系统必须独立**。

L1 · CANDIDATE MARKING 代码层 · 确定性 · 可单测 · 可回放 候选标记 调控:tools/ad_decision.py roi_low · decay_signal · bid_up_candidate · bid_down_candidate · scale_up_candidate (5 个,现有不动) 新建:tools/creation_decision.py add_creative 7 信号 + create_ad 6 信号(L1 全新) 含 tier 级护栏 + 关联点过滤(深度补全) L2 · LLM HEURISTIC 知识层 · 启发式 · 灰色地带 · 综合权衡 LLM 综合判断(skill 注入) 调控:skills/decision_strategy.md "任 X 项命中倾向触发" · 裂变 vs ROI 冲突 · reason 5 元组 → 只注入 调控 Agent prompt 新建:skills/creation_strategy.md(新) "任 4 项命中倾向触发" · 三路素材配比 · 出价 factor 选择 → 只注入 新建 Agent prompt · 不污染调控 L3 · HARDCODED GUARDS 代码层 · 确定性 · 边界硬约束 · 不可绕过 兜底护栏 调控:tools/guardrails.py(现有) BID_FLOOR/CEILING · MAX_ADJUSTMENTS_PER_AD_PER_DAY · 数据新鲜度 + CreativePauseHistory 7 天去重 新建:guardrails 扩展 + creation_history(新) MAX_NEW_ADS_PER_TIER_PER_7D · uniqueness_check · 创意数上限 + CreativeAddHistory · AdCreationHistory(深度补全:7 日累计)

图六 · 关联点放大 — 时序图

UTC 02:00 UTC 02:30 UTC 04:00+ ADJUSTMENT LANE · 调控子系统 execute_once.py 数据→决策→审批→执行 02:30 之前:产物落地 outputs/reports/llm_decisions_{date}.csv 飞书审批进行中(120 min 阻塞 · 与新建并行) 审批通过后执行 · 此期间不影响新建子系统启动 CREATION LANE · 新建子系统 execute_creation_once.py 02:30 启动 Step 1 · 读调控 latest_decisions excluded_ad_ids = {ad_id where action=='pause' in llm_decisions_{date}.csv} latest_decisions(只读) → 候选标记(7 信号)→ LLM 决策 → 唯一性校验 → 飞书新建审批表 → ad_create / creative_create

图七 · 实施甘特图(10 阶段)

名称内容关键产出类别
a共享 infra 抽取im_approval.py 抽 FeishuApprovalBase · execution_engine 抽公共部分 · config.py 拆 [SHARED]/[ADJUSTMENT]/[CREATION] 三段FeishuApprovalBase · config 重排共享
b适配层 stub5 个适配模块接口签名:audience_demand · material_recall · dedup_check · uniqueness_check · creation_history5 个新文件 + 单测新建
c模块 A 内核ad_creation.py 真实化:唯一性预校验 + 出价基准三层 + 命名 + ad_api.ad_create() 调用tools/ad_creation.py新建
d模块 B 内核creative_creation.py 真实化:三路召回(history 路先做)+ AI 改写(light)+ 渐进式控制 + ad_api.creative_create()tools/creative_creation.py新建
e新建 Agent 框架prompts/system_creation.prompt + skills/creation_strategy.md + creation_decision.py 候选标记 + 工具白名单prompt + skill + L1 标记代码新建
f新建子系统入口execute_creation_once.py 完整流水线:关联点过滤 → Agent → 决策落地 → 审批发送execute_creation_once.py新建
g飞书审批扩展FeishuCreationApproval 子类 · 新 chat_id 配置 · 新 APPROVAL_COLUMNStools/im_approval.py 重构共享
h执行 dispatchexecution_engine 加 _execute_create_ad() · _execute_add_creative()(新建独占)execution_engine 新分支新建
i端到端 + 关联点验证execution_enabled=true · 单一测试账户跑 · 验证唯一性 / 创意数 / 关联点过滤 / 调控不受影响回归测试 + 手工 checklist验证
jK8s + 文档k8s/cronjob_creation.yaml · 更新 CLAUDE.md · 监控告警cronjob 上线 · 稳定跑 1 周交付

阶段甘特(相对工作量,水平比例示意)

阶 a
a · 抽 infra
阶 b
b · stub
阶 c
c · 模块 A
阶 d
d · 模块 B
阶 e
e · Agent 框架
阶 f
f · 子系统入口
阶 g
g · 飞书
阶 h
h · execute
阶 i
i · e2e 验证
阶 j
j · K8s + 文档
共享 infra 改动(影响调控,需回归)
新建子系统独占改动
验证 / 交付

设计原则速查

代码 vs 知识 分离工具 / 数据(代码)是确定性的,复用零风险;Skill(LLM 推理框架)是启发式的,共用会污染。Q5/Q6 改方向的核心理由。
分离但不盲两个子系统通过文件系统通信,**最小耦合**:新建启动只读调控当日 latest_decisions 黑名单,避免给即将 pause 的广告补创意。
L1 / L2 / L3 三层分工L1 候选标记(代码,可单测)/ L2 LLM skill(启发式)/ L3 兜底护栏(代码,边界)。两子系统共用这套分工模式。
YAGNI 严格执行本期不做 reshuffle / 重度 AI 改写 / 跨账户素材 / 调控读新建 / 联合审批 / 学习期细粒度保护。接口预留,实现等下期。
深度思考补全(全启用)tier 级护栏 · 渐进式挂创意(≤5/次)· 7 日累计上限 · 出价基准三层降级 · 关联点过滤 · confidence 量纲校准。
回滚边界清晰新建子系统失败 → 删 execute_creation_once.py 即可;CREATION_ENABLED=False 总开关;调控完全不受影响。