TwinEdgeAI

↑ Course home

Engineering AI Agents · Week 1

What Are Agentic Systems?

Foundations and landscape: a short history, the anatomy of an agent, compound AI systems, workflows versus agents, and the hard parts.

Author: Grok Bot Version: 1.0, October 28, 2026 Study time: about 8 hours

CreditThis coursework is adapted from, and inspired by, Stanford CS329Z: Engineering AI Agents (Diyi Yang, Michael Ryan, John Yang), Week 1, "Foundations & Landscape Introduction: What Are Agentic Systems?" The topic list and the three required readings come from that course's public schedule [8]. The notes, lab, quiz and assignment are original writing. This is not an official Stanford document. I did not copy the lecture slides.

1. Week overview and learning objectives

Most people first meet a language model as a chat box. You type. It answers. That is one model call.

Real products rarely stop there. They add search, code runners, databases, checks and retries. Some let the model choose its own next step. This course calls all of these agentic systems. They sit on a range. At one end is a plain LLM pipeline. At the other end is a model that runs on its own for many steps.

Week 1 gives you the map. You learn the vocabulary, the parts, and the main trade-offs. Later weeks go deep on each part: retrieval, tools, memory, evaluation, safety and more [8].

Learning objectives

By the end of this week you should be able to:

  1. Define "agent", "agentic system", "workflow" and "compound AI system" in your own words, and say how they differ.
  2. Name the parts of an LLM agent (LLM core, reasoning, memory, tools, environment) and say what each one does.
  3. Explain why many top results now come from systems with several parts, not from one bigger model [1].
  4. Place a given application on the workflow-to-agent range and defend your choice [4].
  5. List the four big challenges (reliability, training, safety, evaluation) and give one concrete example of each.
  6. Build a small agent loop in Python with one tool call, and test it without an API key.
  7. Read an agent paper critically. Ask what it costs, what it was tested on, and whether the result would repeat [3].

Plan for the week

PartWhat you doTime
ReadingThree required readings, plus optional ones (reading guide)3 h
Lecture notesWork through section 2. Redraw the diagrams from memory.1.5 h
LabRun, read and extend the agent loop1.5 h
Discussion and quizTalk it through with a partner, then take the quiz1 h
AssignmentSmall graded project (section 7)1 h to 2 h

PrerequisitesYou can read basic Python. You have used a chat model. You do not need machine learning math. You do not need an API key. The lab runs offline with a mock model.

2. Lecture notes

2.1 A short history of agents

The word "agent" is old. It did not start with chatbots.

The classic definition

In the standard AI textbook, an agent is something that perceives its environment and acts on it [7]. Kapoor et al. point out one funny result of this: a thermostat counts [3]. It senses the temperature. It turns the furnace on or off.

That is a useful baseline. It shows that "agent" is a weak word on its own. What matters is how much it can sense, decide and do.

Rules and cognitive architectures

Early AI agents ran on hand-written rules. A rule has a condition and an action. "If the temperature is below 70 and the furnace is off, turn the furnace on." Newell and Simon used exactly this thermostat example in their 1972 book on human problem solving [6].

Researchers then built larger designs, called cognitive architectures. Soar is a well-known one. They had working memory, long-term memory and a decision loop [6]. They worked, but they were limited to problems you could write down as logic. They also needed many pre-written rules [6].

The LLM era

Large language models changed the picture. A model trained on huge amounts of text can read any text input and write any text output. It does not need hand-written rules for each task. Around 2022 researchers began to put such a model in a loop with an environment.

Timeline of agent ideas A line from 1972 to 2025 with milestones: production systems, textbook definition, chain of thought and ReAct, LLM agent demos, compound AI systems, Building Effective Agents, AI Agents That Matter. 1972Rules andproduction systemsThermostatas an agent 1995Textbook: agent =perceive + act 2022Chain of thoughtand ReAct 2023AutoGPT-style demosLLM agent survey post Feb 2024Compound AIsystems post Dec 2024BuildingEffective Agents 2024–25AI AgentsThat Matter
Figure 1. Milestones named in this week's sources [2] [3] [4] [5] [6] [7]. Spacing is not to scale. Blue marks the rules era. Green marks the LLM era. The 1995 point is the first edition of the textbook, as cited in [3].

Key idea"Agent" is a spectrum, not a yes-or-no label. Kapoor et al. say it is better to ask how agentic a system is than to ask whether it is an agent [3].

2.2 Anatomy of an agent

Most LLM agents have the same five parts. Figure 2 shows how they connect.

Anatomy of an LLM agent An environment box contains the agent and a tools box. Inside the agent, the LLM core sits in the centre, with reasoning and planning above it and memory below it. The LLM sends actions to tools. Tools send observations back. ENVIRONMENT web pages · files · databases · APIs · a code runner · people AGENT 2. Reasoning and planning split the goal, pick a step, check results 1. LLM core reads text, writes text 3a. Working memory the context window: goal, steps so far, results 3b. Long-term memory outside store the agent reads and writes (files, DB) 4. Tools search, calculator, code, APIs, files action observation 5. Environment tools change it. It sends back results.
Figure 2. The five parts of an LLM agent. The loop is: read the context, think, act with a tool, read what came back, repeat. Based on the component lists in Weng [2] and the memory and action split in CoALA [6].

1. The LLM core

The model is the part that reads text and writes text. Weng calls it the agent's "brain" [2]. CoALA puts it as the core of a bigger design [6].

Two facts matter for builders.

2. Reasoning and planning

