32

Agents and tools

What changes when a model can act, not just talk?

13 minExecutive path

Agents and tools

With voice. You can pause and jump to any step.

Lesson complete

Subtitles

You ask a chatbot: “Buy two movie tickets for tonight, seats together, for under three hundred pesos.” Can it do that?

Voice

No voice: the lesson advances on its own with subtitles.

The voice for this lesson is being recorded: for now it advances on its own with subtitles.

0:00 / 0:00

What you will achieve

  • Explain how a model that only writes text gets to act: it is given tool descriptions, writes function calls, a program runs them, and the result goes back into its context, in a loop of thinking, acting, and observing.
  • Calculate how a task’s success drops when its steps are chained (0.95 to the tenth power is about 0.60) and how human review raises it in exchange for attention.
  • Decide which permissions, limits, logs, and approvals to give an agent depending on how reversible each action is.

Key ideas

  1. A model only writes text. To act, it is given tool descriptions and writes function calls (a name and data); the program around it runs them and pastes the result into its context.
  2. An agent is a model in a loop: it thinks, acts with a tool, observes the result, and repeats until the goal is met. Its context is its working memory, and every round rereads all of it.
  3. Errors pile up: if each step goes right 95% of the time, ten steps go right about 60% of the time and twenty, about 36%. Human review in stretches raises success in exchange for attention, and reviewers miss things too.
  4. An instruction in the text is a plea; a permission is a rule in the program. Before anything irreversible or over a limit, the human in the loop approves or rejects, and it only protects if they really read.
  5. Autonomy comes in degrees (suggest, act with approval, act up to a limit, act alone) and is earned with evidence: you start with reversible actions, minimal permissions, and a log of every call.

What many people believe

Common belief An agent is a smarter model that acts on its own.

What is true It is the same model, which only writes text, inside a loop. The actions are run by a program with the permissions you define. It is not smarter: it is more autonomous, and therefore costlier and riskier.

Check yourself

Four questions. No grade, no account: they just show whether the idea stuck.

ConceptIn function calling, who runs the tool?
CalculationAn agent gets each step right 90% of the time. What is the probability that a seven-step task goes right from start to finish?
ConceptThe purchase request says “don’t spend more than 300 pesos.” Why is that alone not a protection?
ApplicationA team wants an agent that pays supplier invoices. What is the most prudent initial design?

Under the hoodFor those who want the math and the code. You do not need it to follow the course.

The agent loop

An agent is a program with three parts: a model that decides, a set of tools (functions), and a loop that connects them. On each round:

  1. the model receives the full context (system prompt, tool descriptions, task, and history) and produces either a call (a name and data) or the final answer;
  2. the program validates the call, applies the permissions, and runs the function;
  3. the result is added to the history as one more message and we go back to step 1, until the model answers or a step limit runs out.

That is the idea behind ReAct (Yao et al., 2022): interleave reasoning and acting so that each observation corrects the next reasoning step. In their tests, with only one or two examples in the prompt, ReAct beat imitation and reinforcement-learning methods by 34 and 10 points of success rate in two interactive environments (ALFWorld and WebShop), and on questions answered with a Wikipedia API it reduced hallucination compared with chain of thought alone. Since 2023, providers’ interfaces (for example, the “function calling” OpenAI launched on June 13, 2023) make the model emit the call in a structured format. Before that, Toolformer (Schick et al., 2023) had trained a model to decide on its own when to call an API and with which arguments.

A function call, inside

A tool is described by a name, a description, and a schema of its input data (JSON Schema). Field names vary from provider to provider; the idea is the same:

// what the model receives (as text) at the front of its context
{ "name": "buy_tickets",
  "description": "Buys tickets for a showtime. Charges the saved card. Cannot be undone.",
  "input_schema": { "type": "object",
    "properties": { "showtime": { "type": "string" }, "quantity": { "type": "integer", "minimum": 1 } },
    "required": ["showtime", "quantity"] } }

// what the model writes: a request, not an execution
{ "name": "buy_tickets", "input": { "showtime": "9:30 pm", "quantity": 2 } }

The model runs nothing: it produces the text of the call. The program must treat that data as untrusted input: validate it, bound it, and log it. The tool description (for example, “cannot be undone”) helps the model decide, but it does not protect: the spending limit lives in the code that executes.

MCP

