How to build a deep research agent for lead generation using Google’s ADK

Traditional lead generation often relies on brittle scrapers and static scripts that lack the ability to adapt or reason. What if we could architect an agent that doesn’t just fetch data, but emulates the analytical process of a market research team? An agent that can discover patterns, validate information, and generate qualified leads based on a dynamic understanding of success.

This guide details the architecture of such an agent, built using the Agent Development Kit (ADK). We will explore how to structure a complex task into a hierarchy of cooperative agents, manage state across interactions, and design for parallelism to create a system that is both powerful and efficient.

Step 1: Find the root agent

At the core of any complex agentic system is what we call a “primary orchestrator”. In this architecture, the InteractiveLeadGenerator serves as this central hub. Its purpose is not to perform the low-level tasks itself, but to manage the workflow, delegate to specialized sub-agents, and interact with the user. Here’s the Python script:

code_block
<ListValue: [StructValue([(‘code’, ‘# From: LeadGenerationResearch/LeadGenerationResearch/agent.pyrnrnroot_agent = Agent(rn name=”InteractiveLeadGenerator”,rn model=os.getenv(“GEN_ADVANCED_MODEL”, “gemini-2.5-pro”),rn instruction=ROOT_AGENT_INSTRUCTION, # The agent’s core directivern tools=[rn get_user_choice,rn *agent_tools,rn ],rn before_agent_callback=[before_agent_run],rn after_tool_callback=[after_tool_run],rn)’), (‘language’, ‘lang-py’), (‘caption’, <wagtail.rich_text.RichText object at 0x3e5a811a6340>)])]>

This root agent’s actions are determined by its main instruction, which sets its overall goal and how it works.

Root agent instruction:

“You are a lead generation assistant. Your objective is to assist the user in finding new leads by discovering patterns in successful companies. Your process is to: 1. Understand user intent. 2. Execute a pattern discovery workflow. 3. Confirm findings with the user. 4. Execute a lead generation workflow based on the confirmed patterns. Maintain an interactive, proactive, and thorough approach.”

Step 2: Decompose the problem and extract intent 

Complex problems are best solved by breaking them down into discrete phases. Our lead generation task naturally splits into two primary workflows, as illustrated in the diagram below:

  1. Learning from the past (pattern discovery): We need a Research Squad to analyze history and find the signals of success.

  2. Predicting the future (lead generation): We need a Hunter Squad to use those signals to find future wins.

1-flow

Before initiating either workflow, the root agent must first understand the user’s specific requirements. This is delegated to a specialized intent_extractor_agent responsible for parsing the user’s initial request into structured data.

code_block
<ListValue: [StructValue([(‘code’, ‘# From: LeadGenerationResearch/LeadGenerationResearch/sub_agents/intent_extractor/agent.pyrnrnintent_extractor_agent = LlmAgent(rn name=”intent_extractor_agent”,rn model=os.getenv(“GEN_FAST_MODEL”, “gemini-2.5-flash”),rn instruction=INTENT_EXTRACTOR_PROMPT,rn output_schema=IntentExtractionResult,rn description=”Extracts key parameters like user intent, country, and industry.”,rn)’), (‘language’, ‘lang-py’), (‘caption’, <wagtail.rich_text.RichText object at 0x3e5a811a6bb0>)])]>

Step 3: The pattern discovery workflow

We need to find companies, validate them, and dig into their history. Doing this one by one is slow and inefficient.

Let’s have them work as a team, simultaneously. Our ResearchOrchestratorAgent dynamically creates a mini-pipeline for each company and runs them all in parallel. It’s a high-speed, multi-threaded research team managed by a single SequentialAgent.

code_block
<ListValue: [StructValue([(‘code’, ‘#From:LeadGenerationResearch/LeadGenerationResearch/sub_agents/pattern_discovery/agent.pyrnrnpattern_discovery_agent = SequentialAgent(rn name=”PatternDiscoveryAgent”,rn sub_agents=[rn company_finder_agent,rn company_formatter_agent,rn research_orchestrator_agent, # Manages parallel executionrn synthesizer_orchestrator_agent,rn pattern_synthesizer_agent,rn ],rn description=”Orchestrates the multi-step process of discovering investment patterns.”rn)’), (‘language’, ‘lang-py’), (‘caption’, <wagtail.rich_text.RichText object at 0x3e5a811a6fd0>)])]>

The key agents in this sequence include:

  • CompanyFinderAgent: Executes searches to find an initial list of companies based on the user’s specific industry and country.
  • CompanyFormatterAgent: Takes the raw output from the finder agent and formats it into a standardized structure, ensuring the data is clean and ready for the next stages.
  • ResearchOrchestratorAgent: Manages the parallel execution of the research phase. For each company found, it dynamically runs a validation pipeline (which uses the ValidatorAgent) to scrutinize the company against strict criteria.
  • SynthesizerOrchestratorAgent: Gathers and consolidates all the validated data from the parallel research pipelines, preparing a unified dataset for the final analysis step.
  • PatternSynthesizerAgent: Takes the aggregated data from the orchestrator. Its core instruction is to identify common threads and synthesize them into a clear, evidence-based report, citing the sources for every identified pattern.

Step 4: Control mechanisms and state management

To enable the root agent to manage these complex workflows and maintain a coherent conversation, two ADK features are critical.

  1. AgentTool for delegation The SequentialAgent orchestrators are abstracted into a single, callable AgentTool. This allows the root agent to invoke an entire multi-step workflow as if it were a single function call.
code_block
<ListValue: [StructValue([(‘code’, ‘# In tools/agent_tools.py, create the toolset.rnfrom google.adk.tools import AgentToolrnfrom ..sub_agents.pattern_discovery.agent import pattern_discovery_agentrnfrom ..sub_agents.lead_generation.agent import lead_generation_agentrnrnagent_tools = [rn AgentTool(agent=pattern_discovery_agent),rn AgentTool(agent=lead_generation_agent),rn]’), (‘language’, ‘lang-py’), (‘caption’, <wagtail.rich_text.RichText object at 0x3e5a811a6820>)])]>

2. Callbacks for state management Callbacks are essential for managing the session’s state across multiple turns.

  • before_agent_run: Executes before each agent turns to initialize or update the session state.
  • after_tool_run: Executes after any tool completes its run. It processes the tool’s output and updates a stage variable in the session state, which is crucial for guiding the root agent’s next decision.

Step 5: The lead generation workflow

Once success patterns are identified and confirmed, the InteractiveLeadGenerator deploys the second major workflow. This process mirrors the structure of the discovery phase, emphasizing consistency and reuse.

code_block
<ListValue: [StructValue([(‘code’, ‘# In sub_agents/lead_generation/agent.pyrnlead_generation_agent = SequentialAgent(rn name=”LeadGenerationAgent”,rn sub_agents=[rn lead_finder_agent,rn lead_formatter_agent,rn lead_research_orchestrator_agent, # Handles parallel validation and analysisrn report_orchestrator_agent,rn report_compiler_agent,rn ],rn description=”Uses pre-discovered success patterns to find potential leads…”,rn)’), (‘language’, ‘lang-py’), (‘caption’, <wagtail.rich_text.RichText object at 0x3e5a811a6e20>)])]>

The key agents in this sequence are:

  • LeadFinderAgent: Uses the previously synthesized patterns as a new search query to find companies that exhibit similar characteristics.
  • LeadFormatterAgent: Standardizes and structures the raw data from the LeadFinderAgent for subsequent parallel processing.
  • LeadResearchOrchestratorAgent: Manages the parallel execution of the core analysis tasks. For each potential lead, this agent simultaneously runs two critical sub-agents: the reusable ValidatorAgent and the LeadSignalAnalyzerAgent.

Get started

Ready to build? Here are the official resources and source code to help you on your journey.

  • Google Agent Development Kit (ADK): Check out GitHub to explore all the features, tools, and configs the ADK offers.
  • Project source code on GitHub: Access the complete working code for this agent. Clone the repo and use it as a foundation for your own creations.