Try this first
Ask Rover something that needs a lot of reading:
“Which file defines the permission check, and what does it do?”
It reads six files. All six are now in your transcript forever, and you wanted one sentence.
The idea
Start a second agent with a fresh transcript, give it one job, and take back only the answer.
CHEAP = connect("ollama:gemma4") # or any cheaper/faster model you have
def sub_agent(task, tools, llm=CHEAP):
"""Run a task in a fresh context. Return only the final text."""
messages = [{"role": "user", "content": task}]
for _ in range(10):
reply = llm.send(messages, tools)
messages.append({"role": "assistant", "content": reply.text,
"tool_calls": reply.tool_calls})
if not reply.wants_tool:
break
results = []
for call in reply.tool_calls:
output, failed = run_tool(call.name, call.arguments)
results.append({"id": call.id, "content": output, "is_error": failed})
messages.append({"role": "tool_results", "results": results})
return reply.text
That is Module 1’s loop, in a function, returning a string.
Then expose it as a tool:
{
"name": "investigate",
"description": (
"Ask a helper to look into a question that needs reading several files, "
"and get back a short answer. "
"Use this for wide searches so the details do not fill up your own context."
),
"input_schema": {
"type": "object",
"properties": {
"question": {"type": "string", "description": "A specific, self-contained question."}
},
"required": ["question"],
},
}
Six files get read. Six file contents land in the sub-agent’s transcript, which is discarded.
One sentence comes back to yours.
Why a cheaper model
Note that sub_agent takes its own llm, and the default is a cheap one.
Searching and reading is mostly input tokens and little hard reasoning. That is exactly the
work to move to a cheaper model — or to a local one, which costs nothing at all. The main
agent keeps the strong model for planning, judgement, and writing code.
This is also why connect() returns an object rather than setting a global. Two agents, two
models, in one program.
This is the practical version of the point in Lesson 7.5: one agent, more than one model,
chosen per job.
When it is worth it
| Good fit | Bad fit |
|---|---|
| Reading many files to answer one question | Anything needing two tool calls |
| Independent work that can run in parallel | Work needing the main conversation’s context |
| Bulk that would otherwise fill your context | A task you could finish directly |
The failure mode is over-use. Every sub-agent costs a round trip and a re-briefing, and it
starts with no context — it does not know what you discussed, what the user prefers, or
what has been tried. Every one of those must be in the question.
That is why the description says “specific, self-contained”. A sub-agent asked “check if that
works” has no idea what “that” is.
The trade
You are trading detail for room. The main agent gets one sentence instead of six files — which
is the point, and also the risk. If the sentence is wrong or incomplete, the main agent has no
way to notice, because the evidence was discarded.
Use sub-agents for gathering, not for judgement. “Which file defines X?” is a good delegation.
“Is this code correct?” is not.
A sub-agent is your loop in a function with a fresh transcript. It buys context room by
throwing away evidence — so delegate gathering, not judgement.
Try this before the next lesson
Add investigate and ask the six-file question both ways.
Compare the transcript sizes and the answers. Then ask a question that needs context from your
conversation, and watch the sub-agent flounder because it was not told. That failure is the
description doing its job badly, and it is fixable.