The Model Context Protocol (Anthropic, November 25, 2024) standardizes that connection. An application (the client) connects to an MCP server that offers tools; messages are JSON-RPC 2.0: tools/list to discover the tools and tools/call to invoke one, and the result comes back with an isError flag. The specification (version 2025-06-18) says that, for trust and safety, there should always be a human in the loop with the ability to deny an invocation, and that the client should ask for confirmation on sensitive operations, show the inputs before calling the server, and log tool usage for audit purposes. On December 9, 2025, the Linux Foundation announced the Agentic AI Foundation, with MCP, contributed by Anthropic, among its founding projects.

Reliability of a chain

If each step goes right with probability pp, independently, and one error is enough to ruin the task, an nn-step task goes right with probability

P(n)=p nP(n) = p^{\,n}

With p=0.95p = 0.95: P(2)≈0.90P(2) \approx 0.90, P(10)≈0.60P(10)\approx 0.60, P(14)≈0.49P(14)\approx 0.49, P(20)≈0.36P(20)\approx 0.36, and P(40)≈0.13P(40)\approx 0.13. The number of steps at which success falls to one half is

n1/2=ln⁡0.5ln⁡p≈13.5(p=0.95)n_{1/2} = \frac{\ln 0.5}{\ln p} \approx 13.5 \quad (p = 0.95)

This is a simplified model: it assumes independent errors and that any error ruins the attempt. In practice errors correlate (a bad plan drags down the steps after it), and sometimes the agent recovers on its own by reading an error message. That is why end-to-end success is measured, not computed. The lesson’s simulator does exactly this calculation with twenty attempts (fixed seed): the sample gives 12 of 20 with ten steps, 9 with fourteen, 7 with twenty, and 3 with forty.

Review in stretches

A stretch of mm steps goes right with A=pmA = p^{m}. At the end of the stretch, a person reviews it and catches an error with probability qq; if caught, the stretch is redone. One attempt at the stretch is accepted with probability A+(1−A)(1−q)A + (1-A)(1-q), so

s=AA+(1−A)(1−q),expected reviews=1A+(1−A)(1−q)s = \frac{A}{A + (1-A)(1-q)}, \qquad \text{expected reviews} = \frac{1}{A + (1-A)(1-q)}

Total success is the product of the ss of all stretches. With p=0.95p = 0.95, n=20n = 20, and q=0.9q = 0.9 (the lesson’s assumptions): no review, 35.8%; reviewing every 5 steps, 89.1%, with 5.0 reviews and 25.1 agent steps per attempt; every 10, 87.8% (3.1 reviews, 31.3 steps); only at the end, 84.8% (2.4 reviews, but 47.3 steps: everything is redone). The ceiling is set by qq: even reviewing every step, success stays at 90.0%, because one error in ten slips through.

Measuring consistency

τ-bench (Yao, Shinn, Razavi, and Narasimhan, 2024) puts an agent with tools and business rules in front of a customer simulated by another model, and compares the final state of the database with the expected one. It introduces passk\text{pass}^k: the probability that the same task goes right in all kk attempts. With function calling, GPT-4o solved 61.2% of the store’s tasks and 35.2% of the airline’s on the first try (48.2% on average), and in the store its pass8\text{pass}^8 fell below 25%.

Cost

If each query rereads the instructions and the definitions (BB tokens) plus the whole history, and each step adds gg tokens, the total read over nn steps is

∑k=1n(B+(k−1) g)=nB+g n(n−1)2\sum_{k=1}^{n}\bigl(B + (k-1)\,g\bigr) = nB + g\,\frac{n(n-1)}{2}

It grows like n2n^2, like the conversations in lesson 30. With illustrative assumptions (B=2,000B = 2{,}000, g=800g = 800): 10 steps is 56,000 tokens; 20, 192,000; 40, 704,000. And a failed attempt is paid for all the same: the cost per completed task is the cost per attempt divided by the probability of success. With p=0.95p = 0.95 that comes to about 94,000, 536,000, and 5.5 million tokens per completed task.

Levels of autonomy

Feng, McDonald, and Zhang (2025) propose five levels according to the person’s role: operator, collaborator, consultant, approver, and observer, and argue that autonomy is a design decision, separate from the model’s capability. The lesson uses a shorter scale (suggests, acts with approval, acts up to a limit, acts alone) with the same idea: more autonomy means more speed and less control, and it is granted action by action according to reversibility. Anthropic (2024) recommends starting with the simplest solution: if the steps are known in advance, a fixed workflow is usually enough; an agent is justified when the path depends on what is observed, and its autonomy brings higher costs and compounding errors, so it should be tested in a sandbox with guardrails.

In code

