AI Agents β€’ EduArtha

Building AI Agents β€” From Scratch

Master the art of building intelligent agents that reason, plan, use tools, and collaborate. From simple ReAct loops to production multi-agent systems.

⏱ 3–5 months  |  14 Chapters  |  50+ Exercises  |  14 Projects  |  Industry Problems

Part I

Foundations of AI Agents

Understanding what agents are and how they think

Chapter 1

What Are AI Agents?

Learning Objectives

  • Define AI agents and distinguish them from simple chatbots
  • Understand the Observe β†’ Think β†’ Act loop
  • Classify agents by architecture: reactive, deliberative, hybrid
  • Trace the history from ELIZA to modern LLM-powered agents
  • Build a minimal agent skeleton in Python

Agent vs Chatbot

A chatbot responds to messages. An agent pursues goals autonomously. The critical difference is the ability to take actions that affect the external world β€” calling APIs, reading files, writing code, browsing the web β€” and then observing the results to decide what to do next.

FeatureChatbotAI Agent
InteractionSingle turn Q&AMulti-step autonomous loops
ToolsNoneAPIs, code execution, search
MemoryContext window onlyShort-term + long-term memory
PlanningNoDecomposes tasks, re-plans on failure
StateStatelessMaintains state across interactions

The Observe β†’ Think β†’ Act Loop

while not goal_achieved:
  observation = perceive(environment)
  thought = reason(observation, memory, goal)
  action = decide(thought)
  result = execute(action)
  memory.update(result)

Your First Agent Skeleton

Python
class SimpleAgent:
    """Minimal agent skeleton β€” the foundation of everything."""

    def __init__(self, name, tools=None):
        self.name = name
        self.tools = tools or {}
        self.memory = []

    def think(self, observation):
        """Decide what action to take based on observation."""
        # In a real agent, this calls an LLM
        return {"action": "respond", "input": observation}

    def act(self, action):
        """Execute an action using available tools."""
        tool_name = action["action"]
        if tool_name in self.tools:
            return self.tools[tool_name](action["input"])
        return f"No tool found: {tool_name}"

    def run(self, task, max_steps=10):
        """Main agent loop."""
        observation = task
        for step in range(max_steps):
            thought = self.think(observation)
            print(f"Step {step+1}: {thought}")
            if thought["action"] == "finish":
                return thought["input"]
            result = self.act(thought)
            self.memory.append({"thought": thought, "result": result})
            observation = result
        return "Max steps reached"

Key Insight

Every agent framework β€” LangChain, CrewAI, AutoGen, OpenAI Assistants β€” is a variation of this loop. Understanding the skeleton lets you build or debug any framework.

Agent Taxonomy

TypeDescriptionExample
ReactiveStimulus-response, no internal modelThermostat, rule-based bots
DeliberativeMaintains world model, plans aheadChess engines, planners
HybridFast reactive layer + slow deliberative layerModern LLM agents (ReAct)
Multi-AgentMultiple agents collaborating/debatingAutoGen, CrewAI systems

Exercises

Ex 1.1: Add a calculator tool to the SimpleAgent that can evaluate math expressions.

Solution
def calculator(expr):
    try:
        return str(eval(expr))
    except:
        return "Error evaluating expression"

agent = SimpleAgent("MathBot", tools={"calculator": calculator})

Ex 1.2: Extend the agent to log all steps with timestamps to a file.

Solution
import json, time
def run_with_logging(self, task, logfile="agent.log"):
    observation = task
    with open(logfile, "a") as f:
        for step in range(10):
            thought = self.think(observation)
            f.write(json.dumps({"time": time.time(), "step": step, "thought": thought}) + "\n")
            if thought["action"] == "finish": return thought["input"]
            observation = self.act(thought)

Project: CLI Agent with Multiple Tools

Python
import datetime, os

def get_time(_):
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def list_files(path):
    try:
        return "\n".join(os.listdir(path or "."))
    except OSError as e:
        return str(e)

def read_file(path):
    try:
        with open(path) as f: return f.read()[:500]
    except OSError as e:
        return str(e)

agent = SimpleAgent("FileBot", tools={
    "time": get_time,
    "ls": list_files,
    "read": read_file,
    "calculator": lambda x: str(eval(x)),
})
print(agent.act({"action": "time", "input": ""}))
print(agent.act({"action": "ls", "input": "."}))

Industry: Devin by Cognition Labs

Devin is the first "AI software engineer" — an autonomous agent that can plan features, write code, run tests, debug errors, and deploy applications. It operates through a browser + code editor + terminal, using the same Observe→Think→Act loop described above. Devin solved 13.86% of real GitHub issues end-to-end in the SWE-bench benchmark, demonstrating that agent architectures can handle complex, multi-step engineering tasks.

Why This Matters for AI

2024-2025 marked the shift from "AI that talks" to "AI that does." Every major lab β€” OpenAI (Assistants API), Google (Gemini Agents), Anthropic (Claude tool use) β€” now ships agent capabilities. Understanding agent fundamentals puts you at the center of the most important AI paradigm shift since transformers.

Key Takeaways

  • Agents = LLM + Tools + Memory + Planning (not just chat)
  • The Observeβ†’Thinkβ†’Act loop is the universal agent architecture
  • Reactive agents respond instantly; deliberative agents plan ahead
  • Every agent framework is a variation of the SimpleAgent skeleton