Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

AI System Design

Design a Sales CRM Agent

Step 1 / 9

Learn AI system design by building an AI agent embedded in a CRM that enriches leads, scores priority, drafts outreach, and suggests next actions for a sales rep — where the agent writes into a…

The whole design, in writing

Every step of the build above, written out: the problem each piece solves, the option that was taken and the ones that were not, the numbers, and how it fails in production.

The big idea

An agent that writes into a shared, trusted system

Unlike a personal email inbox, a CRM is a SHARED system of record — every rep, sales manager, and automated report depends on it being accurate. An agent here isn't just risking one user's data; a bad write corrupts something many people and processes trust. And for anything relationship-sensitive (an actual sales conversation), the agent needs to stay a suggester, not an autonomous actor.

Sales Repowns the relationship
New in this step: Sales Rep.

We'll build around those two constraints: multi-source enrichment with real provenance tracking, lead scoring, rigorous write-back validation before anything touches the shared CRM, and a suggest-don't-act default for outreach.

What the new pieces do

Sales Repclient
Wants research and busywork automated, but stays the primary actor for anything relationship-sensitive — the agent suggests, the rep decides.

Step 1 · The baseline

Manual research, lead by lead

Simplest version: a rep manually researches each lead — company background, contact role, recent news — one at a time. What's the real cost?

Sales Repowns the relationshipCRMshared system of record
New in this step: CRM.

Reps manually research every lead individually. What's the actual cost of this approach?

  1. Manual research quality can be good, but it doesn't scale — a rep spending most of their time researching rather than actually engaging prospects is a real, significant opportunity cost, especially across a large lead volume.

  2. Every minute spent manually looking up company details or a contact's role is a minute not spent on the conversations and relationship-building that actually drive sales — automating the research (not the relationship) targets exactly this misallocation of a scarce resource: rep time.

  3. The time cost of manual research scales with lead volume per rep, which is a real constraint even for smaller teams — it's not exclusively a large-team problem.

Manual research consumes a large share of a rep's limited time on data-gathering rather than the actual selling and relationship work that drives revenue. Automating research — not the relationship itself — targets this specific misallocation.

Why this piece earns its place

Worth naming what manual research costs beyond the hours. The result lives in a rep's head and in their own notes, in whatever shape they chose, so two reps working comparable accounts record different things. There is no common set of fields across leads, and the steps that have to compare leads are the ones that die without it: scoring needs the same signals present on every lead to rank them against each other at all, and a freshness check needs a date to compare against. The drafting steps still function on hand research — they just function unevenly, richly for the account somebody dug into and thinly for the one nobody got to, with no way to tell which you are looking at. And the gap stays invisible until someone asks why the pipeline report disagrees with itself. The second cost lands on reassignment. A rep leaves or a territory is redrawn, and the research walks out with them — the new owner restarts from nothing on an account that has been worked for months. Where you would skip this: a team running a handful of named enterprise accounts, where the research is the relationship work and one account justifies weeks of a human reading everything. Automation pays off against volume, not against depth.

What the new pieces do

CRMgateway
The shared database every rep, manager, and downstream report depends on — a bad write here doesn't just affect one person, it corrupts a shared asset.

Step 2 · Multi-source enrichment with provenance

Sources disagree and go stale

Automate lead enrichment by pulling company and contact data from multiple external sources. Different sources can disagree with each other, and any of them can go stale. Should the system just trust whichever source it checks first?

Lead Enrichmentmulti-sourceSource Provenancefreshness + origin
New in this step: Lead Enrichment, Source Provenance.

Multiple external data sources are used for enrichment, and they can disagree or go stale. How should this be handled?

  1. Blindly trusting the first-responding source ignores that sources vary in reliability and freshness — a fast but stale or unreliable source could confidently supply wrong information with no way to know it might be outdated.

  2. Explicit provenance tracking means every downstream use of enrichment data can account for how reliable and how CURRENT it actually is — a fact from a frequently-updated, generally-reliable source is treated differently than a stale or less-reliable one, rather than flattening all enrichment data into equally-trusted facts.

  3. A single source misses coverage a multi-source approach provides, and doesn't solve the freshness problem either — a single source can still go stale over time, so the underlying issue isn't actually avoided.

