SOBAN AHMAD
// CASE STUDY / PRE-CALL BRIEF

A research agent that briefs a rep before every call

Reps were meant to research every prospect before a discovery call, and under a full calendar most of that research quietly got skipped. I designed, built and deployed an agent that takes a prospect URL, gathers real data from several sources at once and returns a grounded brief before the call. This build runs inside a team I do not name, the people running it treat it as an edge.

2026B2B salesPre-sales research agentAgent build
// THE BOTTLENECK

What was the manual bottleneck?

Before an inbound call, a rep was expected to work through the prospect: the website, the LinkedIn profile, the ads they were running, the way they positioned themselves. Done properly it takes a good part of an hour per prospect, and the calendar rarely allows it. So it slips. The rep walks into the call with a name and a guess.

The work is not hard, it is repetitive and it sits at exactly the moment a rep has no spare minutes. The prospects who got real preparation were the ones who happened to land on a quiet afternoon, not the ones who mattered most.

They needed the research to happen on every prospect without a person having to find the time for it.

// WHAT WAS BUILT

A URL in, a grounded brief out

An asynchronous pipeline on Python, FastAPI and Celery that turns a single prospect address into a finished brief in a rep's inbox. Three moves carry it.

// INTAKE

One URL in

A rep pastes a prospect URL, or a CRM webhook fires it, and a background job is enqueued through Redis. Nothing else is asked of the rep. The prospect address is the whole input.

// COLLECTION

Parallel data gathering

Seven tasks run at once: Playwright scrapes the website and LinkedIn, the Meta Ad Library and PageSpeed Insights are queried, and the tech stack is fingerprinted. The raw material is real, retrieved data, not the model guessing.

// BRIEF

A structured brief out

The synthesis step writes the brief a rep actually opens: talking points, pricing anchors and red flags. It is rendered to a branded PDF with WeasyPrint, stored in Supabase and emailed through Resend, ready before the call starts.

// THE ARCHITECTURE

How does the agent stay grounded?

The reliability of a brief is an architecture problem, not a prompt trick. Four decisions keep the output tied to real data and standing up when a source refuses to answer.

// PARALLEL COLLECTION

Parallel collection

Seven independent tasks run concurrently with asyncio, each pulling from a different source: the site, LinkedIn, the Meta Ad Library, PageSpeed and a tech-stack scan. The pipeline waits on the slowest source, not the sum of all of them, so a brief is ready quickly instead of after a queue of sequential requests.

// GROUNDED EXTRACTION

Grounded extraction

The raw, unstructured material is handed to Google Gemini, which extracts a structured company profile and reads their marketing posture. The model works only from what the system actually retrieved, so every line in the brief traces back to a source the pipeline pulled, not to the model filling in a blank.

// SYNTHESIS AND DELIVERY

Synthesis and delivery

A second Gemini pass writes the finished brief, openers, pricing anchors and red flags, in the voice a rep can read at a glance. WeasyPrint renders it to a branded PDF, Supabase stores it and Resend emails it, so the deliverable lands in an inbox rather than a dashboard nobody checks.

// GRACEFUL DEGRADATION

Graceful degradation

The collection tasks run through asyncio.gather with return_exceptions set, so if LinkedIn blocks a scrape the pipeline carries on and names the gap in the brief. A rep sees what could not be found rather than a confident sentence built on nothing.

// STACK

Python 3.12FastAPICeleryRedisPlaywrightGoogle GeminiMeta Ad LibraryPageSpeed InsightsWeasyPrintResendSupabaseNext.js 14
// WHAT CHANGED

What changed for the team?

In plain operational terms, three things moved. I am describing what the agent does in production, not putting a number on it.

Every claim in the brief is grounded in the source data the system scraped, so reps stop walking in with guesses and start the call already knowing the account.

The same depth of prep on every prospect, not just the ones a rep had time for. The research that used to get skipped under a full calendar now happens on all of them.

Prep that used to sit between a rep and their selling hours is returned to the work they are actually paid for, without adding a head to the team to do it.

// THE HONEST VERSION

What I learned building it

In this build the hard part was never the writing, it was the scraping. Sources rate limit you, LinkedIn blocks you, a page you relied on last week changes its markup. My first instinct was to make the pipeline try harder. That was wrong. A brief that stalls waiting for a source it will never get is worse than a brief that ships with an honest gap in it.

So I built the whole thing to degrade on purpose. Every collection task can fail without taking the brief down with it, and the failure is written into the output where a rep can see it. The model is never allowed to paper over a missing source with a plausible sentence.

That is the line the whole system is built around: a brief a rep can trust is one that admits what it does not know.


This is the research agent behind the pre-sales work I build for agencies and sales teams: the same depth of prep on every prospect, grounded in real data, without a person having to find the hour.

// See how pre-sales research automation works

A 15-minute call is usually enough to know if there is a fit.

No slides, no pitch.