Module 2 · Tools, Knowledge, Memory & Research Design · scripted

Discovering Tools: The Catalog, Not the Toolbox

25 minoutcomes: tool-design, knowledge-systems

Search doesn't have to happen to the agent

One small step first, to set up a bigger one. RAG, as we built it, acts on the agent from outside: the librarian stacks the desk before the model speaks. But we already know the other posture — everything can be a tool. So hand the search itself over:

Example 1 · The stacks, as a tool
user

Does the harbor allow night deliveries during the herring season? Tools: search_knowledge(query, top), read_piece(id).

assistant
⟨tool_use⟩
search_knowledge(query = "deliveries outside working hours during
herring season", top = 3)
user
⟨tool_result⟩
1. §142 night deliveries — permitted at Quay 3… 2. §142a herring
season exception — quiet period extends to all quays… 3. §8
definitions.
assistant
⟨tool_use⟩
read_piece(id = "142a")
assistant

No — during herring season (weeks 45–2) the quiet period extends to all quays, so night deliveries are suspended. Outside those weeks, Quay 3 allows them.

NoteSame embeddings, same store — but the agent chose the query, saw the neighbors, and followed up. The bet became a purchase: search by meaning is now a rung the agent climbs when it decides to, refining as it learns. Keep this move in mind, because we're about to point it at something more surprising than documents.

The toolbox we carry everywhere

Now the setup for the real lesson. Every agent so far received its language the same way: a fixed list of tools, stated up front — and we know, from the economics, exactly what that list costs. Every name, every description, every parameter spec is part of the preamble, reprinted on every single iteration, needed or not:

The price of a large vocabulary

An agent that can "handle the lab":
74 tools × ~60 words of description each ≈ 4,400 words
…riding on EVERY iteration of EVERY conversation.
The calibration tools bill the budgeting conversations.
The plotting tools bill the scheduling conversations.
On a 30-iteration task, the agent paid for ~130,000
words of tool descriptions — and called 6 tools.

And the pressure this creates is perverse: every new capability makes EVERY conversation more expensive — so we resist adding tools, or we make each tool broader and vaguer to keep the list short.

Read that last line again, because it names a dilemma we've been carrying since the case studies: specific tools are better — easier to reason about, safer, harder to misuse — but specific means many, and many means a preamble nobody can afford. The fixed list forces a choice between a good language and an affordable one.

The catalog

Here is the move that dissolves the dilemma, and you already own every part of it. A tool has a name and a description — text. Text has an address in meaning-space. So: embed the catalog of tools, and give the agent two words instead of seventy-four:

The discovery pair

search_tools(need)     "describe what you want to do" —
                       returns the tools nearest in meaning,
                       with their descriptions

use(tool, args)        call a tool you've discovered

At registry time: each tool's name + description is embedded.
At task time: the agent's stated NEED is embedded, and the
nearest tools come back — exactly RAG, pointed at the language
itself.
Example 2 · Discovering the vocabulary on demand
user

The drone survey data from the fjord came in — convert it to the municipality's coordinate system and package it for their portal. Tools: search_tools(need), use(tool, args).

assistant
⟨tool_use⟩
search_tools(need = "convert geospatial data between coordinate
reference systems")
user
⟨tool_result⟩
3 matches:
· reproject_raster(file, from_crs, to_crs) — converts raster
  geodata between coordinate reference systems (EPSG codes)
· transform_points(file, from_crs, to_crs) — reprojects vector
  point data
· validate_crs(file) — reports the CRS a file actually uses
assistant
⟨tool_use⟩
use(tool = "validate_crs", args = { file = "survey.tif" })
user
⟨tool_result⟩
EPSG:4326 (WGS 84).
assistant
⟨tool_use⟩
search_tools(need = "package geodata for a government portal
upload, Norwegian municipality")
user
⟨tool_result⟩
2 matches: · geonorge_package(files, metadata) — bundles geodata
to Geonorge portal standards · zip_files(files) — generic archive.
assistant
⟨tool_use⟩
use(tool = "reproject_raster", args = { file = "survey.tif",
from_crs = "EPSG:4326", to_crs = "EPSG:25832" })
NoteThe agent's preamble held two tool descriptions. Behind search_tools sits a registry of hundreds — highly specific tools like geonorge_package, exactly the kind we'd never afford in a fixed list — and the agent pulled the four it needed by describing its need. Notice it even discovered a tool it didn't know to want: validate_crs surfaced as a neighbor, and checking the CRS first is the correct first move.

And watch what happened to the wall: the discovered descriptions enter the conversation only after discovery — paid from the moment of need onward, not from turn zero. The vocabulary arrives the way the JIT lessons taught: connection unlocked tools, errors delivered chapters — and now search finds words. Same principle, third trigger.

What discovery buys

The fixed list vs. the catalog

FIXED LISTCATALOG + SEARCH
every tool billed everytwo tools billed always;
iteration, used or notthe rest billed from discovery onward
adding a tool raises theadding a tool costs nothing
price of every conversationuntil some task needs it
pressure toward FEW, BROAD,freedom to build MANY,
VAGUE toolsSPECIFIC, precise tools
the language is what fitsthe language is what the
on the wallregistry holds

That last row is the deep one. Recall the coverage law: the promise sets the language, and a big promise seemed to force either a huge preamble or the universal word. The catalog opens a third path — a large language of small words: hundreds of specific, auditable, hard-to-misuse tools, none of them paid for until needed. The agent stops being limited by what fits on the wall:

The dictionary principle

A speaker's vocabulary is not what they hold in mind —
it is what they can look up.

Don't carry the toolbox. Carry the catalog.
The language is as large as the registry, and the wall
only ever holds the words in use.

One design consequence turns out to matter more than ever: the search sees only names and descriptions — they are now the tool's address, not just its label. A vague description files the tool in the wrong neighborhood, and it will simply never be found: the lying name, upgraded to a lost tool. Everything the language lessons taught about naming now decides discoverability too.

The registry audit
  • In Example 2, what would happen if geonorge_package were described only as "packages files"? Where would it live in the space — and what generic tool would the agent wrongly use instead?
  • Your agent's dream registry: name five highly specific tools you'd build if adding a tool were free. What stopped you before?

Searching everything

Step back and see how wide this pattern just became. Knowledge, searchable by meaning. Tools, searchable by meaning. And from the memory lesson — the journal comes back the same way. In fact anything the system has ever produced can be embedded and addressed:

Example 3 · The agent searches its own past
user

Make a figure like that calibration-drift one you did for me a while back, but for the Q3 data. Tools: search_artifacts( query), search_memory(query), read_artifact(id), plotting tools via search_tools(need).

assistant
⟨tool_use⟩
search_artifacts(query = "calibration drift figure, sensors over
time")
user
⟨tool_result⟩
1. fig-2211 "Sensor calibration drift, Q2" (plot spec + caption,
conversation of 2026-05-14) · 2. fig-1877 "Drift table"…
assistant
⟨tool_use⟩
search_memory(query = "user preferences for figures and reports")
user
⟨tool_result⟩
"Reports: max one page, findings first." · "Figures: colorblind-
safe palette; the user presents on projectors — thick lines."
assistant
⟨tool_use⟩
read_artifact(id = "fig-2211")
assistant

Recreating the Q2 drift figure's design for Q3: same axes and layout, colorblind-safe palette, thick lines. [proceeds]

Note"That figure you did a while back" — a reference into a conversation that no longer exists anywhere but the archive. The agent resolved it by meaning, pulled the artifact's spec, and even recovered the standing preferences. Amnesia hasn't gone away; it has stopped mattering.

The addressable world

knowledge   what the world wrote        → searchable
tools       what the agent can DO       → searchable
memories    what the agent learned      → searchable
artifacts   what the agent has MADE     → searchable

One space, one mechanism. The agent's whole world becomes
addressable by meaning — and the wall carries only what the
current step is using.

This is the completion of a long arc: the wall has edges, and we have spent lesson after lesson deciding what deserves to be inside them. The answer has now fully inverted from where we began. Almost nothing lives on the wall. Everything lives in spaces the agent can search — and the craft is in the addresses.

Your turn

Design the registry for an agent in your domain that you previously would have given 10 broad tools. (1) Explode it: 40+ specific tools, each with a one-line description written to be found — test each by writing the need-query that should retrieve it. (2) Find the collision: two tools whose descriptions land too close, and rewrite them apart. (3) Trace one full task through search_tools/use: what does the wall hold at each step, and what would the fixed-list version have paid by the same point?