Agents
How can a text generator use a tool?
Why can’t the bot find PP-88213?
A payments company’s support bot now answers from the policy PDFs, in the company’s own tone. Then a ticket like this one comes in.
The bot’s reply is polite and well formatted, and it does not know the answer. The status of PP-88213 is stored in the payments database. It is not in any PDF, and it is not in any weight.
Your first instinct as a programmer is to connect the bot to the database so that it can check. But the model cannot check anything or call anything. Everything you built in this course has one output: a probability distribution over the next token. A token is sampled from that distribution, and the result is text. The model produces nothing else.
So how do products built on LLMs look up an order, run code, or book a meeting? Every major model API answers in the same way, under names such as tool use and function calling:
- You describe each tool as data: a name, a sentence saying what it does, and a JSON schema for its arguments. For this ticket that could be
get_transaction, which takes one string, the transaction id. - You send those descriptions along with the conversation. When the model decides a tool would help, its reply is a structured call instead of prose: the tool’s name and arguments such as
{"id": "PP-88213"}. - Your code runs the real lookup against the payments database and sends the result back as a new message. The model then writes its answer from that result, or asks for another tool.
The model never touched the database. It wrote a request, and your code decided whether to run it. The API only makes that request easy to parse.
This lesson takes the API away so that you can see the plain loop underneath it. In the lab, the model writes its request as ordinary text in an agreed format, a parser reads it, and a loop of ordinary code runs the tool and calls the model again. The lab’s question needs two tools, a document search and a calculator:
The rotation size is in a company document and nowhere in the weights. And a next-token predictor has no exact calculator inside. It produces digits the way it produces any other tokens, by predicting what is likely, so on larger numbers it can be confidently wrong.
RAG changed the prompt, and fine-tuning changed the weights. An agent leaves both of them alone and changes the ordinary code around the model: you put the model inside a loop.
The problem
Pause and predict The model’s only output is a probability distribution over the next token. So how can it ever look up PP-88213?
- The problem
- Some tasks need actions (look something up, compute, call an API) and need several steps where each depends on the last result.
- The naive fix
- One model call: put the question in, take the answer out.
- Why it fails
- The model can only emit text. It cannot execute anything, and it cannot see the result of a step it has not been shown.
- The idea
- Agree on a text format that means “please run this tool”. Your code watches for it, runs the real function, appends the result to the context, and calls the model again. Repeat until the model writes a final answer.
- The trade-off
- Many model calls instead of one: slower, costlier, and every step is a new chance to go wrong. Mistakes carry forward, and text returned by a tool can steer the model.
- Tool use
- The model writes a request in an agreed format. Your code parses it, runs a normal function, and pastes the function’s output back into the context.
- For example: Model emits
TOOL: calculator/ARGS: {"expression": "23*7 + 4"}. Your code runs the calculator and appendsRESULT: 165.
- Agent
- A program that calls a model in a loop, letting the model’s text output choose which tool your code runs next, until the model says it is done or a step limit is hit.
- For example: search_docs → calculator → final answer: three model calls, two tool calls.
A mental model
Read the picture as one lap. Everything to the right of the dotted border is ordinary code. The only thing that ever crosses the border from the left is text.
Pause and predict Why does the model “decide” to write a TOOL: block at all?
The second model call does better than the first because its context now contains the answer to the sub-question.
The line “RESULT: The oncall rotation has 4 engineers” is part of the context, and attention can read it, exactly as it reads a retrieved chunk in RAG. For the PP-88213 ticket, the RESULT would be the row from the payments database.
Let's see the numbers
The logs of the three-step oncall run show two numbers that matter.
The context grows, and all of it is re-sent on every call. The model received 412, then 601, then 724 characters: 1,737 characters read in total, to produce 317 characters of output.
The model is stateless, so iteration 3 re-reads everything from iterations 1 and 2. Long agent runs are dominated by the cost of re-reading their own history. (Provider-side prompt caching can make an unchanged prefix cheaper and faster to re-read. The tokens are usually still counted and billed, at a lower rate.)
Errors compound. Suppose each step (choose the right tool, write valid arguments, read the result correctly) succeeds 95% of the time, independently. A run needs every step to succeed.
Pause and predict Ten steps, each right 95% of the time. How often does the whole run succeed?
This one piece of arithmetic explains most of the gap between agent demos (short, chosen) and agent products (long, arbitrary).
Independence is a simplification. Real agents sometimes notice and repair a mistake (the error message comes back as a RESULT), which helps. They also build on a wrong intermediate result as if it were true, which hurts. The direction of the effect is solid: longer chains are less reliable.
The math
It points at the two levers you have: make each step more reliable (better tools, validation, clearer prompts), or make the task need fewer steps.
What you should remember
- An agent leaves the weights alone and changes the code around the model. That code is a loop that you write.
- An LLM only ever emits text. “Using a tool” = the model writes a request in an agreed format; your code parses it, runs the function, and appends the RESULT to the context.
- The loop: observe → decide → act → observe, until
ANSWER:or the step budget. Structured tool calling, RAG agents, planning, memory and multi-agent systems are all small additions to this loop. There is no memory, only what you put back into the context. - Agents fail by compounding errors (0.95¹⁰ ≈ 0.60), full contexts, hallucinated arguments, prompt injection and runaway loops. The guardrails are ordinary engineering: budgets, validation, least privilege, human approval.
Where this appears in a real LLM
- In this lesson
- A scripted stand-in model: a few
ifstatements - Two tools, a regex parser, a plain-text format
- Three iterations, a 3,500-character context budget
- One pattern-matching sanitiser
- A scripted stand-in model: a few
- In a real system
- A real LLM, fine-tuned to follow a tool-calling format
- Dozens of tools described by JSON schemas; the API returns parsed tool requests
- Tens to hundreds of iterations, with summarisation and external stores
- Sandboxed execution, permission systems, logging of every step, human approval for risky actions
Coding assistants, “deep research” tools and computer-use systems are this loop. What differs is the quality of the model in the “decide” step, the tools, and the amount of engineering around failure. The model is still the next-token predictor you built in Build GPT.
RAG, fine-tuning and agents in one table: what changes?
| Prompt | Weights | Surrounding code | Use it for | |
|---|---|---|---|---|
| Plain LLM | your question | as trained | one API call | what the model already knows and can do |
| RAG | changes: retrieved text is pasted in | unchanged | a search step before the call | knowledge that is private, recent or changing; citations |
| Fine-tuning | can get shorter | changes: further training on your examples | unchanged at run time (a training job beforehand) | behaviour: style, tone, narrow skills |
| Agents | grows each step, assembled by the loop | unchanged | changes: a loop that parses output, runs tools, feeds results back | tasks that need actions and several dependent steps |
These approaches combine. A realistic system often uses all of them: a fine-tuned model, inside an agent loop, with retrieval as one of its tools. When you meet a new “AI technique”, ask the same question: does it change the prompt, the weights, or the code around the model?
With one lookup tool, the bot can now answer “Where is PP-88213?” with the real status. The next part asks how you would know that it works: how many tickets you tested it on, and how you scored the answers.