Module 3 · Planning, Context & Multi-agent Systems · scripted

Do We Need an Agent at All?

30 minoutcomes: context-engineering, agent-architectures

Agency and intelligence are different quantities

Before the first technique, a distinction that unlocks all of them. The word agent carries its meaning openly: agency — the right to decide, to choose what happens next, to act. When we build an agent, that is what we are granting: decision rights over the path.

But look at what most problems actually need from us: intelligence — reading a messy email, judging a receipt, drafting a reply, weighing a preference. And here is the distinction:

Two different quantities

AGENCY         the right to CHOOSE — what happens next,
               which action, when to stop.

INTELLIGENCE   the capacity to JUDGE — read, interpret,
               classify, weigh, draft.

An agent has both. But they are separable quantities —
and nearly all of the cost, latency, and unpredictability
comes from the first one.

You can deploy intelligence without granting agency.

That separation is the frame for every technique that follows: the question is never "do we need AI here?" — it is "do we need agency here, or only intelligence?"

The first technique is a question

We have the frame: intrinsic load set by formulation, extraneous load defined by lifetimes. And now the distinction above becomes a question to ask before anything else gets built:

The question

An agent is a conversation whose LLM chooses what happens next —
intelligence WITH agency.

So before building one, ask:
does this problem actually require the choosing?

If the path is fixed — if judgment is needed only WITHIN the
steps, never BETWEEN them — then agency is pure overhead:
a deliberator hired to pick from a menu of one.

The insight comes straight off the lifetime chart. Some problems, charted, have a distinctive shape: every bar is one step long — each piece of information is born at one stage and consumed by exactly the next. Nothing lives across the task; nothing competes for a wall; there is no wall to manage:

The staircase chart

stage:1 2 3 4 5
email text██████
proposed times██████
allowed times██████
selected times██████
reply draft██████

No bar spans. No information outlives its handoff. This is the signature of a problem that does not need an agent.

The scheduler, without an agent

Make it concrete. The task: an email arrives proposing a meeting; reply with times that work. Real judgment lives inside this task — reading messy human text, weighing preferences, writing a natural reply. But watch where the judgment is, and isn't:

The pipeline

Five stages, each a tool — three of them tools made of prompts, two of plain code — each consuming exactly the previous stage's output. Look inside two of the prompt stages, because this is where the intelligence lives:

Stage 1 · extract_times — a one-step mind
user

Extract every proposed meeting time from this email as structured ranges: [{date, start, end}]. Interpret relative dates against 2026-09-14 (today). Output only the JSON.

"Hei! Great meeting you at the conference. Could we talk sometime late next week — Thursday or Friday afternoon would be ideal, though Wednesday after 3 could also work in a pinch?"

assistant

[{"date": "2026-09-24", "start": "12:00", "end": "17:00"}, {"date": "2026-09-25", "start": "12:00", "end": "17:00"}, {"date": "2026-09-23", "start": "15:00", "end": "17:00"}]

NoteReal judgment: "late next week" resolved against a date, "afternoon" given hours, "in a pinch" still included. A whole mind applied to one step — a disposable exchange that reads one email and dies. It will never know a calendar exists.
Stage 3 · select_times — judgment with preferences
user

From these allowed times, choose up to two to offer, applying these preferences: mornings never; avoid slicing open afternoon blocks mid-block; Fridays end by 15:00.

Allowed: Sep 23 15:00–16:00 · Sep 24 13:00–17:00 · Sep 25 13:00–14:30

assistant

[{"date": "2026-09-24", "start": "13:00", "end": "14:00"}, {"date": "2026-09-25", "start": "13:00", "end": "14:00"}] Rationale: the Sep 24 slot opens the block at its edge rather than splitting it; Sep 25 ends well before the Friday cutoff; Sep 23 offered nothing better and was dropped.

NoteAgain: genuine judgment — taste, even — inside the step. And again a one-step lifetime: this exchange sees the allowed times and the preferences, nothing else. It has never read the email. It doesn't need to.

Between the prompts, plain code: the calendar intersection is set arithmetic — no mind required — and sending is a send. The whole task completes with no loop, no deliberation, no growing conversation. Nothing ever chose a path, because there was nothing to choose: the path was known before the email arrived.

What the loop would have cost

Now run the same task as an agent — a loop with tools, deciding each step — and put the two side by side:

The same task, two ways

