Systems Library / Marketing Automation / How to Build AI-Powered Bid Strategy Recommendations
Marketing Automation paid advertising

How to Build AI-Powered Bid Strategy Recommendations

Use AI to analyze data and recommend optimal bid strategies for each campaign.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

AI bid strategy recommendations for Google Ads take the guesswork out of choosing between Target CPA, Maximize Conversions, Target ROAS, and manual bidding. I run this analysis monthly for every account. It looks at conversion volume, CPA stability, and ROAS trends to recommend the right strategy per campaign.

The wrong bid strategy wastes budget quietly. The right one can improve CPA 15-25% with zero creative changes.

What You Need Before Starting

Step 1: Pull Campaign Performance Data

import sqlite3

def get_campaign_stats(db_path, days=30):
    conn = sqlite3.connect(db_path)
    campaigns = conn.execute("""
        SELECT campaign_name,
            COUNT(DISTINCT date) as days_active,
            SUM(spend) as total_spend,
            SUM(conversions) as total_conversions,
            AVG(conversions) as avg_daily_conversions,
            CASE WHEN SUM(conversions)>0 THEN SUM(spend)/SUM(conversions) ELSE 0 END as avg_cpa,
            STDEV(CASE WHEN conversions>0 THEN spend/conversions ELSE NULL END) as cpa_stddev,
            SUM(revenue) as total_revenue,
            CASE WHEN SUM(spend)>0 THEN SUM(revenue)/SUM(spend) ELSE 0 END as roas
        FROM google_ads_daily
        WHERE date >= DATE('now', ? || ' days')
        GROUP BY campaign_name
        HAVING SUM(spend) > 50
    """, (f"-{days}",)).fetchall()
    conn.close()
    
    return [{"name": r[0], "days": r[1], "spend": r[2], "conversions": r[3],
             "avg_daily_conv": r[4], "avg_cpa": r[5], "cpa_stddev": r[6],
             "revenue": r[7], "roas": r[8]} for r in campaigns]

Step 2: Classify Campaign Readiness

def classify_campaigns(campaigns):
    classified = []
    for c in campaigns:
        conv_volume = "high" if c["avg_daily_conv"] >= 2 else "medium" if c["avg_daily_conv"] >= 0.5 else "low"
        cpa_stability = "stable" if c["cpa_stddev"] and c["cpa_stddev"] / c["avg_cpa"] < 0.3 else "volatile"
        has_revenue = c["revenue"] and c["revenue"] > 0
        
        c["conv_volume"] = conv_volume
        c["cpa_stability"] = cpa_stability
        c["has_revenue"] = has_revenue
        classified.append(c)
    
    return classified

Step 3: Generate AI Recommendations

import anthropic

def recommend_bid_strategies(campaigns):
    client = anthropic.Anthropic()
    
    campaign_text = "\n".join([
        f"- {c['name']}: {c['conversions']:.0f} conversions in {c['days']} days, "
        f"CPA ${c['avg_cpa']:.2f} ({'stable' if c['cpa_stability']=='stable' else 'volatile'}), "
        f"ROAS {c['roas']:.2f}x, Conv volume: {c['conv_volume']}"
        for c in campaigns
    ])
    
    prompt = f"""Recommend a Google Ads bid strategy for each campaign.

Available strategies:
- Maximize Conversions: Best for campaigns needing more volume, requires 15+ conv/month
- Target CPA: Best for stable CPA campaigns with 30+ conv/month
- Target ROAS: Best for revenue-focused with stable ROAS and 50+ conv/month
- Maximize Conversion Value: When you have revenue data but not enough for Target ROAS
- Manual CPC: When conversion volume is too low for automation

CAMPAIGNS:
{campaign_text}

For each campaign recommend:
1. Bid strategy name
2. Suggested target (CPA amount or ROAS %)
3. Reasoning (2 sentences max)
4. Risk level (low/medium/high)
5. Expected impact

Be specific with numbers. Do not hedge.
Return as JSON array."""

    resp = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1500,
        messages=[{"role": "user", "content": prompt}]
    )
    return resp.content[0].text

Step 4: Build the Recommendation Report

import json

def format_report(recommendations_json, campaigns):
    recs = json.loads(recommendations_json)
    
    report = "BID STRATEGY RECOMMENDATIONS\n" + "=" * 40 + "\n\n"
    
    for rec in recs:
        report += f"Campaign: {rec['campaign_name']}\n"
        report += f"  Recommended: {rec['bid_strategy']}\n"
        report += f"  Target: {rec['suggested_target']}\n"
        report += f"  Risk: {rec['risk_level']}\n"
        report += f"  Expected: {rec['expected_impact']}\n"
        report += f"  Reasoning: {rec['reasoning']}\n\n"
    
    return report

Step 5: Track Strategy Changes

def log_strategy_change(db_path, campaign_name, old_strategy, new_strategy, reason):
    conn = sqlite3.connect(db_path)
    conn.execute("""CREATE TABLE IF NOT EXISTS bid_strategy_log (
        id INTEGER PRIMARY KEY, campaign TEXT, old_strategy TEXT, new_strategy TEXT,
        reason TEXT, changed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        performance_before TEXT, performance_after TEXT
    )""")
    conn.execute("INSERT INTO bid_strategy_log (campaign, old_strategy, new_strategy, reason) VALUES (?,?,?,?)",
                 (campaign_name, old_strategy, new_strategy, reason))
    conn.commit()
    conn.close()

After implementing a change, check back in 14 days. Compare the before and after CPA and conversion volume. Log the result so the system learns which strategy transitions actually work for your accounts.

What to Build Next

Build an automated performance comparison that checks campaigns 14 days after a bid strategy change and reports whether the switch improved results. Then add seasonal adjustments that recommend strategy shifts during high and low traffic periods.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems