A Multi-Agent Workflow for SEO Content Brief Generation

A single agent doing research and structuring in one pass tends to shortcut both jobs. Splitting them across a Researcher, a Strategist, and a Reviewer that can send work back for a real second pass fixes what a linear pipeline can't catch.
Why a single agent writes a mediocre brief
Ask one model to research a keyword and structure a content brief in the same prompt, and you get an average of two different jobs done adequately instead of either one done well. Research is open-ended: figure out what's actually ranking, what subtopics and entities the top results cover, what the real search intent is. Structuring is closed-ended: turn that research into a writer-usable brief with headers, a target word count, and a specific list of things the draft has to cover. Blending them in one pass means the model tends to shortcut the research to get to the structuring, since a single prompt only gets one shot at both.
Splitting the two jobs across separate agents fixes the shortcut. Adding a third agent whose only job is to check the brief against the research, and send it back for another pass if something's missing, fixes the part neither one-shot prompting nor a simple two-step pipeline catches on its own.
What you're actually building
Inputs: a target keyword and your site's own existing content inventory (so the brief can suggest real internal links instead of imaginary ones). Output: a structured content brief, headers, target word count, required entities, internal link suggestions, that has been checked against the research and sent back for revision at least once if it fell short the first time.
Step 1: Split the job into three roles, plus the one that loops
Define a Researcher (finds what's actually ranking and what it covers), a Strategist (turns that research into a structured brief), and a Reviewer (checks the brief against the research and either approves it or sends it back). The Reviewer is what makes this a graph instead of a pipeline: a linear Researcher-to-Strategist handoff has no way to catch a brief that missed something, it just ships whatever the Strategist produced on the first pass.
Step 2: Build this as a graph, not a chain
Use LangGraph for this specifically, not a linear chain framework. LangGraph models the workflow as a stateful directed graph: each agent is a node, and the edges between them can branch on a condition instead of always moving forward. That's the exact shape this job needs: a normal edge from Researcher to Strategist, then a conditional edge out of the Reviewer node that either continues to "done" or loops back to the Strategist with specific feedback attached. A linear framework can fake a retry with an if-statement wrapped around the whole pipeline; a graph framework makes the loop an explicit, visible part of the workflow instead of a bolted-on exception.
Step 3: Give the Researcher live retrieval, not the model's memory
Wire the Researcher node to Perplexity's API for grounded, cited web search instead of letting it answer from training data. A keyword's top-ranking pages and the specific subtopics they cover change constantly; a model answering from memory will confidently describe a search landscape that's already stale.
Step 4: Force the Strategist's output into a brief schema, not prose
``` You are an SEO content strategist. Using the research below, produce a content brief for the keyword: "{{ keyword }}".
Research: {{ researcherOutput }}
Return ONLY valid JSON matching this schema, no commentary outside the JSON:
{ "target_word_count": "number", "search_intent": "informational | commercial | transactional | navigational", "required_h2s": ["string, each one a specific subtopic the draft must cover"], "required_entities": ["string, specific named things, tools, or concepts the research shows top results mention"], "internal_link_suggestions": ["string, an existing page slug from the provided inventory that's genuinely relevant, not a guess"] } ```
The required_entities field is what separates a real brief from a generic outline. Two articles targeting the same keyword and the same H2 structure can still differ completely in whether they actually name the specific tools, standards, or concepts a reader expects, and that field is what tells the writer exactly which ones to hit.
Step 5: Let the Reviewer check coverage and loop back on a real failure, not a vibe
``` You are reviewing a content brief against the research it was built from.
Brief: {{ strategistOutput }} Research: {{ researcherOutput }}
Check specifically:
- Does every major subtopic in the research appear in required_h2s?
- Does every named entity that appears in at least two of the top-ranking sources appear in required_entities?
- Is target_word_count within 20% of the average length of the top-ranking pages?
Return ONLY valid JSON: { "approved": boolean, "missing": ["string, specifically what's missing if not approved"] } ```
If approved is false, route the brief and the missing list back to the Strategist node instead of forward. This is the one loop worth building: catching a brief that's structurally fine but missing something the research clearly supports, before a writer spends an afternoon on it.
Where this breaks
- The Reviewer only checks against the Researcher's output, not the live web. If the Researcher missed a subtopic in the first pass, the Reviewer has no independent way to catch that, it's checking internal consistency, not re-verifying against the SERP itself.
- An infinite-loop guard is not optional. Cap the Strategist-Reviewer loop at 2-3 attempts before forcing a human review. Without a cap, a Reviewer with an unsatisfiable check (a word count target that's genuinely unreachable given the required entities) will loop forever.
- This does not replace an editor's judgment on angle. The graph checks coverage and structure, it says nothing about voice, whether the angle is actually differentiated from what's already ranking, or whether the keyword is worth targeting in the first place.
The three-question recipe
What are your distinct roles and where does the one loop actually belong (not every step needs to be revisable, just the one where a real failure is both likely and catchable), what's the exact schema each agent hands to the next, and what's your loop cap so a bad check fails safe instead of failing forever. That's the whole workflow, and it's the same shape whether the domain is a content brief or any other multi-step task where one step needs to be able to reject the output of the step before it.
Mentioned in This Post
LangGraph
Build stateful, multi-step AI agents that loop, branch, and pause for human input: modeled as graphs so you see exactly what your agent does at every step.
Perplexity
Get direct answers to hard questions with sources you can verify. Model Council now lets Pro subscribers query up to 8 models at once for a multi-perspective answer.
Claude
The model serious writers and researchers reach for when accuracy matters more than speed. Opus 5 is now the default, with voice mode expanded across every tier.
Related articles

Turning a Manual Competitor-Analysis SOP into a Repeatable AI Agent Skill
Turning a Manual Competitor-Analysis SOP into a Repeatable AI Agent Skill
6 min read

An AI Agent Workflow to Map Keywords to Existing Hub Pages
An AI Agent Workflow to Map Keywords to Existing Hub Pages
7 min read

Automating Google Search Console Data Extraction with AI
Automating Google Search Console Data Extraction with AI
8 min read
Signal, no noise.
A weekly breakdown of the AI tools and workflows actually worth your time.