Loading...
Loading...
The Ad Copy Generation skill produces high-performance responsive search ad (RSA) copy using AI-driven generation pipelines calibrated against millions of ad performance data points.
npx skill4agent add itallstartedwithaidea/agent-skills ad-copy-generationflowchart TD
A[Input: Keywords, Landing Page, USPs] --> B[Context Analysis]
B --> C[Landing Page Scraper]
B --> D[Keyword Intent Classifier]
B --> E[Competitor Ad Analyzer]
C --> F[Message Map Builder]
D --> F
E --> F
F --> G[AI Generation Engine]
G --> H[Headline Generator\nmax 30 chars x 15]
G --> I[Description Generator\nmax 90 chars x 4]
H --> J[Policy Compliance Check]
I --> J
J --> K[Ad Strength Scorer]
K -->|Excellent| L[Final Ad Variants]
K -->|Good| L
K -->|Average| M[Regenerate with Feedback]
K -->|Poor| M
M --> G
L --> N[Pin Strategy Optimizer]
N --> O[A/B Test Plan]
O --> P[Deploy to Google Ads]const HEADLINE_MAX_LENGTH = 30;
const DESCRIPTION_MAX_LENGTH = 90;
const MAX_HEADLINES = 15;
const MAX_DESCRIPTIONS = 4;
const COPYWRITING_FRAMEWORKS = {
AIDA: ['attention', 'interest', 'desire', 'action'],
PAS: ['problem', 'agitate', 'solve'],
BENEFIT: ['primary_benefit', 'secondary_benefit', 'proof', 'cta']
};
async function generateAdCopy(config) {
const { keywords, landingPageUrl, usps, industry, targetAudience } = config;
const landingPageContent = await scrapeLandingPage(landingPageUrl);
const competitorAds = await analyzeCompetitorAds(keywords);
const intentSignals = classifyKeywordIntent(keywords);
const headlines = await generateHeadlines({
keywords,
usps,
competitorAds,
intentSignals,
landingPageContent,
maxLength: HEADLINE_MAX_LENGTH,
count: MAX_HEADLINES
});
const descriptions = await generateDescriptions({
keywords,
usps,
landingPageContent,
maxLength: DESCRIPTION_MAX_LENGTH,
count: MAX_DESCRIPTIONS
});
return buildAdVariants(headlines, descriptions);
}
function applyDynamicKeywordInsertion(headline, defaultText) {
const dkiSyntax = `{KeyWord:${defaultText}}`;
if (dkiSyntax.length <= HEADLINE_MAX_LENGTH) {
return dkiSyntax;
}
return defaultText;
}
function generatePinStrategy(headlines, descriptions) {
return {
position1: headlines.filter(h => h.type === 'brand' || h.type === 'primary_keyword'),
position2: headlines.filter(h => h.type === 'benefit' || h.type === 'usp'),
position3: headlines.filter(h => h.type === 'cta' || h.type === 'offer'),
desc1: descriptions.filter(d => d.type === 'primary'),
desc2: descriptions.filter(d => d.type === 'supporting')
};
}function createABTestPlan(adVariants, config) {
const { minImpressions = 1000, confidenceLevel = 0.95 } = config;
return {
controlGroup: adVariants[0],
testGroups: adVariants.slice(1),
evaluationCriteria: {
primaryMetric: 'conversion_rate',
secondaryMetrics: ['ctr', 'cost_per_conversion'],
minImpressions,
confidenceLevel,
testDuration: calculateMinTestDuration(minImpressions)
},
decisionRules: {
winner: 'statistically_significant_improvement',
loser: 'statistically_significant_decline',
inconclusive: 'extend_test_or_increase_budget'
}
};
}
function evaluateAdStrength(headlines, descriptions) {
let score = 0;
const uniqueHeadlines = new Set(headlines.map(h => h.text.toLowerCase()));
if (uniqueHeadlines.size >= 8) score += 25;
if (headlines.some(h => h.includesKeyword)) score += 15;
if (headlines.some(h => h.includesCTA)) score += 15;
if (headlines.some(h => h.includesNumber)) score += 10;
if (descriptions.length >= 4) score += 15;
if (descriptions.some(d => d.includesCTA)) score += 10;
if (descriptions.some(d => d.includesUSP)) score += 10;
if (score >= 80) return 'Excellent';
if (score >= 60) return 'Good';
if (score >= 40) return 'Average';
return 'Poor';
}| Platform | Supported |
|---|---|
| Claude Code | ✅ |
| Cursor | ✅ |
| Codex | ✅ |
| Gemini | ✅ |