基于 Reson Agent 框架的腾讯广告智能调控系统 数据驱动 + AI推理 + 安全护栏 + 自然语言审批
┌─────────────────────────────────────────────────────────────────┐
│ 用户/运营人员 │
│ "分析广告" | "广告XXX降价10%" | "不要暂停" │
└───────────────────────────────┬─────────────────────────────────┘
│
┌──────────▼──────────┐
│ Agent运行引擎 │
│ (AgentRunner) │
│ │
│ • LLM调用 (qwen) │
│ • 工具注册/调用 │
│ • Skill加载 │
│ • 轨迹追踪 │
└──────────┬──────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
┌───────▼────────┐ ┌────────▼────────┐ ┌───────▼────────┐
│ system.prompt │ │ Skills/知识库 │ │ Tools/工具集 │
│ ─────────────│ │ ───────────── │ │ ───────────── │
│ • Mode路由 │ │ roi-strategy.md │ │ data_query.py │
│ • 决策流程 │ │ guardrail_rules │ │ roi_calculator │
│ • 审批逻辑 │ │ ad_domain.md │ │ ad_decision │
│ • 错误处理 │ │ (领域知识注入) │ │ guardrails │
└────────────────┘ └─────────────────┘ │ execution_engine│
│ im_approval │
│ report_generator│
└────────────────┘
│
┌────────────────────────────────┼────────────┐
│ │ │
┌────────▼─────────┐ ┌───────────▼──────────┐ │
│ 数据层 (ODPS) │ │ 外部服务集成 │ │
│ ───────────── │ │ ────────────── │ │
│ • 创意数据 │ │ • 飞书机器人 │ │
│ • 广告状态 │ │ • 腾讯广告 API │ │
│ • Merged数据 │ │ (分级执行+回调) │ │
└──────────────────┘ └─────────────────────┘ │
│
┌────────────────────────────────────────────┘
│
┌────────▼────────┐
│ 持久化存储 │
│ ───────────── │
│ • metrics_*.csv│
│ • decisions_* │
│ • reports_* │
│ • 调整历史记录 │
└─────────────────┘
用户说 "分析广告" 时触发,执行以下步骤:
fetch_creative_data)# 工具: examples/auto_put_ad_mini/tools/data_query.py
输入: days=7 (拉取最近7天)
处理:
1. 检查本地已有数据(跳过重复拉取)
2. 对于缺失日期,从ODPS拉取创意级数据
3. 同时拉取广告状态数据 (ad_status)
输出:
- outputs/raw/creative_YYYYMMDD.csv (每日创意数据)
- outputs/ad_status/ad_status_YYYYMMDD.csv (每日广告状态)
数据特点:
• 创意级粒度 (一个广告有多个创意)
• 包含ROI计算必需字段: cost, open_count, fission0_count, total_revenue, etc.
merge_creative_data)# 将创意数据 + 广告状态 合并
输入: days=7
处理:
1. 读取 creative_YYYYMMDD.csv
2. 读取 ad_status_YYYYMMDD.csv
3. LEFT JOIN (创意 + 广告状态)
输出:
- outputs/merged/merged_YYYYMMDD.csv
字段包括:
• ad_id, creative_id, account_id, ad_name
• cost, view_count, click_count
• open_count, fission0_count, total_return_count, total_revenue
• bid_amount, configured_status, create_time
calculate_roi_metrics)# 工具: examples/auto_put_ad_mini/tools/roi_calculator.py
输入: end_date="20260415" (默认yesterday)
处理:
1. 加载最近30天的 merged 数据(容错缺失)
2. 聚合到广告级 (GROUP BY ad_id, date)
3. 计算 f_7日动态ROI (考虑裂变效率稳定性)
4. 计算 7日汇总 (cost_7d_avg, revenue_7d_total)
5. 计算 30日汇总 (stable_spend_days_30d)
核心公式:
T0裂变系数 = fission0_count / open_count
arpu = total_revenue / total_return_count
当日裂变收益率 = fission0_count * arpu / cost
当日回流倍数 = total_return_count / open_count
裂变效率稳定因子 = 回流倍数_7日均值 / T0裂变系数_7日均值
f_7日动态ROI = 当日裂变收益率 * 裂变效率稳定因子
输出:
- outputs/metrics_20260415.csv (1570行, 每个广告一行)
关键指标:
• 动态ROI (单日值)
• 动态ROI_7日均值 (决策参考值!)
• cost_7d_avg, cost_7d_total
• ad_age_days (广告年龄)
get_ads_for_review)# 工具: examples/auto_put_ad_mini/tools/ad_decision.py
输入: metrics_csv (步骤3输出)
处理:
1. 计算全体 ROI 分布 (mean, p25, p50, p75, p90)
2. 检测衰退信号 (提价、换创意、消耗下降)
3. 分为三类(语义化命名):
【零消耗待关停】(极端差, 自动关停):
• 7日均消耗 < 1元 (几乎零活动)
【待评估(候选)】(边缘, 需AI推理):
• ROI < 全体均值 × 0.8 (偏低)
• 或检测到衰退信号
【正常运行】(自动保持):
• 其余广告
输出: JSON结构化数据
{
"summary": {total, zero_spend_ads, need_review_ads, normal_ads},
"distribution": {roi_mean, p25, p50, p75, p90},
"bid_adjustment": {bid_down_line, bid_up_line},
"zero_spend_ads": [...], # 自动关停列表
"need_review_ads": [...], # 需要推理的广告(含详细指标)
"normal_ads_summary": {...}
}
# Agent读取【待评估(候选)】广告数据 + roi-strategy.md技能
# 对每个广告进行推理,输出决策JSON
决策逻辑框架:
IF ad_age_days < 4天:
→ hold (冷启动绝对保护)
ELIF ad_age_days < 7天:
→ 仅允许小幅降价 ≤5% (谨慎期)
ELIF ROI < 全体均值 × 0.5:
→ pause (极低ROI, 关停)
ELIF ROI < 全体均值 × 0.8 AND cost_7d_avg ≥ 100元:
→ bid_down -3%~-10% (降价, 越接近关停线降幅越大)
ELIF ROI > 全体均值 × 1.2 AND cost_7d_avg < 中位数 × 0.5:
→ bid_up +3%~-10% (高ROI低消耗, 提价放量)
ELSE:
→ hold (保持)
输出格式:
[
{
"ad_id": 90289631207,
"action": "pause",
"dimension": "ROI过低",
"reason": "f_7日动态ROI=1.18 < 均值3.29×0.5=1.64, 日消耗1524元, 持续亏损",
"confidence": "high"
},
{
"ad_id": 32912382309,
"action": "bid_down",
"dimension": "ROI偏低-降价",
"reason": "动态ROI_7日均值=1.81 < 均值3.29×0.8=2.63, 建议降8%至0.30元",
"confidence": "medium",
"recommended_change_pct": -0.08
},
...
]
apply_decisions)# 工具: examples/auto_put_ad_mini/tools/ad_decision.py
输入: decisions (AI推理的JSON) + metrics_csv
处理:
1. 解析AI输出的JSON
2. 合并【零消耗待关停】自动关停 + 【待评估】AI决策 + 【正常运行】自动保持
3. 过滤已暂停广告 (AD_STATUS_SUSPEND)
4. 计算出价变更(current_bid × (1 + recommended_change_pct))
输出:
- outputs/reports/llm_decisions_20260415.csv
字段:
ad_id, action, dimension, reason, confidence,
recommended_change_pct, current_bid, recommended_bid,
ad_age_days
validate_decisions)# 工具: examples/auto_put_ad_mini/tools/guardrails.py
输入: llm_decisions_20260415.csv
处理: 逐条检查6道护栏
护栏1: 数据新鲜度
IF 数据年龄 > 48小时:
→ Block所有非hold操作
护栏2: 冷启动保护
IF ad_age_days < 4天:
→ Block所有pause/bid_down
IF ad_age_days < 7天:
→ bid_down限制 ≤5%
护栏3: 出价边界
IF recommended_bid < 0.5元:
→ Modified (钳位到0.5元)
IF recommended_bid > 200元:
→ Modified (钳位到200元)
护栏4: 频率限制
IF 今日已调整次数 ≥ 2:
→ Block
IF 距上次调整 < 6小时:
→ Block
IF 今日累计调幅 > 20%:
→ Block
护栏5: 每日操作上限
IF 今日已操作广告数 ≥ 200:
→ 按ROI严重度排序, Block低优先级
护栏6: 干运行模式
IF DRY_RUN_MODE = True:
→ 所有操作标记dry_run (Modified)
输出:
- outputs/reports/validated_decisions_20260415.csv
新增字段:
guardrail_status: approved | modified | blocked
guardrail_reason: 拦截原因说明
final_action: 护栏处理后的最终动作
final_bid: 护栏处理后的最终出价
send_approval_request)# 工具: examples/auto_put_ad_mini/tools/im_approval.py
# ⚠️ 仅当有通过护栏的非hold操作时才调用
输入: wait_for_reply=True (阻塞等待审批)
处理:
1. 读取 validated_decisions (guardrail_status=approved)
2. 按风险分级:
Tier 1 (≤5%调幅): 仅通知, 不需审批
Tier 2 (pause, bid_down>5%): 需审批
Tier 3 (日消耗>1500元): 强制审批
3. 构造飞书消息 (卡片式, 带数据表格)
4. 发送到飞书群组 (FEISHU_OPERATOR_CHAT_ID)
5. 阻塞等待运营回复 (轮询检查, 超时30分钟)
飞书消息格式:
【广告调控审批】2026-04-15
📊 决策摘要
• 总决策数: 38个
• Tier 1 (自动): 10个 (小幅调价 ≤5%)
• Tier 2 (需审批): 20个 (暂停/降价>5%)
• Tier 3 (高价值): 8个 (日消耗>1500元)
🔻 高风险广告 (需审批)
1. 广告90289631207: ROI=1.18, 消耗=1524元/天 → 暂停
2. 广告37429627354: ROI=2.37, 消耗=1228元/天 → 降价5%
...
⏰ 请在30分钟内回复:
- "批准" / "通过" → 全部批准
- "拒绝" / "取消" → 全部拒绝
- "广告XXX不要暂停" → 修改特定决策
审批结果:
- approved_decisions: 通过的决策列表
- rejected_decisions: 拒绝的决策列表
- modified_decisions: 修改后的决策列表
自然语言审批理解 (关键特性):
# Agent具备自然语言理解能力, 可以处理灵活的人类指令
运营说: "批准"
→ 解析为: 全部批准
运营说: "广告90289631207不要暂停, 改为降价10%"
→ 解析为: modify_decisions([
{"ad_id": 90289631207, "new_action": "bid_down", "new_change_pct": -0.10}
])
→ 重新validate → 重新发审批
运营说: "只批准降价的, 暂停的全部拒绝"
→ 解析为: 过滤 action=bid_down → approved
过滤 action=pause → rejected
运营说: "为什么要暂停广告90289631207?"
→ Agent回答: "该广告f_7日动态ROI=1.18 < 关停线1.64,日消耗1524元,
已持续亏损,建议暂停止损"
→ 等待运营最终确认
execute_decisions)# 工具: examples/auto_put_ad_mini/tools/execution_engine.py
# ⚠️ 仅在运营审批通过后调用
输入: 运营审批通过的决策列表
处理:
1. 分批执行 (QPS限制=8, 批次大小=50)
2. 根据action调用腾讯广告API:
• pause → /v3.0/adgroups/update (configured_status=SUSPEND)
• bid_down/bid_up → /v3.0/adgroups/update (bid_amount=final_bid)
3. 错误处理 + 重试 (最多3次)
4. 记录执行日志
输出:
- outputs/execution_log/execution_20260415.json
执行结果:
{
"timestamp": "2026-04-15 14:30:00",
"total": 38,
"success": 36,
"failed": 2,
"details": [
{
"ad_id": 90289631207,
"action": "pause",
"status": "success",
"api_response": {...}
},
{
"ad_id": 32912382309,
"action": "bid_down",
"status": "failed",
"error": "API限流, 重试后成功"
}
]
}
generate_report)# 工具: examples/auto_put_ad_mini/tools/report_generator.py
输入: validated_decisions_20260415.csv
处理:
1. 汇总统计 (总数, pause/bid_down/hold分布)
2. 按ROI严重度排序
3. 生成Excel (带条件格式、颜色标注)
输出:
- outputs/reports/decision_20260415.csv (纯数据)
- outputs/reports/decision_20260415.xlsx (带格式)
Excel样式:
• 绿色: ROI优秀 (>均值×1.2)
• 黄色: ROI偏低 (均值×0.5~0.8)
• 红色: ROI极低 (<均值×0.5)
• 冻结首行, 自动筛选
用户提及 具体广告ID + 操作意图 时触发(如 "广告90289631207降价10%"):
1. query_ad_detail(ad_id) → 查询当前数据+全局上下文
2. AI推理 → 根据用户意图+当前状态生成决策JSON
3. modify_decisions() / apply_decisions() → 保存决策 (upsert模式)
4. validate_decisions() → 护栏验证
5. send_approval_request() → IM发给运营确认
6. execute_decisions() → 执行
用户对已有决策提出修改意见时触发(如 "广告XXX不要暂停"):
1. modify_decisions(modifications) → 修改指定条目
支持:
• 精确修改: [{"ad_id": "XXX", "new_action": "bid_down", "new_change_pct": -0.05}]
• 批量修改: [{"filter": "all_pause", "new_action": "hold"}]
2. validate_decisions() → 重新验证
3. send_approval_request() → 重新发IM
4. execute_decisions() → 执行
护栏是整个系统的核心安全机制,防止AI做出错误决策。
规则:
IF (当前时间 - 数据时间) > 48小时:
→ Block所有非hold操作
原因:
• 广告数据实时性强, 过期数据会导致错误决策
• 超过48小时的数据已失去参考价值
示例:
数据: 20260415 (58小时前)
当前: 20260417 10:26
→ Block所有pause/bid_down, 转为hold
规则:
IF ad_age_days < 4天:
→ Block所有负向操作 (pause, bid_down)
IF 4天 ≤ ad_age_days < 7天:
→ pause仍然Block
→ bid_down限制最大降幅5%
原因:
• 新广告需要时间学习用户画像
• 初始出价通常比目标CPA高20%, 需等系统优化
• 过早干预会打断学习过程
示例:
广告90289631207: ad_age_days=5天, AI建议pause
→ Block (谨慎期不允许暂停)
→ 转为hold
规则:
IF recommended_bid < 0.5元:
→ Modified (钳位到0.5元)
IF recommended_bid > 200元:
→ Modified (钳位到200元)
原因:
• 低于0.5元竞争力不足, 无法获得曝光
• 高于200元风险过高, 可能是计算错误
示例:
AI建议: bid_down -50%, current_bid=0.8元 → recommended_bid=0.4元
→ Modified: final_bid=0.5元
规则:
IF 今日已对该广告调整次数 ≥ 2:
→ Block
IF 距上次调整时间 < 6小时:
→ Block
IF 今日累计调幅 > 20%:
→ Block
原因:
• 频繁调整会触发平台模型重学习
• 超过10%单次调幅会导致流量崩塌
• 需要给系统足够时间反馈效果
示例:
广告32912382309: 今日已降价1次 (-5%), 距离上次调整3小时
AI再次建议降价 (-3%)
→ Block (间隔不足6小时)
规则:
IF 今日已操作广告数 ≥ 200:
→ 按ROI严重度排序
→ Block低优先级广告
原因:
• 避免一次性大规模调整
• 分散风险, 逐步优化
优先级:
1. pause (极低ROI, 持续亏损)
2. bid_down (ROI接近关停线)
3. bid_up (高ROI低消耗)
规则:
IF DRY_RUN_MODE = True:
→ 所有操作标记dry_run
→ 不实际调用API
用途:
• 测试阶段验证决策逻辑
• 模拟执行, 查看效果预测
Token管理 (动态获取):
# tools/ad_api.py
def _get_access_token(account_id):
"""
优先从内部API获取 (30分钟缓存)
失败时降级使用 .env 静态token
"""
url = f"https://api.piaoquantv.com/ad/put/tencent/getAccessToken?accountId={account_id}"
response = requests.get(url)
if response.ok:
return response.json()["data"]["accessToken"]
else:
return os.getenv("TENCENT_AD_ACCESS_TOKEN")
广告操作API:
# 暂停广告
POST /v3.0/adgroups/update
{
"account_id": 80769799,
"adgroup_id": 90289631207,
"configured_status": "AD_STATUS_SUSPEND"
}
# 修改出价
POST /v3.0/adgroups/update
{
"account_id": 80769799,
"adgroup_id": 32912382309,
"bid_amount": 30 # 单位: 分 (0.30元)
}
应用信息:
APP_ID = "cli_a955e97067f85cb3"
APP_SECRET = "NQaG4ci1plXRDTgwCqrLJgMLLoA2tdF8"
OPERATOR_OPEN_ID = "ou_498988d823b61ab89c9afe4310f85bb4"
CHAT_ID = "oc_88e0a1970a7de02eb5ac225a8b0cedea"
消息发送:
# 卡片式消息
POST https://open.feishu.cn/open-api/im/v1/messages
{
"receive_id": CHAT_ID,
"msg_type": "interactive",
"content": {
"config": {"wide_screen_mode": true},
"header": {
"title": {"tag": "plain_text", "content": "【广告调控审批】"}
},
"elements": [
{"tag": "markdown", "content": "**决策摘要**\n..."},
{"tag": "hr"},
{"tag": "action", "actions": [
{"tag": "button", "text": "批准", "type": "primary"},
{"tag": "button", "text": "拒绝", "type": "danger"}
]}
]
}
}
审批轮询:
# 每30秒检查一次运营回复
while not timeout:
messages = get_chat_history(CHAT_ID)
for msg in messages:
if msg.sender == OPERATOR_OPEN_ID:
# 自然语言理解运营意图
intent = parse_approval_intent(msg.content)
if intent.type == "approve":
return ApprovalResult(approved=True)
elif intent.type == "modify":
return ApprovalResult(modified=intent.modifications)
数据拉取:
# tools/data_query.py
def _fetch_from_odps(bizdate, account_id):
"""
从MaxCompute (ODPS)拉取创意数据
"""
sql = f"""
SELECT
bizdate,
ad_id,
creative_id,
ad_name,
cost,
open_count,
fission0_count,
total_return_count,
total_revenue,
view_count,
valid_click_count,
conversions_count
FROM creative_data_table
WHERE bizdate = {bizdate}
AND account_id = {account_id}
"""
odps_client = ODPSClient(project="loghubods")
df = odps_client.query_to_dataframe(sql)
return df
[ODPS数据仓库]
↓
creative_data (创意级, 每日2.5MB)
↓
[data_query.py] fetch_creative_data
↓
outputs/raw/creative_YYYYMMDD.csv (原始创意数据)
↓
[data_query.py] merge_creative_data
↓
outputs/merged/merged_YYYYMMDD.csv (创意+广告状态合并)
↓
[roi_calculator.py] calculate_roi_metrics
• 加载最近30天 merged 数据
• 聚合到广告级 (GROUP BY ad_id, date)
• 计算 f_7日动态ROI
• 计算 7日/30日汇总指标
↓
outputs/metrics_20260415.csv (1570行广告级指标)
↓
[ad_decision.py] get_ads_for_review
• 计算全体ROI分布
• 检测衰退信号
• 分类(零消耗待关停 / 待评估 / 正常运行)
↓
JSON结构化数据 (发给AI)
↓
[Agent AI推理] 52个【待评估(候选)】广告逐个分析
↓
decisions JSON (AI输出)
↓
[ad_decision.py] apply_decisions
• 合并三类决策(零消耗关停 + 待评估AI + 正常保持)
• 过滤已暂停广告
• 计算出价变更
↓
outputs/reports/llm_decisions_20260415.csv (613条决策)
↓
[guardrails.py] validate_decisions
• 6道护栏逐条检查
• 拦截/修正/通过
↓
outputs/reports/validated_decisions_20260415.csv (带护栏状态)
↓
[im_approval.py] send_approval_request
• 过滤 approved 决策
• 分级 (Tier 1/2/3)
• 发送飞书卡片
• 阻塞等待审批
↓
[运营审批] 自然语言回复
↓
[execution_engine.py] execute_decisions
• 调用腾讯广告API
• 记录执行日志
↓
outputs/execution_log/execution_20260415.json (执行结果)
↓
[report_generator.py] generate_report
• 汇总统计
• Excel美化
↓
outputs/reports/decision_20260415.xlsx (最终报告)
# config.py
USE_RULE_ENGINE = False # 规则引擎 (固定阈值, 快速)
USE_AI_ENGINE = True # 智能引擎 (AI推理, 灵活)
优劣对比:
规则引擎:
✅ 速度快 (秒级)
✅ 可解释性强
❌ 无法处理复杂场景
❌ 阈值需人工调整
智能引擎:
✅ 自适应 (动态阈值)
✅ 处理复杂因果关系 (ROI+消耗+趋势)
✅ 自然语言交互
❌ 速度较慢 (分钟级)
❌ 需要LLM调用成本
# 风险分层审批, 平衡效率与安全
Tier 1 (自动执行, 无需审批):
• 出价调整 ≤ 5%
• 日消耗 < 500元
→ 实时生效, 仅通知运营
Tier 2 (需审批):
• pause
• bid_down > 5%
• bid_up > 5%
→ 发飞书等待审批
Tier 3 (强制审批):
• 日消耗 > 1500元 (高价值广告)
• 出价调整 > 10% (高风险操作)
→ 运营必须回复
# 打破传统"批准/拒绝"二元模式
# Agent理解运营的自然语言指令, 灵活调整
示例1:
运营: "广告90289631207改为降价5%, 不要暂停"
→ modify_decisions([{
"ad_id": 90289631207,
"new_action": "bid_down",
"new_change_pct": -0.05
}])
→ validate → 重新发审批
示例2:
运营: "ROI低于1.5的全部暂停, 其他批准"
→ filter decisions where ROI < 1.5 → pause
→ filter decisions where ROI >= 1.5 → approved
→ execute
示例3:
运营: "这个广告为什么要暂停? 我觉得还有机会"
→ Agent解释: "该广告ROI=1.18, 低于关停线1.64, 已持续23天消耗
1524元/天, 总亏损>1万元, 建议暂停止损"
→ 运营: "那降价20%试试"
→ Agent: "降价20%超过单次调幅上限10%, 已调整为-10%"
→ modify_decisions → 重新验证 → 执行
# 执行后6小时检查效果, 持续优化
[execution_engine.py] execute_decisions
→ 记录执行时间戳
↓
[execution_engine.py] check_execution_feedback (6小时后)
→ 拉取最新数据
→ 对比执行前后ROI变化
→ 计算决策准确率
↓
决策准确率统计:
• pause正确率: 95% (暂停后ROI无改善)
• bid_down正确率: 80% (降价后ROI提升)
• bid_up正确率: 70% (提价后收入增长)
↓
反馈到下次决策:
• 调整阈值 (如ROI关停线从0.5→0.6)
• 优化调幅策略 (如降价步长从-8%→-10%)
# 多层级容错机制
数据层:
• ODPS拉取失败 → 使用本地缓存
• merged数据缺失 → 跳过缺失日期, 使用可用数据
API层:
• 腾讯广告API限流 → 自动重试 (指数退避)
• Token过期 → 自动刷新
审批层:
• 飞书审批超时 (30分钟) → 自动取消, 保留决策供下次执行
• 网络错误 → 降级为邮件审批
# 避免重复拉取数据
def fetch_creative_data(days=7):
for i in range(days):
date = (today - timedelta(days=i)).strftime("%Y%m%d")
csv_path = RAW_DIR / f"creative_{date}.csv"
if csv_path.exists() and csv_path.stat().st_size > 1000:
logger.info(f"跳过已有数据: {date}")
continue # 跳过已存在的数据
# 仅拉取缺失数据
df = _fetch_from_odps(date, account_id)
df.to_csv(csv_path)
# 增量计算, 避免重复处理
metrics_cache = {}
def calculate_roi_metrics(end_date):
cache_key = end_date
if cache_key in metrics_cache:
return metrics_cache[cache_key]
# 计算新数据
result = _do_calculation(end_date)
metrics_cache[cache_key] = result
return result
# 减少网络往返
# ❌ 逐个调用 (慢)
for decision in decisions:
update_ad(decision.ad_id, decision.final_bid)
# ✅ 批量调用 (快)
batch_update_ads([
{"adgroup_id": d.ad_id, "bid_amount": d.final_bid}
for d in decisions
])
auto_put_ad_mini (当前) → auto_put_ad (完整版)
┌───────────────────┐ ┌─────────────────────────────┐
│ 监控调控 Agent │ 接入 │ 受众策略 Agent │
│ • ROI分析 │ ───────→ │ 创意策略 Agent │
│ • 出价调整 │ │ 预算策略 Agent │
│ • 广告暂停 │ │ ★ 监控调控 Agent (mini升级) │
└───────────────────┘ │ 数据分析 Agent │
│ 系统运维 Agent │
│ 自学习/反馈环 │
└─────────────────────────────┘
# 训练预测模型
from sklearn.ensemble import RandomForestRegressor
# 特征工程
features = [
"cost_7d_avg", "roi_7d_avg", "ad_age_days",
"bid_amount", "audience_tier", "creative_count",
"cost_trend", "roi_trend"
]
# 训练目标: 预测未来7天ROI
model = RandomForestRegressor()
model.fit(X_train[features], y_train["future_7d_roi"])
# 决策辅助
future_roi_if_bid_down = model.predict(current_features + [-0.10])
if future_roi_if_bid_down > current_roi:
recommend("bid_down", -0.10)
# 对比不同策略效果
def ab_test_bid_strategy():
"""
将广告随机分为A/B组
A组: 激进策略 (降幅10%)
B组: 保守策略 (降幅5%)
"""
group_a = random.sample(low_roi_ads, 20)
group_b = random.sample(low_roi_ads, 20)
execute_decisions(group_a, bid_change_pct=-0.10)
execute_decisions(group_b, bid_change_pct=-0.05)
# 7天后对比
roi_improvement_a = compare_roi(group_a, after=7)
roi_improvement_b = compare_roi(group_b, after=7)
if roi_improvement_a > roi_improvement_b:
adopt_strategy("aggressive")
# 当前: 单一优化ROI
# 未来: 多目标优化 (ROI + Volume + Risk)
from scipy.optimize import minimize
def objective(bid):
roi = predict_roi(bid)
volume = predict_volume(bid)
risk = calculate_risk(bid)
# 加权目标函数
return -1 * (
0.5 * roi + # 50%权重: ROI
0.3 * volume + # 30%权重: 规模
-0.2 * risk # 20%权重: 风险(负向)
)
optimal_bid = minimize(objective, x0=current_bid)
# 症状
ERROR - fetch_creative_data失败: No columns to parse from file
# 原因
• ODPS查询返回空结果
• 网络连接失败
• Token过期
# 解决
1. 检查ODPS连接: odps_client.test_connection()
2. 检查Token有效性: _get_access_token(account_id)
3. 查看空文件: ls -lh outputs/raw/*.csv | grep "4B"
4. 删除空文件: rm outputs/raw/creative_20260416.csv
5. 重新拉取: python3 execute_once.py
# 症状
护栏验证: blocked 599个, approved 1个
原因: [数据新鲜度] 数据已过期(58小时前,上限48小时)
# 原因
使用了过期数据 (20260415), 超过48小时新鲜度上限
# 解决
1. 拉取最新数据: fetch_creative_data(days=2)
2. 计算最新ROI: calculate_roi_metrics(end_date="yesterday")
3. 重新分析: execute_once.py
# 症状
流程执行完成, 但没有发送飞书消息
# 原因
• 所有决策被护栏拦截 → 无需审批
• EXECUTION_ENABLED=False → 不执行操作
• 飞书Token过期
# 检查
1. 查看validated_decisions: guardrail_status列是否全是blocked
2. 检查config.py: EXECUTION_ENABLED = True
3. 测试飞书API: send_test_message()
# 症状
52个【待评估(候选)】广告, AI只建议暂停2个, 其余全hold
# 原因
• ROI阈值设置过严格
• 置信度要求过高
# 调整
1. 降低关停线: ROI_LOW_FACTOR = 0.5 → 0.6 (config.py)
2. 修改Skill提示: "对置信度medium的也可以暂停" (roi-strategy.md)
3. 增加样本: 提供历史决策案例供AI参考
examples/auto_put_ad_mini/
├── run.py # 交互式运行入口 (支持多轮对话)
├── execute_once.py # 单次执行入口 (自动化运行)
├── config.py # 核心配置 (阈值、开关、API凭据)
├── presets.json # 预设参数
├── .env # 环境变量 (Token、密钥)
│
├── prompts/
│ └── system.prompt # Agent系统提示词 (模式路由、决策流程)
│
├── skills/
│ ├── roi_strategy.md # ROI决策框架 (注入给AI的领域知识)
│ ├── guardrail_rules.md # 护栏规则说明
│ └── ad_domain.md # 广告领域知识 (腾讯广告API、营销概念)
│
├── tools/
│ ├── data_query.py # 数据拉取+合并 (ODPS → CSV)
│ ├── roi_calculator.py # ROI计算 (f_7日动态ROI核心算法)
│ ├── ad_decision.py # 决策引擎 (A/B/C分类 + AI决策保存)
│ ├── guardrails.py # 安全护栏 (6道检查)
│ ├── execution_engine.py # 执行引擎 (调用腾讯广告API)
│ ├── im_approval.py # 飞书审批 (阻塞式自然语言审批)
│ ├── report_generator.py # 报告生成 (Excel美化)
│ ├── feishu_doc.py # 飞书文档导入 (可选)
│ └── ad_api.py # 腾讯广告API封装 (底层调用)
│
└── outputs/
├── raw/ # 原始数据 (creative_*.csv, ad_status_*.csv)
├── merged/ # 合并数据 (merged_*.csv)
├── ad_status/ # 广告状态快照
├── reports/ # 决策报告
│ ├── llm_decisions_*.csv # AI原始决策
│ ├── validated_decisions_*.csv # 护栏验证后
│ ├── decision_*.csv # 最终决策(CSV)
│ └── decision_*.xlsx # 最终决策(Excel)
├── execution_log/ # 执行审计日志
├── data/
│ └── adjustment_history.json # 调整历史记录
└── metrics_*.csv # 广告级ROI指标 (核心数据)
auto_put_ad_mini 是一个生产级的智能广告调控系统,具备:
当前状态: 可独立运行,完成"数据→决策→执行"闭环 未来定位: 接入完整auto_put_ad体系,成为监控调控Agent核心
文档版本: v1.0 最后更新: 2026-04-17 作者: Claude Sonnet 4.5