Module 3 · Agent Tools, Knowledge, Memory & Research Design · scripted
Self-Dialogue: Tools Made of Prompts
Overview
Designing the outside of tools — names, descriptions, parameters — leaves a question: what's inside? Opening one up reveals a choice. Code is one substrate. But a tool can also be made of a prompt: behind the tool call, the system spawns a small, disposable conversation, asks it for one act of judgment, and returns its answer as the result. The agent's conversation stays clean; a second conversation did the thinking and vanished. The principle: conversations can contain conversations — computational thought, packaged as a word in the language of action.
What is a tool made of?
We've been designing the outside of tools — names, descriptions, parameters. Now open one up. Every tool so far had the same thing inside: code. The agent's conversation with the computer reached classical computation — arithmetic, files, queries, messages.
But we learned early on that prompting changed what counts as computation. An LLM can compute things no classical program could: draft a marketing plan. Judge a summary. Read a receipt. Reason about a mess of evidence. So a tool's implementation now has a choice of substrate:
The two substrates
A tool made of a prompt works exactly like any other tool from the
outside: the agent calls extract_receipt(image), and behind the tool,
the system sends a prompt to an LLM — a fresh, self-contained
exchange — and returns its answer as the tool result. I call this
self-dialogue: the system talking to itself. One precision matters:
it is not the agent's own conversation talking — it is the system
spawning a disposable, separate conversation on the agent's behalf.
It runs, answers, and vanishes.
The same language laws, in the new substrate
Everything we know about designing the action language transfers unchanged — including the specific-to-generic axis:
Two substrates, one design space
| Code substrate | Prompt substrate | |
|---|---|---|
| specific (nouns) | get_customer(id) · refund_order(id) |
extract_receipt(image) · classify_ticket(text) · draft_reply(points, tone) |
| generic (verbs) | run_sql(statement) |
summarize(text, focus) |
| universal (one word) | execute_code(script) |
send_prompt(messages) |
send_prompt is the execute_code of the prompt substrate: a
universal word. The coverage law applies verbatim — if the judgments
your agent will need are unenumerable, you need the universal word; if
you can name them, nouns like extract_receipt are cheaper, safer, and
easier to audit. What the language can't say, the agent can't think.
Why not just do it in the loop?
The agent's own conversation runs on an LLM — couldn't it read the receipts itself? It could. Watch what that costs. The task: forty expense receipts to reconcile.
Two ways to read forty receipts
| In the loop | As a prompt tool |
|---|---|
| Forty images enter the loop's conversation. | extract_receipt(image) runs forty separate, disposable exchanges. |
| The recurrence bills them again on every later iteration — step 6 re-reads all forty receipts to approve one taxi ride. | Each image is paid once, inside its own call — the loop's conversation receives only forty structured rows. |
| The conversation fills; the trajectory drifts through noise. | Loop iterations stay small; the trajectory stays on the actual task: reconciliation. |
You have the following tools available for use:
- extract_receipt( image )
- check_rule( expense )
- report( text )
Task: Reconcile my Molde trip expenses against the department rules.
extract_receipt(image = "receipt_012.jpg"){ vendor: "Hotel Alexandra", date: "2026-08-24", amount: 1890,
currency: "NOK", category: "lodging" }check_rule(expense = "lodging 1890 NOK")Within limit (max 2000 NOK/night).The principle deserves its own line, because it is the first context-isolation mechanism in the course:
The isolation principle
A prompt tool ISOLATES context: the task gets exactly the context it needs, in its own separate conversation — and only what needs to come back comes back. The scratch work stays inside.
The human version: you're in a meeting and need to work something out. You don't reason aloud into the minutes — you step out, use scratch paper, and come back with the answer. The loop's conversation is the meeting minutes. Self-dialogue is the scratch paper.
- What, exactly, is in the loop's conversation after Example 1's first call? What is not in it?
- What would iteration 12 of the naive version be paying for?
- What's the scratch-paper work in your own research workflow — the thing you'd never write into the minutes?
The agent becomes the prompt engineer
Now the universal word — and a twist. Give the agent send_prompt and
it can compose sub-prompts itself. The task: a data sync failed last
night, and the log is 3,000 lines. First, the obvious approach — the
agent reads the log into its own conversation:
You have the following tools available for use:
- read_file( path )
- send_prompt( instructions, file )
Task: Something went wrong with last night's data sync. The log is in sync-log.txt. What happened?
read_file(path = "sync-log.txt")[3,000 lines of log]The sync failed at batch 88 when db-replica-2 reset the connection at 02:14; three retries hit the same error, so the replica — not the data — is the likely culprit. Recommend checking replica health before rerunning.
Same task, same tools — but this time the agent keeps the log out of its own conversation. It writes a sub-prompt and attaches the log by file name; the file is delivered into the disposable conversation, not the agent's own. Watch what it writes:
Same task.
send_prompt(
instructions = "You are reading a data-sync log. Report ONLY:
(1) the first ERROR line and its timestamp,
(2) the last successful sync step before it,
(3) any retry attempts after it. Ignore routine
INFO lines entirely. Three bullet points, verbatim
quotes.",
file = "sync-log.txt"
)• First ERROR 02:14:31 — "connection reset by peer (db-replica-2)"
• Last success 02:14:29 — "batch 88/120 committed"
• Retries: 3 attempts 02:14–02:20, all failed with same errorThe sync failed at batch 88 when db-replica-2 reset the connection at 02:14; three retries hit the same error, so the replica — not the data — is the likely culprit. Recommend checking replica health before rerunning.
Excellent use cases for prompt tools
The ladder
Step back and see where this sits. There is now an axis running through every word in the agent's language — how much mind is inside it?
The ladder
1. Code tool no mind inside.
A calculator answers.
2. Prompt tool one thought inside.
A fresh, disposable exchange: no tools, no loop.
It runs, answers, and vanishes. ← this lesson
3. ? a whole conversation inside —
with its own role, tools, and loop.
(Later. You already know its name.)Rung 2 dramatically expands what an agent's tools can do — every judgment, extraction, and drafting task becomes a callable word — while keeping the loop's conversation clean. Rung 3 is one short step up.
Take the agent you've been designing and find its heaviest operation — the one that would dump the most context into the loop. Redesign it as a prompt tool: write the tool's name and parameters, then write the actual sub-prompt inside it. Decide precisely: what stays inside the call, and what five lines come back?