Track Source Provenance explicitly — which source supplied each fact, and how recently it was verified — rather than treating every enriched data point as equally trustworthy. This gives downstream consumers the information needed to weigh reliability and catch staleness before acting on outdated data.

Why this piece earns its place

The decision that gets expensive later is granularity. A single last_verified timestamp on the lead record is the obvious first cut and it is close to useless: the record was assembled from several sources at different moments, so one date either condemns the whole record because one field aged out, or blesses it because one field was touched yesterday. Provenance belongs on the field — title, headcount, funding stage each carrying their own origin and date. Retrofitting that means backfilling every record already written, because you cannot reconstruct which source supplied which value after the fact. Field-level provenance also buys something you will need on a Tuesday with no warning: when a data vendor is dropped or a contract lapses, you can find exactly the facts that came from it and re-verify only those. Without it, losing a source means re-enriching the entire database or quietly keeping values nobody can stand behind any more.

What the new pieces do

Lead Enrichmentservice
Pulls company and contact data from multiple external sources — which don't always agree, and go stale at different rates.
Source Provenancedata
Tracks where every piece of enrichment data came from and how recently it was verified — the basis for trusting (or flagging) any given fact.

Step 3 · Score and prioritize leads

Focus effort where it's actually likely to pay off

A rep has far more leads than time to pursue each equally. Should all leads get equal attention?

Sales RepCRMSource ProvenanceLead Scoring
New in this step: Lead Scoring. · swipe to pan the diagram

A rep has many more leads than time allows pursuing equally. Should attention be spread evenly?

  1. Equal effort across leads with wildly different actual conversion likelihood means real time gets spent on low-probability leads at the expense of the ones most likely to actually close — "fair" in this sense doesn't serve the actual goal.

  2. Lead scoring directs a rep's genuinely scarce time toward leads statistically most likely to actually convert, using the enrichment data already being gathered — a materially better use of limited effort than spreading it evenly regardless of likelihood.

  3. Recency alone says nothing about actual conversion likelihood — a lead that arrived yesterday but shows weak fit signals shouldn't automatically outrank a stronger, slightly older lead.

Add a Lead Scoring model that ranks leads by predicted conversion likelihood, using enriched signals, and surfaces that priority to the rep — directing scarce time toward the leads statistically most worth pursuing.

Why this piece earns its place

A score is derived state, and derived state is where quiet wrongness lives. It was computed from a particular set of enriched facts; enrichment then updates and the score sits there unchanged, ranking a lead on a headcount or a funding stage that has since been overwritten. So re-scoring should hang off the write that changed the inputs rather than off a pass over the whole database on a timer. That is affordable here in a way it deliberately is not for the freshness checks in Step 8, and the asymmetry is worth naming rather than leaving as an inconsistency: re-scoring is local compute over data you already hold, while re-verifying a fact is an outbound call to a source that bills for it. Free derived work can be eager; work that costs money per record waits until somebody needs that record. Two knobs also belong in different places. What the model emits is a likelihood. Where the cut line falls — how far down the list a rep gets in a week — is a capacity decision, not a modelling one, so it lives in team configuration and moves without retraining anything. And ship the reasons beside the number: a bare score invites the rep to argue with it in general, where two named signals let them disagree specifically — the only kind of disagreement you can learn from.

What the new pieces do

Lead Scoringservice
Ranks leads by predicted conversion likelihood, so limited rep time and effort goes toward the leads most worth pursuing.

Step 4 · Protect the shared system of record

A bad write corrupts something everyone trusts

Enriched and scored data needs to be written back into the CRM. Should writes happen automatically and immediately, with no validation?

CRMLead EnrichmentSource ProvenanceWrite Validator
New in this step: Write Validator. · swipe to pan the diagram

Enrichment writes need to land in the shared CRM. Should they write immediately with no validation?

  1. An unvalidated write can create duplicate records, overwrite a more-reliable existing value with a less-reliable one, or introduce inconsistent data — and because the CRM is SHARED, that corruption affects every rep, manager, and report relying on it, not just one user.

  2. Because the CRM is a shared system of record many people and automated processes depend on, a bad write is far more consequential than a bad write to one person's private data — validating before commit, and blocking writes entirely if the validator itself is down, protects the shared asset from corruption.

  3. The reasoning for validating writes (protecting shared data integrity) applies to any automated write path, not uniquely to this specific agent — though this design specifically focuses on the agent's own write path, the underlying principle isn't agent-specific.