Hard tasks need several steps. Weng splits planning into two jobs [2]:

ReAct is the simplest way to join thinking and acting. The model writes a short Thought, then an Action, and then it sees an Observation. This repeats [5]. ReAct treats a thought as a kind of action that only changes the agent's own context. It does not touch the outside world [5].

The ReAct paper has a clear finding. Reasoning alone (chain of thought) can invent facts, because it is not grounded in anything outside the model. On HotpotQA, hallucination caused 56% of the chain-of-thought failures the authors checked, against 0% for ReAct. But ReAct had its own problem: it could repeat the same thought and action in a loop [5]. Keep this in mind. We will meet loops again in the lab.

3. Memory

Weng borrows from human memory. She maps it to agents like this [2]:

Human ideaAgent version
Short-term (working) memoryWhat is in the context window right now
Long-term memoryAn outside store, often a vector database, searched when needed

CoALA is more detailed. It names four kinds of memory [6]:

KindWhat it holdsExample
WorkingThe current goal, recent inputs, results of thinkingThe prompt for this step
EpisodicWhat happened in past runsA log of earlier tasks and their results
SemanticFacts about the worldA product catalog, a wiki
ProceduralHow to act: the model weights and the agent's codeYour Python loop and prompt templates

CoALA adds a warning. Letting an agent write to its own procedural memory (its own code) is riskier than letting it write notes. A bug there can change how the whole agent behaves [6].

4. Tools

A tool is a function the model can ask the program to run. Examples: web search, a calculator, a database query, a code runner, or an API call. Tools give the model things its weights lack: fresh facts, exact math, and the power to change something [2].

The model does not run the tool itself. It writes a request, such as a function name and arguments. Your program runs it and passes the result back as text. You will build exactly this in the lab.

Anthropic gives a practical rule. Spend as much effort on the tool interface as you would on a human interface. They call it the agent-computer interface. In their coding agent, they spent more time improving tools than improving the main prompt [4].

5. The environment

The environment is everything outside the agent that the agent can sense or change. It might be a web site, a folder of files, a user, or a test suite. Kapoor et al. say the more complex the environment, and the more open the goal, the more "agentic" the system is [3].

CoALA groups environments into three types: physical (robots), dialogue (people or other agents), and digital (APIs, web sites, code). Digital ones are cheaper and faster to work in, which is why most LLM agents live there [6].

One idea from Anthropic is worth remembering. At each step the agent should get "ground truth" from the environment, such as a tool result or a test run. That is how it can tell whether it is making progress [4].

The same parts, three vocabularies

This course (Week 1)Weng [2]CoALA [6]
LLM coreThe "brain"Core of the architecture
ReasoningPlanning (subgoals, reflection)Reasoning actions and the decision cycle
MemoryShort-term and long-termWorking, episodic, semantic, procedural
ToolsTool useExternal actions (grounding)
EnvironmentNot a separate partPhysical, dialogue, digital

2.3 Compound AI systems

Zaharia et al. define a compound AI system as a system that solves AI tasks using several interacting parts. These include multiple calls to models, retrievers, and external tools. An AI model, in contrast, is just a statistical model, such as a Transformer that predicts the next token [1].

Why this mattersQuality is not only a model question. It is also a design question. You can often improve a product faster by changing the system around the model than by waiting for a better model [1].

Why people build them

The BAIR post gives four reasons [1]:

  1. Some tasks improve more from system design than from scale. The authors give a made-up example. Say the best model solves a contest problem 30% of the time. Tripling its training budget lifts that to 35%. A system that samples many answers and tests each one could do much better. They point to AlphaCode as the real-life case.
  2. Systems can be dynamic. A model's knowledge is frozen at training time. Search and retrieval add current data. They also let you enforce access rules, such as "answer only from files this user may see".
  3. Control and trust are easier. You cannot guarantee that a model never does something. You can filter its output. You can add citations and fact checks through retrieval.
  4. Performance goals differ. Some uses cannot afford the largest model. Others would gladly pay more for a better answer. A system lets you choose the cost and quality point.

Real examples

SystemPartsHow it works
AlphaCode 2Fine-tuned LLMs, code execution, clustering modelGenerates up to 1 million solutions, then filters and scores them
AlphaGeometryLLM and a symbolic math engineThe LLM suggests constructions. The engine checks what follows from them
MedpromptGPT-4, nearest-neighbor search, chain-of-thought examples, ensemblingFinds similar solved questions to build a prompt, then votes over several answers
RAG systemsLLM and a retrieverSearch first, then answer using the results

Source for all rows: Zaharia et al. [1]. The same post reports that Databricks saw 60% of LLM applications using some form of retrieval-augmented generation (RAG) and 30% using multi-step chains.

A simple retrieval-augmented system Userquestion LLM call 1write a search query Retrieverfind passages LLM call 2answer from passages Checkcites sources? Four parts, a fixed path, no tool-choosing by the model. A compound system, but not an agent.
Figure 3. A compound AI system that is not an agent. The developer wrote the path. It follows the "LLM writes a search query, then retrieval" idea described in [1].

The three hard problems of building them

ProblemPlain meaning
Design spaceMany choices: which models, which retriever, how many calls, how to split a fixed time or cost budget between parts.
OptimizationYou cannot train the whole thing end to end. Search engines and code runners are not differentiable. Tools such as DSPy tune prompts and examples for the whole pipeline instead.
OperationYou must log and debug traces, manage data pipelines, and handle new security risks that single models do not have.

Summary of [1].

