A small custom woodworking business needed to stay competitive against larger regional players — without a dedicated analyst, without weekly hours to burn on research, and without the budget to hire either. We built Jordan: a fully autonomous multi-agent intelligence pipeline that delivers a complete competitive brief every week from a single button click.

10 Specialized agents
~9 LLM calls per run
1-click Weekly brief delivery
3 Competitors monitored

The Problem

The client is a custom woodworking business competing against larger regional players that have dedicated marketing teams and pricing analysts. Decisions about what to charge, how to position products, and where to invest effort were driven by gut feel rather than data.

The problem wasn't motivation. Jordan understood the value of competitive intelligence. The problem was bandwidth. Manually tracking competitor pricing, messaging shifts, and market positioning on a weekly basis requires hours Jordan doesn't have — hours that should be spent building furniture, not scraping websites.

The Core Constraint

Any solution had to be fully autonomous. Jordan can't babysit a pipeline. He can't interpret intermediate outputs. He needs a complete, actionable brief delivered to a dashboard — with zero manual steps between "run" and "ready to read."

The Approach

Rather than a monolithic LLM prompt that tries to do everything at once, we decomposed competitive research into a 10-agent pipeline. Each agent has a single, well-defined job. Agents run sequentially where dependent, and in parallel where independent. The output of each stage feeds cleanly into the next.

Stage Agent(s) Role
Collection own_scout, comp_scout Crawl the owner's site and competitor sites for raw content
Extraction own_extractor, extractor, wood_expert Parse product listings, pricing, materials, and woodworking-specific details
Analysis site_analysis, analyst Evaluate site structure, messaging tone, and competitive positioning
Strategy recommender Generate prioritized, actionable recommendations with effort/impact tags
Validation guardrail Flag hallucinated claims, verify pricing math, enforce factual grounding
Output report_gen Compile a structured intelligence report with citations

Each agent has its own system prompt, context cap, output schema, and rate limit. A sliding-window rate limiter and per-agent context cap system prevent token blowout and keep API costs predictable across a full pipeline run.

The Agents

1. Own Scout — own_scout

gpt-4o-mini Context Cap: 50K LLM Calls: 0

The own scout is the only agent in the pipeline that makes zero LLM calls. It's a pure fetch-and-discover agent: it hits Jordan's homepage plus known category pages (/dining-tables/, /dining-chairs/, /custom-projects/), then uses regex to discover product URLs under /store/. The output is a raw inventory of the client's own web presence — page content and product URLs — which feeds directly into the extractor.

Design Choice

The client's own site doesn't need interpretation — it needs scraping. Spending tokens to "understand" your own product pages is waste. A fetch-and-regex approach is faster, cheaper, and deterministic.

2. Own Extractor — own_extractor

gpt-5.4-mini Context Cap: 50K LLM Calls: 1

The own extractor receives the raw page content from the own scout and pulls out every unique product listing with its price. Its system prompt is deliberately narrow: "You are a product listing extractor. You read website content and extract every unique product with its price. Respond with valid JSON only."

It enforces deduplication, skips items under $50 (to filter out accessories and hardware), and outputs a clean [{ name, price }] array. If the LLM call fails for any reason, the agent falls back to a regex-based extraction — a pattern repeated nowhere else in the pipeline, because Jordan's own listings are the one dataset where the format is predictable enough for regex to work.

This is the foundation of the pricing engine. Every downstream pricing comparison starts from this list.

3. Competitor Scout — comp_scout

gpt-4o-mini Context Cap: 50K LLM Calls: 3

The most complex agent in the pipeline. The competitor scout doesn't just fetch pages — it navigates competitor sites intelligently using a three-phase crawl:

Three-Phase Crawl Strategy

Phase 1 — Homepage fetch. Grabs the competitor's root page and extracts all internal links.

Phase 2 — Link picker. An LLM call reviews the discovered URLs and picks up to 8 category or listing pages most likely to contain product links.

Phase 3 — Product page picker. A second LLM call reviews the pages found in Phase 2 and selects up to 12 individual product detail pages most likely to have actual dollar amounts.

After all three phases, a third LLM call performs the main competitive analysis. The prompt is domain-specific: "You are a competitive intelligence scout for [client]... Your PRIMARY mission is to find competitor pricing — exact dollar amounts, price ranges, starting prices, or confirmation that a competitor hides all prices."

Every signal must follow a strict format: "[Competitor domain] [what they do] — [why that matters for Jordan]". The agent is explicitly told never to fabricate pricing data — if a competitor hides prices, that itself becomes a signal.