Add a Write Validator that checks every enrichment write for duplicates and consistency before it commits to the CRM — and fails closed: while the validator is unavailable, writes queue rather than risking corruption of a system of record that many people and downstream processes trust.

Why this piece earns its place

Failing closed is the easy half. The hard half is draining the queue. A held write was computed against the record as it looked an hour ago, and in that hour a rep may have edited the same field by hand. Replaying it blindly overwrites a human correction with a machine guess, which is the fastest way there is to lose a sales team's trust in the whole system. So queued writes should be conditional — carrying the record version they read, failing if it moved — and a human edit should win the tie rather than being silently reapplied over. The other place the effort goes is duplicate detection, where the two error directions are not symmetric. Two records for one company is annoying and reversible. Merging two genuinely different companies with similar names destroys history nobody can pull apart afterwards, because the writes that built it are gone. Bias the matcher against merging and route ambiguous pairs to human review: an unmerged duplicate is a task, a bad merge is an incident.

What the new pieces do

Write Validatorservice
Checks every write for duplicates and consistency before it lands in the shared CRM — protecting a system many others trust from corruption.

Step 5 · Suggest, don't act

The agent proposes; the rep decides

The system has enriched, scored, and can draft outreach for a lead. Should it autonomously send that outreach, or something else?

Sales RepCRMSource ProvenanceLead ScoringOutreach Drafter
New in this step: Outreach Drafter. · swipe to pan the diagram

A drafted outreach message is ready for a promising lead. Should the agent send it autonomously?

  1. Sales outreach is inherently relationship-sensitive — tone, timing, and specific phrasing matter to a real human relationship in ways that are hard to fully validate automatically, and a wrong or poorly-timed autonomous message can damage a real prospect relationship in a way that's hard to undo.

  2. Defaulting to suggestion rather than autonomous action respects that sales outreach carries relationship stakes an automated check can't fully capture — the rep's judgment stays in the loop for the actual send, while the agent still saves them the drafting and research effort.

  3. Even a high-scored lead is a real relationship with real stakes if the outreach is wrong or mistimed — a high score reflects conversion LIKELIHOOD, not confidence that a specific automated message is appropriate to send unreviewed.

Default the Outreach Drafter to suggestion, not autonomous action: it proposes a next-best-action (a drafted email, a recommended call) but the rep remains the one who reviews and actually sends or acts. This keeps a human as the primary actor for anything relationship-sensitive, while still eliminating the drafting and research burden.

Why this piece earns its place

Two things about suggestions only show up once people use them. First, the edit is the signal. When a rep rewrites a draft before sending, the difference between what was proposed and what actually went out is the most useful data this system produces — it says precisely where the drafter is wrong, for free, from someone who knows. That signal only exists if both versions are kept: store the outcome alone — sent or discarded — and the most informative thing the rep produced is thrown away at the moment they hit send, leaving the drafter to be improved by guesswork. Second, the message goes out under the rep's name, so the rep carries whatever it claims. That means the review surface has to show the facts behind the draft and where they came from, not just the prose — nobody can sanity-check a line about a funding round without being told which source said so and when. And suggestions need an expiry. An unreviewed pile is a second inbox, and a week-old draft rests on a week-old picture of the account, which is the staleness problem arriving through a different door.

What the new pieces do

Outreach Drafterservice
Drafts personalized outreach using real enrichment data — proposed to the rep, who remains the one who actually sends it.

Step 6 · Personalize at scale without genericness

Real data, not mail-merge

Drafting outreach for many leads at once risks reading as obviously mass-produced, generic content — the opposite of what makes outreach effective.

Sales RepCRMLead EnrichmentSource ProvenanceLead ScoringWrite ValidatorOutreach Drafter
The system as it stands at this step. · swipe to pan the diagram

Draft outreach using actually-relevant enrichment data — recent company news, a specific role-based pain point, a concrete detail from provenance-tracked research — rather than templated mail-merge with only a name swapped in. The scale comes from automating the RESEARCH and drafting effort, not from producing identical content with superficial substitution.

