πŸ“š Study Notes / Home / GenAI / Session 3
Session 03 Β· Introduction to AI Agents

Giving the AI hands: from chatbot to agent

In Session 1 you learned that an LLM is just a next-token predictor that lives in a frozen brain with no memory and a knowledge cutoff. In Session 2 you learned to talk to it well. Today we give it hands. We'll build up β€” gently, from scratch β€” the idea of an AI agent: an LLM that can decide what to do, use tools, look at the results, and keep going until the job is done. Same beginner pace as always: a little story first, then the real mechanics, then a worked example.

⏱ 23 min readπŸ“– 7 topics

1 Why a plain LLM isn't enough


Explain like I'm 5

Imagine the smartest person you know, but they're locked in a windowless room with no phone, no internet, and no clock. They've read a zillion books β€” but only books printed before they got locked in. Ask them "what's the weather right now?" and they honestly can't tell you. Ask them to "turn off my bedroom light" and they can't reach it. They can only talk. That brilliant locked-in person is a plain LLM. An agent is that same person, but now we slide them a phone, a calculator, and a notepad under the door.

Let's recall exactly why a raw LLM is limited. Every limitation here comes straight from Session 1, and each one is a reason agents exist.

The four walls of the locked room

LimitationWhere it comes from (Session 1)What goes wrong
Knowledge cutoffThe model learned everything during training, which ended on a fixed date.It can't know anything that happened after that date β€” yesterday's news, a price that changed this morning, a sports score from last night.
No live / real-time dataInference doesn't fetch anything; the model only "reads" the prompt you give it.It can't check the weather, a stock price, your calendar, or a live database on its own.
Can't take actionsThe model only outputs text (predicted tokens). That's its only superpower.It can describe how to send an email, but it can't actually send one. It can't book a flight, run code, or edit a file.
No memoryThe model is stateless β€” parameters are frozen and nothing carries between requests.It forgets everything the moment a request ends. It can't remember what you told it an hour ago unless the app re-sends it.
Quick refresher on "stateless"

From Session 1: an LLM doesn't truly remember your conversation. The app fakes memory by re-sending the whole history with every message. The model itself is a frozen, one-shot text-predictor. Hold onto this β€” it shapes how agents have to be built, because the agent's "memory" of what it has done so far must also be stuffed back into the prompt each step.

So what would fix this?

Notice that three of the four problems are really the same wish: "let the model reach outside its room." If we could let the LLM look things up, run a calculation, call an API, or write to a file β€” and then read the result and decide what to do next β€” almost all of those walls fall down. The model stays a text-predictor, but now its text can trigger real actions, and the actions' results flow back in as new text. That bridge is exactly what an agent is.

Concrete example of the gap

You ask a plain chatbot: "What's the current price of 3 units of product SKU-42 including today's sales tax?"

  • It doesn't know the current price (that lives in a live database β€” no real-time data).
  • It might get the multiplication slightly wrong (LLMs are shaky at exact arithmetic).
  • It can't look up today's tax rate if it changed after the cutoff.

An agent, by contrast, could call a get_price tool, call a get_tax_rate tool, use a calculator tool, and only then answer β€” with real numbers.

Recap A plain LLM is a brilliant but locked-in text-predictor: knowledge cutoff, no live data, can't act in the world, no memory. Agents exist to break those walls by letting the model's text trigger real actions and then read the results back in.

2 What is an AI agent?


Explain like I'm 5

A chatbot is like a friend on the phone who can only talk to you. An agent is like a friend who can talk to you and get up, walk to the kitchen, check the fridge, and come back to tell you what's there. Same friend, same brain β€” but now they can do things, look at what happened, and keep going until your question is actually answered.

Here's a clean definition we'll use all session:

The one big idea

An AI agent is an LLM "brain" + tools + a loop. The LLM decides what to do next, calls a tool to actually do it, reads the result, and repeats β€” looping until the task is finished. The LLM is the decision-maker; the tools are its hands; the loop is what lets it take more than one step.

