Getting Started with AI Agents

Learn how to build your first AI agent from scratch — understanding the core loop, tool use, and memory patterns that power modern AI applications.

TFH Technologies
3 min read

What Is an AI Agent?

An AI agent is a software system that can perceive its environment, reason about goals, and take actions autonomously to achieve those goals. Unlike a simple chatbot that just generates text, an agent can call external tools, browse the web, write and execute code, and chain multiple steps together.

The core loop of any agent looks like this:

  1. Perceive — receive input (user message, sensor data, API response)
  2. Reason — decide what to do next (often via an LLM)
  3. Act — call a tool, write to memory, or produce output
  4. Observe — process the result and loop again

The ReAct Pattern

The most widely-used agent architecture today is ReAct (Reason + Act). The LLM alternates between reasoning (chain-of-thought) and acting (tool calls) until it reaches a final answer.

import anthropic

client = anthropic.Anthropic()

tools = [
    {
        "name": "search_web",
        "description": "Search the web for current information",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "The search query"}
            },
            "required": ["query"]
        }
    }
]

def run_agent(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]

    while True:
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=4096,
            tools=tools,
            messages=messages
        )

        # If the model wants to use a tool
        if response.stop_reason == "tool_use":
            tool_use = next(b for b in response.content if b.type == "tool_use")
            tool_result = execute_tool(tool_use.name, tool_use.input)

            messages.append({"role": "assistant", "content": response.content})
            messages.append({
                "role": "user",
                "content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": tool_result}]
            })
        else:
            # Final answer
            return response.content[0].text

Tool Design Principles

Good tools make good agents. When designing tools for your agent:

  • Keep tools focused — one tool should do one thing well
  • Write clear descriptions — the LLM reads your description to decide when to use the tool
  • Return structured data — JSON is easier for the model to parse than raw text
  • Handle errors gracefully — return error messages in the tool result rather than raising exceptions
A poorly described tool is worse than no tool at all. The LLM will misuse it or ignore it entirely.

Memory Patterns

Agents need memory to handle long tasks and maintain context. There are four main memory types:

  • In-context memory — the conversation history in the prompt window
  • External storage — databases, vector stores (Pinecone, Chroma), files
  • Episodic memory — summaries of past sessions retrieved at startup
  • Semantic memory — indexed knowledge bases searched via embeddings

For most projects, start with in-context memory and add a vector store only when you hit the context limit.

Building Your First Agent

Here is a minimal agent with two tools — a calculator and a current-date lookup:

from datetime import datetime

def execute_tool(name: str, inputs: dict) -> str:
    if name == "calculate":
        try:
            result = eval(inputs["expression"])  # Use numexpr in production
            return str(result)
        except Exception as e:
            return f"Error: {e}"

    if name == "get_date":
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    return "Unknown tool"

Run it with a question like "What is 1234 5678 and what is today's date?"* — you will see the agent call both tools and compose a final answer.

Next Steps

Once you have a basic agent running:

  1. Add streaming so users see partial output in real time
  2. Implement human-in-the-loop confirmation for destructive actions
  3. Add observability — log every tool call and model response for debugging
  4. Explore multi-agent patterns where specialized agents collaborate

AI agents are rapidly becoming the primary way complex software tasks get automated. Building fluency now puts you ahead of the curve.

Related Articles

MCP 4 min read

Building MCP Servers with Python

A hands-on guide to building Model Context Protocol (MCP) servers — the open standard that lets AI models connect securely to your tools, databases, and APIs.

Read