Why this piece earns its place

The interesting case is the lead with nothing specific about it — thin enrichment, a company nobody has written about. A drafter that must always produce something personalized will reach for the weakest detail available, and a stretched specific reads worse than a plain sentence: it is visibly a machine that tried. So the drafter needs permission to write something short and unremarkable, or to hand back a blank, and every concrete claim it does make should trace to a provenance-tracked fact rather than to the model's own sense of what a company like this is probably doing. The consequence nobody plans for is the second one. A rep's drafting time was an accidental rate limit, and removing it removes the natural ceiling on outbound volume along with it. Sending capacity now has to be a number somebody deliberately chose, per rep and per domain, because the cost of getting that wrong is not one bad email — it is a sending reputation that is slow to rebuild and shared by everyone on the team.

Step 7 · Automatic activity logging

Pipeline visibility without manual data entry

Sales pipeline reporting depends on accurate records of every call, email, and meeting. Should reps be responsible for manually logging every interaction?

CRMSource ProvenanceLead ScoringOutreach DrafterActivity Log
New in this step: Activity Log. · swipe to pan the diagram

Automatically capture and log every interaction — calls, emails, meetings — into the Activity Log, feeding back into the CRM without requiring reps to manually re-enter what already happened. This keeps pipeline reporting accurate and current without adding administrative burden that competes with the actual selling time this whole design exists to protect.

Why this piece earns its place

The hard part of auto-capture is that one real-world interaction arrives more than once — a meeting from the calendar and again from the thread that scheduled it, a call from the dialer and again from the follow-up mail. So the log needs an idempotency key derived from the event itself, participants plus a time window, rather than a row id minted whenever a connector happens to notice. Get it wrong and nothing errors: the log simply counts one conversation twice, and a pipeline report claiming a rep had twice the conversations they had is the least useful kind of wrong, because it is confidently precise. This is also the one store here that should be append-only. Activity is evidence about what happened, so a mistake is corrected with a new entry, never by editing the old one — the moment history becomes editable, a forecast built on it stops being defensible to the first person who asks how it was derived. And draw a line at content. That a call happened, with whom, for how long, is CRM data; what was said in it is a recording, and capturing that carries consent rules that vary by jurisdiction — a setting somebody signs off on per region, never an agent default.

What the new pieces do

Activity Logdata
Every call, email, and meeting logged automatically, keeping pipeline reporting accurate without manual rep data entry.

Step 8 · The sharp edges

Stale facts and a scoring model that drifts

Two real risks: enrichment data that was accurate when gathered but is now outdated (a contact changed roles months ago), and a lead-scoring model whose predictions quietly degrade as market conditions shift.

Sales RepCRMLead EnrichmentSource ProvenanceLead ScoringWrite ValidatorOutreach DrafterActivity Log
The system as it stands at this step. · swipe to pan the diagram

Apply freshness thresholds using the Source Provenance data — enrichment past a certain age gets flagged for re-verification before it's used in outreach, catching exactly the kind of stale-fact embarrassment (congratulating someone on a role they've left) that undermines trust in the whole system. For scoring, apply the same drift-monitoring principle used for any production ML model: track the scoring model's real-world accuracy over time and re-validate or retrain as market conditions shift, rather than assuming a model validated once stays accurate indefinitely.

Why this piece earns its place

A freshness threshold can only flag — the replacement fact is a source call nobody has made yet — so what the solution leaves open is what happens in that gap, and both obvious answers are bad. Hold the draft until re-verification lands and the rep queues behind an API to reach a lead already talking to a competitor. Drop the aging field silently and the draft gets thinner with nobody told why. Show the age on the fact and let the rep judge whether it matters for the sentence they are writing. Two details make the threshold workable: age belongs per field, since a founding year does not rot while a job title does; and a re-verification returning unchanged is itself a write, because confirming a fact resets its clock. Skip that write and the field fails every cycle while you buy the same answer again. On drift, the awkward part is that the label arrives late: whether a lead converted is known long after the score was assigned, so an accuracy number always reports on a model version you have already replaced. Watch the inputs, available the same day — the distribution of enriched features going in, and the rate at which top-ranked leads are actually being worked. If reps quietly stop trusting the ranking, that shows up in their behaviour well before it shows up in conversion data.