AS AN AGENTAS A PIPELINE
iteration 1: read wall,stage 1: one prompt, one
"what should I do first?"output
→ extract timesstage 2: code
iteration 2: re-read wallstage 3: one prompt
(email + extraction),stage 4: one prompt
"what now?" → check calendarstage 5: code
iteration 3: re-read wall
(all of the above)…total: 3 focused prompts,
…5 deliberations, eacheach seeing ONLY its inputs.
re-reading a growingNo re-reading. No possibility
conversation, each endingof a surprising step order.
in the only possible answer.Same result, every time.

The agent paid 5 rounds of re-orientation tax to make 0 actual choices.

The pipeline is cheaper and faster — but note the third win, because for production systems it often matters most: predictability. The pipeline cannot decide to skip the calendar. It cannot reorder the steps on a strange email. Its failure modes are the failure modes of its stages, not of a navigator — there is no navigator.

The principle

Judgment IN the steps, not BETWEEN them.

When the path is fixed, keep the intelligence and drop the
agent: cast each step as a one-step mind — a prompt with a
typed input and a typed output — and let the outputs hand
forward. Enormous intelligence per step; zero deliberation
between steps. Faster, cheaper, and the same shape every run.

There's a familiar frame for what we just built. The conversation is a play — and this play's script is already fully cast: who speaks at each stage, what they'll be asked, what form their answer takes — all written before the email arrived. The actors still act; each brings real interpretation to their scene. But no one on stage decides what scene comes next. A pipeline is a play with no improvisation about the plot — only within the lines.

When can you cast it this way?

The test, in three parts — and note that the first one is exactly what the lifetime chart shows at a glance:

The pipeline test

ONE-STEP LIFETIMESeach stage needs only the previous stage's output (plus its own fixed brief). The chart is a staircase.
A KNOWN PATHthe stages and their order can be written down in advance. Branches are allowed — IF code can take them: "no times extracted → reply asking for proposals" is an if-statement, not a judgment.
BRIEFABLE STEPSeach stage's job fits a self-contained prompt: role, input, output format. (You have been writing these since the pattern library.)

Fail condition 2 — the next step depends on judging what just happened — and you need a navigator: an agent, exactly there and only there.

That branching clause deserves emphasis: a deterministic branch ("if the list is empty…") keeps you in pipeline country — code chooses, instantly and for free. You cross into agent country only when choosing requires a mind: when what happened must be interpreted before anyone knows what should happen next.

The spectrum

fixed pipelinethe path is a line
pipeline + code branchesthe path is a flowchart — code steers at the forks
agentthe path is discovered — judgment steers at the forks

Reach for the loop LAST. Every step left of it is faster, cheaper, and more predictable — with no ceiling on the intelligence inside each step.

The honest tail

One caveat, and it's one we've met before wearing other clothes. A pipeline handles the cases its designer imagined — and the world ships the 1%. The email that proposes times and asks to reschedule a different meeting. The reply-all with three conflicting proposals from two people. A pipeline meeting the case outside its path doesn't improvise — it does something worse: each stage processes its slice locally-correctly, and the composed result is confidently wrong.

The remedy is not "use an agent everywhere after all." It is the same move as covering the tail with a handoff: give stages a way to say this is outside my brief — and route those cases to the expensive machinery:

The escape hatch

Every stage may return NOT_MY_CASE(reason) instead of output.

The pipeline handles the 99% at pipeline prices.
NOT_MY_CASE routes the 1% to a navigator — an agent, or a
human — with the stage's reason as the brief.

Enumerate the head. Hand off the tail.
The pipeline and the agent are not rivals; they are the
cheap path and the exception path of one design.
The audit
  • In the scheduler, find the judgment closest to breaking condition 2 — the place where a code branch would most tempt you to make it a judgment branch. What email would push it over?
  • Take Stage 3's preferences. At what point does "apply these preferences" become "understand this person's calendar politics" — and which side of the pipeline test does each live on?
Your turn

Take a task from your research workflow you assumed needed an agent. (1) Chart it: are the lifetimes a staircase? (2) If yes, design the pipeline: each stage's name, substrate (prompt or code), input format, output format — write the actual prompt for the two most judgment-heavy stages. (3) Find the 1% case that breaks it, and write the NOT_MY_CASE it should raise. (4) If the chart is NOT a staircase — one bar spans stages — say precisely which decision needs a navigator, and how small the agent around it could be.