Agent skill
google-ads-search-framework
Keyword-first, table-driven method for planning, building, restructuring and auditing Google Ads Search campaigns.
Filed under ABM and paid.
From lbarberis/gtm-skills · 7 skill entries · 0 · pushed 2026-09-26
What it does when it runs
Keyword-first, table-driven method for planning, building, restructuring and auditing Google Ads Search campaigns. It forces the work through fixed tables (intake, keyword inventory, master table, budget split, negatives, details, self-check) so every keyword is paired with an intent, one ad group, one relevant ad and a bid, and campaigns exist only for budget control. Use this skill whenever someone asks to plan, launch, rebuild, audit or review a Google Ads Search campaign or account, build or clean a keyword list, group ad groups, choose match types, write responsive search ads, set search bidding or budgets, build negative keyword lists, or sanity-check a paid search structure, even if they never say "framework" or "Google Ads" explicitly (for example "paid search plan", "PPC structure", "search ads for X"). Not for Performance Max, Display, Demand Gen, YouTube, Meta or LinkedIn ads.
Automated analysis of the skill and the 0 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- None found.
- Hosts it reaches
- No third-party host appears in the skill or its bundled files.
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It only issues instructions, so there is nothing to bound. - Actions present in the files
- None. Instructions only.
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/lbarberis/gtm-skills.git /tmp/gtm-skills git -C /tmp/gtm-skills sparse-checkout set "skills/google-ads-search-framework" mkdir -p ~/.claude/skills/google-ads-search-framework cp -R "/tmp/gtm-skills/skills/google-ads-search-framework/." ~/.claude/skills/google-ads-search-framework/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
Or take the whole library
This repo ships a .claude-plugin manifest, so Claude Code can install all 7 skills at once. Plugin skills are invoked as /<plugin>:<skill>, so they never collide with your own.
/plugin marketplace add lbarberis/gtm-skills /plugin
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
The skill
Source on GitHub ↗Reproduced in full from lbarberis/gtm-skills/blob/aba514c75be2102fa8c91074bb978ee36cfa050b/skills/google-ads-search-framework/SKILL.md, which is licensed MIT (repository). 2,552 words, 18 headings.
Google Ads Search framework
The model
A Search account is a list of keywords. Each keyword is paired with a match type, an intent, one ad group, one ad written for that ad group (with its landing page) and a bid. Everything else is grouping, and each grouping layer has one job:
Rows: the three layers of the framework. Columns: what each layer is built for, and the test that decides what belongs in it.
| Layer | Built for | Membership test |
|---|---|---|
| Keyword, match type, bid | What you buy | Would we pay this price to appear for this search? |
| Ad group, ad, landing page | Relevance | Can this ad group's ad and page fully answer the keyword's intent? |
| Campaign | Budget control | Does the keyword's expected CPA or ROAS, and its role, match the campaign's budget and target? |
Google's own structure guidance uses the same two grouping tests: keywords sharing a budget and target share a campaign; keywords sharing a landing page and creative theme share an ad group.
Always start from keywords, never from campaigns. Campaigns are named last, once the performance tiers are visible in the keyword inventory.
House style for every output
- Tables first. Prose only as one or two lines of connective commentary between tables.
- Directly above every table, write one line stating what the rows and the columns represent (
Rows: ... Columns: ...). - Mark assumptions inside the tables (a
Sourcecolumn withgivenorassumed), not in a paragraph afterwards. - Label illustrative numbers as illustrative.
- Never use em dashes.
- Default to markdown tables. If the user asks for a document, page or printable output, render the same tables as HTML.
Why tables: they force every keyword through the same attributes, so gaps become visible empty cells (a keyword with no landing page, an ad group serving two intents, a campaign with no target) instead of being hidden in prose.
Workflow
Run the stages in order and end each stage with its table. Do not jump to the master table: the earlier tables are where the thinking happens. For a small request (for example "write ads for this ad group"), run only the stages it needs, but still use their tables.
Stage 1: Intake
Rows: inputs needed to build the account. Columns: Input | Value | Source (given or assumed) | What breaks if it is wrong.
Required inputs: product and core use case; target customer; markets and languages; primary conversion action; target CPA or ROAS; daily or monthly budget; landing pages that exist; brand terms; main competitors; sales cycle (B2B long or B2C short); current monthly conversion volume; existing account (yes or no).
If target CPA (or ROAS) or budget is missing, ask for it once before Stage 4, because campaigns cannot be split without it. For everything else, assume, flag it as assumed, and continue.
Stage 2: Keyword inventory
Rows: candidate keywords, typically 30 to 150. Columns: Keyword | Intent | Fit | Expected tier | Landing page that answers it | Decision.
| Column | Allowed values |
|---|---|
| Intent | Navigational, Transactional, Comparative, Problem-aware, Informational, Irrelevant |
| Fit | High, Lower, Negative |
| Expected tier | Brand, Core, Competitor, Discovery (add a tier only when its expected CPA truly differs) |
| Decision | Keep, Negate, Park |
Rules:
- Informational and Irrelevant intents become negatives, not ad groups.
- A keyword with no page that answers it is Parked, and the page to build is named.
- Group near-duplicates (plurals, reorderings) on one row; close variants will catch them.
Stage 3: Master table (the core deliverable)
Rows: one per keyword, grouped into ad groups, with ad groups grouped under a campaign band row. Columns, exactly in this order: Keyword and match type | Intent | Ad group | Ad text written for the ad group | Bidding.
Format rules:
- Keyword syntax:
[exact],"phrase",broad, followed by the match type in words. - Campaign band row before each campaign: first cell
**Campaign: <name>**, second cellBudget: <daily amount> (<share>), third cellStrategy: <bid strategy and target>, remaining cells empty. - Ad text cell, on the first row of each ad group:
H1 (pinned) / H2 / one description / final URL. On the following rows of the same ad group, writesame ad. - Bidding cell: the max CPC under Manual CPC, or
Set by strategyplus the target or cap.
Apply the two tests to every row, then fix the table before moving on:
- Relevance test: if the ad group's ad and page cannot answer the keyword's intent, move the keyword or create an ad group (one keyword is fine when it needs its own page, like "brand pricing").
- Budget test: if the keyword's expected CPA differs from its campaign's, move it to another campaign.
See references/northbill-example.md for a complete master table at the expected level of detail.
Stage 4: Campaign budget split
Rows: campaigns. Columns: Campaign | Keyword group | Match types | Expected performance | Budget share | Bid strategy | Budget rule.
Rows: default campaign tiers. Columns: starting budget share (illustrative) and the rule that protects it.
| Campaign | Starting share | Budget rule |
|---|---|---|
| Brand | 5 to 10% | Never limited by budget |
| Core: high fit | 50 to 60% | First claim on money; should never show "Limited by budget" while on target |
| Competitor | 10 to 15% | Capped, judged on its own CPA, never averaged into Core |
| Discovery: lower fit | 15 to 25% | Hard cap; carries routing negatives of Core keywords |
Create another campaign only when budget, target, country, language or conversion goal differs. Never split by device or by match type.
Stage 5: Negative keywords
Rows: negative categories. Columns: Category | Why it wastes spend | Example negatives | Match type | Level.
Check every one of these categories: free and pirated; job seekers; learning and DIY; informational; existing customers (login, support, cancel); different meaning of the same words; wrong segment; wrong geography or tax regime; competitors (only if no competitor campaign); own brand in non-brand campaigns; cross-campaign routing; cross-ad-group routing.
Rows: negative match types. Columns: syntax and blocking rule.
| Negative type | Syntax | Blocks a search when |
|---|---|---|
| Negative broad | free invoice | It contains every word, in any order |
| Negative phrase | "free invoice" | It contains the words in the same order |
| Negative exact | [free invoice] | It is exactly those words, nothing else |
Negatives do not expand to close variants: add plurals and synonyms yourself. They do follow casing and the misspellings Google auto-corrects.
Rows: where negatives live. Columns: scope and use.
| Level | Scope | Use it for |
|---|---|---|
| Account-level | All Search and Shopping inventory, including the search part of Performance Max | Universal exclusions |
| Shared list | Campaigns it is attached to (up to 20 lists of 5,000) | Themed lists reused across campaigns |
| Campaign | That campaign | Routing between campaigns, country exclusions |
| Ad group | That ad group | Routing between ad groups |
Add each new negative at the narrowest level that solves the problem.
Stage 6: Important details (kept separate)
Rows: settings and assets. Columns: Detail | What to do | Setting for this account.
Keep this table outside the master table: none of these items changes which keyword sits in which ad group or campaign. Cover at least: sitelinks (at least 4, ad-group-level where a theme has its own pages, unique text, both description lines); callouts (specific, not repeating headlines); structured snippets; at least 3 image assets; 4 or more asset types; headline 3 pin decision; Display Network off and Search partners off on Search campaigns; location option "Presence"; AI Max for Search off in Brand and Core; auto-apply recommendations off; conversion quality checked against the CRM; weekly search terms review.
Stage 7: Self-check
Rows: checks. Columns: Check | Pass or Fail | Fix.
- Every keyword has exactly one match type in its ad group (no duplicates across match types).
- Every keyword's intent is answered by its ad group's ad and landing page.
- Every campaign has one budget and one target; no two tiers with different expected CPA share a campaign.
- Broad match appears only where a winning experiment justifies it.
- Headlines at most 30 characters, descriptions at most 90, paths at most 15, sitelink text and callouts at most 25. Run
scripts/check_ad_lengths.pywhen code execution is available. - No competitor trademarks in ad text.
- Routing negatives exist in Discovery for Core keywords and their variants.
- Assumptions are flagged in the tables.
Rules (vetted against Google documentation and practitioners, September 2026)
Read references/sources.md when someone challenges a rule or asks why.
Match types
Rows: match types. Columns: role in this framework.
| Match type | Role |
|---|---|
| Exact | Top converters and brand. Most efficient on CPA and ROAS in practitioner data. |
| Phrase | The everyday workhorse for Core and Competitor; strongest in lead generation. |
| Broad | Not a default. Only in Discovery, and only after the broad match experiment below proves its extra conversions cost no more than target. |
Why this departs from Google: Google recommends broad match only, one ad group per theme, arguing broad reaches everything exact and phrase do plus more. That argument is about reach, and reach also grows spend. Practitioner data measures cost per conversion and favours exact and phrase, especially in lead generation. Two caveats keep this honest: practitioner data has its own biases (exact usually holds the proven best terms), and broad can find conversions exact never would. Hence the test.
Other rules:
- One match type per keyword per ad group. An eligible exact keyword identical to the search already wins over phrase, broad and Performance Max, so duplicates only split data.
- Plurals and synonyms are not "identical" for that priority rule: use routing negatives to push them to the right campaign.
- Broad match modifier no longer exists (retired 2021).
Broad match experiment: Google Ads custom experiment on the Discovery campaign, 50/50 split. Control: phrase keywords on current bidding. Treatment: the same keywords in broad with Target CPA and the same negatives. Run at least 4 weeks and until both arms have enough conversions to compare. Marginal CPA = (treatment cost minus control cost) divided by (treatment conversions minus control conversions). Adopt broad only if marginal CPA is at or below target and lead quality holds in the CRM. Brand and Core stay on exact and phrase regardless.
Ads (responsive search ads)
Rows: RSA elements. Columns: limit and relevance rule.
| Element | Limit | Rule |
|---|---|---|
| Headline 1 | 30 characters | The ad group's core keyword, pinned to position 1 |
| Headline 2 | 30 characters | A proven benefit; pin it in low-volume ad groups so the system learns faster |
| Headlines 3 to 15 | Up to 15 in total, at least 3 | Variants, proof, offer, call to action; each must read correctly next to every keyword in the ad group, in any order |
| Descriptions | Up to 4, 90 characters each, at least 2 | The job the searcher wants done, one proof point, one next step |
| Paths | 2 fields, 15 characters each | Repeat the theme |
| Final URL | One page | Built for the ad group's intent, headline echoing the search |
| Ads per ad group | Up to 3 enabled | Run 1 or 2 with different angles; judge on conversions per impression |
- Write every ad for one ad group only. Never share ad copy across themes.
- Ignore Ad Strength as a score: practitioner data finds no link to CTR or conversion rate. Its "more unique" and "more relevant to keywords" prompts are still useful checks.
- If AI Max final URL expansion is on, Google can send traffic to other pages and skip pinned assets. Keep AI Max off where ad-to-page relevance is the point.
- No competitor trademarks in ad text.
Bidding
Rows: bid strategies (Google's labels from June 2026). Columns: per-keyword control and where they fit.
| Strategy | Separate bid per keyword? | Use it for |
|---|---|---|
| Manual CPC | Yes (ad group default, keyword overrides) | Launch, brand, Discovery tests, B2B or long sales cycles with thin data |
| Maximize clicks | No (one cap) | Gathering search-term data before conversions exist |
| Target impression share | No (one cap) | Brand defence |
| Maximize conversions / Target CPA | No; target settable per ad group | Core and Competitor once conversion tracking is reliable |
| Maximize conversion value / Target ROAS | No; target settable per ad group | When conversions carry different values |
- Google says Target CPA can start with no history; practitioners wait for roughly 30 to 50 conversions a month. State which rule you are applying.
- Smart Bidding removes per-keyword bids, so tiering survives only through separate campaign (or portfolio) targets. This is why the budget test matters.
- For B2B with long sales cycles, Manual CPC plus rule-based adjustments is a legitimate long-term choice, not only a launch phase.
Quality Score
Quality Score is a keyword-level diagnostic (expected CTR, ad relevance, landing page experience), not an auction input and not a KPI. Never optimize the number. Use the weakest component to decide the fix: weak ad relevance means split the ad group; weak landing page experience means build a matching page.
Audit mode
When given an existing account (export, screenshots or a description):
- Rebuild its master table from what exists, as-is, including the flaws.
- Produce a findings table. Rows: findings. Columns: Finding | Rule broken | Evidence | Fix | Priority (High, Medium, Low).
- Produce the corrected master table and the diff: Rows: keywords that move. Columns: Keyword | From (campaign / ad group / match type) | To | Reason.
Common findings to look for: several intents in one ad group; one ad reused across ad groups; the same keyword in several match types; broad match everywhere without experiment evidence; brand and non-brand in one campaign; campaigns split by device or match type; Core "Limited by budget" while Discovery is not; Display or Search partners on; AI Max final URL expansion on in Core; no routing negatives; negatives missing plurals.
Reference files
references/northbill-example.md: a complete worked example of every stage table. Read it before the first build in a session to calibrate the level of detail.references/sources.md: official Google positions versus practitioner positions, with links and the date checked. Read when a rule is challenged, and re-verify anything older than six months.scripts/check_ad_lengths.py: checks headline, description, path, sitelink, callout and snippet lengths from a CSV. Usage:python scripts/check_ad_lengths.py ads.csvwith atype,textheader line (types: headline, description, path, sitelink, sitelink_description, callout, snippet).
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- google-ads-pmax-search-cannibalization-detector by Ad-Superpowers · 5
- google-ads-search-campaign-builder by Ad-Superpowers · 5
- google-ads-youtube-ads-strategist by Ad-Superpowers · 5
- google-search-ads-builder by edupegoretti · 0
- google-ads-audit by irinabuht12-oss · 3,698
- playbook-google-site-search by growthenginenowoslawski · 739
- google-ads by OpenClaudia · 708
- google-ads-report by OpenClaudia · 708
Need help setting it up?
This page tells you what google-ads-search-framework does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.