You did it

You just designed a sales CRM agent.

Sales RepCRMLead EnrichmentSource ProvenanceLead ScoringWrite ValidatorOutreach DrafterActivity Log
The finished design, end to end. · swipe to pan the diagram

Everything you assembled, in order

  • Manual lead research consumes rep time that's better spent on actual selling — automate the research, not the relationship.
  • Multi-source enrichment needs explicit provenance tracking (source and freshness) since sources disagree and go stale at different rates.
  • Lead scoring predicts future conversion likelihood, directing scarce rep time — a genuinely different, more predictive problem than simple urgency triage.
  • Writes to the shared CRM are validated and fail closed, because a bad write corrupts a system of record many people and processes trust, not just one user.
  • The agent defaults to suggesting next actions, not autonomously executing them, keeping a human as the primary actor for relationship-sensitive outreach.
  • Personalization at scale comes from using real, relevant enrichment data, not mail-merge templating.
  • Automatic activity logging preserves pipeline reporting accuracy without reintroducing the manual burden the design set out to remove.
  • Freshness thresholds and ongoing scoring-model drift monitoring catch stale data and degrading predictions before they cause real harm.

Where an interviewer pokes next

Getting the boxes right is the easy half. These are the questions that separate a candidate who drew the diagram from one who has run the thing. Answer each one out loud before you open it.

  1. Why does this agent default to suggestion while the Email Agent design auto-executes some low-risk actions?

    Both designs are scoping autonomy to actual risk, but they reach different DEFAULTS because their typical action mix differs. An email agent handles a large volume of routine, often genuinely low-stakes actions (archiving an obvious newsletter) alongside occasional consequential ones — so a reversibility-scoped gate that auto-executes the clearly safe majority makes sense. A sales agent's core outputs (outreach to a real prospect) are almost always relationship-sensitive by nature — there isn't a large volume of genuinely low-stakes autonomous actions to safely automate in the same way, so defaulting to suggestion-first, with the rep as the consistent actor, better fits what this specific domain's actions actually look like.

  2. How is CRM write-validation different from the tenant-isolation enforcement in the Multi-Tenant SaaS design?

    Tenant isolation protects data from crossing a boundary BETWEEN separate customer organizations who should never see each other's data at all. CRM write validation protects data integrity WITHIN one shared system that many people on the SAME team are all supposed to see and rely on — the risk isn't unauthorized access, it's CORRUPTION (duplicates, inconsistent facts, stale overwrites) of a system everyone is meant to trust equally. Different failure mode, same underlying lesson: a write with a large blast radius (many trusting consumers) deserves more validation rigor than a write with a small one (one user's own data).

  3. Could lead scoring itself introduce unfair bias — systematically deprioritizing certain types of leads?

    This is a real risk worth naming explicitly: if the scoring model is trained on historical conversion data, and that history reflects past biases in who reps happened to pursue (rather than who was actually MOST likely to convert if pursued equally), the model can learn and perpetuate that same skew — systematically scoring certain lead types lower not because they're genuinely less likely to convert, but because they were historically under-pursued. This is the same fairness concern raised for active learning in the Data Labeling Platform design (a model can develop blind spots reflecting its training data's own gaps) — periodic bias auditing of scoring outcomes against ACTUAL outcomes when leads of different types ARE pursued is a reasonable safeguard.

  4. What would need to change if a rep wants the agent to have more autonomy for a specific, trusted type of lead (say, inbound leads who already requested a demo)?

    The suggest-don't-act default from Step 5 doesn't have to be a single global rule — it can be scoped per lead-type or per-signal, similar to how the Email Agent's auto-action allowlist expands carefully for proven-safe patterns over time. An inbound lead who explicitly requested a demo carries a meaningfully different relationship context than a cold outbound prospect, and a team might reasonably configure a narrower, well-justified autonomous action (like auto-sending a demo confirmation with logistics) for that specific, lower-relationship-risk case — while keeping the suggest-first default for genuinely cold, relationship-building outreach where tone and timing matter most.

  5. Why track BOTH source and freshness for enrichment data, rather than just freshness?

    They catch different failure modes. Freshness alone tells you HOW OLD a fact is, but not how reliable it was even at the moment it was gathered — a fact from a notoriously unreliable source is questionable even if it was captured yesterday, while a fact from a highly authoritative source might reasonably be trusted a bit longer before needing re-verification. Tracking both dimensions lets the system apply a more nuanced trust policy (e.g., "trust this reliable source's data for 90 days, but re-verify this less-reliable source's data after just 30") rather than a single flat freshness rule that either over-trusts unreliable sources or unnecessarily re-verifies highly reliable ones too often.