On a typical run with 3 competitors, this agent accounts for approximately 9 LLM calls — the most of any single agent.

4. Extractor — extractor

gpt-5.4-mini Context Cap: 2M LLM Calls: 1 Toggleable

The extractor takes the raw signals from the competitor scout and normalizes them into a structured comparison schema. Where the scout produces free-text observations, the extractor produces rows in a table: competitor, offerFocus, pricingVisibility (Low/Medium/High), trustSignal, messagingShift, sourceType.

Its context cap is 2M — the largest tier — because it receives the full raw crawl data from the scout. The system prompt is terse: "You are a structured data extraction agent. You receive raw competitive intelligence signals and normalise them into a strict comparison schema."

This normalization step is what makes downstream analysis possible. The analyst and recommender don't parse free text — they work with structured competitor profiles.

5. Wood Expert — wood_expert

gpt-5.4-mini Context Cap: 2M LLM Calls: 1

This is the domain-specific agent — the one that knows the difference between white oak and red oak, understands why a mortise-and-tenon joint costs more than a pocket-screw joint, and can tell whether two tables from different makers are actually comparable.

The wood expert receives Jordan's product catalog (from the own extractor) and the competitor product listings (from the competitor scout), then identifies comparable products. Two products are considered comparable if they share the same category and similar characteristics. The output includes a similarity score (minimum 0.5), match reason, and category.

Why This Agent Exists

Without the wood expert, the system would compare a $4,000 custom dining table to a $200 particle-board desk and call it a pricing insight.

6. Site Analysis — site_analysis

Global default model Context Cap: 50K LLM Calls: 1 Toggleable

The site analysis agent turns the lens inward. Given the client's own website content and the structured competitor benchmark, it performs a SWOT-style evaluation: strengths[], weaknesses[], opportunities[], and a summary.

The system prompt includes a critical instruction: "Be specific and honest — this analysis drives the recommendations." Early iterations produced generic advice ("improve your SEO"). The current prompt forces the agent to ground every observation in the actual site content and competitor data it received. If Jordan's gallery is buried below the fold while a competitor's is front and center, that's a weakness — not a strength.

7. Analyst — analyst

gpt-5.4-mini Context Cap: 2M LLM Calls: 1

The analyst is the strategic brain. It cross-references the structured competitor data with the internal site analysis and produces exactly 5 insights — each with a theme, evidence, impact, priority, and source URL.

The Key Prompt Constraint

"Every insight tells Jordan what HIS site does, what competitors do differently, and what he should do about it. Never describe a competitor without also describing what Jordan currently does. Skip any theme where Jordan is already doing what competitors are doing."

Early versions of the analyst would say things like "Competitor A has strong trust messaging." That's interesting but not actionable. The current version says: "The client's site has no trust block on the homepage. Competitor A has a craftsmanship guarantee above the fold. Adding a similar block would address this gap." Same data, completely different utility.

Priorities must be distributed — the agent can't mark everything as High. This prevents the action queue from becoming a wall of equal-urgency items.

8. Recommender — recommender

gpt-5.4-mini Context Cap: 2M LLM Calls: 1

The recommender turns insights into specific, approval-ready actions. It receives the analyst's insights, the extractor's competitor data, and the original input context, then produces exactly 9 actions: 3 UX improvements, 3 pricing recommendations, and 3 quoting workflow changes.

Every recommendation must start with hedged language: "Suggest testing:", "Consider adding:", or "Review whether:". This isn't timidity — it's a design constraint that prevents the system from generating directives that sound like commands. The business owner approves actions; the system suggests them.

Grounded Pricing Suggestions

Pricing recommendations are required to reference the client's actual dollar figures. Example output: "Suggest testing: raising the Farmhouse Dining Table from $1,757 to $1,895, since comparable tables from a competitor start at $2,100." This grounds every pricing suggestion in real data rather than abstract percentages.

Each action includes impact (High/Medium/Low), effort (High/Medium/Low), owner (Website/Content), category (ux/pricing/quoting), rationale, and a source URL. The action queue in the UI surfaces all of this as an approvable card with tags.

9. Guardrail — guardrail

gpt-5.4-mini Context Cap: 2M LLM Calls: 1 Toggleable

The guardrail is the final validation gate before report generation. It receives the complete output of all preceding agents and checks for policy violations.

The first pass is regex-based — four patterns that catch the most common LLM overstatements:

Regex Validation Patterns

/guarantee[sd]?\s+\d+\s*%/i — percentage guarantees
/will\s+definitely\s+(increase|improve|convert)/i — certainty claims
/always\s+works/i — absolute claims
/proven\s+to\s+(double|triple|increase)/i — unverified proof claims

