Duck
Tutorials8 min read

How to Build an AI Agent That Actually Works

Samet Turan— Editor··8 min read

Learn how to build an AI agent that goes beyond simple chatbots. This guide covers the essential components—state, tools, and loops—to create automations that perform real work.

The Core Components of a Real AI Agent

An AI agent isn’t just a single call to ChatGPT. That’s a glorified function. A real agent has three parts that work in a loop: a brain, tools, and state. If you miss one of these, you don’t have an agent; you have a script that will break the first time it sees something unexpected.

  • The Brain (LLM): This is the decision-making core. It’s an LLM like OpenAI’s GPT-4o or Anthropic’s Claude 3 Opus. Its job isn’t to do the work, but to decide what work needs to be done next. It takes in the current situation and chooses a tool.
  • The Tools (APIs): These are the agent’s hands. They are functions the agent can call to interact with the world. This could be a `send_email` function that uses the SendGrid API, a `get_stock_price` function using Finnhub, or a `scrape_website` function. Each tool should do one thing well and return a clear result.
  • The State (Memory): This is the most critical and most overlooked part. State is the agent’s short-term memory. It’s a record of the overall goal, the steps taken so far, and the results of those steps. Without it, the agent has no context and can’t perform multi-step tasks. It’s the difference between asking a person to bake a cake versus giving them one instruction at a time with no memory of the previous one.

These three components run in a loop. The brain looks at the state and the goal, picks a tool, the tool runs, and its result is saved back to the state. The loop repeats until the goal is met. That’s it. That’s the core of every useful AI agent I’ve ever built.

What Most Guides Get Wrong

Almost every online tutorial on how to build an AI agent gets the most important part wrong. They show you how to write a clever prompt that can choose between a few functions in a single turn. They call an LLM, it returns a JSON object saying which function to run, the code runs it, and the demo ends. Impressive, but useless in production.

That’s not an agent. It’s a stateless router.

The real work happens in the second, third, and fourth steps. A real agent needs to take the output of the first tool, add it to its memory (the state), and then re-evaluate the goal to decide on the next action. It’s a conversation with itself, mediated by the tools you give it. This requires an orchestrator—a control loop that manages the state and repeatedly calls the LLM brain. Most guides conveniently skip this part because it’s less flashy than a single, clever prompt.

Another mistake is cramming all the logic into one massive god-prompt. Don’t do that. Your agent will be brittle and impossible to debug. Instead, use multiple, smaller, specialized prompts. You might have one prompt for routing (choosing the next tool), another for summarizing scraped text, and a third for drafting an email. This makes the system modular and much easier to fix when one part goes off the rails.

A Practical Build: The Lead Qualification Agent

Let’s build something real. Imagine an agent that takes a company URL, qualifies it as a potential lead, and drafts a personalized email intro. This is a perfect task for an agent because it’s a multi-step process involving data gathering and synthesis.

The Goal: Given `example.com`, find out what the company does, what tech it uses, and draft a two-sentence email intro.

Here’s the process, step-by-step:

  1. The Orchestrator: This is the master function. It can be a simple serverless function on Vercel or Cloudflare Workers. It initializes an empty state object, like `state = {}`, and starts the main loop.
  2. The Router Prompt: Inside the loop, the orchestrator calls the LLM with a prompt that tells it to choose the next tool. It’s not a conversational prompt; it’s a command.
You are a task routing system. Based on the goal and the current state, choose the next tool to use.Available Tools:1. `scrape_website(url)`: Scrapes the text content of a given URL.2. `check_tech_stack(url)`: Uses an API to identify technologies on a website.3. `draft_email_intro(context)`: Drafts a personalized email intro based on the provided context.4. `finish(output)`: Completes the task and provides the final output.Goal: Qualify example.com and draft an email intro.Current State: {{state_json}}Respond with ONLY the JSON for the tool to use, like this: {"tool": "scrape_website", "params": {"url": "example.com"}}
  1. First Loop: The `state_json` is initially empty (`{}`). The LLM will logically choose `scrape_website`. The orchestrator receives `{“tool”: “scrape_website”, “params”: {“url”: “example.com”}}`.
  2. Tool Execution: The orchestrator calls your actual Python or Node.js function for scraping. Let’s say it returns a big blob of text from the homepage.
  3. Update State: The orchestrator updates the state object: `state = {“scraped_content”: “ExampleCorp is a leader in synergistic blockchain solutions…”}`.
  4. Second Loop: The orchestrator runs the loop again. This time, it sends the updated state to the router prompt. The LLM sees the scraped content and now chooses the next logical step: `{“tool”: “check_tech_stack”, “params”: {“url”: “example.com”}}`.
  5. Rinse and Repeat: The `check_tech_stack` tool (which could be calling the BuiltWith API) runs and its output is added to the state. The state now has scraped content and tech data. In the next loop, the LLM will see that it has enough information and will finally call `draft_email_intro`. Once that’s done, it calls `finish`. The loop terminates.