The post also asks a design question that leads straight into the next section: should the control logic live in ordinary code, or should an LLM drive it [1]?

2.4 Workflows versus agents

Anthropic draws one clear line. Both kinds are "agentic systems", but they differ in who controls the path [4].

WorkflowAgent
LLMs and tools are orchestrated through predefined code paths.LLMs dynamically direct their own processes and tool use, and keep control over how they do the task.
The developer decides the steps.The model decides the steps.
Predictable. Easy to test.Flexible. Harder to predict.
The workflow-to-agent spectrum A left-to-right scale. On the left the developer controls the path. On the right the model controls the path. Marked points: single LLM call, prompt chain, routing and parallel, orchestrator and workers, evaluator and optimizer, autonomous agent. Developer controls the path Model controls the path SingleLLM callone prompt,one answer Promptchainingfixed steps,output feeds next Routing andparallelizationclassify, then branch;or run parts at once Orchestrator-workersan LLM splits the taskat run time Evaluator-optimizerwrite, critique,repeat AutonomousagentLLM in a loopwith tools Workflows: predefined code paths (the five patterns, plus the single call as a baseline) Agent ← More predictable, cheaper, easier to test More flexible, with more cost and risk →
Figure 4. The workflow-to-agent range. The workflow patterns are the five named by Anthropic [4]. The single call is the left edge, added here for comparison. Kapoor et al. also treat "agentic" as a range [3].

Five workflow patterns (Anthropic)

PatternWhat it doesUse it when
Prompt chainingSplits a task into fixed steps. Each call uses the last output. You can add checks between steps.The task splits cleanly into subtasks. You trade speed for accuracy.
RoutingClassifies the input and sends it to a specialist prompt or tool.There are distinct categories and the classification is reliable.
ParallelizationRuns subtasks at once ("sectioning") or runs the same task several times ("voting").You want speed, or several attempts for higher confidence.
Orchestrator-workersA central LLM breaks the task down, hands parts to workers, and combines results.You cannot predict the subtasks in advance, such as multi-file code changes.
Evaluator-optimizerOne call writes. Another critiques. They loop.You have clear criteria and feedback improves the result.

Source: [4].

What makes something an agent

Anthropic describes agents as "typically just LLMs using tools based on environmental feedback in a loop" [4]. The agent starts from a command or a chat with a person. Once the task is clear, it plans and acts on its own. It may stop to ask a person. It should have stop rules, such as a maximum number of steps [4].

Kapoor et al. list three groups of factors that make a system more agentic [3]:

Which one should you build?

Anthropic's advice is blunt. Find the simplest solution that works. Add complexity only when it clearly helps. This may mean no agent at all. Often one well-prompted call with retrieval and examples is enough [4].

Choose a workflow when…Choose an agent when…
The steps are known ahead of timeYou cannot predict how many steps are needed
You need steady, repeatable resultsYou need the model to choose its path
Cost and speed limits are tightYou can pay more for flexibility
Mistakes are costlyYou can run in a sandbox, with checks, in a setting you trust

Based on [4]. Anthropic adds that agents mean higher cost and a chance of errors that pile up, so they suggest tests in sandboxes and guardrails.

A note on datesThe Anthropic post now carries a banner saying that much of the tooling it describes has changed since December 2024 [4]. The definitions and the pattern list are still a good foundation. Check current docs before you pick a framework.

2.5 Key challenges

The lecture names four: reliability, training, safety and evaluation [8]. Here is what each means, with evidence from the readings.

Reliability

Training

Safety

Evaluation

ChallengeOne-line exampleMain sources
ReliabilityTen steps at 95% each is about 60% overall[2] [4] [5]
TrainingTuning a pipeline that has a search engine in it[1] [3]
SafetyAn action like "delete" or "send" needs a human check[3] [4] [6]
EvaluationA cheap retry loop beats a fancy agent on cost and accuracy[3]

2.6 Week 1 in one page

  1. "Agent" means a thing that senses and acts. LLM agents are a new, flexible case of an old idea [7] [6].
  2. An LLM agent has five parts: LLM core, reasoning, memory, tools, environment [2] [6].
  3. Top results often come from compound systems with several parts, not from one model [1].
  4. A workflow has a path written by a developer. An agent chooses its own path. Most real systems sit in between [4].
  5. Start simple. Add agency only when it clearly pays for its cost and risk [4].
  6. Measure cost as well as accuracy. Use holdouts. Make runs repeatable [3].
  7. Reliability, training, safety and evaluation are the open problems. The rest of the course works on them [8].

3. Reading guide

Three readings are required. Four more are optional. For each one you get: why it matters, the key ideas, and questions to think about as you read. Read the questions first. Take short notes as you go.

How to read a paper or a long postPass 1: read the title, the intro and the conclusion (10 minutes). Pass 2: read the figures and tables. Pass 3: read the parts that matter for your questions. You do not need to read every appendix.

Required 1 The Shift from Models to Compound AI Systems

Zaharia, Khattab, Chen, Davis, Miller, Potts, Zou, Carbin, Frankle, Rao, Ghodsi. BAIR Blog, February 18, 2024. Read online · reference [1]

Why read it

It gives you the key phrase for the whole course: compound AI system. It argues that building around a model matters as much as the model itself. The course site uses the same framing in its welcome text [8].

Key ideas

Questions to think about

  1. Pick one product you use. List its parts. Which ones are models, and which are ordinary software?
  2. The post says control logic could be code or an LLM. What would push you toward each choice?
  3. The post was written in early 2024. Which of its claims have aged well? Which tools it names would you check again today?
  4. Why can't you train a pipeline with a search engine in it using normal backpropagation?

