Skip to content

active agent

The lead agent that qualifies leads for you

You give it an ICP. It returns contacts you can reach, research on each one and an outreach campaign written for them.

Status
Live. Outreach campaign generation in validation
Runs for
Our own outbound, and client campaigns in fintech and BPO
Services
Agent build

The lesson

26 qualified contacts that you know need your service and how to reach them beats 500 you need to research for.

What you give it

One thing: an ICP. Written down properly, not described on a call.

What you sell, who buys it, the job titles that sign off, company size, the countries you serve, the pain points you fix. That file is the entire configuration of the agent. Everything downstream reads from it, and changing your targeting means editing it rather than rebuilding anything.

What you get back

Per contact:

  • Name, role and company
  • A work email that has been checked, not guessed
  • A direct phone number where the record has one
  • Research on that specific person and business, with the source next to each claim
  • A score for how well they match what you sell, with the overlap that produced it

Per list:

  • A 3 email sequence for each contact: an opener that leads with something useful, a bump, a break up
  • A LinkedIn connection note plus a follow up message
  • Talking angles for whoever makes the call, each one cited back to something real about that company
  • One call script for the whole campaign, with the variable slots filled per lead
  • Free value offer options for the campaign, which you approve before anything gets written

Language is detected per contact, so a Spanish decision maker gets Spanish.

The chain

Every stage writes its own file before the next one starts. Any row in the final sheet traces back to the seed it came from, and any missing row traces to the stage that removed it.

  1. ICP definition. Your file. Nothing runs without it.
  2. Seed scrape. Companies pulled off the open web, not bought from a database.
  3. ICP match. Rules from your file decide who continues. This is a gate, not a suggestion.
  4. Dedup. Against this campaign and against everyone you have already contacted, held between runs rather than in memory.
  5. Email reveal. The paid database gets asked about people at the companies that survived. No email means the row stops here.
  6. Enrich. A crawl of the site plus recent public posts, for the companies still standing.
  7. Keyword overlap score. What they publish, measured against what you sell.
  8. QA flags. A human reads the flagged rows before anything is written to anyone. Unverifiable rows are marked rather than quietly delivered.
  9. Outreach campaign. Only after QA passes. Every specific claim in every email has to trace back to a field in that lead's row or to the approved offer, and a checking pass enforces it. A sentence that cannot be traced gets marked for review instead of sent.

The agent writes. It never sends. What lands in your inbox is a sheet you approve, not activity that already happened in your name.

The run we keep pointing at

One campaign, aimed at finance teams at small businesses across Europe. It ran on the previous version of this agent, which matters for one line below:

  • 83 companies built into the seed list
  • 20 trimmed by hand before the pipeline ran
  • 63 enriched
  • 7 dropped by a model scoring each company against the ICP
  • 30 had nobody with a reachable email
  • 26 contactable people delivered, 25 of them with a phone number

That is a 41% yield. The interesting part is not the 26. It is that we can say what happened to the other 57 without opening a single tool.

Why the ICP gate stopped using a model

That scoring step is the line we changed afterwards, and it is the clearest example of the difference we sell. A model reading a company and giving it a number is quick to build. It is also impossible to defend, because when somebody asks why a company is missing, the only honest answer is that the model gave it a 38.

The gate is now a set of rules that live in your campaign folder. You can read the rule, disagree with the rule and change the rule. Nothing else in the funnel moved, so the counts above still describe how a run behaves, but the reason attached to each drop is now a fact about the company rather than an opinion about it.

The number we were not tracking

The run cost $1.45 to execute, about $0.06 per contactable person. That number was measured to the cent on every run, and it was the wrong number to be proud of.

Building the seed list cost around $14, because we rebuilt it 3 times. Fully loaded, each usable lead cost about $0.61, which is 10 times what the pipeline reported. The field that should have caught this logged zero on every single run. The code wrote the column and nothing ever filled it, so the cheap half of the job was instrumented and the expensive half was invisible.

The fix was not a better model or a better prompt. It was a counter. Since then the rule on every agent we build is that anything which spends money increments something, and a metric that reads zero forever is treated as broken rather than good.

Once we could see the number, the seeding method had to go. Asking the contact database to find companies burned a credit per company and cost several times what it costs to enrich a company we already know about. Seeds now come off the open web, and the paid database only ever gets asked about people.

Delete early, spend late

The gates are ordered by cost, not by logic. Deduplication and the ICP match are nearly free, so they run first. Enrichment costs money per company, so it only ever runs on rows that already survived.

The hardest rule to accept was the simplest one: no email, no lead. A company that fits the ICP perfectly and has nobody reachable behind it is worth nothing to a person who has to send something. A generic inbox is not a contact either. Both get dropped at the gate rather than passed on for somebody to discover later.

Trimming the seed list harder made the whole thing better. On one batch we cut it from 40 companies to 20 before running. Yield on that batch went from an expected 25% to 55%. Fewer inputs, more output. That result is why the trim happens before the spend and not after it.

Where the agent part actually sits

Most of this is a workflow, on purpose. Fixed stages, fixed order, a file on disk at every step. We tried the open-ended version first and could not answer the only question that matters when somebody asks about a name on the list: why is this person here.

The model does the parts that need reading rather than matching. It reads a site and decides whether the company does what its category says it does. It scores overlap between what they publish and what you sell. It writes the outreach. Those judgments arrive with the evidence next to them, so you can disagree with a specific row instead of distrusting the whole file.

Everything else is code. That split is the whole design.

What it still gets wrong

Borderline rows get flagged rather than dropped. Adjacent industries, a job title that drifted, a company sitting just outside the size band. Somebody still has to look at those, and on a good run that is a handful of rows out of 26.

A filter on job titles once let the wrong roles through for a full batch. A smoke test caught it, not a review, which is the argument for having the smoke test.

The outreach stage is the newest part. It is built, its checking gate is built and 165 tests pass offline, but it has not yet run a full live campaign end to end. That is the status line at the top of this page, and it will keep saying so until it is not true.

Updated

All agents

Got a job that looks like this?

Send us the shape of it. We'll tell you whether it needs an agent or a script.