# Agents 201: The Unit Shrank
**作者**: Rohit Ghumare
**日期**: 2026-04-23T19:46:45.000Z
**来源**: [https://x.com/ghumare64/status/2047401813364683007](https://x.com/ghumare64/status/2047401813364683007)
---

Three months ago, I wrote an article that went viral: Agents 201 about orchestrating multiple agents without burning your token budget or turning coordination into chaos.
That's still true. What I missed is that the unit itself was about to change.
## What changed since January
Then, the agent was the atomic unit. Supervisor pattern. Swarm pattern. Hierarchical pattern. Every node in every diagram was "an agent."
r/claude, April 19, 866 upvotes: "Try Haiku 4.5 agents. Just as good as Sonnet if Opus is orchestrating."

- r/ClaudeCode, April 4: 138 sessions. 61.8M tokens. $11.55 per session. 15x the Max plan cost.

Nobody is shipping a better agent. They're shipping parts of one. Tier model allocation. Dependent handoffs. Blackboards. Verifier gates. Observability dashboards.
The agent got disassembled.
## Why monolithic agents are failing
A monolithic agent is a generalist. It plans, retrieves, reasons, writes, verifies, and answers in one context window. All on one model. All billed per token.
Three things break at production.
Token economics. One agent coordinating four sub-agents on the most expensive model turns a 15K-token task into 60K. The $1,593-a-month Claude Code story is what "one smart agent doing everything" actually costs.
Specialization loss. When one model plays router, coder, reviewer, summarizer, and verifier, it's good at none of them. We keep relearning this. It's the ML lesson at a new layer.
Debugging by vibes. When a supervisor holds the plan and four workers write to shared state and something is wrong at the end, you don't debug. You re-run and hope. Exactly the problem tailclaude is trying to fix with a Kubernetes-style dashboard.
## The unit is a worker

A worker does one thing. Clear identity. Defined input. Defined output. One job it gets good at.
A retriever worker retrieves. One model. One prompt. One schema. Benchmarkable. Swappable.
A verifier worker verifies. Runs after other workers. Fails loud. Has a test.
A summarizer worker summarizes. That's it. Boring. Boring is the feature.
An agent is a composition of workers. Not the other way around.
This is the shift. In January I was writing about how to orchestrate agents. The question was wrong. The question is how to compose workers into something that looks like an agent from the outside.
## Three primitives
iii ships three primitives. Worker, Function, Trigger. That's the vocabulary.

A Worker is any process that connects. Rust daemon, TypeScript service, Python script, browser tab, microVM, or an LLM itself. Long-lived WebSocket client on websockets.
A Function is a named unit of work a Worker registers. memory::recall. retrieve::web. verify::code. Called by ID plus a JSON payload.
A Trigger is what causes a Function to run. HTTP. Cron. Queue. State change. Stream event. User-defined.
That's it. No separate mental model for agents, queues, workflows, or observability.
React shipped with four concepts. Unix shipped with three. SQL shipped with three. Every paradigm that compounded over decades did it on a vocabulary small enough to hold in one head.
The smallness is the bet.
The smallest real worker
That's a complete worker. One function. One trigger. Any other worker on the engine can now call retrieve::web. Any HTTP client can POST /retrieve.
## Orchestration patterns are triggers, not architectures
Three months ago I drew supervisor, swarm, and hierarchical as three distinct architectures. They're not. They're patterns that reduce to the same primitives.
Supervisor as workers

Supervisor + specialized sub-agents (retriever, coder, analyst, summarizer) + shared memory bus. In iii the bus is the engine.
Swarm via state triggers
No supervisor. Workers subscribe to shared state. Each reacts to changes others wrote.

Swarm is not an architecture. It's a state trigger. When destination changes, flights react. When flights resolve, hotels react. No central coordinator. No framework.
Hierarchical is supervisor, recursive

Each mid-level is itself a function that triggers leaf functions. Same primitive. Different shape. You're not picking an architecture. You're picking which Functions subscribe to which Triggers.
Narrow-worker decomposition
A domain with multiple concerns is not one worker. It's several.
Memory is the canonical example. Not one memory worker. Five of them:

Each is iii worker add-able. Minimal app installs memory. Research assistant installs four. Same pattern for auth, routing, observability, anything with multiple concerns.
That's the rule. One scope per worker. No cross-scope reads. Split on complexity, not on speculation.
## What you actually build
Start with one worker. One function. Measure it.
Find the bottleneck. Usually specialization or token cost.
Extract one concern. Make it a second worker with its own function.
Wire them with iii.trigger(). The call site doesn't change when the callee moves to another machine, another language, another process.
Now memory::compress is swappable. Benchmarkable. You can downgrade its model independent of the store path. You can install a community version. The call site didn't change.
## The categories that collapse
A partial list of things you stop buying once workers are the unit:

Not because iii has equivalents. Because once work is triggered Functions on Workers, the conditions that made these separate categories are gone.
## Where it gets interesting
A worker can create workers. An agent hits a task outside its current capabilities, installs a sandbox worker from the registry, runs the task, tears it down. The agent extended itself at runtime. No human in the loop for the capability. No fixed tool set prepared in advance.
A browser tab is a worker. Cron on the backend calls a function on your open tab. Long-running workflows pause, invoke a human-in-the-loop function in an admin's browser, wait for the return. One trace across backend, agent, browser.
## Sandbox is a worker
Running untrusted code is the hard part of autonomy. Agent writes code. Agent wants to run it. You don't want it touching your filesystem, your network, your process tree, or your production DB.
Every agent framework today wires this separately. Docker container here. Firecracker there. A custom RPC shim on top. Two different RBAC models. Two different logging paths.
In iii, a sandbox is a worker. Same shape as everything else.

A sandbox worker registers three functions. sandbox::create opens a hardware-isolated microVM. sandbox::exec runs a command in it. sandbox::destroy tears it down. The worker implementation is Firecracker or Docker or Wasm or anything else. The contract is the same.
The agent doesn't know what's under sandbox::create. It could be sandbox-firecracker, sandbox-docker, sandbox-wasm, or a fake one in tests. Swap by iii worker add-ing a different sandbox worker. No agent code changes.
Three things fall out of this shape.
CLI and agent are peers. When you run iii worker add <name>, the CLI calls sandbox::create to install in isolation. When an agent runs generated Python, it calls the same sandbox::create. Same function. Same engine. Same auth path.
RBAC is just a function. An allow::check function (its own worker) sits in front of sandbox::create via a condition trigger. Same gate governs the CLI and the agent. You don't maintain two policy systems.
The spawned microVM is itself a worker. It connects to the engine as an ephemeral peer, runs its task, disconnects. While alive it can register its own functions and be invoked like any other worker. The recursion is the point: a worker that creates workers that register functions that other workers can trigger.
sandbox-docker or sandbox-firecracker can be written in Rust and can be used anytime, anywhere. Swap at will.
Isolation stopped being platform infrastructure. It's a function on the same engine as your queue.
## The quadratic problem

New capability is n+1, not n². Every worker joins by connecting. No consumer services to update. No gateway config. No registry entries. No restarts. The coordination cost of shipping a capability goes to zero.
For a multi-agent system this is the difference between a tree you hand-maintain and a graph that self-assembles.
## Bottom line
Stop building agents. Start building workers.
One worker at a time. Narrow scope. Clear identity. Defined tools. Let the composition emerge from Triggers and Functions.
An agent isn't a thing you build. It's what you call the composition when it's working.
Pick the smallest real task your current agent struggles with. Extract it into a worker. Give it one function. Measure it. Ship.
That's how you move.
Don't forget to check out iii.dev, It's open-source.
https://github.com/iii-hq/iii (⭐️)
Follow @ghumare64 for more lessons on AI Agentic Engineering.

## 相关链接
- [Rohit Ghumare](https://x.com/ghumare64)
- [@ghumare64](https://x.com/ghumare64)
- [10K](https://x.com/ghumare64/status/2047401813364683007/analytics)
- [Agents 201](https://x.com/ghumare64/status/2012136491133145364)
- [relearning this](https://x.com/doppenhe/status/2046997971812884640)
- [tailclaude](https://github.com/rohitg00/tailclaude)
- [iii](https://iii.dev/)
- [iii.dev](https://iii.dev/)
- [https://github.com/iii-hq/iii](https://github.com/iii-hq/iii)
- [@ghumare64](https://x.com/@ghumare64)
- [Upgrade to Premium](https://x.com/i/premium_sign_up)
- [3:46 AM · Apr 24, 2026](https://x.com/ghumare64/status/2047401813364683007)
- [10.5K Views](https://x.com/ghumare64/status/2047401813364683007/analytics)
---
*导出时间: 2026/4/24 22:51:44*