SHOWTIMES = {"8:00 pm": {"seats": 0, "price": 95}, "9:30 pm": {"seats": 14, "price": 95}}
LIMIT = 300   # permission: above this, the program asks for approval

def find_showtimes(date):
    return {time: dict(s) for time, s in SHOWTIMES.items()}

def buy_tickets(showtime, quantity):
    s = SHOWTIMES[showtime]
    if quantity > s["seats"]:
        raise ValueError("not enough seats")
    s["seats"] -= quantity
    return {"showtime": showtime, "quantity": quantity, "total": quantity * s["price"]}

TOOLS = {"find_showtimes": find_showtimes, "buy_tickets": buy_tickets}

def model(context):
    """A script instead of an LLM: it decides from the last thing in the context."""
    last = context[-1]
    if last["role"] == "user":
        return {"tool": "find_showtimes", "args": {"date": "today"}}
    if last["tool"] == "find_showtimes":
        time = next(t for t, s in last["result"].items() if s["seats"] >= 2)
        return {"tool": "buy_tickets", "args": {"showtime": time, "quantity": 20}}  # mistake: one zero too many
    if last["result"] == "rejected by the person":
        return {"tool": "buy_tickets", "args": {"showtime": "9:30 pm", "quantity": 2}}
    return {"answer": f"Done: {last['result']}"}

def approves(request):   # the human in the loop (here, a rule that mimics their decision)
    print("Approve?", request["args"])
    return request["args"]["quantity"] <= 4

def agent(task, max_steps=6):
    context = [{"role": "user", "text": task}]
    for step in range(1, max_steps + 1):
        decision = model(context)                            # 1. think
        if "answer" in decision:
            return decision["answer"], step
        name, args = decision["tool"], decision["args"]
        if name == "buy_tickets":                            # permission: a rule in the program
            total = args["quantity"] * SHOWTIMES[args["showtime"]]["price"]
            if total > LIMIT and not approves(decision):
                context.append({"role": "result", "tool": name, "result": "rejected by the person"})
                continue
        try:
            result = TOOLS[name](**args)                     # 2. act: the program runs it
        except Exception as e:
            result = f"error: {e}"                           # an error is also an observation
        context.append({"role": "result", "tool": name, "result": result})  # 3. observe
    return "I did not finish.", max_steps

print(agent("Buy two tickets for tonight, for under 300 pesos."))

# Reliability of a chain: each step goes right with p = 0.95
for n in (1, 2, 10, 14, 20, 40):
    print(n, round(0.95 ** n, 2))

Output:

Approve? {'showtime': '9:30 pm', 'quantity': 20}
("Done: {'showtime': '9:30 pm', 'quantity': 2, 'total': 190}", 4)
1 0.95
2 0.9
10 0.6
14 0.49
20 0.36
40 0.13

Swap model for a call to an LLM and you have the skeleton of a real agent. What a serious product adds is what is only sketched here: input validation, per-tool permissions, step and spending limits, a log of every call, and error handling.

What comes next

An agent that reads and acts is wrong with confidence: lesson 33 covers hallucinations. Lesson 34 teaches how to measure a system with your own tasks, and lesson 35 covers the risks that tool access opens (for example, instructions hidden in what the agent reads) and how to govern them.

Decision lens

What this idea means if your job is to decide, not to code.

  • Autonomy is permission. Define minimal permissions per tool, limits enforced in the program (not in the prompt), a log of every call, and human approval before anything irreversible: paying, deleting, sending. Ask: what is the worst it could do with the credentials it holds?
  • Ask for the end-to-end success rate on tasks as long as yours, measured on your data (lesson 34), and how often it goes right when repeated. Per-step success misleads: 95% per step is 60% over ten steps and 36% over twenty. And compare cost per completed task, not per attempt.
  • Start with the reversible (reading, searching, drafting) and move up a level only with evidence. In 2025, Anthropic put an agent with web search, notes, and a channel to customers in charge of a small office shop for a month, and concluded it would not hire it: it made too many mistakes.
  • Do you really need an agent? If the steps are known in advance, a fixed workflow is cheaper, faster, and more reliable; an agent is justified when the path depends on what it observes. And whatever the agent reads (pages, emails, documents) enters its context: it can carry hidden instructions (lessons 31 and 35).

Terms in this lesson

Full transcript
CommentsThis lesson’s public conversation: questions, facts to check, ideas.

Comments live in GitHub Discussions, in the course’s public repository; writing one requires a GitHub account. They load from giscus.app when you open this section. The course reviewers read them, and if a change is accepted, it is applied in both languages. Open the thread on GitHub

Sources