Required 2 LLM Powered Autonomous Agents

Lilian Weng. Lil'Log, June 23, 2023. Read online · reference [2]. The page lists a reading time of about 31 minutes.

Why read it

It is the clearest early tour of how LLM agents are put together. Many later papers and posts use its three-part view: planning, memory, tool use.

Key ideas

Questions to think about

  1. Match each of Weng's three components to a box in Figure 2.
  2. Weng says short-term memory is "in-context learning". What goes wrong when the context fills up?
  3. In the ChemCrow case, LLM-based and expert evaluation disagreed. What does that say about using one model to grade another?
  4. Of the three challenges at the end, which do you think is easiest to fix with better engineering? Which needs a better model?
  5. You can skim the long maximum-inner-product-search section. Why does an agent need fast search at all?

Required 3 AI Agents That Matter

Kapoor, Stroebl, Siegel, Nadgir, Narayanan. Transactions on Machine Learning Research (TMLR), May 2025. arXiv 2407.01502 (first posted July 1, 2024). arXiv · OpenReview (TMLR) · reference [3]

Why read it

It is a reality check. It asks if the agent results you read about are real, useful and repeatable. It will make you a better reader of every other agent paper in this course.

Key ideas

Questions to think about

  1. Why does retrying a model several times "improve accuracy" without being a real advance in agent design?
  2. The paper says a thermostat is an agent in the classic sense. Does that change how you use the word?
  3. The WebArena case study found an agent that hard-coded fixes for the benchmark's own tasks. How would you spot this in a paper you were reviewing?
  4. If you were buying an agent for your company, which of the paper's recommendations would you ask the vendor about first?
  5. Why do the authors want token counts reported alongside dollar costs?

Reading tip: you can skip most of the appendices. The tables and figures in the main text are the key evidence.

Optional 1 Building Effective AI Agents

Schluntz and Zhang (Anthropic Engineering), December 19, 2024. Read online · reference [4]. The course also assigns it in Week 4 [8].

Why: It is the source for the workflow-versus-agent line and the five workflow patterns used in these notes.

Think about: Pick one pattern. Describe a task from your own work that fits it. Then say what would have to be true for you to upgrade it to an agent.

Optional 2 ReAct: Synergizing Reasoning and Acting in Language Models

Yao, Zhao, Yu, Du, Shafran, Narasimhan, Cao. ICLR 2023. arXiv 2210.03629 · reference [5]. The course also assigns it in Week 4 [8].

Why: The Thought, Action, Observation pattern is the root of the loop you build in the lab. Read the introduction, section 2 and the failure analysis in section 3.

Think about: In the paper's tests, ReAct beat chain of thought on fact checking (FEVER) but slightly trailed it on HotpotQA. Why might grounding help one task and hurt the other?

Optional 3 Cognitive Architectures for Language Agents (CoALA)

Sumers, Yao, Narasimhan, Griffiths. TMLR 2024. arXiv 2309.02427 · reference [6]. The course assigns it in Week 4 [8].

Why: It gives a precise vocabulary for memory, actions and decision-making, and connects LLM agents to older AI work. The authors say readers who care about practical design can focus on sections 4 to 6.

Think about: Describe the lab agent in CoALA terms. What is its working memory? Does it have any long-term memory? What are its internal and external actions?

Optional 4 Artificial Intelligence: A Modern Approach, Chapter 2 "Intelligent Agents"

Russell and Norvig. Book website · reference [7]. The site lists the 4th US edition, with Chapter 2 starting on page 36.

Why: It is the source of the textbook meaning of "agent" and a good base for thinking about environments and rational behavior.

Think about: Under this definition, is a spam filter an agent? Is a recommender system? What extra properties would you need before calling a system "agentic"?

4. Hands-on lab: a minimal agent loop

Time: about 90 minutes. Goal: build the smallest real agent. It reads a question, picks a tool, runs it, reads the result, and answers. You do not need an API key. A mock model stands in for the LLM.

What you will learn

The agent loop Messagesquestion + history llm.complete()JSON reply Has "final"?yes: return answer Run the toolcatch any error add the result to the messages, then repeat (up to max_steps)
Figure 5. The lab loop. It is the pattern Anthropic describes: an LLM using tools based on feedback in a loop, with a stop rule [4].

Setup

  1. You need Python 3.9 or newer. There is nothing to install. The code uses only the standard library.
  2. Save the code below as agent.py. Or download it: agent.py.
  3. Save the tests as test_agent.py in the same folder. Or download: test_agent.py. The test code is listed after the lab exercises.

The code: agent.py

"""A minimal agent loop. Standard library only. Python 3.9+.

Run with the mock model (no API key needed):
    python agent.py "What is (12 + 8) * 3?"
Run with a real model (any OpenAI-compatible chat API):
    export OPENAI_API_KEY=...        # your key
    export LLM_MODEL=...             # a model name your provider offers
    export LLM_BASE_URL=https://api.openai.com/v1   # optional
    python agent.py --real "What is (12 + 8) * 3?"
"""
import ast
import json
import operator
import os
import re
import sys
import urllib.request

# ---------- 1. Tools: plain Python functions plus a short description ----------

_OPS = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul,
        ast.Div: operator.truediv, ast.Pow: operator.pow, ast.USub: operator.neg}

