AI Agents Examples: Building a Lead enrichment agent from Scratch
You spend hours copying LinkedIn profiles, drafting cold emails, and logging results into a spreadsheet. It’s tedious, error‑prone, and scales poorly. After reading this, you’ll be able to assemble a no‑code AI agent that does those steps for you, and you’ll know where to tweak it when things go sideways.
Why does my agent hallucinate when scraping LinkedIn?
One of the first surprises I hit was the agent making up job titles or company names that never existed on the profile. The root cause wasn’t the AI model itself; it was the way the raw HTML was fed into the prompt. When the scraper returned a blob of JavaScript‑heavy markup, the language model tried to “fill in the gaps” and invented plausible‑sounding details.
Fixing it meant cleaning the scraped data before it ever reached the LLM. I used Apify’s LinkedIn scraper actor, which returns a clean JSON array of fields like firstName, lastName, headline, companyName. By mapping those fields directly into the prompt, I removed the noise that caused hallucinations.
Here’s the exact prompt I use (note the placeholders):
Write a short, personalized cold email to {{firstName}} {{lastName}} who works as a {{headline}} at {{companyName}}. Mention one specific detail from their headline that shows you did your research. Keep it under 120 words.
The templating is handled by Make.com’s text parser module, which swaps the double‑braces for the scraped values before sending the string to OpenAI.
What most guides get wrong about AI agent prompts
Many tutorials tell you to “be clear and specific” but then give a vague example like “Write a professional email.” That leaves too much room for the model to drift. In practice, specificity isn’t just about length; it’s about constraining the output format and giving the model a concrete anchor.
What works better is to give the model a strict structure and a single source of truth. For the lead‑enrichment agent I built, I added three constraints:
- Limit the email to exactly two sentences.
- Include the prospect’s first name in the greeting.
- End with a clear call‑to‑action: “Let me know if you’d like to see a short demo.”
When I enforced those rules, the variance in tone dropped dramatically and the edit‑time per email fell from five minutes to under thirty seconds.
Choosing the right no‑code stack
You don’t need a PhD in machine learning to wire this together. The stack I settled on consists of four pieces, each handling a distinct slice of the workflow:
- Apify – runs the LinkedIn scraper actor and returns clean JSON.
- Make.com – orchestrates the flow, handles authentication, and calls OpenAI.
- OpenAI API – generates the email copy using the prompt above.
- HubSpot’s CRM (or any CRM you prefer) – stores the prospect data and the generated email for follow‑up.
All of these offer free tiers that are enough to test the idea. Apify gives you 10,000 scraper credits monthly, which covers roughly 200 LinkedIn profiles. Make.com’s free plan allows 1,000 operations a month—more than enough for a solopreneur testing a few dozen leads per week. OpenAI’s pricing is token‑based; a typical email generation uses about 150 tokens, costing roughly $0.002. HubSpot’s free CRM stores unlimited contacts.
I think the combined monthly cost of running this agent at a modest volume (500 leads) stays under $15, which feels fair for the time saved.
Setting up the scraper in Apify
First, create an Apify account and navigate to the Actors store. Search for “LinkedIn Profile Scraper” and click “Deploy.” You’ll need to provide a list of profile URLs; I store mine in a Google Sheet and use Make’s HTTP module to fetch them as a JSON array.
The scraper returns a payload like this:
[{"firstName":"Ada","lastName":"Lovelt","headline":"Senior Data Engineer at Futurice","companyName":"Futurice"}]
Note that the actor automatically strips scripts and ads, leaving only the fields you need. That clean output is why the hallucination problem disappeared.
