How to Build AI-Powered Bid Strategy Recommendations
Use AI to analyze data and recommend optimal bid strategies for each campaign.
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
- Google Ads performance data (at least 30 days)
- Python 3.8+ with
anthropicandsqlite3 - Campaign-level daily data with conversions and revenue
- Current bid strategy for each campaign
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
- AI in Paid Advertising: The Complete Overview - full ad operations landscape
- The Trust Framework for AI Decisions - trusting AI recommendations
- Three Types of Business AI - analytical AI for decision support
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