def _eval(node):
    if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
        return node.value
    if isinstance(node, ast.BinOp) and type(node.op) in _OPS:
        return _OPS[type(node.op)](_eval(node.left), _eval(node.right))
    if isinstance(node, ast.UnaryOp) and type(node.op) in _OPS:
        return _OPS[type(node.op)](_eval(node.operand))
    raise ValueError("unsupported expression")

def calculator(expression: str) -> str:
    """Safely evaluate basic arithmetic such as '(12 + 8) * 3'."""
    tree = ast.parse(expression, mode="eval")
    return str(_eval(tree.body))

FACTS = {
    "react": "ReAct (2022) mixes reasoning steps and tool actions in one loop.",
    "compound ai system": "A system that uses several parts: model calls, retrievers, tools.",
    "workflow": "LLMs and tools are run along a path the developer wrote in code.",
    "agent": "The LLM decides its own next step and which tool to use.",
}

def lookup(term: str) -> str:
    """Look up a short definition in a tiny local knowledge base."""
    key = term.strip().lower()
    if key in FACTS:
        return FACTS[key]
    raise KeyError(f"no entry for '{term}'. Known terms: {', '.join(FACTS)}")

TOOLS = {
    "calculator": {"fn": calculator, "args": ["expression"],
                   "doc": "Evaluate basic arithmetic."},
    "lookup": {"fn": lookup, "args": ["term"],
               "doc": "Get a short definition of a term."},
}

# ---------- 2. The model: any object with .complete(messages) -> str ----------
# The model must answer with JSON, in one of two shapes:
#   {"thought": "...", "action": "calculator", "input": {"expression": "2+2"}}
#   {"thought": "...", "final": "The answer is 4"}

def system_prompt() -> str:
    lines = ["You are an agent. Think, then act. Reply with ONE JSON object only.",
             'To use a tool: {"thought": "...", "action": "<tool>", "input": {...}}',
             'To finish:     {"thought": "...", "final": "<answer>"}',
             "Tools:"]
    for name, t in TOOLS.items():
        lines.append(f"- {name}({', '.join(t['args'])}): {t['doc']}")
    return "\n".join(lines)

class MockLLM:
    """A rule-based stand-in for a real model. It lets the loop run offline.
    It is NOT smart. It only shows the shape of the conversation."""

    def complete(self, messages):
        last = messages[-1]
        if last["role"] == "user":
            question = last["content"]
            expr = re.search(r"[\d(][\d\s+\-*/().^]*[\d)]", question)
            if expr and any(c in expr.group(0) for c in "+-*/^"):
                return json.dumps({"thought": "This is arithmetic. I will use the calculator.",
                                   "action": "calculator",
                                   "input": {"expression": expr.group(0).replace("^", "**")}})
            m = re.search(r"(?:what is|define|explain)\s+(?:a |an |the )?([a-z\- ]+?)\??$",
                          question.strip().lower())
            if m:
                return json.dumps({"thought": "I need a definition. I will look it up.",
                                   "action": "lookup", "input": {"term": m.group(1)}})
            return json.dumps({"thought": "No tool fits.", "final": "I cannot help with that."})
        # last message is a tool observation
        obs = last["content"]
        if obs.startswith("ERROR"):
            return json.dumps({"thought": "The tool failed. I will report it.",
                               "final": f"Sorry, the tool failed. {obs}"})
        return json.dumps({"thought": "I have what I need.", "final": obs})

class OpenAICompatibleLLM:
    """Calls any chat-completions API that follows the OpenAI format."""

    def __init__(self):
        self.key = os.environ["OPENAI_API_KEY"]
        self.model = os.environ["LLM_MODEL"]
        self.base = os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1")

    def complete(self, messages):
        body = json.dumps({"model": self.model, "messages": messages,
                           "temperature": 0}).encode()
        req = urllib.request.Request(
            self.base + "/chat/completions", data=body,
            headers={"Content-Type": "application/json",
                     "Authorization": "Bearer " + self.key})
        with urllib.request.urlopen(req, timeout=60) as r:
            return json.load(r)["choices"][0]["message"]["content"]

# ---------- 3. The loop ----------

def run_agent(question, llm, max_steps=5, verbose=True):
    messages = [{"role": "system", "content": system_prompt()},
                {"role": "user", "content": question}]
    for step in range(1, max_steps + 1):
        raw = llm.complete(messages)
        messages.append({"role": "assistant", "content": raw})
        try:
            msg = json.loads(raw)
        except json.JSONDecodeError:
            obs = "ERROR: reply was not valid JSON. Reply with one JSON object."
            messages.append({"role": "tool", "content": obs})
            if verbose: print(f"[{step}] bad JSON -> asking again")
            continue
        if verbose: print(f"[{step}] thought: {msg.get('thought', '')}")
        if "final" in msg:
            if verbose: print(f"[{step}] final:   {msg['final']}")
            return msg["final"]
        name, args = msg.get("action"), msg.get("input", {})
        if name not in TOOLS:
            obs = f"ERROR: unknown tool '{name}'. Tools: {', '.join(TOOLS)}"
        else:
            try:
                obs = TOOLS[name]["fn"](**args)
            except Exception as e:           # tool errors go back to the model
                obs = f"ERROR: {type(e).__name__}: {e}"
        if verbose: print(f"[{step}] action:  {name}({args}) -> {obs}")
        messages.append({"role": "tool", "content": obs})
    return "Stopped: step limit reached."

if __name__ == "__main__":
    argv = sys.argv[1:]
    real = "--real" in argv
    argv = [a for a in argv if a != "--real"]
    q = " ".join(argv) or "What is (12 + 8) * 3?"
    run_agent(q, OpenAICompatibleLLM() if real else MockLLM())

