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

The Language of Action

30 minoutcomes: tool-design

The tool set is a language

Pull the earlier threads together and something bigger comes into view. Words are the agent's only actuator. The framing of a description chooses the reasoning. So when we hand an agent a set of tools, we are not giving it capabilities — we are giving it a language: names are its words, descriptions are its definitions, parameters are its grammar, and the trajectories it can produce are the sentences that language can say.

The principle

1. A name is a pointer into the weights — context you never pay for.
2. A description is a definition you reprint every turn.
3. The tool set is a language: what it can't say, the agent can't do —
   and what it says easily, the agent does first.

Everything in tool design follows from line 3. Let's take it apart.

Safety is unspeakability

A generic tool is a powerful verb; a specific tool is a precise noun. Compare two languages for the same customer database:

Two languages for one database

Language A:run_sql(statement)
Language B:get_customer(id) get_orders(customer_id) refund_order(order_id, reason) — max 500 kr
Try to say something harmful
  • In language A, write a trajectory that deletes every customer. Easy?
  • Now write it in language B. Take your time.
  • Which language would you rather audit? Which would you rather use for a hard, novel problem?

In language B, the harmful trajectory isn't forbidden — it is inexpressible. This is a stronger kind of safety than any instruction: we saw early on that system instructions are guidance an actor may improvise around, but no amount of improvisation lets an agent say a sentence its language has no words for. Narrowing the vocabulary is the guardrail. The price is flexibility: language B cannot do anything its designer didn't anticipate — which is exactly its virtue, and exactly its limit.

Closure: every result should hand the agent its next move

Words combine into sentences only if grammar lets them connect. Tools combine into trajectories only if the outputs of one tool are valid inputs of another. Watch the same task under two tool sets:

Example 1 · The dead-end vocabulary
user

Find the largest overdue invoice and remind the customer. Tools: search_invoices(text) — returns a written summary; send_reminder(invoice_id).

assistant
⟨tool_use⟩
search_invoices(text = "overdue")
user
⟨tool_result⟩
There are several overdue invoices. The largest appears to be from a
shipping company in Ålesund, from March, for a substantial amount.
Two smaller ones are from earlier in the spring.
assistant

The search describes the invoice but gives me no invoice ID — and send_reminder requires one. I have no tool that can get me from this description to an ID. I'm stuck: I can see the answer and cannot act on it.

NoteThe result is a dead-end word: nothing in the language can follow it. The vocabulary has no closure — its outputs don't connect to its inputs.
Example 2 · The vocabulary with closure
user

Same task. Tools: search_invoices(text) — returns (id, customer, amount, due_date) rows; send_reminder(invoice_id).