Check yourself — the answers, and why

Nine steps in, these are the calls you should be able to make cold. Pick one, then read why.

  1. Manual, per-lead research is the main baseline problem because…

    Automating research targets the specific misallocation of scarce rep time, not the relationship itself.

  2. Source provenance is tracked for enrichment data because…

    Provenance is what makes catching a stale or unreliable fact possible before it's acted on.

  3. The Write Validator fails closed because…

    The blast radius of a bad write to a shared system of record justifies blocking writes during a validator outage.

  4. The agent defaults to suggesting outreach rather than sending it autonomously because…

    This keeps human judgment in the loop for interactions where tone and relationship stakes matter most.

  5. Lead scoring is a different problem from simple inbox-style urgency triage because…

    Predictive scoring and urgency classification solve genuinely different underlying problems.

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

What it must do

Agree on these before drawing a single box.

  • Enrich leads: pull company and contact data from multiple external sources automatically.
  • Track provenance: record which source supplied each fact and how recently it was verified.
  • Score & prioritize: rank leads by predicted conversion likelihood so scarce rep time goes to the best.
  • Validate writes: check every write for duplicates and consistency before it lands in the shared CRM.
  • Suggest & log: draft outreach the rep reviews and sends, and auto-capture every call, email and meeting.

The qualities that shape everything

Each one names the mechanism that buys it.

Free rep time for actual selling
Automated multi-source lead enrichment replaces manual, per-lead research — automating the work, not the relationship.
Direct scarce rep time to the best leads
A Lead Scoring model ranks leads by predicted conversion likelihood using enriched signals, surfacing priority to the rep.
Protect a shared system of record
A Write Validator checks every write for duplicates and consistency and fails closed — writes queue rather than risk corrupting data many people trust.
Human stays the actor for relationship work
Suggest-don’t-act: the Outreach Drafter proposes a next-best-action but the rep reviews and actually sends anything relationship-sensitive.
Preserve reporting without new busywork
Automatic activity logging captures every call, email, and meeting into the CRM without reps re-entering what already happened.
Catch stale facts before they embarrass
Freshness thresholds over the provenance data flag aging enrichment for re-verification, plus drift monitoring on the scoring model.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

Automate the research, not the relationship over manual per-lead research

Research consumes a large share of a rep’s limited time — every minute looking up company details is a minute not spent on the conversations that actually drive sales.

Track source provenance (origin + freshness) over trusting whichever source responds first

Sources vary in reliability and go stale at different rates; a fast but stale source could confidently supply wrong information with no way to flag it.

Score leads by conversion likelihood over equal effort across every lead

Equal effort spends real time on low-probability leads at the expense of the ones most likely to close — “fair” in that sense doesn’t serve the actual goal.

Validate writes and fail closed over immediate unvalidated writes

The CRM is shared, so a duplicate or inconsistent write corrupts every rep’s view, report, and downstream automation — validation rigor should scale with that blast radius.

Suggest, don’t act over autonomously sending outreach

Sales outreach is relationship-sensitive — tone and timing matter in ways hard to validate automatically, and a wrong or mistimed message can damage a real prospect relationship.

The answer, out loud