Run it with the mock model

$ python agent.py "What is (12 + 8) * 3?"
[1] thought: This is arithmetic. I will use the calculator.
[1] action:  calculator({'expression': '(12 + 8) * 3'}) -> 60
[2] thought: I have what I need.
[2] final:   60

$ python agent.py "What is a workflow?"
[1] thought: I need a definition. I will look it up.
[1] action:  lookup({'term': 'workflow'}) -> LLMs and tools are run along a path the developer wrote in code.
[2] thought: I have what I need.
[2] final:   LLMs and tools are run along a path the developer wrote in code.

TestedI ran this code with Python 3.13 on October 28, 2026. Both demo runs printed the output shown above. All nine unit tests passed.

Read the code in three parts

  1. Tools. A tool is a normal Python function plus a short description. The TOOLS dictionary is the agent's menu. The calculator uses ast to parse the math. It does not use eval. The model's output is untrusted input, so never run it as code.
  2. The model. Any object with a complete(messages) method works. MockLLM uses simple rules. OpenAICompatibleLLM calls a real chat API. The model must reply with JSON: either an action or a final answer.
  3. The loop. run_agent asks the model, parses the reply, runs the tool, and adds the result to the messages. It stops on a final answer or after max_steps. Tool errors are sent back to the model as text. They do not crash the program.

Honest note about the mockMockLLM is not smart. It matches patterns with regular expressions. It exists so that you can see the shape of an agent run, and test your loop, without any account or cost. The loop and tools are the real thing. Only the "brain" is fake.

Use a real model (optional)

Any service with an OpenAI-style chat API should work. I tested only the mock path on the box. Set three variables, then add --real:

export OPENAI_API_KEY="your key"
export LLM_MODEL="a model name your provider offers"
export LLM_BASE_URL="https://api.openai.com/v1"   # change for other providers
python agent.py --real "What is (12 + 8) * 3?"

Real models sometimes wrap JSON in extra text or code fences. If that happens, the loop sends "bad JSON" back and tries again. A good extension is to make the parser more forgiving.

Exercises

  1. Break it on purpose. Run python agent.py "What is 1/0?". Which line of the loop catches the error? What does the model see?
  2. Add a tool. Add word_count(text) to TOOLS. Update MockLLM so it can choose it for a question like "How many words are in 'to be or not to be'?". Add a test.
  3. Hit the step limit. Use a Scripted model that always asks for a tool. Check that the loop stops. Why is this stop rule the most important safety feature in the file?
  4. Add memory. Keep a list of past questions and answers in a file. Pass the last three into the first prompt. Which CoALA memory type is this [6]?
  5. Two-step questions. Make the agent handle "What is (3+4)*5, and what is an agent?" with two tool calls. What must change in MockLLM?
  6. Count the cost. Add a counter for model calls. Report calls per question. This is the first step towards a cost-aware evaluation as in [3].

The tests: test_agent.py

import unittest
from agent import calculator, lookup, run_agent, MockLLM

class Scripted:
    """Plays back fixed replies, so we can test the loop itself."""
    def __init__(self, replies): self.replies = list(replies)
    def complete(self, messages): return self.replies.pop(0)

class Tests(unittest.TestCase):
    def test_calculator(self):
        self.assertEqual(calculator("(12 + 8) * 3"), "60")
    def test_calculator_blocks_code(self):
        with self.assertRaises(Exception):
            calculator("__import__('os').system('echo hi')")
    def test_lookup_missing(self):
        with self.assertRaises(KeyError): lookup("banana")
    def test_mock_math(self):
        self.assertEqual(run_agent("What is (12 + 8) * 3?", MockLLM(), verbose=False), "60")
    def test_mock_lookup(self):
        out = run_agent("What is a workflow?", MockLLM(), verbose=False)
        self.assertIn("path the developer wrote", out)
    def test_unknown_tool_is_reported_not_crashed(self):
        llm = Scripted(['{"action": "email", "input": {}}', '{"final": "ok"}'])
        self.assertEqual(run_agent("hi", llm, verbose=False), "ok")
    def test_bad_json_retry(self):
        llm = Scripted(["not json", '{"final": "done"}'])
        self.assertEqual(run_agent("hi", llm, verbose=False), "done")
    def test_step_limit(self):
        llm = Scripted(['{"action": "calculator", "input": {"expression": "1+1"}}'] * 3)
        self.assertEqual(run_agent("hi", llm, max_steps=3, verbose=False),
                         "Stopped: step limit reached.")
    def test_tool_error_goes_back_to_model(self):
        llm = Scripted(['{"action": "calculator", "input": {"expression": "1/0"}}',
                        '{"final": "handled"}'])
        self.assertEqual(run_agent("hi", llm, verbose=False), "handled")

if __name__ == "__main__":
    unittest.main(verbosity=2)
$ python test_agent.py
test_bad_json_retry (__main__.Tests.test_bad_json_retry) ... ok
test_calculator (__main__.Tests.test_calculator) ... ok
test_calculator_blocks_code (__main__.Tests.test_calculator_blocks_code) ... ok
test_lookup_missing (__main__.Tests.test_lookup_missing) ... ok
test_mock_lookup (__main__.Tests.test_mock_lookup) ... ok
test_mock_math (__main__.Tests.test_mock_math) ... ok
test_step_limit (__main__.Tests.test_step_limit) ... ok
test_tool_error_goes_back_to_model (__main__.Tests.test_tool_error_goes_back_to_model) ... ok
test_unknown_tool_is_reported_not_crashed (__main__.Tests.test_unknown_tool_is_reported_not_crashed) ... ok

