In previous chapters of Agents Unpacked, we explored what makes an AI agent different from a chatbot and how the model, its tools, and the software connecting them work together.
You ask an AI agent whether you’ll need a raincoat tomorrow. To check the forecast, it can't rely on its knowledge. It needs up-to-date information. It needs to turn your question into a request that a weather service can understand.
This time, we look inside the request itself. How does a large language model (LLM) turn everyday wording into a named operation with specific inputs? And why can a request contain all the right fields yet still ask for the wrong thing?
Who’s Monty? Monty is my personal AI agent. Read the introduction to this series.
In conversation • Chapter 3
Monty:
Suppose you ask an assistant:
“Will I need a raincoat in Oxford next Saturday?”
It has a weather-lookup tool available, but “Oxford next Saturday” isn’t quite as precise as it looks.
What might the assistant need to clarify before requesting the forecast?
Stephen:
You got me here. I can't figure out why this is not precise. The only thing I'd pick is that "next Saturday" can be ambiguous. It sometimes refers to the Saturday coming up, and sometimes to the next one after the one coming up. Is that the ambiguity?
Monty:
Yes, that’s exactly the ambiguity. A specific date, such as “24 October 2026”, avoids those two readings.
I also had the place in mind. There’s an Oxford in England, but there are Oxfords elsewhere, too. Context might make the intended one obvious, so the assistant needn’t ask unnecessarily. My opening made that sound more mysterious than it was. I’ve managed to turn choosing a coat into a geography test.
The useful point is that the assistant needs to turn our everyday wording into the particular location and date it will send to the weather tool. That involves interpreting what we mean, not just copying our words.
Stephen:
Got it.
Monty:
Suppose we’ve settled on Oxford in England and Saturday, 24 October.
As we saw in Chapter 2, the surrounding software, or harness, tells the model what tools are available and what information each needs. For our weather example, a tool description could say:
get_weather: Look up a forecast. Requires a location and a date written as year-month-day.
It can then produce a request like this:
(Illustrative request, not a real lookup)
{
"name": "get_weather",
"arguments": {
"location": "Oxford, UK",
"date": "2026-10-24"
}
}This format is called JSON. You don’t need to learn its punctuation. Here, name identifies the tool, and arguments contains the inputs supplied to it.
Notice that the request doesn’t mention a raincoat even though that’s what your prompt asked. The model has translated your question into a request for information it can use to answer you.
Stephen:
So, let's see if I follow. The harness receives this response from the LLM and it recognises it's not text but it's a tool call. The harness has all the information it needs, so it can choose to call the get_weather tool and pass the location and date to it. The tool then fetches the weather forecast for that location and date, presumably by accessing some online service that provides this information.
Monty:
Yes, that’s the sequence for our example. The weather tool could contact an online forecasting service using those inputs.
One refinement: the JSON is still text. In a typical tool-use interface, the model’s response is explicitly marked as a tool request. The harness isn’t simply spotting curly brackets in an ordinary reply. Our mock-up represents that request, rather than showing a particular provider’s exact format.
After any checks the software implements, it can run the tool. Here’s a hypothetical successful result (not a real forecast):
{
"location": "Oxford, UK",
"date": "2026-10-24",
"forecast": "Rain likely",
"temperature_c": 12
}That gives the model evidence for its raincoat recommendation. Notice that the forecast comes from the tool’s result, not from the model generating a plausible answer about October weather.
Stephen:
So the tool returns this output. Then the harness sends this to the model, which makes sense of it and uses it to provide text for the user. Makes sense, yes. So, to pick up on something you said earlier, does the LLM label each thing it sends to the harness as either text or a tool call, which is how the harness knows what type of output comes from the LLM?
Monty:
Broadly, yes. The model communicates through an interface that distinguishes ordinary text from requests to use tools.
Think of the response as arriving in labelled sections. A text section contains words to show the user. A tool-request section identifies the tool and supplies its inputs. The harness reads those section types rather than guessing from the wording.
The exact arrangement varies between systems. A single response can also contain both, such as “I’ll check the forecast” followed by a tool request. It needn’t be entirely one or the other.
That’s why showing you our JSON example doesn’t trigger a weather lookup. It’s inside an ordinary text reply, not sent as an actual tool request.
Stephen:
Got it. What's next?
Monty:
There’s a useful question hiding behind our example: how did the model know how to ask for the weather?
Two things come together:
Learned behaviour: a tool-capable model has learned how to use supplied tool definitions to choose an operation and construct a request.
Information supplied now: the harness tells it which tools are available, what they do, and what inputs they accept.
The model needn’t have encountered our particular get_weather tool during training. Its description might be enough for it to use the tool, much as you can follow instructions for an unfamiliar appliance.
But that isn’t guaranteed. Understanding a description, choosing the right tool, and supplying sensible inputs can all go wrong.
Supplying a new tool description isn’t retraining the model. It’s giving the existing model information to work with.
Stephen:
So the model sees the tool as a black box. It doesn't know how it works, but it knows what it's meant to do and what it needs as input. This means that whoever creates tools needs to write a good description for the tool. However, this is not something that a user needs to worry about, right?
Monty:
Yes. The model doesn’t need to know how the tool works internally. It needs enough information to understand what the tool offers and how to request it. “Black box” is a useful way to think about that, although the model might know something about its workings.
And generally, you’re right about the user. If you’re using a ready-made assistant, its builders or whoever connects the tools should supply clear descriptions and input requirements. You shouldn’t need to write those yourself.
Your part is usually to explain what you want and clarify anything the assistant can’t reasonably infer.
But a good description isn’t a safeguard by itself. Saying “a date is required” tells the model what to provide. Software that rejects a request with no date actually checks that requirement.
Stephen:
If I recall correctly, in the early days of LLMs, when they first hit the mainstream, they could only provide text, right? Presumably tool calling came later.
Monty:
Yes, broadly, if you mean the early mainstream chat interfaces. You typed text, and they replied with text. Dedicated tool-calling support became more common later.
But text output wasn’t an absolute barrier to using tools. A developer could instruct a model:
If you need a forecast, write
WEATHER_REQUEST, followed by the location and date.
Software could watch for that convention, interpret it, and run the tool. Whether the model followed the convention reliably was another matter.
Dedicated tool-calling interfaces make that distinction explicit, rather than requiring developers to invent their own conventions. Models can also be trained specifically to produce appropriate tool requests.
So it wasn’t a jump from “words” to an entirely different ability to act. Software could already treat generated words as instructions. Dedicated support made that exchange more structured, though not automatically correct.
Stephen:
And I assume the harnesses around those first chat interfaces, like the first ChatGPT, were fairly basic and mostly just relayed the text to the user and kept the messages together to form the full conversation. So, the harnesses have also evolved to allow tool calls, right?
Monty:
Yes. The surrounding software has evolved too, not just the models.
Your description captures the visible interaction in an early text-only chat product: pass the conversation to the model, receive its reply, and display it. I’d avoid calling the whole system basic, though. There were also accounts, safety measures, and other machinery behind that simple interface.
To support tools, the software needs additional responsibilities: supply tool definitions, recognise tool requests, arrange execution, and return the results. It also needs to handle whatever checks, approvals, and errors its builders choose to support.
The two sides have to fit together. A model capable of requesting tools can’t use them through software that only displays its output. Equally, adding tools to the software doesn’t guarantee that a particular model will request them correctly.
Stephen:
Understood. I'm ready to move on.
Monty:
Let’s look at what the software can actually check.
Suppose the model requests a forecast for Oxford but leaves out the date. If the software checks that all required inputs are present, it can reject that request before attempting a lookup. The model then needs to supply the missing date, asking you if necessary.
Now suppose both inputs are present:
Location: Oxford, Mississippi, US
Date: 24 October 2026
That’s a real place and a valid date. But you meant Oxford in England.
Would checking that the request contains an acceptable location and date catch that mistake?
Stephen:
No, in this case the harness and the tool won’t catch this error. This was the model that made an assumption without checking.
Monty:
Right. Those input checks wouldn’t catch a valid location that wasn’t the one you meant. If the context didn’t justify choosing Mississippi, the model should have clarified rather than silently committing to it. Additional software checks could help, but checking the required fields alone wouldn’t.
Now suppose it requests the correct Oxford and date, but receives:
“No forecast available for that date.”
That’s different again. The request was accepted, and the service answered, but the answer lacks the information needed.
The model shouldn’t treat that as “no rain expected”. Missing information isn’t a negative forecast. It might try another suitable source or explain that it couldn’t obtain the forecast, rather than invent a raincoat recommendation.
Stephen:
That makes sense.
Monty:
Two other outcomes call for different responses:
“Access denied” means the request wasn’t permitted. Repeating it unchanged won’t solve that, and the assistant shouldn’t try to evade the restriction.
“Service temporarily unavailable” means the lookup couldn’t be completed. A limited retry might help.
Neither tells us what the weather will be.
Now let’s contrast that lookup with a calculation. Suppose you ask:
“Calculate the fuel cost for a 100-mile journey, assuming fuel costs 15p per mile.”
A calculator tool returns £15. Unlike the weather tool, it hasn’t fetched an external fact. It has calculated from supplied inputs.
What does that result establish, and what does it leave unconfirmed about the journey’s actual fuel cost?
Stephen:
It doesn’t check what assumptions are behind the 15p per mile estimate.
Monty:
Exactly. The calculator establishes that 100 miles at 15p per mile comes to £15. It doesn’t establish whether 15p is realistic for that car and journey, or whether the journey is actually 100 miles. Correct arithmetic can rest on inaccurate assumptions.
Stephen:
But the request from the user was clear about calculating the cost of the journey. Why would the agent need to doubt the user? It wasn’t asked to confirm that the values used make sense?
Monty:
You’re right. For that request, the agent should use the supplied assumptions and calculate £15. It wasn’t asked to investigate whether 15p per mile was realistic.
My question was about what the result proves, but I blurred that into what the agent ought to check. Those are different things. You asked for arithmetic. I’d apparently decided to conduct an inquiry.
“Using your figures, the fuel cost is £15” answers the request accurately. It needn’t challenge your figures or add a disclaimer.
The distinction matters if the agent supplies the assumptions itself, or presents £15 as a verified real-world cost rather than a calculation from your inputs.
Now consider our third example, purely hypothetically:
“Add ‘Trip to Oxford’ to my calendar next Saturday at nine.”
A calendar tool would need more precise inputs, just as the weather tool did. But there’s a new distinction: this request would change something stored, rather than retrieve information or calculate an answer.
Even if the model supplies an exact date and time, what else might need settling before that request should go ahead?
Stephen:
The harness would need to make sure that it has permission to make changes to the user’s calendar.
Monty:
Yes. A request can be correctly formed without being authorised. Software needs to check whether this system is allowed to write to that calendar. Merely showing the model a calendar tool doesn’t grant that permission.
In our hypothetical example, the user has explicitly asked for an event to be added. Whether separate confirmation is needed depends on the system’s rules, not on a universal requirement to ask again.
There are also practical details to settle: which calendar, whether “nine” means morning or evening, the time zone, and the event’s duration. Context or agreed defaults may supply those. Otherwise, the assistant should ask only for what’s missing.
Permission answers “May this change be made?” Precise inputs answer “Which change should be made?”
Stephen:
Which part of the agent deals with permission? The model or the harness? And how is permission set?
Monty:
Both have a role, but they do different jobs. The model can interpret your instructions. Software must enforce access restrictions.
The calendar service might give the connected account read-only access. The harness might also block changes or require approval. Those controls are set by whoever connects the account or configures the assistant.
Your request can authorise a particular action within those limits. It can’t turn a read-only connection into a writable one.
Stephen:
So the protection level depends on where that permission is set. If you ask the model not to write in a calendar, it may or may not do so. If the harness has rules to prevent calling the tool to update the calendar, it’s safer, but presumably a model may send a request that could bypass that protection, in theory. However, if the tool to write to a calendar is not present in the system, then nothing can possibly write to the calendar. The third option is the strictest and safest.
Monty:
Broadly, yes, but the important question is whether another route to the calendar remains open.
A properly enforced harness rule can reject a write request regardless of how the model phrases it. Sending a different request doesn’t automatically bypass that rule. A bypass would require a gap, such as another tool that can make the same change without passing through the check.
That also qualifies your third option. Removing the dedicated calendar-writing tool isn’t enough if a general-purpose tool can still contact the calendar service using credentials that permit changes.
If the system genuinely has no route capable of writing to the calendar, it can’t write to it. A read-only calendar connection provides a strong boundary because the service itself refuses writes through that connection, even if the model requests one.
We’ll explore permissions and safeguards more fully in a later chapter. For now, the key distinction is that a request can contain all the right details without the system being allowed to carry it out.
Stephen:
Got it.
Monty:
Let’s bring that back to the contents of a request.
Suppose the user has specified a one-hour “Trip to Oxford” event at 9 a.m., UK time, on 24 October, in their work calendar:
{
"name": "create_event",
"arguments": {
"calendar": "work",
"title": "Trip to Oxford",
"date": "2026-10-24",
"start_time": "09:00",
"time_zone": "Europe/London",
"duration_minutes": 30
}
}Suppose the tool accepts all those values and the system has permission to create events. Does this request match what the user asked for?
Stephen:
Not quite since the duration in the request sent to the tool is 30 minutes not one hour as requested by the user. But why would such an error happen?
Monty:
Exactly. The model supplied a valid duration, but not the one requested.
Generating a tool request isn’t guaranteed to be an exact translation. The model might carry over 30 minutes from an earlier example, use a familiar default instead of the stated duration, or simply make a mistake when producing that value. We couldn’t tell which happened from this request alone.
In effect, it has translated “one hour” incorrectly. The tidy structure doesn’t prevent that, just as a neatly completed form can contain the wrong answer.
A check that says “duration must be a positive number” would accept 30. Catching this error requires comparing the requested duration with the user’s instruction, not merely checking whether the tool accepts it.
Stephen:
And presumably a better LLM is less likely to make such a mistake, and more likely to call the correct tool, right?
Monty:
Yes, a model that’s better at tool use should make those mistakes less often. That includes choosing an appropriate tool, following its input requirements, and preserving details such as “one hour”.
But “better” needs to mean better at those particular tasks. A model that writes excellent prose isn’t necessarily better at using tools. Performance also depends on how clearly the tools are described and how much competing information is in the conversation.
You’d compare models on realistic tasks, checking both which tool they choose and the values they supply. A request can run successfully yet still contain the wrong duration.
So model quality matters, but a more capable model reduces the risk. It doesn’t remove the need for appropriate checks.
Stephen:
Understood.
Monty:
Let’s close the article conversation here. How an agent checks its work deserves its own conversation, rather than being squeezed into the end of this one.
What we’ve unpacked in this chapter
Turning words into an action involves interpretation. The model has to choose an available tool and translate what we mean into the inputs that tool expects. A neatly structured request can still contain the wrong place, date, or duration.
The key points:
A tool request is marked as such by the interface. Showing JSON in an ordinary reply doesn’t, by itself, run a tool.
The model brings learned tool-use behaviour to the task. The supplied tool descriptions tell it what is available now. Supplying a new description isn’t retraining.
Everyday phrases may need clarifying before they become precise inputs. The model performs this clarification, asking the user if necessary. Required fields and acceptable values don’t establish that those inputs match the user’s intention.
A weather lookup retrieves information, a calculator works from supplied assumptions, and a calendar-writing tool changes stored information. Those are different jobs.
A request can be precise without being permitted. It can also fail or return too little information to answer the question. Those outcomes call for different responses.
Tool choice and input values both matter. Better tool-use performance can reduce mistakes, but doesn’t remove the need for appropriate checks.
Next, we’ll move from a single request to a sequence of actions and ask whether an agent needs a plan.
<< Previous Post: 2. Who actually does the work, the model or the software?
>> Next Post: Coming soon…