If any action text matches these patterns, it's flagged before the LLM even sees it. The second pass is an LLM review against the full policy constraints: JSON format preserved, context budgets enforced, recommendations framed as suggestions, no unsourced pricing claims, and human approval required for all actions.

The output is binary: "passed" or "review-needed". The business owner sees exactly what was flagged and why.

10. Report Generator — report_gen

gpt-5.4-mini Context Cap: 50K LLM Calls: 1

The final agent synthesizes everything — approved actions, strategic insights, site analysis, competitor overview, and guardrail status — into a polished weekly intelligence report.

The output is structured as reportTitle, executiveSummary, strategicContext, and nextSteps[] (top 3 priority actions). The report is rendered in the dashboard as a multi-page document with cover, sections, insight cards, action rows, and guardrail status.

The context cap here is intentionally lower (50K vs. 2M for the analysts) because the report agent should be working with already-distilled insights, not re-processing raw data.

Pipeline Architecture

The pipeline is mostly sequential, with one parallel fork: extractor and wood_expert run simultaneously since they depend on the same upstream data but don't depend on each other.

own_scout ──→ own_extractor ──→ comp_scout ──→ extractor ──┬──→ site_analysis ──→ analyst ──→ recommender ──→ guardrail ──→ report_gen └──→ wood_expert ──┘

Every agent call is wrapped by the executeAgent runner, which checks the sliding-window rate limiter, serializes the payload against the agent's context cap, executes the agent's run() function, validates the output against the agent's schema, and returns a metadata envelope with full observability data.

Agent Model Context Cap Rate Limit
own_scout gpt-4o-mini 50K 12/min
own_extractor gpt-5.4-mini 50K 20/min
comp_scout gpt-4o-mini 50K 12/min
extractor gpt-5.4-mini 2M 20/min
wood_expert gpt-5.4-mini 2M 12/min
site_analysis Global default 50K 10/min
analyst gpt-5.4-mini 2M 10/min
recommender gpt-5.4-mini 2M 8/min
guardrail gpt-5.4-mini 2M 30/min
report_gen gpt-5.4-mini 50K 6/min

The scouts use gpt-4o-mini — a smaller, faster model suited for page discovery and link picking where deep reasoning isn't needed. Everything from extraction onward uses gpt-5.4-mini for the heavier analytical work.

The Interface

The dashboard was built as a single-page vanilla JS application — no React, no framework — intentionally. The priorities were zero build step (edit, save, refresh), full visibility into agent execution, actionable output rather than just reports, and a pricing dashboard tied to real product data.

Interface Components

Brain-network visualization: All 10 agents rendered as 3D sphere nodes with SVG radial gradients, live status coloring (pending → active → complete/capped/error), and animated edge connections showing data flow.

Action Queue: Each recommendation surfaces as an approvable/dismissable card with impact and effort tags. The owner can edit recommendations before applying them.

Pricing dashboard: Per-product cards showing current vs. recommended pricing, percentage diffs, source citations, and expandable rationale.

The UI runs on a dark woodshop theme — #0e0b09 background, amber #d4883e accents, glassmorphism panels with backdrop-filter: blur(24px), JetBrains Mono for data, Lato for headings. Everything inline in a single <style> block for zero-dependency deployment.

Key Technical Decisions

1. No Framework by Design

The entire client is ~4,000 lines in one app.js. For a tool with one user and one purpose, the overhead of React or Vue adds complexity without value. DOM manipulation is direct and predictable.

2. Context Caps Per Agent, Not Globally

Each agent has a tuned context cap. Real data truncation happens inside each agent's run() function via capJson() and .slice() — giving each agent control over what it keeps and what it drops.

3. Guardrail as a Pipeline Stage, Not a Wrapper

Instead of post-hoc filtering, the guardrail agent receives the full recommendation set and validates pricing math, source attribution, and factual claims before the report is generated. It's a first-class citizen in the pipeline, not an afterthought.

4. Three-Phase Competitor Crawling

Rather than dumping a homepage into an LLM and asking "what do you see?", the comp_scout navigates intelligently: discover links → pick category pages → pick product pages → analyze. This dramatically improves the quality of pricing data captured.

The Result

The client now receives a structured competitive intelligence brief every week — pricing comparisons grounded in actual product data, prioritized action recommendations they can approve or dismiss, and a guardrail-verified report they can trust. What used to require hours of manual research now runs autonomously.

Want to Build Something Like This?

If you have a repetitive research, analysis, or reporting workflow that currently eats hours — we build the pipeline that runs it autonomously.

Let's talk about your project →