----------------------------------------------------------------------
Ran 9 tests in 0.001s

OK

The tests use a Scripted model that plays back fixed replies. That is the trick for testing agents: replace the unpredictable part with a predictable one, and test the loop around it.

Think about

5. Discussion questions

Use these in a study group or a class. Try to answer with an example and a source. Give each about 5 to 10 minutes.

  1. Is a thermostat an agent [7] [3]? Is a spam filter? Is a chatbot with web search? Where would you draw the line, and why is the line fuzzy?
  2. The BAIR post says system design can beat scale for some tasks [1]. Name a task where you think scale will win in the end. Name one where system design will keep winning.
  3. Anthropic says to use the simplest solution that works [4]. Think of a time you over-built something. What was the signal that you should have stopped?
  4. Reasoning alone can invent facts. Acting alone can lose its way. Why does mixing the two help [5]? When does the mix hurt?
  5. Kapoor et al. show cheap retries matching fancy agents [3]. Does that mean complex agent designs are useless? What other evidence would you want?
  6. Choose one action an agent should never take without a human saying yes. Choose one it should always be free to take. What is your rule for sorting actions [6] [3]?
  7. Imagine you can only measure two numbers for your agent. Which two? Defend the choice with the evaluation problems in section 2.5.
  8. Who should be responsible when an agent with tools makes a costly mistake: the model maker, the developer, or the user? What would you build in to make the answer clearer?

6. Quiz (10 questions)

Pick one answer for each question, then press Check answers. 0 of 10 answered.

  1. According to the BAIR post, what is a compound AI system [1]?
    • A very large language model trained on many data sets
    • A system that tackles AI tasks using multiple interacting components, such as model calls, retrievers and tools
    • Any model that uses chain-of-thought prompting
    • A group of researchers building one model together
  2. In Anthropic's wording, what is the main difference between a workflow and an agent [4]?
    • Workflows use tools. Agents do not.
    • Workflows are always cheaper than single calls.
    • Workflows use small models. Agents use large models.
    • Workflows follow predefined code paths. Agents let the LLM direct its own process and tool use.
  3. Weng's overview of an LLM-powered agent has the LLM as the "brain" plus which three components [2]?
    • Planning, memory, tool use
    • Training, evaluation, deployment
    • Perception, action, reward
    • Retrieval, ranking, generation
  4. In ReAct, what does a "thought" do [5]?
    • It changes the external environment and returns an observation.
    • It is a tool call to a search engine.
    • It is an action in the language space. It updates the agent's context but does not change the outside world.
    • It resets the agent's memory.
  5. In CoALA, which memory type holds the agent's own code and the model weights [6]?
    • Working memory
    • Episodic memory
    • Semantic memory
    • Procedural memory
  6. Kapoor et al. tested simple baselines (retry, warming, escalation) on HumanEval. What did they find [3]?
    • The baselines were far less accurate than every complex agent.
    • The baselines matched the accuracy of complex agent designs while costing much less in many cases.
    • The baselines could not be run on HumanEval.
    • The baselines were more accurate only when cost was ignored.
  7. Why do Kapoor et al. say agent evaluations must be cost-controlled [3]?
    • Because cheap models are always better
    • Because cost is the only metric users care about
    • Because accuracy can be raised by repeating calls, so accuracy alone rewards costly designs that are not real advances
    • Because benchmarks forbid expensive models
  8. Under the classic textbook definition, what is an agent [7] [3]?
    • An entity that perceives its environment and acts on it, so a thermostat counts
    • A program that uses a large language model
    • A system that can write and run code
    • A chatbot with a memory
  9. An agent must complete 10 steps in a row. Each step succeeds 95% of the time, and steps are independent. About how often does the whole run succeed? (This illustrates the compounding errors that Anthropic warns about [4].)
    • About 95%
    • About 80%
    • About 60%
    • About 5%
  10. In the lab, why does the calculator tool parse the expression with ast instead of calling eval?
    • It is faster than eval.
    • The mock model requires it.
    • eval cannot do addition.
    • The model's output is untrusted input, and eval could run arbitrary code.

Answer key

Question 1

B. The post defines a compound AI system as one that tackles AI tasks using multiple interacting components, including multiple model calls, retrievers, or external tools. A plain model, by contrast, is just a statistical model [1].

Question 2

D. Workflows are "orchestrated through predefined code paths". In agents, LLMs "dynamically direct their own processes and tool usage" [4]. Both kinds can use tools. Cost and model size are not the defining difference.

Question 3

A. Planning (subgoals and reflection), memory (short-term and long-term), and tool use [2].

Question 4

C. ReAct widens the action space to include language. A thought "does not affect the external environment, thus leading to no observation feedback". It updates the context to help later reasoning or acting [5].

Question 5

D. Procedural memory holds implicit knowledge in the model weights and explicit knowledge in the agent's code [6]. Working memory is the current context. Episodic is past experience. Semantic is facts about the world.

Question 6

B. There was no significant accuracy difference between their warming baseline and the best complex agent on HumanEval, and for substantially similar accuracy the cost could differ by almost two orders of magnitude [3].

Question 7

C. Calling a model many times can lift accuracy, so a leaderboard that only shows accuracy can reward needless cost and hide whether a design is truly better [3].

Question 8