This stateful, iterative process is what makes an agent powerful. It can reason, gather information over multiple steps, and react to the information it finds.

Is an AI Agent Framework Like LangChain Necessary?

This is a common question. Frameworks like LangChain or LlamaIndex promise to make building agents easier. My direct opinion? For most single-purpose agents like the one we just designed, they are complete overkill and often introduce more problems than they solve.

I have a concrete gripe here. I once lost two full days trying to debug a simple agent built with LangChain. It was getting stuck in a loop, and the framework’s internal abstractions made it impossible to see the raw LLM calls and responses. It turned out a minor version update had changed the default error-handling behavior in one of its chains. The documentation was useless. I eventually rebuilt the entire agent’s orchestrator loop myself in about 150 lines of Python, and it’s been running flawlessly ever since.

The value of these frameworks is in their pre-built integrations for complex systems, especially those involving Retrieval-Augmented Generation (RAG) with vector databases. If you need to connect to 15 different data sources and manage complex query transformations, they can be a good starting point. But for a tool-using agent, the core loop is so simple that building it yourself gives you 100% control and transparency. You’ll thank yourself when it’s 2 AM and you need to debug a production failure.

How to Debug When Your Agent Goes Haywire

Your agent will break. It will get stuck in loops, hallucinate parameters for your tools, or just give up. Expect it. The key is to build for debuggability from day one.

  • Log Everything Aggressively: Don’t just log “Agent started.” Log the *exact* prompt sent to the LLM, the raw JSON response from the LLM, which tool was executed, what the tool returned, and the updated state object. Do this for every single step of the loop. When something breaks, this trail is the only way you’ll figure out why.
  • Implement a Circuit Breaker: An agent can get stuck in a loop, calling the same two tools back and forth forever. This racks up API costs fast. Implement a simple counter. If the agent runs more than, say, 15 steps without calling the `finish` tool, kill the process and log an error. This is a critical safety net.
  • Make Your Tools Resilient: What happens if your `scrape_website` tool gets a 404 error? If it just crashes, the whole agent fails. Instead, the tool should catch the error and return a structured JSON message, like `{“error”: “Website returned 404 Not Found”}`. You then need to tell your main router prompt how to handle that error. Maybe it should try finding a different URL, or maybe it should just give up and finish. Planning for tool failures makes your agent far more reliable.

The Real Cost of Running an AI Agent

Building the agent is one thing; running it is another. The costs aren’t always obvious.

First, there’s the LLM API cost. GPT-4o is relatively cheap, but an agent that makes 5-10 LLM calls per task will add up. That lead qualification agent might cost $0.05 per run. If you’re processing 10,000 leads a month, that’s $500 right there.

Second, there are the tool API costs. Some APIs are free, but the valuable ones aren’t. Using the BuiltWith API for tech stack data is a great example. Their pro plan, which you’d need for this, is $295/month. Honestly, for a small agency running this automation, that price is a bargain if it helps close even one extra deal a month. For a solo operator just starting out, it might be too steep.

Finally, there’s the hidden cost: your time. Your time spent debugging, tweaking prompts, and handling the 5% of cases where the agent messes up. An agent that is 95% accurate is not a 95% solution. It’s often a 0% solution because you still have to check 100% of its work. The goal is to get it to 99%+ reliability on a well-defined task, and that takes iteration.

The good news is that the compute cost for the orchestrator itself is negligible. Running a serverless function on Vercel or Cloudflare is effectively free at any reasonable scale. My love for serverless for this kind of work is huge—it just works, scales automatically, and costs pennies.

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 entire workflow as a ready-to-deploy blueprint. You can find our AI Agent Builder Kit 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.