What a strong answer to “Design a Sales CRM Agent” sounds like, first question to last trade-off. It is about 7 minutes of talking; the whiteboard and the interviewer fill the rest of the 45. Read it aloud once, then close the page and give it yourself.

  1. 0-3 min

    What makes this different from a personal assistant

    I want to name the constraint first, because it shapes everything after it. A CRM is not one person's inbox — it is a shared system of record. Every rep, every manager, every pipeline report reads out of it. So when an agent writes here it is not risking one user's data, it is risking something a whole team relies on. And the agent's main output is outreach to a real prospect, which is relationship work. Those two facts give me my two rules for the design: be rigorous about writes, and stay a suggester rather than an actor for anything that touches a relationship.

  2. 3-8 min

    The baseline, and what I am actually automating

    The baseline is a rep researching each lead by hand — company background, who the contact is, what has happened there recently. That is not bad work, it just consumes a large share of a limited resource. Every minute spent looking something up is a minute not spent in a conversation, and the conversations are what actually drive sales. So I would be precise about the target: I am automating the research and the admin, not the relationship. That distinction is what stops me over-automating later, when it starts to look tempting to just let the agent send things by itself.

    Built in step 1: Manual research, lead by lead
  3. 8-15 min

    Enrich from several sources, and record why you believe it

    Enrichment goes out to several providers rather than one, because no single one covers everything, and they will not always agree. The tempting shortcut is to reconcile what comes back into one clean record and move on. I would not do that, because that merge is lossy in a direction I cannot undo: once the fields are flattened I cannot tell you who stood behind a job title or when anybody last looked at it, and there is no reconstructing it. So I would keep the origin and the last-checked date sitting on each field as it lands. It costs a little storage and some schema complexity, and it buys every later decision that has to ask whether a fact still holds — I would rather pay on the way in than find out on the way out that I threw it away.

    Built in step 2: Sources disagree and go stale
  4. 15-21 min

    Score, because rep time is the scarce thing

    Reps have far more leads than time, so I would add a scoring model that ranks by predicted likelihood to convert, using the enriched signals we are already gathering. It is worth being clear that this is a prediction, not a triage rule — it is guessing at a future outcome from present signals, which is a harder problem than sorting an inbox by urgency. I would surface the ranking to the rep as priority rather than as a gate. And I would watch how it treats a thinly enriched lead: missing enrichment is an absence of evidence, not evidence of a bad fit.

    Built in step 3: Focus effort where it's actually likely to pay off
  5. 21-28 min

    The write path is where the rigor goes

    Enriched, scored data has to land back in the CRM, and this is the part I would not rush. Every write goes through a validator that checks for duplicates and for consistency with what is already there before it commits. And it fails closed: if the validator is unavailable, writes queue rather than going in unchecked. That will feel over-cautious right up until the first duplicate record splits one account across two owners and two reports. The rule I would state out loud is that validation rigor should scale with blast radius, and the blast radius here is the whole team.

    Built in step 4: A bad write corrupts something everyone trusts
  6. 28-34 min

    Propose the action, let the rep send it

    The drafter proposes a next best action — an email, a call — and the rep reviews and sends. I would hold that line even for high-scoring leads, because a high score is about conversion likelihood, not about whether one specific message is appropriate to send unread. Tone and timing matter to a real relationship in ways I cannot validate automatically. And whatever is specific in that draft has to trace to something we actually found out about the company, not to a slot in a template. The volume comes from the rep never doing the lookup and never starting at a blank page — not from one letter going out many times wearing different names.

    Built in step 5: The agent proposes; the rep decides
  7. 34-40 min

    Close the loop, then plan for the unhappy path

    Two things finish it. Activity logging captures calls, emails and meetings automatically, so pipeline reporting stays accurate without handing the rep back the busywork I just removed. Then the failure modes. Enrichment that was right when we gathered it goes stale — a contact changes roles — and if we do nothing the first to notice is the prospect, in an email. The dates we kept in step two let us catch it first — a fact past its window is held for a re-check instead of going out. And the scoring model drifts as the market moves, so it gets the same ongoing monitoring and retraining any production model needs. A system that only works on perfectly fresh data is a demo.

    Built in step 7: Pipeline visibility without manual data entry
  8. 40-45 min

    The trade-off, and what I would do with more time

    So: multi-source enrichment with provenance, scoring to direct attention, validated fail-closed writes, and suggestion rather than autonomous action. The trade-off I am making throughout is speed for trust. Fail-closed writes mean the CRM is sometimes behind. Suggest-do-not-act means the rep is still in the loop on every send. Both cost time deliberately, because a corrupted system of record or a damaged prospect relationship is far more expensive to undo than a delay. With more time, two things. First, how we would know any of this helps: the honest measure is whether reps are having more real conversations, and that needs a baseline taken before we ship — the thing nobody remembers until it is too late. Second, the activity log. We are filling it, and the scoring model does not read it; how a lead actually behaves is probably stronger evidence than anything we bought about their company.