The three ingredients

  • The brain (LLM) β€” the same next-token predictor from Session 1. Its job in an agent is to reason about the goal and choose actions. It never magically gains new powers; it just decides which tool to use and what to say.
  • The tools β€” functions the agent is allowed to call: search the web, run code, query a database, send an email, read a file. Each tool is a real piece of code you write or provide. (Full detail in Topic 3.)
  • The loop β€” the controller code that runs the brain, executes whichever tool the brain asked for, feeds the result back to the brain, and runs it again. Without the loop you just have a one-shot answer; with it, the agent can take many steps. (Full detail in Topic 4.)

Chatbot vs agent β€” the key contrast

AspectChatbot (just talks)Agent (talks and does)
What it producesText, and only text.Text and actions in the world (via tools).
StepsOne shot: prompt in, answer out.Many steps in a loop until the goal is met.
Access to fresh infoNone β€” limited to its training data + your prompt.Can fetch live data through tools.
Who decides the next moveYou (you ask the next question).The agent decides its own next action.
Example"Here's how you'd check the weather…"Actually calls a weather API and tells you it's 22Β°C.
A subtle but important point

The LLM does not run the tools itself. It can only output text. When it "uses a tool," it really just writes a request ("please call get_weather for Paris"), and your surrounding code actually runs the function and hands the result back. The agent is a partnership: the model thinks, your code acts. We'll see exactly how this handshake works in the next topic.

Concrete example

Goal: "Email me a summary of today's top AI news."

  • A chatbot replies with general AI facts from before its cutoff. It can't see "today," and it can't send email. Dead end.
  • An agent: (1) calls a web_search tool for today's AI news, (2) reads the results, (3) writes a summary, (4) calls a send_email tool. Done β€” a real action happened.
Recap An AI agent = LLM brain + tools + a loop. The brain decides, the tools act, the loop lets it take many steps. A chatbot only talks; an agent talks and does β€” but remember the model still only outputs text; your code is what actually runs the tools.

3 Tools & function calling β€” how an LLM "uses" a tool


Explain like I'm 5

Imagine the locked-in genius can't leave the room, but they can write notes and slip them under the door. On a note they write: "Please look up the weather in Paris." A helper outside reads the note, actually checks the weather, and slides back another note: "It's 18Β°C and raining." The genius reads that and continues. The genius never left the room β€” they just asked, and someone outside did the doing. That note-passing is function calling.

A tool is just a function the agent is allowed to call β€” for example get_weather(city) or calculator(expression). The mechanism by which the LLM requests one is called function calling (also known as tool use). Let's build it from scratch.

Step 1 β€” You describe the tools to the model

Before the agent runs, you give the model a list of available tools. Each tool has a name, a description (what it does and when to use it), and a schema of its inputs (which arguments it takes, and their types). The description is basically a tiny instruction manual β€” the model reads it to decide whether and how to use the tool.

A tool definition (illustrative)
{
  "name": "get_weather",
  "description": "Get the current weather for a given city.",
  "parameters": {
    "city":  { "type": "string", "description": "City name, e.g. 'Paris'" },
    "units": { "type": "string", "enum": ["celsius", "fahrenheit"] }
  }
}

You're not giving the model the code β€” only a description of the tool and what arguments it expects. The real code lives in your program.

Step 2 β€” The model outputs a structured tool request

Here's the crucial bit, and it ties straight back to Session 1: the model still does only one thing β€” it outputs text/tokens. When it "decides" to use a tool, it produces a structured request (usually JSON) that names the tool and fills in the arguments. It does not run anything. It's the note slipped under the door.

What the model emits
{
  "tool_call": {
    "name": "get_weather",
    "arguments": { "city": "Paris", "units": "celsius" }
  }
}

Step 3 β€” Your code runs the tool

