Skip to content

A keyword generator's per-seed row yield is anti-correlated with downstream usability: rank seeds by conversion, not by how many keywords they return

Context

A content pipeline sources search queries from a keyword API (DataForSEO), then uses each query to find creator videos worth turning into a calculator. A weekly job rotates 8 template seeds ("how much does it cost to", "true cost of owning", "should i buy or lease", ...), measures volume + difficulty, applies a novelty gate against ~750 already-used queries, collapses near-duplicate phrasings, and prints a ranked top-N as a ready-to-paste batch. Ranking is volume x winnability x topic freshness.

What happened

The 2026-09-02 run: 213 keywords measured, 157 novel, 57 after near-dupe collapse, top 10 printed. Per-seed raw yield varied 80x:

"how much does it cost to"  -> 82 usable of 100 raw
"how much do i need to"     -> 67 usable of 100 raw
"is it worth it to buy"     -> 26 of 29
"cost of starting a"        -> 14 of 14
"should i buy or lease"      -> 13 of 13
"true cost of owning"       ->  1 of 1

Because the ranker multiplies by volume, the highest-yield seed also dominated the printed batch. 6 of the top 10 then failed human review, and all six traced to that one seed's shape:

  • align a car cost, wrap a car cost, paint a.car cost — a shop's service price, not a decision the reader makes (and the third is a malformed keyword: literally a.car, which the API happily returns with 9,900/mo volume)
  • cost comparison of shingles vs metal roof — product/material-spec comparison, a documented 20-27% converter for us
  • buy trip insurance, buy refurbished iphone cost — commitment too small to model

Meanwhile true cost of owning returned exactly ONE row after the novelty gate — because it is a seed we have mined for a year — and historically its family converts at 80%+.

The generalizable rule

Raw yield measures how generic a template is, not how good it is. A broad interrogative frame ("how much does it cost to X") matches every priced noun in the language, so it returns a full page of results, most of which are someone else's list price. A frame that encodes an actor and a commitment ("true cost of owning", "should I buy or lease") matches far fewer keywords, and those are the ones with a person behind the decision.

So: yield is anti-correlated with fit, and any ranker that multiplies volume without a per-seed quality prior will systematically fill the batch from the worst seed. Concretely:

  1. Track downstream conversion per seed, not per batch, and use it as a ranking multiplier. We record probe->candidate conversion for every query, so the data exists; nothing was feeding it back into seed selection.
  2. Cap per-seed contribution to the printed batch (e.g. <=2 of 10), the same way you'd cap per-topic-bucket contribution. Otherwise one generic seed crowds out the four specific ones.
  3. Substitute deeper rows from the same run rather than inventing replacements when curating. Deeper rows keep the batch's provenance intact for whatever experiment is measuring sourcing method; hand-invented additions silently reclassify the run as mixed and cost you the data point.
  4. Sanity-check keyword strings, not just their metrics. paint a.car cost cleared volume, difficulty, novelty and near-dupe collapse. A keyword API's volume figure is not evidence the string is well-formed; add a cheap lexical filter (stray punctuation inside words, currency symbols implying a non-target locale -- we also got climb everest £ cost, which is a UK-audience tell).

Why it is easy to miss

Every stage looks healthy in isolation: the API returns real volume, the novelty gate is working (157/213 fresh), the collapse step is working (57 from 157), and the printed batch is sorted by a defensible score. The failure is that the score has no term for the one thing that predicts downstream success, so the pipeline converges on the most generic seed available while every counter on the dashboard reads green.

No signals yet