What this teaches

Learn AI system design by building an AI agent embedded in a CRM that enriches leads, scores priority, drafts outreach, and suggests next actions for a sales rep — where the agent writes into a SHARED system of record many people and processes depend on, and stays a suggester rather than an autonomous actor for relationship-sensitive interactions. An interactive guide covering why manual lead research doesn't scale, multi-source enrichment with provenance tracking, lead scoring, write-back validation to protect a shared CRM from corruption, next-best-action suggestion instead of autonomous action, genuine personalization at scale, automatic activity logging, and stale-data safeguards.

Key takeaways

  • Manual lead research consumes rep time that's better spent on actual selling — automate the research, not the relationship.
  • Multi-source enrichment needs explicit provenance tracking (source and freshness) since sources disagree and go stale at different rates.
  • Lead scoring predicts future conversion likelihood, directing scarce rep time — a genuinely different, more predictive problem than simple urgency triage.
  • Writes to the shared CRM are validated and fail closed, because a bad write corrupts a system of record many people and processes trust, not just one user.
  • The agent defaults to suggesting next actions, not autonomously executing them, keeping a human as the primary actor for relationship-sensitive outreach.
  • Personalization at scale comes from using real, relevant enrichment data, not mail-merge templating.
  • Automatic activity logging preserves pipeline reporting accuracy without reintroducing the manual burden the design set out to remove.
  • Freshness thresholds and ongoing scoring-model drift monitoring catch stale data and degrading predictions before they cause real harm.

Concepts covered

  • An agent that writes into a shared, trusted system
  • Manual research, lead by lead
  • Sources disagree and go stale
  • Focus effort where it's actually likely to pay off
  • A bad write corrupts something everyone trusts
  • The agent proposes; the rep decides
  • Real data, not mail-merge
  • Pipeline visibility without manual data entry
  • Stale facts and a scoring model that drifts
RUN IT YOURSELF

Two different people score higher than one person twice

Twenty-four CRM contact records, deduplicated two ways — grouped by exact email, then blocked on a cheap key and merged above a similarity threshold — running for real in your browser. It prints what each rule merged, what it invented, what it walked past, and the score of the best false pair against the best true pair below it. Change AUTO at the top, hit Run, and watch the wrong merges and the missed ones trade places.

HOW TO READ THE CODE — 5 IDEAS
  1. Blocking is what makes this affordable and what caps it: 17 pairs are scored instead of 276, and the one true pair whose surname was typed Novak in one record and Nowak in the other lands in a different block, so no threshold ever reaches it. The fix is a second blocking pass, not a lower bar.
  2. The rule everyone ships first is not the safe one. Grouping on an exact email match merges two different people who share one info@ mailbox, and still walks past 5 of the 7 real duplicates — wrong in both directions at once (step 4).
  3. The score orders overlap by 0.192, and at the knife edge by 0.006: two different Ortizes at one account score 0.806, one Robert Chen recorded twice as Bob scores 0.800, and the weakest real duplicate of all — one Priya Raman, twice — scores 0.614. Any threshold that catches Robert merges the Ortizes, and the threshold that catches Priya is far below both.
  4. That is not a tuning failure — 5 of 5 weightings tried still overlap. The false pair agrees on exactly the fields a matcher trusts most (surname, company, switchboard), while the real duplicate at the bottom of the range — Priya Raman, at 0.614 — disagrees on them because she changed jobs — step 8's stale-data problem arriving as a matching problem.
  5. So the band, not the threshold: auto-merge the 3 pairs above it with zero wrong merges, and hand a human the 6 the evidence cannot separate, 3 of which are real. Step 4's asymmetry is the reason — an unmerged duplicate is a task, a bad merge into a shared system of record is an incident nobody can pull apart afterwards.
CPython · WebAssembly
built so a bad write never corrupts the shared system of record every rep depends on — make the calls, feed it stale data, run the gauntlet.
Finished this one? 0 / 65 AI System Designs done
NextDesign a Conversational AI Closest AI system design to this one

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More AI System Designs