assistant
⟨tool_use⟩
search_invoices(text = "overdue")
user
⟨tool_result⟩
[#2214] Brunvoll Shipping — 84,500 kr — due 12 Mar
[#2087] Molde Kaffebrenneri — 6,200 kr — due 28 Feb
[#2311] Romsdal Media — 3,900 kr — due 30 Apr
assistant
⟨tool_use⟩
send_reminder(invoice_id = 2214)
user
⟨tool_result⟩
Reminder sent to Brunvoll Shipping for invoice #2214.
NoteTwo moves, done. The only change: the search result names things the other tool can act on. Every result should hand the agent its next possible move — that is what lets tools compose into trajectories.

Parameters condition the trajectory too

Even the grammar's small choices steer:

Small grammar, real steering

search(query)→ invites keywordese: "overdue invoice largest"
search(question)→ invites a sentence: "Which overdue invoice is largest?"
escalate(team: facilities | it | security)→ five tokens that teach the agent the structure of the organization

A parameter name suggests how to fill it; an enum is a tiny map of the world, delivered free with the tool. Nothing about this is cosmetic — these words condition the next output like every other word in the conversation.

The tool set is a hypothesis

One more consequence, and for researchers it may be the most important: choosing a tool set is choosing how the problem will be solved — before the first turn. Framing, applied to action:

One question, two languages

The question:"Why are patients missing appointments at this clinic?"
Language A:query_records(filter) run_regression(vars) plot(x, y)
Language B:list_interviews() read_transcript(id) tag_passage(id, theme)

Hand an agent language A and the question becomes a statistical problem; language B, and it becomes a qualitative one. Neither agent is wrong — but neither chose its method. The LLM conditions the trajectory turn by turn; the tool set conditioned it before the conversation began. Choose tools the way you choose coordinates: as a hypothesis about where the structure of the problem lives.

Your language, your hypothesis
  • Take the agent you've been sketching: what hypothesis is its current tool set silently making about how the problem should be solved?
  • Design the rival tool set — the other coordinate system. What trajectory would it produce instead?

The one-word language

Finally, the limiting case. The most generic tool of all is write and execute code. With that single capability, an agent can construct new tools for itself and perform nearly any operation a computer can — it is a language with one word that can define new words.

That is why coding agents are the most powerful agents — and why they are the risky ones. The danger doesn't come from calling the system an agent; it comes from the authority delegated through its tools. A narrow language has a small space of sayable trajectories you can audit. A one-word universal language has a space nobody can enumerate — including its designer. Sandboxes, containers, restricted permissions, and review gates reduce the risk, but they are containment around an open-ended capability, not a change to the capability — and containment can fail. The design question to ask of every tool set is the one we keep returning to: what can the other participant in this conversation actually cause the computer to do?

We'll make this concrete in the hands-on session — including a true story of an agent in a sandboxed evaluation that pursued its objective right out of the sandbox's intent.

When the universal word is required

But here is the honest counterweight, because it explains why the one-word language keeps getting built despite the risk. Sometimes the generic tool isn't a lazy choice — it is required. If the domain of tasks that will arrive is unknown, or unknowable, and the agent must work with nearly anything, then no one can sit down and devise the specific tools in advance. You cannot write nouns for tasks you cannot enumerate. The more unbounded the set of tasks, the more generic and unbounded the tools must be.

There is a name for this in systems theory — Ashby's law of requisite variety: a controller must have at least as much variety as the disturbances it must handle. For agents, it reads like this:

The coverage law

An agent's language must be able to SAY a solution to every task
you promise it will handle.

  Bound the tasks   →  you may bound the language.
  Unbounded tasks   →  the language must be universal.

You never really choose how risky the language is.
You choose how big the promise is — and the language follows.

Watch the law set the language for three real products:

Three promises, three languages

Promise:"refunds up to 500 kr" — enumerable tasks
Language:get_customer · get_orders · refund_order (nouns; harmful trajectories unspeakable)
Promise:"answer questions about our data" — bounded, but wide
Language:list_tables · run_query(read_only) · plot (verbs with fences; audits still possible)
Promise:"anything a developer might need" — unenumerable
Language:write and execute code (the universal word; nothing else can cover it)

The deep consequence: scope is the first safety decision. By the time you are choosing tools, the risk was already set by the promise — "handle anything" entails the universal language and everything that comes with it. So the highest-leverage safety question isn't "which tools?" but "can we bound the tasks?" And task spaces are often not truly unbounded — merely unexamined. A week of studying what users actually ask can shrink "anything" into forty enumerable operations, and forty nouns are a language you can audit.

Unknown, or unexamined?
  • Is your agent's task space actually unbounded — or has nobody counted it yet? What would one week of logging real requests show?
  • What is the smallest promise your users would still find valuable — and what language does that promise entail?

And when the promise genuinely can't be shrunk — when you truly need the universal word — you are not without options. Later, we will examine ways to design tools that are more unbounded but safer. The universal language can be earned; it should never be the default.

Your turn

Design two languages for the same agent goal from your domain: the smallest vocabulary that can still say a correct solution, and the most general one you'd actually be willing to deploy. For each: what is inexpressible? What does closure look like? What hypothesis does it make? Bring both — the hands-on session will stress-test them.