A. Traditional AI defines agents as entities that perceive and act on their environment. Kapoor et al. note that a thermostat qualifies under that definition, and that the LLM-era use of the word is narrower [3] [7].

Question 9

C. 0.9510 is about 0.60. This is my own arithmetic, used to illustrate Anthropic's warning about compounding errors [4]. Real steps are rarely fully independent, so treat the number as a rough guide.

Question 10

D. Model output is untrusted. eval would execute any Python it was given. Parsing with ast and allowing only a few safe operations keeps the tool limited to math. This echoes CoALA's point that the action space carries safety risks [6].

Scoring: 9 to 10 means you are ready for Week 2. 7 to 8: re-read the sections linked in the answers. Below 7: redo the reading guide questions first. When you print this page, check the quiz first if you want your marks on the paper copy. The answer key is included when you print.

7. Graded assignment and rubric

Title: Workflow or agent? Build, measure, decide.
Time: 1 to 2 hours. Total: 100 points. Work: solo.

The task

Extend the lab code and write a short memo (one to two pages). You may use the mock model. You may also use a real model if you have a key.

Part A. Extend the agent (30 points)

Part B. Measure it (30 points)

Part C. Design memo (25 points)

For each of the three scenarios below, say whether you would build a single call, a workflow (name the pattern from [4]), or an agent. Give two or three sentences of reasons. Note one risk per scenario.

  1. A tool that turns support emails into one of five labels and drafts a reply from a template.
  2. A research helper that must find, read and compare an unknown number of web sources for a question.
  3. A coding helper that fixes failing tests across several files in a repository.

Part D. Safety and honesty (15 points)

What to hand in

Rubric

CriterionFull marksPartialPoints
A. New tool and testsTool works. Three or more tests plus an error case pass. The model can choose the tool. Code is clear.Tool works, but tests are thin or the model cannot choose it reliably.30
B. MeasurementEight good questions. Both versions run. Table has accuracy and model calls. The pick is justified using cost and accuracy.Table is missing calls, or the pick has no reasoning.30
C. Design memoThree sensible choices, each tied to a named pattern or to the agent definition, with a stated risk.Choices are right, but reasons are vague or risks are missing.25
D. Safety and honestyThree realistic failure modes with guards. Limits of the tests are stated plainly.Failure modes are generic, or limits are not stated.15
Total100

Grade bands: 90 to 100 excellent. 75 to 89 good. 60 to 74 needs work. Under 60: redo and resubmit. Plain writing is rewarded: short sentences, no filler.

8. Glossary

TermMeaning
ActionSomething the agent does. External actions affect the environment (call a tool). Internal actions affect its own memory or thinking [6].
AgentIn the classic sense, an entity that perceives its environment and acts on it [7]. In LLM work, a system where the model directs its own process and tool use [4].
Agent-computer interface (ACI)The way tools and their descriptions are presented to an agent. Anthropic says it deserves as much care as a human interface [4].
Agentic systemAnthropic's umbrella term for both workflows and agents [4]. Kapoor et al. treat "agentic" as a range [3].
Compound AI systemA system that uses several interacting parts, such as model calls, retrievers and tools [1].
Context windowThe amount of text the model can read in one call. It limits how much history and tool output fits [2].
Cost-controlled evaluationComparing agents on accuracy and cost together, for example with a Pareto curve [3].
DSPyA framework that tunes the prompts and examples of a multi-step LLM pipeline to maximize a metric [1].
EnvironmentEverything outside the agent that it can sense or change: web, files, people, APIs [6].
Episodic memoryMemory of past events and runs [6].
GroundingConnecting the model to real information or actions outside itself, such as tool results. CoALA calls external actions "grounding actions" [6].
HallucinationWhen a model states something that is not true or not supported. Retrieval and tools can reduce it [5] [1].
Holdout setTest data kept apart from what developers tune on, so results show real skill and not memorized shortcuts [3].
Long-term memoryInformation kept outside the context window and fetched when needed [2].
ObservationThe result an agent sees after an action, such as a tool's output [5].
Orchestrator-workersA workflow in which a central LLM splits a task, hands parts to workers and merges results [4].
Pareto frontierThe set of designs where you cannot improve one measure (like accuracy) without hurting another (like cost) [3].
Procedural memoryKnowledge of how to act: model weights and the agent's code [6].
Prompt chainingA workflow of fixed steps where each model call uses the previous output [4].
ReActA pattern that interleaves reasoning steps ("thoughts") with actions and observations [5].
Retrieval-augmented generation (RAG)Searching a data source first, then having the model answer using what was found [1].
RoutingA workflow that classifies an input and sends it to a specialized path [4].
Semantic memoryFacts about the world and about the agent itself [6].
Stopping conditionA rule that ends an agent run, such as a final answer or a maximum number of steps [4].
ToolA function or service the model can ask the program to run, such as search, a calculator or an API [2].
TraceThe recorded list of steps, tool calls and results from one run. It is the main thing you read when you debug [1].
WorkflowA system where LLMs and tools follow predefined code paths [4].
Working memoryThe information active in the current step: goal, recent inputs, results of thinking [6].

9. References

All links were opened and checked on October 28, 2026. Items 1 to 3 are the required readings for this week.

About the sourcesEvery claim about a source in these notes comes from that source's own page, which I opened while writing. Where a number is my own arithmetic, the text says so. Where the source gives a made-up example, the text says that too. I did not read the two books in full. I did not use the lecture slides, and this pack does not reproduce them. If you find a mistake, please tell the author.