Inside a Multi-Agent SEO Machine: 6 Months in Production

The difficult part of autonomous content production is not getting an LLM to write 1,500 words. It is making sure the system chooses work worth doing, uses real evidence, follows a site’s editorial rules, publishes safely, and learns when its output does not perform.
For the past six months, I have been running that kind of system inside BizFlowAI ContentStudio. It is an autonomous content and SEO/AEO machine that researches, writes, optimizes, validates, and publishes across multiple sites. This is what the production architecture looks like, where the costs actually come from, and what broke once the system started handling real work instead of carefully prepared demos.
The system is not one agent, it is a controlled workflow of specialized agents
A production multi-agent SEO system should not be a group chat where five models debate a topic until one produces an article. It should be a durable workflow where each agent has a narrow job, structured inputs, explicit outputs, and permission to fail without corrupting the rest of the pipeline.
My content pipeline is organized around a job record, not around a long-lived conversation. Every article begins as a persisted job with a site, topic candidate, target audience, content type, status, and a trace of every decision made along the way.
At a high level, the flow looks like this:
Measure search performance
↓
Select opportunity
↓
Research and evidence collection
↓
Content brief and angle validation
↓
Draft generation
↓
Editorial, SEO, and factual checks
↓
Publish or hold for review
↓
Measure performance again
Each stage is handled by a different agent or deterministic service. That distinction matters.
An LLM is useful where interpretation is required. It is not the right tool for checking whether a URL returns a 200 response, validating markdown frontmatter, detecting duplicate slugs, or confirming that an article has an internal link. Those are ordinary software problems. I solve them with deterministic checks.
The agent topology I use
| Component | Primary responsibility | Output |
|---|---|---|
| Performance analyzer | Reads search and content performance data | Ranked opportunity list |
| Topic selector | Chooses a topic aligned with business goals and site coverage | Content job |
| Research agent | Collects source material and extracts claims worth using | Research packet with citations |
| Brief agent | Defines intent, audience, structure, exclusions, and angle | Structured content brief |
| Writer agent | Produces the first complete draft | Markdown draft |
| Editor agent | Checks clarity, redundancy, unsupported claims, and voice | Revised draft and issue list |
| SEO/AEO validator | Checks title, headings, internal links, metadata, extractable answers | Pass, fail, or required fixes |
| Publisher | Creates or schedules the CMS entry | Published URL or failure record |
| Learning loop | Connects published content to later performance data | Updated targeting signals |
The most important design choice is that agents do not get unlimited authority.
The research agent cannot publish. The writer cannot decide which site receives the article. The publisher cannot silently repair factual problems. The system carries state forward, but each stage has a constrained contract.
For example, the writer receives a brief and a research packet. It does not receive raw search data, every past article, or the credentials to publish. Giving every agent everything feels flexible in a prototype. In production, it creates unnecessary token cost, larger attack surfaces, and a much harder debugging problem.
The job record is the real backbone of the system
The durable job record is more valuable than the prompts. Prompts change constantly as models, site requirements, and editorial rules evolve. The job record lets me reproduce what happened when an article is wrong, missing, duplicated, or unexpectedly expensive.
For each content job, I persist fields such as:
{
"job_id": "content_01H...",
"site_id": "site_a",
"topic": "AI MVP development cost",
"intent": "commercial investigation",
"status": "editorial_review",
"brief_version": "v12",
"prompt_version": "writer_v18",
"model": "selected-at-runtime",
"source_count": 8,
"draft_revision": 2,
"validation_result": "failed",
"validation_reasons": [
"missing primary source for cost claim",
"duplicate H2 intent"
]
}
This is the difference between an AI workflow and a script that happens to call an API.
When a job fails, I need to know whether the failure came from:
- bad topic selection
- insufficient source material
- a prompt regression
- model behavior
- an unavailable publishing endpoint
- a validation rule that was too strict
- a site-specific editorial constraint
Without persisted state, a failure becomes anecdotal. Someone sees a bad article, changes a prompt, and hopes the next run is better. That does not scale.
I also version prompts, schemas, and validation rules. An article produced by writer prompt version 18 should be traceable back to that version months later. If I improve the editorial agent, I want to know whether outcomes improved because of the new prompt, a different model, stronger research inputs, or simply an easier topic.
That traceability is especially important in enterprise AI automation. A CTO does not need a story about what the model “probably did.” They need an operational record.
Research quality determines whether automation creates assets or liabilities
The research stage is the part most teams underinvest in. If the model receives a vague topic and a request to “write an SEO article,” it will usually produce polished, generic prose. It may sound credible while making claims nobody can support.
That is not a writing problem. It is an evidence problem.
My research agent creates a bounded research packet before any drafting begins. The packet separates:
- Primary sources, such as official product documentation, standards, government sources, original research, and direct company announcements.
- Secondary sources, which can provide context but should not be the only support for strong claims.
- First-hand observations, which I label clearly as my own production experience.
- Claims that must not be made, including unsupported performance numbers, legal conclusions, medical advice, or stale product details.
Google’s own guidance is direct: “Create helpful, reliable, people-first content.” That standard is worth treating as an engineering requirement, not an SEO slogan. I use Google Search’s guidance on helpful content as a baseline for what the system should optimize for.
A useful research packet is not a dump of URLs. It contains extracted facts, source links, publication dates where relevant, and a clear distinction between verified claims and possible angles.
For a technical article, a research item might look like this:
Claim: Reciprocal Rank Fusion can combine rankings from lexical and vector search.
Source: Original RRF paper or verified technical documentation.
Use: Explain hybrid retrieval architecture.
Constraint: Do not claim a universal uplift percentage without a source
or a measured result from the specific implementation.
This sounds basic, but it prevents a common multi-agent failure mode: the writer treats a collection of loosely relevant text as permission to state conclusions with certainty.
The writer is allowed to synthesize. It is not allowed to invent evidence.
Token costs are driven by context duplication, retries, and bad routing
The cost of a multi-agent system is not simply “number of agents times price per token.” The real cost comes from repeated context, oversized prompts, unnecessary model escalation, tool calls, retries, and work that should never have entered the pipeline.
I track cost at the job level, then break it down by stage. The useful unit is not just cost per model call. It is cost per accepted, publishable content job.
A simplified model is:
Total job cost =
research calls
+ brief generation
+ draft generation
+ editorial revisions
+ validation retries
+ enrichment and publishing calls
The expensive behavior is usually not the initial draft. It is the loop caused by weak upstream inputs.
For example, a vague content brief causes the writer to miss intent. The editor then requests a rewrite. The rewrite introduces unsupported claims. The validator fails the article. A second research pass is triggered. Four calls that looked cheap individually become a costly job that still may not be publishable.
I reduce this waste in a few practical ways.
1. Route work by difficulty
Not every task needs the most capable model available.
A deterministic parser can extract headings. A smaller, lower-cost model can classify search intent or check whether a meta description exceeds a character limit. A stronger model is reserved for work that actually requires reasoning across evidence, editorial judgment, and nuanced trade-offs.
This is model routing, but the larger principle is simpler: do not pay premium reasoning costs for predictable operations.
2. Pass references, not entire histories
A common agentic AI mistake is sending the full job history into every call. The research agent sees everything. The writer sees everything. The editor sees everything. Soon the system spends more tokens remembering its own process than doing useful work.
Instead, each stage receives a compact, purpose-built context package. The writer gets the approved brief, source-backed research packet, voice guide, and a short list of relevant internal links. The publisher gets final markdown, metadata, and structured validation results.
3. Fail early
I would rather reject a weak topic before research than generate an article that gets blocked at publishing.
Topic selection should check for:
- overlap with existing content
- vague or mixed search intent
- lack of credible source material
- a mismatch between the topic and the site’s real expertise
- no plausible internal-link path
- no measurable reason to publish it
This is one reason my system is not designed as an unlimited content generator. Autonomous publishing without selection discipline can become scaled low-value output very quickly.
The failure modes were operational, not just model mistakes
The most damaging failures in production were not dramatic hallucinations. They were quiet workflow failures: duplicated work, stale assumptions, missing dependencies, and automation acting with more confidence than it deserved.
Here are the failure modes I now design around.
Similar topics compete with each other
An agent can generate five topics that look different linguistically but answer the same query. For example, “AI MVP cost,” “budget for an AI MVP,” and “how much does an AI prototype cost” may belong on one canonical page, not three separate articles.
I check semantic similarity against existing titles, URLs, summaries, and primary query intent. This is not perfect, but it is far better than relying on a slug comparison.
The decision is not “are these sentences different?” It is “would a searcher reasonably expect one page to answer both?”
Publishing is treated as a reversible deployment
Publishing content is a production deployment. It needs idempotency, rollback, and audit logs.
A publishing worker should be safe to retry after a timeout. If a CMS API accepts a request but the worker never receives the response, retrying should update the existing article rather than create a duplicate. The job record needs the external post ID as soon as it exists.
I also separate draft creation from public publication. A technically successful CMS response is not the same thing as a safe public release.
Validation can become a loop with no exit
If an editor agent says “improve this section” and the writer agent rewrites it indefinitely, the system will burn tokens and never complete.
Every revision loop needs a cap and a fallback state:
Attempt 1: revise automatically
Attempt 2: revise with narrower instruction
Attempt 3: hold for human review
A held job is not a system failure. It is an honest outcome. The system has recognized that it cannot satisfy its own quality bar safely.
Search performance arrives too late for real-time learning
SEO feedback loops are slow. A newly published article may need time to be crawled, indexed, and evaluated. That means I do not let early pageviews or referral traffic rewrite the strategy.
The learning loop uses search performance as a delayed signal. I look at impressions, ranking position, clicks, query patterns, indexation status, and whether the page is being surfaced for the intended intent. A few social visits do not validate an SEO hypothesis.
This has shaped my opinion on autonomous content systems: they should be patient. A system that reacts aggressively to short-term noise will optimize for the wrong thing.
What I’d do differently if I were starting again
I would build fewer agents at the beginning and invest earlier in the workflow around them.
My first version would have only four AI responsibilities: topic qualification, research, writing, and editorial review. Everything else would be deterministic software: job scheduling, schemas, retries, duplicate detection, publication state, observability, and notifications.
I would also make these decisions from day one:
- Use a canonical content map before generating at scale. The system needs to know what already exists.
- Store source-level evidence separately from prose. Sources are data, not decoration.
- Measure accepted output, not generated output. A hundred drafts are worthless if most cannot be published safely.
- Make human review selective. Review high-risk claims, new content types, and failed validations, not every comma.
- Treat publishing permissions as production credentials. Keep them narrow, auditable, and separate from research or drafting systems.
- Optimize for useful coverage, not article count. More pages can create more maintenance, cannibalization, and quality debt.
The goal is not to build AI agents that appear autonomous. The goal is to build agentic workflows that can run unattended while staying inside explicit quality and business constraints.
Where this architecture is useful
BizFlowAI ContentStudio is the system where I have applied these lessons most directly. It is designed to research, write, optimize, and publish content across multiple sites, then feed search performance back into future topic selection.
The broader architecture applies well beyond SEO. I use the same pattern for AI workflow automation in support operations, internal knowledge systems, RAG applications, and document-heavy business processes: narrow agent roles, durable state, deterministic guardrails, measured outcomes, and a clear path for escalation when automation is uncertain.
After six months, my main lesson is that production AI is less about finding a clever prompt and more about building a system that can be observed, corrected, and trusted. The agent is only one component. The workflow around it is the product.
If you are designing an AI automation system that needs to operate reliably after the demo, you can reach me through lazar-milicevic.com/#contact. I also write more field notes here about LLM applications, RAG, serverless AI architecture, and agentic workflows.
Frequently asked questions
What is a multi-agent SEO content system?
I define a multi-agent SEO content system as a controlled workflow in which specialized agents and software services handle distinct stages of content production. My system measures performance, selects opportunities, researches evidence, creates briefs, drafts content, validates it, publishes it, and feeds results back into future decisions. It is not a group of AI models freely debating a topic. Each stage has structured inputs, explicit outputs, and limited permissions so a failure does not corrupt the entire pipeline.
Why should an AI content workflow use deterministic checks instead of LLMs for everything?
I use LLMs for interpretation-heavy work such as research synthesis, angle development, and drafting, but I use deterministic software checks for verifiable requirements. For example, URL status codes, duplicate slugs, markdown frontmatter, internal-link presence, and CMS publishing rules are ordinary software problems. Using deterministic validation makes these checks more reliable, easier to debug, and less expensive than asking a model to infer them. This separation also prevents an AI model from silently overlooking basic publishing or SEO failures.
What information should be stored in an AI content job record?
I store a durable job record for every article because it is the operational backbone of the workflow. It includes the site, topic, search intent, workflow status, brief version, prompt version, selected model, source count, draft revision, and validation results. I also save specific failure reasons, such as missing primary evidence or duplicate heading intent. This record lets me reproduce problems and determine whether a bad outcome came from topic selection, research quality, a prompt regression, model behavior, validation rules, or a publishing failure.
How do you prevent AI agents from publishing inaccurate or unsuitable content?
I prevent unsafe publishing by giving each agent narrow authority rather than allowing every agent to access every system capability. The research agent can collect evidence but cannot publish, while the writer receives only the approved brief and research packet rather than raw data or CMS credentials. Editorial, factual, SEO, and AEO validation happen before publishing, and failed content can be held for human review. This controlled handoff model reduces factual risk, token waste, security exposure, and debugging complexity.
Why is research quality so important for AI-generated SEO content?
In my experience, research quality determines whether automated content becomes a useful business asset or a credibility liability. A model given only a broad topic can produce polished, generic writing that sounds convincing while containing claims that cannot be supported. I therefore treat research as evidence collection: the output should include source material, extractable claims, and citations that support the eventual article. Strong research gives the writer factual constraints and gives editors a basis for rejecting unsupported statements.
Building something hard with AI or automation? I am open to talk.
Get in touch