Until now, the loop often had one tool. Real agents usually offer many.
You still own the loop. The new idea is simple: the model picks which tool to ask for. Your code runs the one it names.
A menu of tools
On each call you send:
- The person’s question
- A list of tools the model may use
Example list:
| Tool | What it does |
|---|---|
read_file |
Reads a file and returns the text |
get_time |
Returns the current time |
The model does not see your code. It only sees each tool’s name, description, and inputs. Then it chooses.
prompt + tool list
│
▼
Server / model
│
│ "use read_file" / "use get_time" / both / neither
▼
Your program runs the named tool(s)Who chooses?
The model chooses. Your loop does not say “always call read_file.”
It waits for the reply, then:
- If there is no tool call → show the final answer
- If there is a tool call → run that tool by name, send the result back, call again
| Person asks… | Model might pick… |
|---|---|
| “What’s in notes.txt?” | read_file |
| “What time is it?” | get_time |
| “What’s in notes.txt, and what time is it?” | both (one after another, or both in one reply) |
Clear names help the pick
Bad descriptions confuse the model.
| Hard to choose | Easy to choose |
|---|---|
do_stuff — “helps with files” |
read_file — “Read a text file by path and return its contents.” |
info — “returns info” |
get_time — “Return the current local time as a short string.” |
Write names and descriptions the way you would explain the tool to a new teammate.
Your code matches the name
When the model asks for a tool, you look at the name and run the matching function:
"read_file" → read the file
"get_time" → get the time
anything else → send back an error (do not crash)
Only list tools you really built. If you advertise send_email but never wrote it, the loop will break when the model picks it.
Two tools in one reply
Sometimes one reply asks for two tools at once.
Then you:
- Run both
- Send both results back
- Call the model again
Do not ignore one tool call. The model expects every result.
Example
Person: “What is in notes.txt, and what time is it?”
First reply might look like:
[
{ "tool": "read_file", "inputs": { "path": "notes.txt" } },
{ "tool": "get_time", "inputs": {} }
]
You run both. You add both results to history. Next call: the model writes the final answer.
Same loop as before — only now the menu has more than one item.
When things go wrong
| Problem | Fix |
|---|---|
| Wrong tool picked | Make descriptions clearer; avoid two tools that sound the same |
| Needed tool never picked | Check it is on the list; make the question clearer |
| Unknown tool name | Return an error result; keep the loop going |
| Too many tools | Offer fewer tools for this job |
Words to keep
| Word | Meaning |
|---|---|
| Tool list | The tools you offer on this call |
| Selection | The model choosing which tool to ask for |
| Dispatcher | Your code that runs the right function for that name |
See it in Code
The Code panel offers read_file and get_time, runs the loop, and prints which tool the model picked. Same idea in Python, Java, Go, and TypeScript.