Designing a Hierarchical Deep Agent Architecture for Market Research
Introduction
Designing a Hierarchical Deep Agent Architecture for Market Research
Introduction
Most AI applications today are little more than a single prompt sent to an LLM. While this works for simple tasks, it breaks down when the problem requires extensive research, validation, reasoning, and synthesis.
To solve this challenge, I built a multi-agent market research system capable of conducting deep industry analysis, gathering information from multiple sources, validating findings, and generating executive-level reports.
The architecture combines:
- GPT-4o as the primary reasoning engine
- DeepAgents for agent orchestration
- LangGraph for memory and execution state
- Tavily for web and news retrieval
- Specialized sub-agents for parallel research
- Retry mechanisms for production reliability
The result is a research workflow that resembles how a consulting team operates rather than how a traditional chatbot functions.
System Architecture
The system follows a hierarchical agent architecture.
User Query
│
▼
Lead Research Agent
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
Financial Competitive Trend Research
Research Analysis Analysis
▼ ▼ ▼
Fact Checker
│
▼
Synthesizer
│
▼
Final Report
Instead of asking one model to perform every task, the workload is divided among domain-specific agents.
Each agent operates independently, performs focused research, and returns structured findings.
The final synthesis agent combines all outputs into a single report.
Persistent Knowledge Layer
One of the most important aspects of the architecture is the knowledge-loading mechanism.
agents_md
skills_md
instructions_md
examples_md
These files are loaded into memory and injected into the agent’s context.
This creates a lightweight knowledge base containing:
- Research methodologies
- Strategic frameworks
- Writing guidelines
- Output templates
- Internal operating procedures
Rather than hardcoding instructions inside prompts, the agent retrieves them from a centralized repository.
Benefits:
- Easier maintenance
- Better scalability
- Version-controlled prompt engineering
- Reusable across multiple projects
This pattern resembles Retrieval-Augmented Generation (RAG), but instead of retrieving business documents, the system retrieves operational knowledge.
Memory Management with LangGraph
The system uses LangGraph’s memory components:
InMemoryStore()
MemorySaver()
These solve two different problems.
InMemoryStore
Acts as a long-term knowledge repository.
Stores:
- Frameworks
- Templates
- Instructions
- Examples
This allows agents to access shared knowledge throughout execution.
MemorySaver
Acts as conversational state management.
Stores:
- Intermediate reasoning
- Agent outputs
- Previous interactions
- Workflow state
This becomes critical when reports require dozens of reasoning steps.
Without checkpointing, long-running workflows can lose context or exceed execution limits.
Tool-Augmented Research
The system doesn’t rely solely on model knowledge.
Instead, it uses external retrieval tools.
Web Search Tool
web_search()
Provides:
- Industry reports
- Company information
- Market data
- Analyst commentary
Parameters such as:
topic
time_range
search_depth
max_results
allow retrieval quality to be controlled.
News Search Tool
news_search()
Dedicated to recent developments.
Useful for:
- Product launches
- Acquisitions
- Funding rounds
- Earnings announcements
Separating general search from news search prevents the model from mixing evergreen information with rapidly changing events.
Dynamic Prompt Engineering
The system generates prompts dynamically using:
TODAY = date.today()
THIS_YEAR = date.today().year
These values are injected directly into prompts.
Example:
Include 2026 in every search query
Why?
Market research becomes stale very quickly.
By enforcing year-specific searches:
- Old statistics are avoided
- Current market conditions are prioritized
- Recency bias is controlled systematically
This is a simple but highly effective prompt-engineering strategy.
Multi-Agent Specialization
The most interesting aspect of the architecture is agent specialization.
Instead of one general-purpose researcher, multiple experts are created.
Example categories:
Financial Analyst
Responsible for:
- Revenue analysis
- Valuation metrics
- Earnings data
- Investor sentiment
Competitive Analyst
Responsible for:
- Market share
- Product comparisons
- Vendor positioning
Trend Analyst
Responsible for:
- Emerging technologies
- Growth signals
- Adoption patterns
Fact Checker
Responsible for:
- Verifying claims
- Cross-validating statistics
- Identifying inconsistencies
Synthesizer
Responsible for:
- Report generation
- Executive summaries
- Final recommendations
This mimics real-world consulting teams where specialists contribute domain expertise before findings are consolidated.
Parallel Execution
A major limitation of traditional agents is sequential execution.
For example:
Search A
Wait
Search B
Wait
Search C
Wait
This leads to high latency.
DeepAgents allows sub-agents to operate independently.
Conceptually:
Financial Research
Competitive Research
Trend Research
Fact Checking
can all run simultaneously.
Benefits:
- Lower response times
- Increased research coverage
- Better utilization of LLM resources
This pattern becomes increasingly important when workflows contain dozens of searches.
Reliability Through Retries
Production systems inevitably encounter:
- API rate limits
- Temporary failures
- Network instability
The architecture handles this using:
@retry(...)
with exponential backoff.
15s
30s
60s
90s
This approach provides several advantages:
- Reduces transient failures
- Prevents workflow termination
- Improves reliability under heavy load
Without retry logic, large research pipelines become fragile.
Hierarchical Prompt Design
The architecture uses two levels of prompts.
Global System Prompt
Defines:
- Research standards
- Validation requirements
- Citation rules
- Output quality expectations
This acts as the organization’s operating manual.
Agent-Specific Prompts
Each sub-agent receives:
- Shared context
- Domain responsibilities
- Specialized objectives
Example:
You are a competitive landscape researcher...
This ensures each agent remains focused and avoids task overlap.
The result is significantly better output quality than assigning all responsibilities to a single model.
Fact Verification Layer
One of the biggest problems in AI-generated research is hallucination.
To address this, the architecture introduces a dedicated verification agent.
Responsibilities include:
- Cross-referencing statistics
- Triangulating data
- Detecting inconsistencies
- Flagging unsupported claims
This creates a quality-control stage before final synthesis.
In practice, this dramatically improves trustworthiness.
Report Synthesis
After research is completed, outputs are merged by a synthesizer agent.
Responsibilities:
- Remove duplication
- Resolve conflicting findings
- Maintain consistent structure
- Generate executive-level recommendations
This final stage transforms fragmented research into a coherent strategic narrative.
Without synthesis, users receive disconnected information rather than actionable insights.
Key Engineering Patterns Demonstrated
This project showcases several advanced GenAI engineering concepts:
Agent Orchestration
Coordinating multiple specialized agents toward a shared objective.
Retrieval-Augmented Reasoning
Combining external search with LLM reasoning.
Long-Term Context Management
Maintaining frameworks, templates, and memory across workflows.
Parallel Research Pipelines
Reducing latency while improving research breadth.
Reliability Engineering
Handling failures through retries and checkpointing.
Fact Validation
Introducing verification layers to reduce hallucinations.
Dynamic Prompt Construction
Generating context-aware prompts based on time and task requirements.
Conclusion
The most interesting aspect of this system is that it moves beyond the traditional chatbot paradigm.
Instead of relying on a single model to answer a question, the architecture behaves more like a consulting organization:
- Researchers gather evidence
- Specialists analyze findings
- Fact checkers validate information
- Synthesizers produce recommendations
By combining DeepAgents, LangGraph, Tavily, and GPT-4o, the system demonstrates how modern AI applications can evolve from simple prompt-response interactions into scalable, multi-agent reasoning systems capable of producing high-quality research at enterprise scale.
This architecture can be extended far beyond market research into competitive intelligence, investment analysis, due diligence, policy research, strategic planning, and any domain requiring deep investigation and synthesis.
import os
from datetime import date
from pathlib import Path
from typing import Literal, Optional, List
from dotenv import load_dotenv
from tavily import TavilyClient
from tenacity import retry, wait_exponential, stop_after_attempt, retry_if_exception_type
from openai import RateLimitError
from deepagents import create_deep_agent
from deepagents.backends.store import StoreBackend
from deepagents.backends.utils import create_file_data
from langgraph.store.memory import InMemoryStore
from langgraph.checkpoint.memory import MemorySaver
load_dotenv("/Users/sandidas/Documents/Agentic_AI/.env")
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")
TODAY = date.today().isoformat()
THIS_YEAR = date.today().year
PROJECTS = Path("/Users/sandidas/Documents/Agentic_AI/Deep Agents/Projects")
SKILLS = PROJECTS / "skills"
agents_md = (PROJECTS / "agents.md").read_text(encoding="utf-8")
skills_md = (SKILLS / "skills.md").read_text(encoding="utf-8")
instructions_md = (SKILLS / "instructions.md").read_text(encoding="utf-8")
examples_md = (SKILLS / "examples.md").read_text(encoding="utf-8")
print(" Loaded:",
f"agents.md={len(agents_md)} chars,",
f"skills.md={len(skills_md)} chars,",
f"instructions.md={len(instructions_md)} chars,",
f"examples.md={len(examples_md)} chars")
store = InMemoryStore()
store.put(("memories",), "agents.md", create_file_data(agents_md))
store.put(("memories",), "skills.md", create_file_data(skills_md))
store.put(("memories",), "instructions.md", create_file_data(instructions_md))
store.put(("memories",), "examples.md", create_file_data(examples_md))
tavily = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
def web_search(
query: str,
max_results: int = 6,
topic: Literal["general", "news"] = "general",
time_range: Literal["day", "week", "month", "year"] = "year",
search_depth: Literal["basic", "advanced"] = "advanced",
include_domains: Optional[List[str]] = None,
):
"""Search the web with Tavily. ALWAYS include the year in the query for current data."""
return tavily.search(
query=query,
max_results=max_results,
topic=topic,
time_range=time_range,
search_depth=search_depth,
include_domains=include_domains or [],
include_answer=True,
)
def news_search(query: str, days: int = 30, max_results: int = 6):
"""Breaking-news search — last N days only."""
return tavily.search(
query=query, topic="news", days=days,
max_results=max_results, search_depth="advanced",
)
SHARED_CONTEXT = f"""
TODAY IS {TODAY}. CURRENT YEAR IS {THIS_YEAR}.
Treat any source older than 18 months as STALE unless foundational.
Prefer sources from the last 6 months for market-size, share, and trend claims.
Include "{THIS_YEAR}" in EVERY web_search query.
================================================================================
KNOWLEDGE 1 — PROJECT GUIDE (agents.md)
================================================================================
{agents_md}
================================================================================
KNOWLEDGE 2 — ANALYTICAL FRAMEWORKS (skills.md)
================================================================================
{skills_md}
================================================================================
KNOWLEDGE 3 — WORKFLOW & QUALITY RULES (instructions.md)
================================================================================
{instructions_md}
================================================================================
KNOWLEDGE 4 — OUTPUT FORMAT EXAMPLES (examples.md)
================================================================================
{examples_md}
"""
LIGHT_CONTEXT = f"""
TODAY IS {TODAY}. CURRENT YEAR IS {THIS_YEAR}.
Include "{THIS_YEAR}" in EVERY web_search query.
Reject sources older than 18 months unless foundational.
================================================================================
FRAMEWORKS YOU MUST APPLY (skills.md)
================================================================================
{skills_md}
================================================================================
WORKFLOW & QUALITY RULES (instructions.md)
================================================================================
{instructions_md}
"""
SYSTEM_PROMPT = f"""You are an elite market research analyst for Cisco, operating
at the level of a top-tier strategy consultant (McKinsey / BCG / Gartner / Forrester).
{SHARED_CONTEXT}
================================================================================
HARD RULES (override anything else)
================================================================================
1. Always include "{THIS_YEAR}" or "{THIS_YEAR-1}" in EVERY web_search query.
2. Run AT LEAST 8–12 searches before writing the final report.
3. Use `news_search` for earnings, product launches, M&A in the last 90 days.
4. Apply frameworks from skills.md (TAM/SAM/SOM, Porter's 5F, JTBD, SWOT).
5. Match the format and citation style from examples.md exactly.
6. Cite EVERY claim with [n] inline + a Sources block (URL + publish date).
7. Triangulate every material number across 3+ independent sources.
8. Reject sources older than 18 months unless foundational; label stale stats.
9. Never invent statistics, companies, quotes, or executives.
10. End with a "Strategic Implications" section (3 specific recs for Cisco).
11. Target 1,800–2,500 words. Depth beats brevity.
12. Delegate research to sub-agents, then synthesize their findings.
"""
def build_subagent(name: str, role: str, focus: str) -> dict:
return {
"name": name,
"description": f"{role} {focus}",
"system_prompt": f"""You are a {role}
{LIGHT_CONTEXT}
================================================================================
YOUR SPECIFIC FOCUS
================================================================================
{focus}
RULES:
- Include "{THIS_YEAR}" in every search query.
- Run 3–5 searches before answering.
- Apply the relevant frameworks from skills.md.
- Cite every claim with [n] + a Sources block (URL + date).
- Return a ≤400-word findings summary.
""",
"tools": [web_search, news_search],
"model": "openai:gpt-4o-mini",
}
subagents = [
build_subagent(
"StockMarketResearcher",
"Stock-market and financial-data specialist.",
f"Pull the latest 10-K/10-Q numbers, EV/Revenue multiples, and analyst price "
f"targets for Cisco, Arista, Juniper, HPE/Aruba, Palo Alto, Fortinet, NVIDIA "
f"networking. Use SEC filings and earnings transcripts dated {THIS_YEAR}.",
),
build_subagent(
"StrategyArchitect",
"Strategy framework expert.",
"Apply Porter's 5 Forces, TAM/SAM/SOM, and SWOT to the AI-networking market "
"with Cisco as the anchor. Return numbers + framework outputs in tables.",
),
build_subagent(
"CompetitiveAnalyst",
"Competitive-landscape researcher.",
f"Map top 7 networking vendors: market share (IDC, Dell'Oro, Synergy {THIS_YEAR}), "
"product portfolio, recent launches, pricing posture, partnerships.",
),
build_subagent(
"TrendsAnalyst",
"Quantitative trend researcher.",
"Quantify 5 trends: AI fabric / RoCE, AIOps, SASE/SSE, 800G optics, "
"hyperscaler capex. Use search/funding/hiring signals as evidence.",
),
build_subagent(
"FactChecker",
"Technical fact-checker.",
"Re-verify EVERY numeric claim across 3+ independent sources. Flag any "
"number that cannot be triangulated. Return a verification table.",
),
build_subagent(
"Synthesizer",
"Senior synthesizer / deck designer.",
"Merge sub-agent outputs into the final brief in the EXACT format shown "
"in examples.md. Preserve all citations.",
),
]
agent = create_deep_agent(
model="openai:gpt-4o",
tools=[web_search, news_search],
backend=StoreBackend(store=store),
system_prompt=SYSTEM_PROMPT,
checkpointer=MemorySaver(),
subagents=subagents,
)
USER_PROMPT = f"""TODAY IS {TODAY}. Produce a market-research brief for Cisco's
exec team on the AI-driven enterprise networking market. Cover:
1. Market size & growth ({THIS_YEAR} → 2028, with TAM/SAM/SOM and CAGR).
2. Top 7 competitors with the LATEST quarterly financials, product moves, posture.
3. Buyer personas + top 5 purchase criteria (G2 / Gartner Peer Insights {THIS_YEAR}).
4. 5 key trends quantified with {THIS_YEAR-1}–{THIS_YEAR} evidence.
5. Strategic implications + 3 specific 12-month recommendations for Cisco.
Delegate to your sub-agents in PARALLEL where possible. Have the Synthesizer
assemble the final brief in the EXACT format from examples.md. Target 2,000–2,500 words.
"""
@retry(
retry=retry_if_exception_type(RateLimitError),
wait=wait_exponential(multiplier=2, min=15, max=90), # 15s → 30s → 60s → 90s
stop=stop_after_attempt(5),
reraise=True,
)
def safe_invoke(payload, cfg):
return agent.invoke(payload, config=cfg)
result = safe_invoke(
{"messages": [{"role": "user", "content": USER_PROMPT}]},
{
"configurable": {"thread_id": f"cisco_brief_{TODAY}"},
"recursion_limit": 100,
},
)
final = result["messages"][-1].content
if isinstance(final, list):
for block in final:
print(block.get("text", block) if isinstance(block, dict) else block)
else:
print(final) 메타데이터
- post_id
- fa9eaf5960f5
- slug
- designing-a-hierarchical-deep-agent-architecture-for-market-research-fa9eaf5960f5
- url
- https://medium.com/@dassandipan9080/designing-a-hierarchical-deep-agent-architecture-for-market-research-fa9eaf5960f5
- canonical_url
- https://medium.com/@dassandipan9080/designing-a-hierarchical-deep-agent-architecture-for-market-research-fa9eaf5960f5
- author_url
- https://medium.com/@dassandipan9080
- status
- ok
- fetched_at
- 2026-06-26 03:39:16