Building AI Agents from Scratch
Multiple Tools and Tool Selection
Give the agent several tools and see how names and descriptions drive which one it picks.
Selection is not a classifier you train. It is the model reading names and descriptions. Bad copy makes it call the wrong function.
Two jobs, two tools
Keep list_dir. Add a fetch that only allows one host:
import json
import urllib.request
ALLOWED = "https://httpbin.org/get"
def http_get() -> dict:
req = urllib.request.Request(
ALLOWED,
headers={"User-Agent": "geek-university-agents/1.0"},
)
with urllib.request.urlopen(req, timeout=10) as resp:
body = resp.read(2000).decode("utf-8", errors="replace")
return {"ok": True, "status": resp.status, "preview": body[:500]}
REGISTRY = {"list_dir": list_dir, "http_get": http_get}The advertised description for http_get should say “GET the lesson echo endpoint. Use when the user asks you to call the demo HTTP API. Do not use this for local files.” Negative instructions matter.
Why the model picks wrong
- Two tools that both say “get data.”
- A catch-all
run_commandsitting next to a precise tool. - Parameters the model must invent (
url) when you should have hard-coded the host.
Check it
- “List the files here” → only
list_dirin the log. - “Hit the demo HTTP endpoint” → only
http_get. - Rename
http_gettofetchwith a vague description and watch the disk question start calling it. Then put the good name back.
Print each call.function.name as you dispatch. That log is how you debug selection. Next: combine the pieces into one practical job.