Duck
Tutorials5 min read

how to build AI agents for client tasks

Samet Turan— Editor··5 min read

Learn to build reliable AI agents for client work with real prompts, tool picks, and debugging tips—then decide if you want the blueprint.

how to build AI agents for client tasks

Last month I needed to automate a client’s lead follow‑up sequence without hiring a developer.

By the end of this article you’ll have a working agent that can draft emails, update a CRM, and flag hot leads—all driven by a single prompt.

You’ll see the exact prompts, tool choices, and where things usually break, plus a quick path to a ready‑made blueprint.

What most guides get wrong about AI agent building

Most tutorials treat the agent as a magic black box that just “works” once you plug in an API key.

They skip the part where you have to define clear boundaries for what the agent can and cannot do.

That leads to hallucinations, endless loops, or the agent sending the same email three times.

I learned this the hard way when my first prototype kept offering a discount that didn’t exist.

The fix isn’t more prompting—it’s giving the agent a strict schema and a fallback rule.

Think of the agent as a junior employee: you give it a checklist, a script, and a manager who steps in when it’s unsure.

How I picked the tools (real named example)

I started with LangChain because it lets you chain prompts, tools, and memory in a readable way.

For the CRM I used Airtable—its free tier offers enough records for a solo operator and the API is straightforward.

To handle the email sending I hooked into Make.com (formerly Integromat) which provides a visual workflow builder and webhook endpoints.

The language model is the OpenAI API with the gpt-4o model; temperature set to 0.2 for consistency.

Here’s the core prompt I use, stored as a LangChain template:

You are a lead‑follow‑up assistant for {{client_name}}.
Your goal: draft a personalized reply, log the interaction in Airtable, and flag any lead that shows buying intent.

1. Read the latest inbound email from {{lead_email}}.
2. Extract the lead’s name, company, and any mention of budget or timeline.
3. If the email contains a question about pricing, reply with our standard price sheet and ask for a meeting.
4. If the email shows clear buying intent (e.g., "Let’s move forward"), set the Airtable field "Hot Lead" to true.
5. Otherwise, draft a friendly, short reply that references a specific detail from their message.
6. Output JSON with keys: "reply", "update_fields" (Airtable fields to change), "flag_hot" (true/false).

Do not add any extra text outside the JSON.

Notice how the prompt forces a JSON output—this makes it easy to parse in the next step.

In Make.com I set up a webhook that receives the JSON, then runs two actions:

  • Update the Airtable record with the fields from “update_fields”.
  • Send an email via Gmail using the “reply” string.

The whole chain runs in under five seconds.

Cost breakdown:

  • LangChain is open‑source—free.
  • Airtable free tier: $0 (up to 1,200 records).
  • Make.com free plan: $0 but limited to 1,000 operations/month; I upgraded to the $9/mo plan for 10,000 operations.
  • OpenAI API: roughly $0.006 per 1k tokens; with ~800 tokens per run that’s about $0.005 per execution.

At 100 runs a day the API cost is about $15/mo.

I think the $9/mo Make.com plan is a fair price for the reliability it gives—especially when the free tier blocks webhook access, which forced me to upgrade after just two test runs.

Why does the agent lose context after three steps?

This is a reader‑question I see a lot.

The short answer: LangChain’s default conversation memory only keeps the last two exchanges unless you tell it otherwise.

When you chain multiple tool calls, each call resets the memory buffer unless you pass the accumulated history back into the next prompt.

I solved it by creating a custom memory object that stores the full conversation in a Airtable table and pulls it back on every step.

Here’s a simplified snippet:

from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(return_messages=True)
# after each tool run
memory.save_context({"input": user_input}, {"output": agent_output})
# before the next run
loaded = memory.load_memory_variables({})
# inject loaded['history'] into the prompt template

With this in place the agent remembers the lead’s name, company, and any budget mentions across five or more steps.

If you skip this, the agent will start treating each email as a brand‑new conversation and will forget whether you already quoted a price.

How to debug when this breaks

First, check the logs from Make.com—each step shows the raw input and output.

If the JSON is malformed, the agent likely fell back to plain text; look for missing braces or extra commentary after the JSON block.

Second, verify the Airtable update: sometimes a field name typo causes the write to fail silently.

Third, test the prompt in isolation using the OpenAI playground; set temperature to 0 and see if the model still returns JSON.

One concrete gripe: the OpenAI API occasionally returns a JSON string wrapped in markdown code fences ( … ), which breaks the parser.

I added a small preprocessing step in Make.com that strips any leading/trailing backticks before trying to parse.

Finally, watch the token usage; if you exceed the model’s context window the response will be truncated and you’ll get half‑finished JSON.

Keeping each prompt under 600 tokens has saved me from that headache.

That’s the gap.

Adjacent reading: deeper coverage of AI agent platforms.

If you’d rather skip the build and deploy a working version in an afternoon, we’ve packaged this workflow as a blueprint at deepusecase.com/vault/ai-agent-builder-kit.

— The Colophon

One AI tool. Tested. Reviewed.
In your inbox every Sunday.

~3 minute read. Real outcomes from operators, not marketers.

Free. One email per Sunday. Unsubscribe in one click.