Skip to content
Learn Agentic AI9 min read0 views

Building an AI Sales Development Rep: Automated Lead Outreach and Qualification

Learn how to architect an AI-powered SDR agent that scores leads, generates personalized outreach messages, and manages multi-step follow-up sequences automatically.

Why Sales Needs Agentic AI

Sales development representatives spend the majority of their time on repetitive tasks: researching prospects, writing personalized emails, scoring leads, and scheduling follow-ups. An AI SDR agent automates this entire pipeline while maintaining the personalization that drives response rates. Unlike simple email templates, an agentic SDR reasons about each prospect individually, adapts messaging based on engagement signals, and decides when to escalate a warm lead to a human rep.

The architecture we will build has four components: a lead ingestion layer, a scoring engine, a message generation module, and a follow-up orchestrator.

Lead Ingestion and Enrichment

Before the agent can do anything useful, it needs structured data about each prospect. Raw leads from forms or CRM exports often lack the context needed for personalization. The ingestion layer enriches each lead with company information, recent news, and technology stack signals.

from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
import httpx


@dataclass
class Lead:
    email: str
    name: str
    company: str
    title: Optional[str] = None
    industry: Optional[str] = None
    company_size: Optional[str] = None
    enrichment_data: dict = field(default_factory=dict)
    score: float = 0.0
    stage: str = "new"
    created_at: datetime = field(default_factory=datetime.utcnow)


async def enrich_lead(lead: Lead, api_key: str) -> Lead:
    """Enrich a lead with company data from an external API."""
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            "https://api.clearbit.com/v2/companies/find",
            params={"domain": lead.email.split("@")[1]},
            headers={"Authorization": f"Bearer {api_key}"},
        )
        if resp.status_code == 200:
            data = resp.json()
            lead.industry = data.get("category", {}).get("industry")
            lead.company_size = data.get("metrics", {}).get("employeesRange")
            lead.enrichment_data = data
    return lead

Lead Scoring with an LLM

Traditional scoring uses weighted feature models. An LLM-augmented scorer can evaluate unstructured signals like job title relevance, company news sentiment, and technology fit that rule-based systems struggle with.

from openai import AsyncOpenAI

client = AsyncOpenAI()

SCORING_PROMPT = """You are a lead scoring assistant for a B2B SaaS company
that sells AI-powered customer service tools.

Evaluate this lead and return a JSON object with:
- "score": integer from 1 to 100
- "reasoning": one sentence explaining the score
- "priority": "hot", "warm", or "cold"

Lead data:
- Name: {name}
- Title: {title}
- Company: {company}
- Industry: {industry}
- Company size: {company_size}
"""


async def score_lead(lead: Lead) -> dict:
    response = await client.chat.completions.create(
        model="gpt-4o",
        response_format={"type": "json_object"},
        messages=[
            {"role": "system", "content": "Return valid JSON only."},
            {
                "role": "user",
                "content": SCORING_PROMPT.format(
                    name=lead.name,
                    title=lead.title or "Unknown",
                    company=lead.company,
                    industry=lead.industry or "Unknown",
                    company_size=lead.company_size or "Unknown",
                ),
            },
        ],
    )
    import json
    result = json.loads(response.choices[0].message.content)
    lead.score = result["score"]
    lead.stage = result["priority"]
    return result

Personalized Outreach Generation

Generic emails get ignored. The agent uses enrichment data to craft messages that reference specific company details, recent events, or role-relevant pain points.

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

OUTREACH_PROMPT = """Write a short, personalized cold outreach email.

Prospect: {name}, {title} at {company}
Industry: {industry}
Company size: {company_size}
Key insight: {insight}

Rules:
- Keep it under 120 words
- Reference something specific about their company
- End with a clear, low-friction call to action
- Do NOT use generic phrases like "I hope this finds you well"
"""


async def generate_outreach(lead: Lead) -> str:
    insight = lead.enrichment_data.get("description", "a growing company")
    response = await client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "user",
                "content": OUTREACH_PROMPT.format(
                    name=lead.name,
                    title=lead.title,
                    company=lead.company,
                    industry=lead.industry,
                    company_size=lead.company_size,
                    insight=insight,
                ),
            },
        ],
    )
    return response.choices[0].message.content

Follow-Up Sequence Orchestration

The most critical part of an SDR agent is persistence. Research shows that most conversions happen after the third or fourth touch. The orchestrator tracks engagement events and decides when and what to send next.

from datetime import timedelta

FOLLOW_UP_SCHEDULE = [
    {"delay_days": 3, "strategy": "value_add"},
    {"delay_days": 5, "strategy": "social_proof"},
    {"delay_days": 7, "strategy": "breakup"},
]


async def process_follow_ups(leads: list[Lead], email_service):
    now = datetime.utcnow()
    for lead in leads:
        if lead.stage == "cold":
            continue
        history = await email_service.get_history(lead.email)
        if history.last_replied:
            # Lead engaged — escalate to human rep
            await email_service.notify_rep(lead, reason="reply_received")
            continue
        touches = history.touch_count
        if touches >= len(FOLLOW_UP_SCHEDULE):
            lead.stage = "exhausted"
            continue
        step = FOLLOW_UP_SCHEDULE[touches]
        due_date = history.last_sent + timedelta(days=step["delay_days"])
        if now >= due_date:
            message = await generate_follow_up(lead, step["strategy"])
            await email_service.send(lead.email, message)

Putting It All Together

The main agent loop pulls new leads, enriches them, scores them, and starts the outreach pipeline. Hot leads get immediate outreach while warm leads enter a nurture sequence.

async def run_sdr_agent(new_leads: list[Lead], email_service):
    for lead in new_leads:
        lead = await enrich_lead(lead, api_key="your-key")
        scoring = await score_lead(lead)
        if scoring["priority"] == "hot":
            message = await generate_outreach(lead)
            await email_service.send(lead.email, message)
        elif scoring["priority"] == "warm":
            await email_service.add_to_nurture(lead)
    # Process existing follow-ups
    active_leads = await email_service.get_active_leads()
    await process_follow_ups(active_leads, email_service)

FAQ

How do I prevent the AI SDR from sending embarrassing or off-brand messages?

Implement a review layer. Score every generated message against your brand guidelines using a second LLM call that acts as a quality gate. Messages below a confidence threshold get queued for human review instead of sending automatically.

What CRM integrations are needed for a production SDR agent?

At minimum you need read access to contacts and deals (to avoid contacting existing customers), write access to log activities and update lead stages, and webhook support to receive engagement events like email opens and replies. HubSpot and Salesforce both provide robust APIs for this.

How do I measure the effectiveness of the AI SDR agent?

Track reply rate, meeting booked rate, and pipeline generated per lead. Compare these against your human SDR benchmarks. Also monitor negative signals like unsubscribe rate and spam complaints to ensure the agent is not damaging your domain reputation.


#SalesAI #SDRAgent #LeadQualification #OutreachAutomation #Python #AgenticAI #LearnAI #AIEngineering

Share this article
C

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.