@houtini/fanout-mcp 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextpro
5
5
  import { analyzeContentGap, AnalyzeContentGapSchema, } from "./tools/analyze-content-gap.js";
6
6
  const server = new Server({
7
7
  name: "fanout-mcp",
8
- version: "0.1.0",
8
+ version: "0.2.8",
9
9
  }, {
10
10
  capabilities: {
11
11
  tools: {},
package/package.json CHANGED
@@ -1,69 +1,69 @@
1
- {
2
- "name": "@houtini/fanout-mcp",
3
- "version": "0.2.8",
4
- "mcpName": "io.github.houtini-ai/fanout",
5
- "description": "Multi-URL comparative content analysis with topical gap detection",
6
- "type": "module",
7
- "main": "dist/index.js",
8
- "bin": {
9
- "fanout-mcp": "dist/index.js"
10
- },
11
- "scripts": {
12
- "build": "tsc",
13
- "dev": "tsc --watch",
14
- "prepare": "npm run build"
15
- },
16
- "keywords": [
17
- "mcp",
18
- "model-context-protocol",
19
- "content-analysis",
20
- "content-gap-analysis",
21
- "seo",
22
- "geo",
23
- "generative-engine-optimization",
24
- "query-generation",
25
- "query-decomposition",
26
- "keyword-fanout",
27
- "self-rag",
28
- "rag",
29
- "ai-search",
30
- "claude",
31
- "anthropic"
32
- ],
33
- "author": "Richard Baxter <richard@houtini.ai>",
34
- "license": "Apache-2.0",
35
- "repository": {
36
- "type": "git",
37
- "url": "git+https://github.com/houtini-ai/fanout-mcp.git"
38
- },
39
- "homepage": "https://houtini.com/query-fan-out-mcp-for-ai-search-optimisation/",
40
- "bugs": {
41
- "url": "https://github.com/houtini-ai/fanout-mcp/issues"
42
- },
43
- "engines": {
44
- "node": ">=18.0.0"
45
- },
46
- "files": [
47
- "dist",
48
- "README.md",
49
- "LICENSE",
50
- "houtini-logo.jpg",
51
- "server.json",
52
- "research/keyword-fanout-explained.md",
53
- "research/google-fanout-adaptation.md"
54
- ],
55
- "dependencies": {
56
- "@anthropic-ai/sdk": "^0.32.1",
57
- "@modelcontextprotocol/sdk": "^1.26.0",
58
- "cheerio": "^1.0.0-rc.12",
59
- "fast-xml-parser": "^5.3.4",
60
- "node-fetch": "^3.3.2",
61
- "turndown": "^7.1.2",
62
- "zod": "^3.22.4"
63
- },
64
- "devDependencies": {
65
- "@types/node": "^20.10.0",
66
- "@types/turndown": "^5.0.4",
67
- "typescript": "^5.3.0"
68
- }
69
- }
1
+ {
2
+ "name": "@houtini/fanout-mcp",
3
+ "version": "0.2.9",
4
+ "mcpName": "io.github.houtini-ai/fanout",
5
+ "description": "Multi-URL comparative content analysis with topical gap detection",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "bin": {
9
+ "fanout-mcp": "dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "prepare": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "content-analysis",
20
+ "content-gap-analysis",
21
+ "seo",
22
+ "geo",
23
+ "generative-engine-optimization",
24
+ "query-generation",
25
+ "query-decomposition",
26
+ "keyword-fanout",
27
+ "self-rag",
28
+ "rag",
29
+ "ai-search",
30
+ "claude",
31
+ "anthropic"
32
+ ],
33
+ "author": "Richard Baxter <richard@houtini.ai>",
34
+ "license": "Apache-2.0",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/houtini-ai/fanout-mcp.git"
38
+ },
39
+ "homepage": "https://houtini.com/query-fan-out-mcp-for-ai-search-optimisation/",
40
+ "bugs": {
41
+ "url": "https://github.com/houtini-ai/fanout-mcp/issues"
42
+ },
43
+ "engines": {
44
+ "node": ">=18.0.0"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "README.md",
49
+ "LICENSE",
50
+ "houtini-logo.jpg",
51
+ "server.json",
52
+ "research/keyword-fanout-explained.md",
53
+ "research/google-fanout-adaptation.md"
54
+ ],
55
+ "dependencies": {
56
+ "@anthropic-ai/sdk": "^0.32.1",
57
+ "@modelcontextprotocol/sdk": "^1.26.0",
58
+ "cheerio": "^1.0.0-rc.12",
59
+ "fast-xml-parser": "^5.3.6",
60
+ "node-fetch": "^3.3.2",
61
+ "turndown": "^7.1.2",
62
+ "zod": "^3.22.4"
63
+ },
64
+ "devDependencies": {
65
+ "@types/node": "^20.10.0",
66
+ "@types/turndown": "^5.0.4",
67
+ "typescript": "^5.3.0"
68
+ }
69
+ }
@@ -1,242 +0,0 @@
1
- # Fan-Out MCP: Research Phase Complete
2
-
3
- **Date:** December 15, 2024
4
- **Status:** ✅ Research Validated → Ready for Implementation
5
-
6
- ---
7
-
8
- ## Executive Summary
9
-
10
- We've successfully validated the "fan-out" MCP concept through deep research into cutting-edge Information Retrieval science. **The approach is sound and implementable.**
11
-
12
- ### What We Validated
13
-
14
- ✅ **Query Decomposition** - Established technique from 2022+ research
15
- ✅ **Reverse HyDE** - Emerging but validated for intent prediction
16
- ✅ **Self-RAG** - Perfect for coverage assessment and validation
17
- ✅ **Content Gap Analysis (GEO)** - Hot topic in AI search optimization
18
-
19
- ### What We Decided
20
-
21
- **Multi-Mode Architecture:**
22
- 1. **Single URL** - Deep analysis with full query graph (start here)
23
- 2. **Batch Processing** - 5-20 URLs with aggregate coverage matrix
24
- 3. **Sitemap Analysis** - Full site audit with dashboard (future)
25
-
26
- **Output Format:**
27
- - Data-driven with coverage scores
28
- - Justified with evidence quotes or explicit gaps
29
- - Actionable with specific, prioritized recommendations
30
- - Downloadable for larger analyses (JSON/HTML reports)
31
-
32
- ---
33
-
34
- ## Research Findings (TL;DR)
35
-
36
- ### Is The Approach Sound?
37
-
38
- **YES - 95% Confidence**
39
-
40
- The four techniques we identified are all actively researched at MIT, Stanford, Microsoft Research, and Google Research. Our innovation is **combining all four** into a unified content gap analysis system.
41
-
42
- ### Key Papers
43
-
44
- 1. **Least-to-Most Prompting** (2022) - Query decomposition foundation
45
- 2. **Self-RAG** (2023, arXiv:2310.05837) - Coverage assessment
46
- 3. **HyDE** (Gao et al., 2022) - Hypothetical document embeddings
47
- 4. **GEO Research** - Google/Stanford work on AI search biases
48
-
49
- ### The Gap We're Filling
50
-
51
- Nobody has combined these techniques into a practical content gap analysis tool. This is our opportunity to build something cutting-edge that addresses a real need (optimizing content for AI search engines).
52
-
53
- ---
54
-
55
- ## Technical Architecture
56
-
57
- ### MCP Tools
58
-
59
- ```typescript
60
- 1. analyze_content_gap(url: string, depth?: string, focus_area?: string)
61
- // Single URL analysis with full query graph
62
- // Returns: Detailed coverage report with recommendations
63
-
64
- 2. analyze_batch_urls(urls: string[], depth?: string)
65
- // Batch processing with coverage matrix
66
- // Returns: Aggregate analysis + downloadable data
67
-
68
- 3. analyze_sitemap(sitemap_url: string, max_pages?: number)
69
- // Full site analysis (future enhancement)
70
- // Returns: Dashboard artifact + downloadable report
71
- ```
72
-
73
- ### Processing Pipeline
74
-
75
- ```
76
- 1. FETCH → Scrape content (Supadata/Firecrawl)
77
- 2. DECOMPOSE → Generate query graph (Sonnet 4.5 + LtM principles)
78
- 3. ASSESS → Coverage validation (Sonnet 4.5 + Self-RAG critique)
79
- 4. ANALYZE → Gap prioritization and recommendations
80
- 5. OUTPUT → Formatted report (markdown/JSON/artifact)
81
- ```
82
-
83
- ### Token Budget
84
-
85
- **Single URL:** ~19K tokens per analysis
86
- **Batch (10 URLs):** ~50K tokens
87
- **Conclusion:** Very feasible within Claude Desktop limits
88
-
89
- ---
90
-
91
- ## Implementation Plan
92
-
93
- ### Phase 1: MVP (Single URL) - Week 1
94
- - [ ] Create `fanout-mcp` repository structure
95
- - [ ] Implement `analyze_content_gap` tool
96
- - [ ] Create prompt templates for decomposition + assessment
97
- - [ ] Test on your own articles (known content)
98
- - [ ] Iterate until output quality is reliable
99
-
100
- ### Phase 2: Batch Processing - Week 2
101
- - [ ] Implement `analyze_batch_urls` tool
102
- - [ ] Add coverage matrix aggregation
103
- - [ ] Create downloadable JSON output
104
- - [ ] Test with 5-10 related articles
105
-
106
- ### Phase 3: Polish & Publish - Week 3
107
- - [ ] Error handling and edge cases
108
- - [ ] Documentation and examples
109
- - [ ] Publish as `@houtini/fanout-mcp`
110
- - [ ] Write article about the process
111
-
112
- ### Phase 4: Integration (Future)
113
- - [ ] Integrate with Content Machine pipeline
114
- - [ ] Add sitemap analysis mode
115
- - [ ] Create artifact dashboards for visualization
116
-
117
- ---
118
-
119
- ## Success Criteria
120
-
121
- ### MVP Success
122
- - ✅ Generates specific, realistic queries (not generic)
123
- - ✅ Accurately identifies gaps (no false positives)
124
- - ✅ Provides actionable recommendations (not vague)
125
- - ✅ Completes in <30 seconds per URL
126
-
127
- ### Production Success
128
- - ✅ Content writers actually use it
129
- - ✅ Recommendations improve coverage scores
130
- - ✅ Integration with Content Machine works smoothly
131
-
132
- ---
133
-
134
- ## Files Created
135
-
136
- All research documentation is in `C:\MCP\fanout-mcp\research\`:
137
-
138
- 1. **ir-research-findings.md** - Full Gemini deep research report
139
- 2. **design-decisions.md** - Answers to your specific questions
140
- 3. **technical-implementation.md** - Detailed architecture and code patterns
141
- 4. **README.md** - This summary document
142
-
143
- ---
144
-
145
- ## What Makes This Cutting-Edge
146
-
147
- ### Research-Backed Innovation
148
-
149
- - **Least-to-Most Prompting** - Proven to outperform Chain-of-Thought
150
- - **Reverse HyDE** - Novel application of embedding alignment to content
151
- - **Self-RAG** - Latest technique for self-critique and validation
152
- - **GEO Context** - Perfect timing as AI search becomes dominant
153
-
154
- ### Practical Value
155
-
156
- - Solves real problem (content gap analysis for AI search)
157
- - Automates tedious manual process
158
- - Provides data-driven, justified recommendations
159
- - Integrates with existing content workflows
160
-
161
- ### Technical Excellence
162
-
163
- - Proper separation of concerns (MCP handles data, Sonnet handles reasoning)
164
- - Adversarial validation prevents hallucinated coverage
165
- - Prioritization based on query importance and tier
166
- - Scalable from single URL to full site analysis
167
-
168
- ---
169
-
170
- ## Confidence Assessment
171
-
172
- | Aspect | Confidence | Notes |
173
- |--------|-----------|-------|
174
- | Research Backing | 100% ✅ | All techniques validated in literature |
175
- | Technical Feasibility | 95% ✅ | Prompting complexity is main challenge |
176
- | Market Timing | 95% ✅ | GEO is emerging now |
177
- | Implementation Effort | 70% ⚠️ | Will require prompt iteration |
178
-
179
- ---
180
-
181
- ## Risks & Mitigations
182
-
183
- ### Risk 1: Query Generation Too Generic
184
- **Mitigation:** Prompt engineering with specific examples, iterative refinement
185
-
186
- ### Risk 2: False Positives in Coverage
187
- **Mitigation:** Self-RAG adversarial validation, require exact evidence quotes
188
-
189
- ### Risk 3: Processing Time Too Long
190
- **Mitigation:** Start with single URL mode, add caching for batch processing
191
-
192
- ### Risk 4: Output Too Complex
193
- **Mitigation:** Multiple output modes (quick/standard/comprehensive)
194
-
195
- ---
196
-
197
- ## Next Action: Start Building
198
-
199
- You now have everything needed to start implementation:
200
- - ✅ Research validates the approach
201
- - ✅ Architecture is designed
202
- - ✅ Tool signatures are defined
203
- - ✅ Prompt templates are sketched
204
- - ✅ Success criteria are clear
205
-
206
- **Recommended First Step:** Create the repository structure and implement a minimal version of `analyze_content_gap` that just does query decomposition. Test that first, then add coverage assessment.
207
-
208
- ---
209
-
210
- ## Questions Answered
211
-
212
- ### Q1: Is our approach sound?
213
- **A:** YES - Extremely sound, backed by cutting-edge research from top institutions.
214
-
215
- ### Q2: Single URL or batch processing?
216
- **A:** BOTH - Start with single URL (MVP), add batch processing (practical), then sitemap (enterprise).
217
-
218
- ### Q3: What should the output look like?
219
- **A:** Data-driven coverage scores, justified with evidence, actionable recommendations, downloadable for larger analyses.
220
-
221
- ---
222
-
223
- ## Final Recommendation
224
-
225
- 🚀 **BUILD IT**
226
-
227
- This is a cutting-edge tool at the perfect time:
228
- - Research is solid (100% validated)
229
- - Market need is emerging (GEO is hot)
230
- - Technical feasibility is high (95%)
231
- - Integration path is clear (Content Machine)
232
-
233
- Start with the MVP (single URL analysis) to prove the concept. If that works well, the batch and sitemap modes are straightforward extensions.
234
-
235
- The combination of these four research techniques hasn't been done before in a practical tool. This could become a reference implementation for content gap analysis in the GEO era.
236
-
237
- ---
238
-
239
- **Status:** ✅ Research Phase Complete
240
- **Next Phase:** Implementation
241
- **Timeline:** 2-3 weeks to MVP
242
- **Confidence:** 🟢 High
@@ -1,738 +0,0 @@
1
- # Google's Query Fan-Out: Research Adaptation
2
-
3
- **Date:** December 15, 2024
4
- **Status:** Design Document - Ready for Implementation
5
- **Research Source:** Google's query variant generation methodology (Patent US 11663201 B2, related research)
6
-
7
- ---
8
-
9
- ## Executive Summary
10
-
11
- This document outlines how we're adapting Google's query fan-out methodology for our content gap analysis use case. Google's approach uses trained generative models to expand user queries into multiple variants, leveraging contextual signals and iterative refinement. We're implementing a similar system using Claude Sonnet 4.5 via LLM prompting rather than neural network training.
12
-
13
- **Key Decision:** Use LLM prompting with Claude Sonnet 4.5 instead of trained models for flexibility, faster iteration, and avoiding training data requirements.
14
-
15
- ---
16
-
17
- ## Source Research: Google's Methodology
18
-
19
- ### Core Approach
20
-
21
- Google's system generates query variants through a "multitask model" that can produce different types of variants on demand. The system:
22
-
23
- 1. Takes an original query as input
24
- 2. Incorporates contextual signals (temporal, user profile, intent)
25
- 3. Generates multiple variant types simultaneously
26
- 4. Scores variants based on relevance and answer-finding capability
27
- 5. Uses iterative refinement with feedback loops
28
-
29
- ### Technical Architecture
30
-
31
- **Input Features:**
32
- - Original query text
33
- - Context vector (temporal, user attributes, dialog history)
34
- - Type value input (specifies which variant type to generate)
35
- - Prior variants and search responses (for iterative refinement)
36
-
37
- **Output:**
38
- - Multiple query variants with response scores
39
- - Grading based on answer retrieval success
40
- - Filtering of misleading/irrelevant variants
41
-
42
- ---
43
-
44
- ## Query Variant Types: Google's Taxonomy
45
-
46
- ### The 8 Core Types
47
-
48
- Based on Google's research and our analysis, we're implementing these variant types:
49
-
50
- #### 1. **Follow-up Queries**
51
- **Definition:** Logical next questions a user might ask after the original query.
52
-
53
- **Google Example:**
54
- - Original: "What are the best protein powders for runners?"
55
- - Follow-up: "best protein powder for post-run recovery"
56
-
57
- **Our Adaptation:** Generate 3-5 follow-up queries that assume the user has consumed the content and wants to go deeper or explore related aspects.
58
-
59
- ---
60
-
61
- #### 2. **Generalization Queries**
62
- **Definition:** Broader versions of the original query that encompass the specific query within a larger context.
63
-
64
- **Our Adaptation:** Create variants that zoom out from the specific keyword to related broader topics.
65
-
66
- **Example:**
67
- - Original: "direct drive sim racing wheels"
68
- - Generalization: "sim racing wheels comparison", "force feedback racing wheels"
69
-
70
- ---
71
-
72
- #### 3. **Specification Queries**
73
- **Definition:** More detailed or specific versions that drill down into particular aspects.
74
-
75
- **Our Adaptation:** Add qualifiers, brands, use cases, or technical details to make queries more specific.
76
-
77
- **Example:**
78
- - Original: "sim racing wheels"
79
- - Specification: "Fanatec DD Pro wheel review", "best sim racing wheel for Formula 1", "direct drive vs belt driven racing wheels"
80
-
81
- ---
82
-
83
- #### 4. **Entailment/Equivalent Queries**
84
- **Definition:** Alternative phrasings with the same intent; logically implied questions.
85
-
86
- **Google calls these:** "Canonicalization Queries" - standardized forms
87
-
88
- **Our Adaptation:** Rephrase the keyword in different ways whilst maintaining semantic meaning.
89
-
90
- **Example:**
91
- - Original: "sim racing cockpit"
92
- - Equivalent: "racing simulator rig", "sim rig setup", "racing seat and wheel stand"
93
-
94
- ---
95
-
96
- #### 5. **Comparison Queries**
97
- **Definition:** Queries seeking to compare options, alternatives, or competing solutions.
98
-
99
- **Our Adaptation:** Generate "vs" queries, "best of" queries, and alternative exploration queries.
100
-
101
- **Example:**
102
- - Original: "sim racing wheels"
103
- - Comparison: "Fanatec vs Thrustmaster wheels", "direct drive vs gear driven sim wheels", "best budget sim racing wheel"
104
-
105
- ---
106
-
107
- #### 6. **Clarification Queries**
108
- **Definition:** Questions seeking to understand concepts, definitions, or mechanisms.
109
-
110
- **Our Adaptation:** "What is...", "How does...", "Why..." variants that address understanding gaps.
111
-
112
- **Example:**
113
- - Original: "direct drive sim racing wheels"
114
- - Clarification: "what is direct drive technology", "how do direct drive wheels work", "why are direct drive wheels better"
115
-
116
- ---
117
-
118
- #### 7. **Related Aspects Queries**
119
- **Definition:** Connected topics or latent sub-intents not explicitly stated in the original query.
120
-
121
- **Google Example:** For "Bluetooth headphones with comfortable over-ear design and long-lasting battery", fan-out recognizes facets like design, technology, then generates sub-queries about user reviews, expert reviews, comparisons.
122
-
123
- **Our Adaptation:** Identify implicit facets and generate queries exploring those aspects.
124
-
125
- **Example:**
126
- - Original: "sim racing wheels"
127
- - Related Aspects: "sim racing wheel setup guide", "best pedals for sim racing", "wheel compatibility with PC games"
128
-
129
- ---
130
-
131
- #### 8. **Temporal Queries**
132
- **Definition:** Time-specific versions incorporating seasonal, current, or time-bound context.
133
-
134
- **Our Adaptation:** When temporal context is provided, generate variants with time qualifiers.
135
-
136
- **Example:**
137
- - Original: "sim racing wheels"
138
- - With context {season: "winter", year: "2024"}: "best sim racing wheels 2024", "sim racing black friday deals", "new sim racing wheels released in 2024"
139
-
140
- ---
141
-
142
- ## Context Signals and Attributes
143
-
144
- ### What Google Uses
145
-
146
- **Temporal Context:**
147
- - Time of query
148
- - Season
149
- - Proximity to events
150
-
151
- **User-Specific Context:**
152
- - Profile data
153
- - Past queries
154
- - Dialog history
155
- - User attributes
156
-
157
- **Task/Intent Context:**
158
- - Dialog intent classification
159
- - Query intent (research, commercial, comparison)
160
- - Entity and variable identification
161
-
162
- **Environmental Context:**
163
- - Ambient noise
164
- - Device type
165
- - Input modality (spoken/typed)
166
-
167
- ### What We're Implementing
168
-
169
- **Phase 1 (Immediate):**
170
- ```typescript
171
- interface AnalysisContext {
172
- temporal?: {
173
- currentDate?: string;
174
- season?: string;
175
- };
176
- intent?: "shopping" | "research" | "navigation" | "entertainment";
177
- specificity_preference?: "broad" | "specific" | "balanced";
178
- }
179
- ```
180
-
181
- **Why Limited Context?**
182
- 1. Privacy - we don't have user profile data
183
- 2. Simplicity - content analysis doesn't need full user modeling
184
- 3. Extensibility - structure allows future expansion
185
-
186
- **Phase 2 (Future Enhancement):**
187
- - User location for regional queries
188
- - Content language detection
189
- - Topic domain classification
190
-
191
- ---
192
-
193
- ## Quality Criteria for Variants
194
-
195
- ### Google's Criteria
196
-
197
- 1. **Relevance:** Variants must relate to original intent
198
- 2. **Answer-Finding:** Must lead to retrievable answers
199
- 3. **Diversity:** Cover different facets without redundancy
200
- 4. **Factual Accuracy:** No hallucinated or misleading queries
201
- 5. **Response Scores:** Each variant gets scored for quality
202
-
203
- ### Our Implementation
204
-
205
- **Validation Methods:**
206
-
207
- 1. **Relevance Check (Prompt-Level):**
208
- - Instruct Claude to maintain semantic relationship
209
- - Request realistic, user-typed queries only
210
- - Emphasize connection to source keyword
211
-
212
- 2. **Coverage Check (Self-RAG):**
213
- - Test each variant against actual content
214
- - Assess if content can answer the variant
215
- - Filter out variants with no content support
216
-
217
- 3. **Diversity Check (Post-Processing):**
218
- - Deduplicate near-identical variants
219
- - Ensure distribution across variant types
220
- - Check for complementary rather than overlapping coverage
221
-
222
- 4. **Quality Metrics:**
223
- ```typescript
224
- interface VariantQuality {
225
- totalVariants: number;
226
- variantDistribution: Record<FanOutVariantType, number>;
227
- avgCoverageScore: number;
228
- uniquenessRatio: number; // % of non-duplicate variants
229
- answerabilityRate: number; // % that content can answer
230
- }
231
- ```
232
-
233
- ---
234
-
235
- ## Iterative Refinement Approach
236
-
237
- ### Google's Method
238
-
239
- **Actor-Critic Model:**
240
- - Actor (generative model) creates variants
241
- - Critic (evaluation system) scores them
242
- - Feedback from search responses informs next iteration
243
- - Up to 20 iterations with reinforcement learning
244
-
245
- **Feedback Loop:**
246
- - Prior variants inform new generation
247
- - Search system responses guide refinement
248
- - User interactions update context vector
249
-
250
- ### Our Adaptation
251
-
252
- **Single-Pass Generation (Phase 1):**
253
-
254
- We're starting with single-pass generation for these reasons:
255
-
256
- 1. **Speed:** Content analysis needs fast results
257
- 2. **Simplicity:** Easier to implement and debug
258
- 3. **Cost:** Multiple LLM calls expensive at scale
259
- 4. **Use Case:** Our analysis doesn't require search-engine-level precision
260
-
261
- **Quality Control Without Iteration:**
262
- - Comprehensive prompt with examples
263
- - Few-shot learning within prompt
264
- - Post-generation validation
265
- - Self-RAG coverage assessment
266
-
267
- **Future Enhancement (Phase 2):**
268
-
269
- If quality isn't sufficient, we can add:
270
-
271
- ```typescript
272
- async generateVariantsIterative(
273
- keyword: string,
274
- content: ContentData,
275
- maxIterations: number = 3
276
- ): Promise<FanOutQuery[]> {
277
- let variants: FanOutQuery[] = [];
278
- let feedback: string = "";
279
-
280
- for (let i = 0; i < maxIterations; i++) {
281
- const newVariants = await this.generateVariants(
282
- keyword,
283
- content,
284
- variantTypes,
285
- context,
286
- feedback // Include feedback from previous iteration
287
- );
288
-
289
- variants = this.mergeAndDeduplicate(variants, newVariants);
290
- feedback = await this.assessQuality(variants, content);
291
-
292
- if (this.qualityThresholdMet(variants)) break;
293
- }
294
-
295
- return variants;
296
- }
297
- ```
298
-
299
- ---
300
-
301
- ## Prompt Engineering Methodology
302
-
303
- ### Structure Based on Google's Approach
304
-
305
- **Our Prompt Template:**
306
-
307
- ```typescript
308
- const VARIANT_GENERATION_PROMPT = `
309
- <thinking>
310
- You are implementing Google's Query Fan-Out methodology for content gap analysis.
311
-
312
- CONTEXT:
313
- - Target Keyword: "{keyword}"
314
- - Content Topic: {contentSummary}
315
- - Content Type: {article/guide/product page}
316
- ${temporal context if provided}
317
- ${intent context if provided}
318
-
319
- YOUR TASK:
320
- Generate query variants that real users would actually type when searching for information
321
- related to "{keyword}". Each variant must maintain semantic relationship to the keyword.
322
-
323
- VARIANT TYPES TO GENERATE:
324
-
325
- 1. FOLLOW-UP QUERIES (3-5 variants)
326
- Definition: Logical next questions after learning about {keyword}
327
- Quality Criteria:
328
- - Assumes user has basic knowledge from original query
329
- - Explores deeper aspects or related topics
330
- - Natural progression of learning/research
331
-
332
- Examples from your domain:
333
- - [Domain-specific few-shot examples]
334
-
335
- Your follow-up variants:
336
-
337
- 2. SPECIFICATION QUERIES (3-5 variants)
338
- Definition: More specific/detailed versions with added qualifiers
339
- Quality Criteria:
340
- - Add brands, models, use cases, or technical details
341
- - Must be answerable with specific information
342
- - Drill down into particular aspects
343
-
344
- Examples:
345
- - [Domain-specific few-shot examples]
346
-
347
- Your specification variants:
348
-
349
- [Continue for all 8 types...]
350
-
351
- QUALITY REQUIREMENTS:
352
- ✅ Realistic (users would actually type these)
353
- ✅ Semantically related to "{keyword}"
354
- ✅ Answerable by content (when checking coverage)
355
- ✅ Diverse (different angles, not repetitive)
356
- ✅ No hallucinated brands/products
357
- ❌ No marketing jargon
358
- ❌ No overly complex queries
359
- ❌ No irrelevant tangents
360
-
361
- OUTPUT FORMAT:
362
- Return ONLY valid JSON (no markdown, no explanation):
363
- {
364
- "followUp": ["query1", "query2", "query3"],
365
- "specification": ["query1", "query2", "query3"],
366
- "generalization": ["query1", "query2"],
367
- "equivalent": ["query1", "query2", "query3"],
368
- "comparison": ["query1", "query2", "query3"],
369
- "clarification": ["query1", "query2"],
370
- "relatedAspects": ["query1", "query2", "query3"],
371
- "temporal": ["query1", "query2"] // Only if temporal context provided
372
- }
373
- </thinking>
374
-
375
- Generate the variants now:
376
- `;
377
- ```
378
-
379
- ### Key Prompt Engineering Principles
380
-
381
- **1. Few-Shot Examples:**
382
- - Provide 2-3 examples per variant type
383
- - Use domain-relevant examples (sim racing, in our case)
384
- - Show both good and bad examples with explanation
385
-
386
- **2. Explicit Quality Criteria:**
387
- - List requirements inline for each type
388
- - Reference Google's methodology where relevant
389
- - Use checkmarks/crosses for visual clarity
390
-
391
- **3. Output Structure Enforcement:**
392
- - Request specific JSON format
393
- - Use `<thinking>` tags to prevent JSON pollution
394
- - Specify "no markdown, no explanation"
395
-
396
- **4. Context Incorporation:**
397
- - Inject temporal/intent context naturally
398
- - Make context optional (fallback to generic if missing)
399
- - Show how context influences generation
400
-
401
- **5. Semantic Constraints:**
402
- - Emphasize "realistic user queries"
403
- - Require semantic relationship to source
404
- - Prohibit hallucinations and jargon
405
-
406
- ---
407
-
408
- ## Implementation Decisions
409
-
410
- ### Why Claude Sonnet 4.5?
411
-
412
- **Advantages:**
413
- 1. **Strong reasoning:** Can understand complex variant type definitions
414
- 2. **Few-shot learning:** Excellent at following examples
415
- 3. **JSON reliability:** With `<thinking>` tags, produces clean JSON
416
- 4. **Context window:** Can handle extensive prompt with examples
417
- 5. **Speed:** Fast enough for real-time analysis
418
-
419
- **Comparison to Google's Approach:**
420
- - Google: Custom-trained neural networks
421
- - Us: General-purpose LLM with prompting
422
- - Trade-off: We sacrifice some precision for flexibility and speed
423
-
424
- ### Why Skip Neural Network Training?
425
-
426
- **Reasons:**
427
- 1. **No Training Data:** Don't have Google's query logs
428
- 2. **Flexibility:** LLM can adapt to new domains instantly
429
- 3. **Iteration Speed:** Prompt changes vs model retraining
430
- 4. **Resource Constraints:** Training expensive and time-consuming
431
- 5. **Generalization:** LLM handles diverse topics without domain-specific training
432
-
433
- **Validation:**
434
- - Google's patent shows LLMs work for this task
435
- - We can match quality through prompt engineering
436
- - If needed, future fine-tuning possible with collected data
437
-
438
- ### Why These 8 Variant Types?
439
-
440
- **Selection Criteria:**
441
- 1. **Coverage:** These types cover all major search intents
442
- 2. **Google's Validation:** All types mentioned in their research
443
- 3. **Content Analysis Fit:** Relevant to gap identification
444
- 4. **Implementability:** Can be prompted effectively
445
-
446
- **Types We Considered But Excluded:**
447
- - **Language Translation:** Not relevant for English content analysis
448
- - **Latent Topics (as separate type):** Covered by "Related Aspects"
449
- - **Canonicalization (as separate):** Merged into "Equivalent"
450
-
451
- ### Why Single-Pass Generation?
452
-
453
- **Decision:** Start with single-pass, add iteration if needed
454
-
455
- **Reasoning:**
456
- 1. **Speed Matters:** Content analysis should be fast
457
- 2. **Cost Control:** Each LLM call has API cost
458
- 3. **YAGNI Principle:** Don't build iteration until we prove we need it
459
- 4. **Quality First Pass:** Good prompting can produce quality without iteration
460
-
461
- **Success Criteria for Single-Pass:**
462
- - 80%+ variants are relevant
463
- - 60%+ variants are answerable by content
464
- - <10% duplicate/near-duplicate variants
465
-
466
- **Trigger for Adding Iteration:**
467
- - Relevance drops below 70%
468
- - Duplication exceeds 20%
469
- - User feedback indicates quality issues
470
-
471
- ---
472
-
473
- ## Integration Strategy
474
-
475
- ### Hybrid Mode Philosophy
476
-
477
- **Three Analysis Modes:**
478
-
479
- 1. **Content-Only (Original):**
480
- - Infer queries from content structure
481
- - No external keyword input
482
- - Pure content-based decomposition
483
-
484
- 2. **Hybrid (New Primary):**
485
- - Content inference + keyword fan-out
486
- - Merge both query sets intelligently
487
- - Show clear attribution in report
488
-
489
- 3. **Keyword-Only (New Optional):**
490
- - Skip content inference entirely
491
- - Focus purely on keyword variants
492
- - Faster for targeted analysis
493
-
494
- ### Merging Strategy
495
-
496
- **Challenge:** Avoid duplicates between content-inferred and keyword variants
497
-
498
- **Solution:**
499
- ```typescript
500
- mergeQueryGraphs(
501
- contentQueries: QueryGraph,
502
- fanOutQueries: FanOutQuery[]
503
- ): EnhancedQueryGraph {
504
- // 1. Normalize all queries (lowercase, remove punctuation)
505
- // 2. Calculate semantic similarity (cosine similarity on embeddings)
506
- // 3. Deduplicate if similarity > 0.85
507
- // 4. Distribute fan-out variants into tiers based on specificity
508
- // 5. Mark source clearly for reporting
509
- }
510
- ```
511
-
512
- **Distribution Logic:**
513
- - **Tier 1 (Prerequisite):** Clarification, Generalization variants
514
- - **Tier 2 (Core):** Equivalent, Specification variants
515
- - **Tier 3 (Follow-up):** Follow-up, Comparison, Related Aspects variants
516
- - **Temporal:** Distributed based on specificity
517
-
518
- ### Report Presentation
519
-
520
- **Two-Section Layout:**
521
-
522
- **Section 1: Content-Inferred Queries**
523
- - Standard 3-tier layout
524
- - Queries generated from content analysis
525
- - Shows how well content addresses natural progression
526
-
527
- **Section 2: Keyword Fan-Out Analysis**
528
- - Grouped by variant type
529
- - Color-coded differently (teal/cyan vs blue/purple/orange)
530
- - Includes variant type descriptions
531
- - Shows coverage by type
532
-
533
- **Synthesis Section:**
534
- - Combined coverage score
535
- - Recommendations prioritized by source
536
- - Gap analysis considering both methods
537
-
538
- ---
539
-
540
- ## What We're NOT Implementing (And Why)
541
-
542
- ### 1. User Profiling System
543
-
544
- **Google Has:** Rich user profiles (location, demographics, history)
545
-
546
- **We Don't Need:**
547
- - **Privacy Concerns:** Don't want to track user data
548
- - **Use Case Difference:** Analyzing content, not personalizing search
549
- - **Complexity:** Adds significant overhead for minimal benefit
550
-
551
- **What We Do Instead:** Optional basic context (intent, temporal)
552
-
553
- ---
554
-
555
- ### 2. Reinforcement Learning / Neural Network Training
556
-
557
- **Google Has:** Trained models with RL optimization
558
-
559
- **We Don't Need:**
560
- - **No Training Data:** Don't have query logs at scale
561
- - **Flexibility:** LLM adapts instantly without retraining
562
- - **Maintenance:** No model versioning/deployment overhead
563
-
564
- **What We Do Instead:** Prompt engineering with Claude Sonnet 4.5
565
-
566
- ---
567
-
568
- ### 3. Multi-Iteration Refinement (Initially)
569
-
570
- **Google Has:** Up to 20 iterations with actor-critic architecture
571
-
572
- **We Don't Need (Yet):**
573
- - **Speed:** Single-pass is faster
574
- - **Cost:** Multiple LLM calls expensive
575
- - **YAGNI:** Build it if quality isn't good enough
576
-
577
- **What We Do Instead:** High-quality single-pass with thorough prompting
578
-
579
- ---
580
-
581
- ### 4. Search System Integration
582
-
583
- **Google Has:** Feedback loop with actual search results
584
-
585
- **We Don't Need:**
586
- - **Different Use Case:** Analyzing content, not searching web
587
- - **Complexity:** Would require search API integration
588
- - **Self-RAG Sufficient:** Coverage assessment handles validation
589
-
590
- **What We Do Instead:** Self-RAG against content for validation
591
-
592
- ---
593
-
594
- ### 5. Real-Time Query Log Analysis
595
-
596
- **Google Has:** Massive query logs for pattern learning
597
-
598
- **We Don't Need:**
599
- - **Scale:** Not building search engine
600
- - **Privacy:** Don't collect user queries
601
- - **LLM Handles It:** General model understands query patterns
602
-
603
- **What We Do Instead:** Rely on LLM's training on web-scale text
604
-
605
- ---
606
-
607
- ## Future Enhancement Opportunities
608
-
609
- ### Phase 2 Additions (If Needed)
610
-
611
- **1. Iterative Refinement:**
612
- ```typescript
613
- // Add if single-pass quality insufficient
614
- async generateVariantsIterative(...) {
615
- // Actor-critic loop with feedback
616
- }
617
- ```
618
-
619
- **2. Semantic Deduplication:**
620
- ```typescript
621
- // Use embeddings for better duplicate detection
622
- async deduplicateWithEmbeddings(variants: string[]) {
623
- // Calculate cosine similarity
624
- // Cluster near-duplicates
625
- }
626
- ```
627
-
628
- **3. Context Prediction:**
629
- ```typescript
630
- // Auto-infer intent from content
631
- async inferContext(content: ContentData): Promise<AnalysisContext> {
632
- // Classify content type
633
- // Detect temporal signals
634
- // Predict user intent
635
- }
636
- ```
637
-
638
- **4. Cross-Variant Verification:**
639
- ```typescript
640
- // Check variants against each other for coherence
641
- async verifyVariantCoherence(variants: FanOutQuery[]) {
642
- // Ensure no contradictions
643
- // Validate logical relationships
644
- }
645
- ```
646
-
647
- ### Research Opportunities
648
-
649
- **1. LLM vs Trained Model Comparison:**
650
- - Collect quality metrics from our system
651
- - Compare to benchmarks from Google's research
652
- - Publish findings if novel insights emerge
653
-
654
- **2. Optimal Variant Count Study:**
655
- - Test 3 vs 5 vs 10 variants per type
656
- - Measure coverage improvement per additional variant
657
- - Find diminishing returns point
658
-
659
- **3. Context Signal Effectiveness:**
660
- - A/B test with/without context
661
- - Measure quality improvement per signal type
662
- - Identify most valuable signals for content analysis
663
-
664
- ---
665
-
666
- ## Success Criteria
667
-
668
- ### MVP Success (Phase 1)
669
-
670
- **Functional Requirements:**
671
- ✅ Generates variants for all 8 types
672
- ✅ Variants are realistic and user-typed
673
- ✅ Coverage assessment works for both content and keyword queries
674
- ✅ Reports clearly distinguish query sources
675
- ✅ No performance regression from current system
676
-
677
- **Quality Metrics:**
678
- - **Relevance:** 80%+ variants semantically related to keyword
679
- - **Answerability:** 60%+ variants answerable by content
680
- - **Diversity:** <10% duplicate/near-duplicate variants
681
- - **Speed:** Complete analysis in <60 seconds for standard depth
682
-
683
- ### Long-Term Success (Phase 2+)
684
-
685
- **Enhancement Triggers:**
686
- - User feedback requests iteration
687
- - Quality metrics below targets consistently
688
- - New use cases require advanced features
689
-
690
- ---
691
-
692
- ## Implementation Checklist
693
-
694
- **Design Phase (This Document):**
695
- - [x] Read and analyze Google's research
696
- - [x] Document variant type taxonomy
697
- - [x] Define context signal structure
698
- - [x] Design prompt engineering approach
699
- - [x] Identify what we're NOT implementing
700
- - [x] Establish success criteria
701
-
702
- **Implementation Phase (Next Steps):**
703
- - [ ] Extend TypeScript types (src/types.ts)
704
- - [ ] Create KeywordFanOut service (src/services/keyword-fanout.ts)
705
- - [ ] Update analyze-content-gap tool (src/tools/analyze-content-gap.ts)
706
- - [ ] Enhance report formatter (src/services/report-formatter.ts)
707
- - [ ] Update artifact instructions
708
- - [ ] Write comprehensive tests
709
- - [ ] Update README with examples
710
- - [ ] Validate against quality criteria
711
-
712
- **Documentation Phase:**
713
- - [ ] Update TESTING-HANDOVER.md with new scenarios
714
- - [ ] Add "Based on Research" section to README
715
- - [ ] Create example outputs for all three modes
716
- - [ ] Document prompt engineering decisions
717
-
718
- ---
719
-
720
- ## Conclusion
721
-
722
- We're adapting Google's sophisticated query fan-out methodology for a focused content analysis use case. By using LLM prompting instead of neural network training, we achieve flexibility and fast iteration whilst maintaining the core principles of Google's approach:
723
-
724
- 1. **Multiple variant types** for comprehensive coverage
725
- 2. **Context signals** to improve relevance
726
- 3. **Quality criteria** to filter poor variants
727
- 4. **Systematic methodology** grounded in research
728
-
729
- The design prioritizes pragmatism—implementing what's necessary for our use case whilst leaving room for future enhancement based on real-world usage.
730
-
731
- **Next Step:** Begin Phase 1 implementation, starting with type system extensions.
732
-
733
- ---
734
-
735
- **Document Version:** 1.0
736
- **Last Updated:** December 15, 2024
737
- **Author:** Richard Baxter (with Claude)
738
- **Review Status:** ✅ Ready for Implementation
@@ -1,274 +0,0 @@
1
- # Understanding Keyword Fan-Out: From Google Research to Production
2
-
3
- **I've been building content optimization tools for about three months now, and the gap between traditional keyword research and what AI search engines actually need is... significant.** Not because keywords don't matter anymore – they absolutely do – but because AI search engines like ChatGPT and Perplexity don't just match keywords, they understand query intent and retrieve content based on semantic variants you've probably never considered.
4
-
5
- This is where Google's query fan-out methodology becomes genuinely useful (to their detriment, I might add – this research should be more widely known).
6
-
7
- ---
8
-
9
- ## The Problem with Traditional Keyword Research
10
-
11
- Here's what I noticed whilst building the Fan-Out MCP: traditional keyword tools give you exact-match variants and maybe some synonyms. "Sim racing wheel" becomes "racing wheel" or "steering wheel for racing games". Useful, but incomplete.
12
-
13
- AI search engines work differently. When someone asks ChatGPT "what's the best wheel for Gran Turismo 7", the AI isn't just matching those exact words. It's understanding that this query relates to:
14
- - PS5 compatibility questions
15
- - Direct drive vs belt-driven comparisons
16
- - Budget ranges for different wheel types
17
- - Force feedback technology explanations
18
- - Setup complexity for beginners
19
-
20
- That's eight different content angles from one query, and you'd miss most of them with traditional keyword research.
21
-
22
- ---
23
-
24
- ## Google's Approach: Query Fan-Out
25
-
26
- Google's research (documented in [arXiv:2210.12084](https://arxiv.org/pdf/2210.12084) and Patent US 11663201 B2) uses neural networks to expand queries into multiple variant types. The system generates what they call "multitask" variants – different types of query transformations happening simultaneously.
27
-
28
- ### The Eight Variant Types
29
-
30
- I've implemented all eight types in the Fan-Out MCP, and here's what each one actually does:
31
-
32
- **1. Equivalent Variants**
33
- Alternative phrasings with identical intent. "PS5 racing wheel" → "PlayStation 5 steering wheel", "Sony PS5 racing controller".
34
-
35
- Test results: 100% coverage on these. Content that mentions one phrasing almost always covers the equivalents naturally.
36
-
37
- **2. Specification Variants**
38
- More detailed versions with qualifiers. "racing wheel" → "Fanatec GT DD Pro review", "budget racing wheel under £300".
39
-
40
- Test results: 80-90% coverage. These expose real gaps – my sim racing guide covered general wheels but missed specific budget breakdowns.
41
-
42
- **3. Follow-Up Variants**
43
- Logical next questions. "racing wheel" → "how to calibrate racing wheel", "best games for racing wheel".
44
-
45
- Test results: 60-70% coverage. Major gap area. Content answers the primary question but misses the obvious follow-ups users will search for next.
46
-
47
- **4. Comparison Variants**
48
- "Vs" queries and alternatives. "racing wheel" → "Thrustmaster vs Logitech wheels", "direct drive vs belt driven".
49
-
50
- Test results: 85% coverage. Buyer's guides naturally include comparisons, so content performs well here.
51
-
52
- **5. Clarification Variants**
53
- Understanding questions. "direct drive wheel" → "what is direct drive technology", "how does force feedback work".
54
-
55
- Test results: 50-60% coverage. Content assumes knowledge. Big opportunity for SEO + AI search optimization.
56
-
57
- **6. Generalization Variants**
58
- Broader encompassing queries. "Fanatec DD Pro" → "direct drive wheels", "force feedback racing wheels".
59
-
60
- Test results: 70% coverage. Content written for specific products usually mentions the broader category.
61
-
62
- **7. Related Aspects Variants**
63
- Connected implicit needs. "racing wheel" → "racing wheel desk mount", "wheel compatibility with PC".
64
-
65
- Test results: 40-60% coverage. These are the "I didn't even think to include this" gaps.
66
-
67
- **8. Temporal Variants**
68
- Time-specific versions. "racing wheels" → "best racing wheels 2024", "new racing wheels December 2024".
69
-
70
- Test results: Variable. Depends entirely on whether content includes dates and temporal qualifiers.
71
-
72
- ---
73
-
74
- ## Our Adaptation: Why Prompts Instead of Neural Networks
75
-
76
- Google's approach uses trained generative models. Ours uses Claude Sonnet 4.5 with carefully structured prompts. Here's why:
77
-
78
- **Flexibility:** I can adjust variant types, add new ones, or tune generation behaviour in minutes. Training a neural network takes days and requires GPU infrastructure.
79
-
80
- **Quality:** Claude Sonnet 4.5 generates remarkably realistic queries. Average realism score from testing: 0.75/1.0. That's better than I expected, honestly.
81
-
82
- **Cost:** Running inference on a 70B parameter model is expensive. Claude's API is predictable and scalable.
83
-
84
- **Iteration speed:** When I discovered that default should be 5 types instead of 8 (generalization, relatedAspects, and temporal are less actionable), I changed one line of code. With a trained model, that's a complete retraining cycle.
85
-
86
- The tradeoff? We can't do iterative refinement like Google's system (where the model uses search results to improve variants). But for content gap analysis, we don't need that – we're assessing content, not retrieving it.
87
-
88
- ---
89
-
90
- ## What Testing Revealed
91
-
92
- I ran seven comprehensive tests on a 6,491-word sim racing buyer's guide. Here's what actually happened:
93
-
94
- ### Test 1: Content-Only Baseline
95
- 14 queries generated purely from content structure. Coverage: 79/100. Processing time: 90 seconds.
96
-
97
- This validated the query decomposition approach. The three-tier system (prerequisite/core/follow-up) produces natural, realistic queries.
98
-
99
- ### Test 2: Hybrid Mode (The Critical Test)
100
- 14 content queries + 21 fan-out variants = 35 total. Coverage: 80/100. Processing time: 174 seconds.
101
-
102
- **Key finding:** Fan-out variants exposed gaps content analysis missed. The article covered "best PS5 racing wheel" but missed "wireless PS5 racing wheel options" and "how to calibrate PS5 racing wheel". Both are obvious user needs that content-only analysis didn't surface.
103
-
104
- This is the value proposition, basically. Content analysis tells you what queries your content answers. Fan-out tells you what query variants users will actually search for.
105
-
106
- ### Test 3: Keyword-Only Mode
107
- 19 variants, no content queries. Coverage: 76/100. Processing time: 86 seconds (50% faster).
108
-
109
- Validated that keyword variants alone provide actionable insights. Users who know their target keyword can skip content inference entirely.
110
-
111
- ### Test 7: Single-Word Keyword Edge Case
112
- Keyword: "PS5". Generated 20 variants, ALL contextually relevant to sim racing.
113
-
114
- **Critical finding:** Single-word keywords work brilliantly when content context is strong. No generic drift ("what is PS5") because the content understanding guides variant generation. I wasn't expecting this level of context awareness, genuinely.
115
-
116
- ---
117
-
118
- ## The Default Five vs All Eight Types
119
-
120
- Look, this is an important distinction that took testing to clarify.
121
-
122
- **Default (5 types):** equivalent, specification, followUp, comparison, clarification
123
- - 15-25 variants per keyword
124
- - Most actionable for content optimization
125
- - Covers immediate user needs
126
-
127
- **Opt-in (3 additional types):** generalization, relatedAspects, temporal
128
- - Adds 9-15 more variants
129
- - Broader coverage but less immediately actionable
130
- - Useful for comprehensive content audits
131
-
132
- The research shows all eight types, but in practice, the default five hit the sweet spot between coverage and actionability. The other three are available via the `fan_out_types` parameter when you need them.
133
-
134
- ---
135
-
136
- ## Quality Metrics That Actually Matter
137
-
138
- From testing across multiple scenarios:
139
-
140
- **Realism: 0.75/1.0**
141
- Variants sound like natural user queries. No AI slop like "leverage your sim racing setup" or "unlock direct drive potential".
142
-
143
- **Specificity: 0.44/1.0**
144
- Appropriate detail level. Not too generic ("racing" alone), not overly specific ("Fanatec Clubsport V2.5 with BMW GT2 wheel and CSL Elite pedals load cell brake mod version 1.2").
145
-
146
- **Generic Query Count: 0**
147
- Zero "what is PS5" style variants despite using "PS5" as a single-word keyword. Context guides generation effectively.
148
-
149
- **Domain Term Usage: 0.55**
150
- Good use of technical vocabulary. Variants include terms like "direct drive", "force feedback", "load cell" appropriately.
151
-
152
- **Coverage Accuracy: 85%**
153
- Low hallucination rate. When the system says content covers a query, it actually does.
154
-
155
- ---
156
-
157
- ## Performance Characteristics
158
-
159
- Assessment time dominates everything. Query generation is fast (~20 seconds for 15-35 queries), but assessing each query takes 4-5 seconds. This scales linearly.
160
-
161
- **Processing times:**
162
- - Content-Only: ~90s (14 queries)
163
- - Hybrid: ~174s (35 queries)
164
- - Keyword-Only: ~86s (19 queries)
165
-
166
- The math checks out: assessment time per query is consistent regardless of mode. Keyword complexity has zero impact (single-word vs multi-word identical).
167
-
168
- ---
169
-
170
- ## What This Means for Content Optimization
171
-
172
- Traditional SEO workflow:
173
- 1. Research keywords
174
- 2. Write content targeting those keywords
175
- 3. Hope you rank
176
-
177
- AI search optimization workflow:
178
- 1. Research primary keywords
179
- 2. **Generate query variants** (fan-out)
180
- 3. Write content addressing primary + variants
181
- 4. **Validate coverage** (Self-RAG assessment)
182
- 5. Fill identified gaps
183
-
184
- The fan-out step is what's missing from most content strategies. You're optimizing for the exact query but missing the 15-20 variants AI search engines will use to evaluate whether your content is authoritative.
185
-
186
- This is why some perfectly good articles get cited by ChatGPT whilst others don't – it's not keyword density, it's coverage of semantic variants.
187
-
188
- ---
189
-
190
- ## The Technical Implementation
191
-
192
- The system uses Claude Sonnet 4.5 with structured prompts in `<thinking>` tags to prevent JSON parsing errors. Each variant type gets specific instructions:
193
-
194
- ```typescript
195
- "Generate 3-5 EQUIVALENT variants that have identical search intent
196
- but use different phrasings. Must be natural user queries, not
197
- marketing speak. Examples: 'sim racing wheel' → 'racing simulator wheel',
198
- 'steering wheel for racing games'"
199
- ```
200
-
201
- Context signals (temporal, intent, specificity_preference) influence generation via prompt injection. Shopping intent produces "where to buy" and "best budget" variants. Research intent produces "how to" and comparison variants.
202
-
203
- The quality validation step filters unrealistic queries (over 15 words, marketing jargon, overly complex) before returning results.
204
-
205
- ---
206
-
207
- ## Limitations Worth Knowing
208
-
209
- **Assessment time scales linearly.** 50+ queries will take 4-5 minutes. This is fine for single-page analysis but would be slow for site-wide audits. Batch processing helps but doesn't eliminate the constraint.
210
-
211
- **Content length matters.** The system works best with 2,000-10,000 word articles. Very short content generates few queries. Very long content may exceed context windows.
212
-
213
- **English only.** Non-English content will be analyzed but query generation quality suffers. This is a Claude limitation, not a fan-out limitation.
214
-
215
- **Context understanding required.** Works brilliantly with focused topical content (like a sim racing guide). Less effective with highly diverse content (like general news sites).
216
-
217
- ---
218
-
219
- ## Where This Fits in the Toolchain
220
-
221
- I built this MCP server to fill a specific gap in my content optimization workflow. Traditional tools tell you which keywords to target. This tool tells you whether your content actually addresses those keywords *and their variants*.
222
-
223
- It sits between keyword research and content creation:
224
-
225
- ```
226
- Keyword Research (Ahrefs, SEMrush)
227
-
228
- Fan-Out Analysis (this MCP)
229
-
230
- Content Creation (with variant coverage)
231
-
232
- Coverage Validation (Self-RAG assessment)
233
- ```
234
-
235
- The research explainer might make it sound complicated, but in practice it's straightforward: give it a URL and a keyword, get back a list of query variants your content should address.
236
-
237
- ---
238
-
239
- ## Future Directions
240
-
241
- The patent mentions iterative refinement – using search results to improve variants. That's interesting for search engines but probably overkill for content analysis. What would be useful:
242
-
243
- **Batch URL analysis:** Process 10-20 URLs simultaneously, identify which pages cover which variants, surface coverage gaps across the entire site.
244
-
245
- **Competitive analysis:** Compare variant coverage between your content and competitors. Show specifically which variants they're covering that you're missing.
246
-
247
- **Historical tracking:** Monitor variant coverage over time. See if content updates actually improved coverage or just added words.
248
-
249
- These are all feasible extensions of the current architecture (fair enough – I'm already thinking about implementation).
250
-
251
- ---
252
-
253
- ## The Bottom Line
254
-
255
- Google's query fan-out research provides a legitimate framework for understanding how search engines expand user queries. Our adaptation using Claude Sonnet 4.5 proves the approach works without neural network training overhead.
256
-
257
- Testing validates the core hypothesis: content that addresses query variants performs better in AI search results. The system generates realistic variants (0.75 realism score), maintains appropriate specificity (0.44), and achieves high coverage accuracy (85%).
258
-
259
- The default five variant types provide the most actionable insights for content optimization. The additional three types are available when you need comprehensive coverage.
260
-
261
- If you're optimizing content for AI search engines, understanding query variants isn't optional anymore. It's the difference between getting cited by ChatGPT and getting ignored.
262
-
263
- ---
264
-
265
- **Research Sources:**
266
- - [Google Query Fan-Out Research (arXiv:2210.12084)](https://arxiv.org/pdf/2210.12084)
267
- - Google Patent US 11663201 B2: Query variant generation
268
- - Our implementation: `google-fanout-adaptation.md`
269
- - Test results: `TESTING-REPORT.md`
270
-
271
- **Version:** 1.0
272
- **Date:** December 15, 2024
273
- **Author:** Richard Baxter
274
- **Testing Corpus:** 6,491-word sim racing buyer's guide across 7 test scenarios