Your surrounding program (the agent's loop) sees this request, recognises the tool name, and actually calls the real get_weather("Paris") function β€” which might hit a weather API over the internet. This is the step that breaks out of the locked room: real code, real network, real fresh data.

Step 4 β€” The result is fed back to the model

The tool returns a result (e.g. {"temp": 18, "condition": "rain"}). Your code appends that result to the conversation and sends the whole thing back to the model. Now the model can read the live answer and continue β€” maybe answering you, maybe calling another tool.

The full handshake as a flow

🧠
1. Model decides
Outputs a tool request (JSON)
β†’
πŸ”§
2. Code runs tool
Your program calls the real function
β†’
πŸ“¦
3. Tool returns
Result comes back (live data)
β†’
πŸ“¨
4. Feed back
Result added to the prompt
β†’
πŸ’¬
5. Model continues
Answers or calls another tool
Worked example: a calculator tool

You ask: "What is 4,817 Γ— 392?" LLMs are unreliable at exact arithmetic (remember from Session 1, they predict tokens, they don't truly "compute"). With a calculator tool:

  • Model emits: {"tool_call":{"name":"calculator","arguments":{"expression":"4817*392"}}}
  • Your code runs it β†’ 1888264
  • You feed 1888264 back to the model
  • Model replies: "4,817 Γ— 392 = 1,888,264."

The model offloaded the part it's bad at to a tool that's perfect at it. That's the whole spirit of tools: let the LLM reason, let reliable code do the exact work.

Watch out

The model can only request tools you actually gave it, and it can produce malformed requests (wrong arguments, a tool that doesn't exist, invalid JSON). Your code must validate every tool call before running it β€” never blindly execute what the model asks. More on this in Topic 7.

Recap A tool is a function the agent may call. Function calling is a four-beat handshake: you describe the tools β†’ the model outputs a structured request β†’ your code runs the real function β†’ the result is fed back so the model can continue. The model only ever writes the request; your code does the doing.

4 The reasoning loop β€” ReAct (Reason β†’ Act β†’ Observe)


Explain like I'm 5

Think about how you'd find a friend's house in a new town. You think ("I should check the map"), you do ("open the map app"), you look ("oh, it says turn left"), then you think again, do again, look again β€” until you arrive. You don't plan the entire trip perfectly in your head first; you take a step, see what happened, and adjust. An agent does exactly this little think–do–look cycle, over and over.

The most common pattern for an agent's loop is called ReAct, short for Reason + Act. Each turn of the loop has three beats:

BeatNameWhat the agent does
1Reason (Thought)The LLM thinks out loud: what's the goal, what do I know, what should I do next?
2Act (Action)It picks a tool and outputs a tool call (the function-calling request from Topic 3).
3Observe (Observation)Your code runs the tool and feeds the result back. The agent reads it.

Then it loops: reason again using the new observation, act again, observe again β€” until the agent decides it has enough to give a final answer (and stops calling tools).

Why the loop is the heart of an agent

A single tool call answers single-step questions. The loop is what lets an agent chain several steps together and handle questions where you don't know all the steps in advance β€” because each new observation can change what it does next. Remember the model is stateless (Session 1), so the loop must re-send the growing trail of thoughts, actions, and observations on every turn β€” that trail is the agent's working memory.

Worked example: a multi-step question

Question: "Who is the current CEO of the company that makes the iPhone, and how old are they?" This needs live lookups and chaining. Watch the loop:

  • Thought 1: "The iPhone is made by Apple. I need Apple's current CEO β€” that's live info, I should search."
  • Action 1: web_search("current CEO of Apple")
  • Observation 1: "Tim Cook is the CEO of Apple."
  • Thought 2: "Good. Now I need Tim Cook's age. I'll search his birth date."
  • Action 2: web_search("Tim Cook date of birth")
  • Observation 2: "Born November 1, 1960."
  • Thought 3: "Today is June 2026, so he is 65. I'll compute it to be safe."
  • Action 3: calculator("2026 - 1960") β†’ 66 (then adjust for birthday) β†’ 65.
  • Thought 4: "I now have both facts. I can answer."
  • Final answer: "Apple makes the iPhone. Its CEO is Tim Cook, who is 65."

Notice: the agent never planned all three searches up front. It discovered step 2 only after seeing the answer to step 1. That adaptiveness is the point of ReAct.

How does it know when to stop?

When the model decides no more tools are needed, it simply outputs a normal text answer instead of a tool call. The loop sees "no tool requested" and ends, returning that text to you. (We also add a hard safety limit on the number of loops β€” see Topic 7 β€” in case it never decides to stop.)

Recap ReAct = Reason β†’ Act β†’ Observe, repeated. The agent thinks, calls a tool, reads the result, and loops, adapting each step to what it just learned, until it's ready to answer. The growing thought/action/observation trail is the agent's working memory, re-sent each turn because the model is stateless.

5 Planning agents vs reactive agents


Explain like I'm 5

Two ways to cook dinner. One cook reads the whole recipe first and writes out every step before touching a pan β€” that's planning. Another cook just starts: tastes, sees what's in the fridge, and figures out the next step as they go β€” that's reactive. Both can make dinner. The planner is great when the recipe is clear; the improviser is great when things keep changing.

The ReAct loop in Topic 4 is the reactive style: decide one step at a time. But there's another flavour where the agent makes a plan first. Let's compare.

Reactive agents (decide step-by-step)

A reactive agent chooses its next action based only on the current situation, one step at a time β€” exactly the ReAct loop. It has no long-term plan; it just keeps asking "given what I know right now, what's the best next move?"

Planning agents (plan, then execute)

A planning agent first asks the LLM to break the goal into an ordered list of sub-steps β€” a plan β€” and then executes that plan step by step. This is often called plan-and-execute. Some planning agents also re-plan: if a step fails or surprises them, they go back and revise the remaining plan.

Same goal, two styles

Goal: "Plan a weekend trip to a nearby city under $300."

  • Reactive: searches a city β†’ looks at it β†’ maybe searches hotels β†’ looks β†’ maybe searches trains… deciding each move as results come in.
  • Planning: first writes a plan β€” (1) pick a city, (2) find transport cost, (3) find a hotel, (4) sum costs, (5) check under $300 β€” then executes each step in order.

Pros and cons

Reactive (step-by-step)Planning (plan-then-execute)
Best forOpen-ended tasks where you can't know the steps up front; quick, exploratory work.Complex, multi-part tasks with a clear structure; tasks where order matters.
AdaptabilityHigh β€” adjusts instantly to each new observation.Lower unless it re-plans; a rigid plan can go stale.
Big-picture coherenceCan "lose the thread" or wander on long tasks.Strong β€” the plan keeps it organised and on-goal.
Cost / stepsCan waste steps backtracking.Planning up front can reduce wasted steps β€” but a bad plan wastes them all.
RiskMay get stuck in short-sighted loops.If the initial plan is wrong, it may stubbornly follow a bad path.
In practice: a blend

Real agents often mix both: make a rough plan, then execute each step reactively, and re-plan when reality doesn't match expectations. You don't have to pick one religiously β€” pick what fits the task, and lean on planning as tasks get longer and more structured.

Recap Reactive agents decide one step at a time (the ReAct loop) β€” flexible but can wander. Planning agents write a plan first, then execute it β€” organised for complex tasks but brittle if the plan is wrong. Many real agents blend the two and re-plan when surprised.

6 Deterministic vs non-deterministic behavior


Explain like I'm 5

A vending machine is deterministic: press B4 and you always get the same chocolate bar. A box of assorted chocolates is non-deterministic: reach in and you might get a different one each time. Agents are more like the box of chocolates β€” ask the same thing twice and they might take slightly different paths to the answer. Sometimes that's fun; sometimes you really want the vending machine.

Something is deterministic if the same input always produces the same output. It's non-deterministic if the same input can produce different outputs on different runs. Agents are often non-deterministic, and it's important to know why.

Why agents wander

Recall temperature from Session 1: it controls how randomly the model samples its next token. At higher temperature the model sometimes picks a less-likely token, so it can word things differently β€” or, in an agent, decide differently. Because an agent's whole path is a chain of these decisions, a small difference early on can snowball into a completely different route: a different tool chosen, a different search query, a different number of steps.

Same question, two different paths

Ask an agent twice: "Find me a good pizza place nearby and its rating."

  • Run 1: searches "best pizza near me" β†’ picks the top result β†’ looks up its rating.
  • Run 2: searches "top rated pizza restaurants" β†’ compares three β†’ returns a different one.

Both are reasonable; neither is "wrong." But they're different β€” that's non-determinism in action.

When you want determinism

  • Testing & debugging β€” if every run differs, you can't tell whether your change helped or you just got a different roll of the dice (this echoes the prompt-testing advice from Session 1).
  • Critical, repeatable tasks β€” financial calculations, compliance steps, anything where "the same input must give the same output" is a requirement.
  • Reproducibility β€” when a user reports a bug, you want to reproduce the exact run.

How to push an agent toward determinism

LeverEffect
Set temperature low (β‰ˆ0)The model almost always picks its most-likely token, so decisions become far more repeatable.
Set a fixed seed (if supported)Pins the random number generator so sampling repeats identically.
Constrain the tools & choicesFewer valid moves = fewer ways to diverge.
Use rigid plans / hard-coded steps for critical partsMove the must-be-exact logic out of the LLM and into plain code.
Watch out

Even at temperature 0, agents are not guaranteed perfectly deterministic. Tools that hit the live world (a web search, a database) return different data over time, and some model infrastructure has tiny unavoidable variations. Low temperature reduces randomness a lot β€” it doesn't make the outside world freeze.

Key takeaway

Non-determinism is a feature for creative, exploratory tasks and a bug for critical, repeatable ones. The main dial is temperature (from Session 1): turn it down when you need the vending machine, leave it up when you want the box of chocolates.

Recap Deterministic = same input β†’ same output; non-deterministic = it can vary. Agents wander because temperature makes token (and thus decision) choices random, and small differences snowball. Lower temperature, fixed seeds, fewer choices, and hard-coded steps push toward determinism β€” but live tools and infrastructure mean it's never 100% guaranteed.

7 Failure modes & guardrails


Explain like I'm 5

Giving the AI hands is powerful β€” but a toddler with scissors is also powerful. Agents can mess up: ask for a tool that doesn't exist, get stuck doing the same thing forever, grab the wrong tool, or run up a giant bill. So we put up little fences β€” like a "you've tried 10 times, stop now" rule, or "ask a grown-up before doing the risky thing." Those fences are called guardrails.

Because an agent makes its own decisions and takes real actions, it has more ways to go wrong than a plain chatbot. Knowing the common failure modes β€” and the guardrails that contain them β€” is essential before you let one loose.

Common failure modes

Failure modeWhat it looks like
Hallucinated / invalid tool callThe model invents a tool that doesn't exist, or fills in arguments that are malformed or wrong (recall hallucination from Session 1 β€” it's predicting, not checking).
Infinite loopThe agent keeps reasoning and acting but never decides it's done β€” looping forever (and burning money each turn).
Wrong tool choiceIt uses the search tool when it should have used the calculator, or calls a destructive tool when a read-only one would do.
Getting stuckIt repeats the same failed action over and over, or thrashes between two steps without making progress.
Runaway costLong loops, large tool outputs, and re-sending the whole growing history every turn (remember: stateless model, Session 1) can quietly rack up huge token bills.

Guardrails β€” how we contain the damage

GuardrailWhat it does
Max steps (loop limit)Cap the number of loop iterations (e.g. "stop after 10 steps"). Kills infinite loops dead.
ValidationBefore running any tool call, check it: does this tool exist? Are the arguments the right type and within allowed ranges? Reject bad calls instead of executing them.
Human-in-the-loopFor risky or irreversible actions (sending money, deleting files, emailing customers), pause and ask a human to approve before acting.
Budget / cost limitsCap total tokens or dollars per run; stop when the budget is hit.
Tool permissions & sandboxingOnly expose tools the task actually needs; run risky tools (like code execution) in an isolated sandbox so mistakes can't harm the real system.
Loop / repetition detectionNotice when the agent repeats the same action and break out or change strategy.
Worked example: guardrails saving the day

An agent is asked to "clean up old files." Without guardrails it might call delete_file on the wrong folder. With guardrails:

  • Validation rejects a delete call whose path is outside the allowed directory.
  • Human-in-the-loop shows you the list of files and waits for your "yes" before deleting.
  • Max steps ensures that even if it gets confused, it can't loop forever trying.

The agent still does the useful work β€” but the fences keep a mistake from becoming a disaster.

Golden rule

Never let an agent take an irreversible or expensive action without a guardrail in front of it. The more powerful the tools you hand an agent, the more important the fences become.

Looking ahead: Assignment 02

This session's hands-on project is Assignment 02: build a website-cloning agent β€” an agent that's given tools (fetch a page, read its HTML/CSS, write files) and loops until it has reproduced a target website. As you build it, you'll feel every idea from today: choosing tools, the ReAct loop, non-determinism between runs, and why a max-steps guardrail keeps it from spinning forever. Keep this checklist of failure modes nearby while you build.

Recap Agents fail in characteristic ways: hallucinated/invalid tool calls, infinite loops, wrong tool choice, getting stuck, and runaway cost. Guardrails β€” max steps, validation, human-in-the-loop, budget limits, sandboxing, and loop detection β€” keep those failures contained. Always fence off irreversible or costly actions.

β˜… Putting it all together


You just turned a locked-in text-predictor into something that can act in the world. Here's the one-paragraph story that connects all 7 topics:

A plain LLM is brilliant but trapped β€” knowledge cutoff, no live data, can't act, no memory (all from Session 1). An AI agent frees it by adding tools and a loop: the LLM brain reasons and emits a structured function call, your code actually runs the tool and feeds the result back, and the ReAct loop (Reason β†’ Act β†’ Observe) repeats until the job is done. Agents can work reactively (step-by-step) or by planning first, and because of temperature they're often non-deterministic β€” taking different paths on the same question, which you tame with low temperature when you need repeatability. Finally, because agents take real actions, you must respect their failure modes and wrap them in guardrails (max steps, validation, human-in-the-loop) β€” which is exactly what you'll practise in Assignment 02's website-cloning agent.

Quick self-check

Why can't a plain LLM tell you the current weather, and what fixes it?

It has no live/real-time data and can't take actions β€” it only predicts text from its frozen training data (knowledge cutoff). An agent fixes this by giving it a weather tool it can call to fetch live data.

When an agent "uses a tool," what does the LLM actually do?

It only outputs text β€” a structured request (usually JSON) naming the tool and its arguments. It does not run anything. Your surrounding code reads that request, runs the real function, and feeds the result back.

What are the three beats of the ReAct loop?

Reason (think about what to do) β†’ Act (call a tool) β†’ Observe (read the result) β€” then repeat until the agent is ready to give a final answer.

Why might an agent give different answers to the exact same question twice?

Non-determinism: temperature (from Session 1) makes token β€” and therefore decision β€” choices partly random, and small early differences snowball into different tool calls and paths. Lower the temperature for more repeatable runs.

Name two guardrails that prevent an agent from causing damage, and what each stops.

Max steps (a loop limit) stops infinite loops and runaway cost; human-in-the-loop pauses for approval before risky/irreversible actions; validation rejects malformed or invalid tool calls before they run. (Any two.)

πŸ“š References & Further Reading


Class material

Papers, docs & deep dives