Managed Agents
Infrastructure at scale — decoupling the brain from the hands, sessions as durable logs, and interfaces that outlast implementations
The Stale Assumption Problem
Every harness encodes assumptions about model limitations. These assumptions become outdated as models improve.
A real example: Claude Sonnet 4.5 exhibited “context anxiety” — the model would prematurely terminate tasks when approaching the context window limit, even when it had sufficient room to continue. Engineers added context reset logic to the harness to work around this. But when Opus 4.5 no longer exhibited the behavior, that code became dead weight. Similarly, sprint decomposition added because models couldn’t maintain long-term coherence became unnecessary with Opus 4.6’s improved long-horizon planning.
Anthropic’s response: build infrastructure with interfaces general enough to outlast any particular harness implementation.
“We expect harnesses to continue evolving. So we built Managed Agents: a hosted service that runs long-horizon agents through a small set of interfaces meant to outlast any particular implementation — including the ones we run today.”
Further analysis: This reveals a structural tension — harness evolution must keep pace with model evolution, but infrastructure evolves far slower than either. Most teams’ instinct is “model improved, update the harness,” but as patches accumulate, the harness itself becomes an unmaintainable stack of assumptions. Anthropic’s choice was not to change the harness faster, but to make the harness disposable — let stable interfaces carry ever-changing implementations.
Design Philosophy: Programs as Yet Unthought Of
The design draws inspiration from operating systems. Early OS designers faced the same problem: how to build infrastructure for programs that don’t exist yet.
Their solution: virtualize hardware into general abstractions — process, file, socket — that outlast any specific
implementation. The read() syscall is agnostic to whether it accesses a 1970s disk pack or a modern SSD.
Managed Agents apply the same principle, virtualizing agent components into three stable abstractions:
| Abstraction | Purpose |
|---|---|
| Session | The append-only log of everything that happened |
| Harness | The loop that calls the model and routes tool calls |
| Sandbox | The execution environment where the agent can run code |
Don’t Adopt a Pet
The first architecture placed everything in a single container — model, harness, sandbox. The design was straightforward: model-generated code that needed to modify a file could issue a direct syscall. No elaborate service boundaries or communication protocols required.
But servers come in two kinds: pets and cattle. A pet server is unique — it has a name, requires manual care, and when it gets sick, you must nurse it back to health because it’s irreplaceable. A cattle server is standardized and interchangeable — if one goes down, you replace it and the system carries on.
Bundling all components into a single container turned every agent session into a pet.
This created cascading problems:
- Crash = total loss — Container fails, session is gone. No recovery, no replay. The WebSocket event stream couldn’t distinguish between a harness bug, a network drop, and a container crash.
- Debug = privacy paradox — Troubleshooting required shell access into containers holding user data. Maintaining the system meant compromising its security.
- Code + credentials colocated — Untrusted model-generated code ran alongside OAuth tokens and API keys.
- Network lock-in — Everything the agent operated on had to live in the same environment. Customers wanting VPC access had to peer with Anthropic’s network.
Further analysis: These four problems aren’t isolated — they share a single root cause: components that should be independent were forced to share a fate. And each “fix” only addressed one symptom: restart logic for crashes, permission isolation for security, network proxies for VPC — more patches, but the underlying coupling remained. A design initially chosen for simplicity had become a massive technical debt blocking business expansion. The real solution wasn’t more patches, but eliminating the premise that made patches necessary.
Decoupling the Brain from the Hands
The solution: separate the brain (model + harness) from the hands (execution environments). Three components split into independently existing, independently failing entities:
- Brain: Claude and its harness loop — thinking, decision-making, and dispatch
- Hands: Sandbox and tools — executing concrete operations
- Session: An append-only event log outside both — recording everything
Each component has a clear interface definition — as long as the right column’s conditions are met, the left column can be implemented with any technology:
| Component | Interface (pseudocode) | Satisfied by |
|---|---|---|
| Session | getSession(id) → (Session, Event[]) | Any append-only log that accepts idempotent appends |
getEvents(id) → PendingEvent[] | ||
emitEvent(id, event) | ||
| Orchestration | wake(session_id) → void | Any scheduler that can call a function by ID and retry on failure |
| Harness | yield Effect<T> → EffectResult<T> | Any loop that yields effects and appends results to the session |
| Sandbox | provision(resources) / execute(name, input) → string | Any executor configurable once and callable many times |
| Resources | [(source_ref, mount_path)] | Any durable store fetchable by reference |
| Tools | (name, description, input_schema) | Any capability describable as a name and an input shape |
The Harness Leaves the Container
The harness no longer lives inside the container — it became a stateless service. It treats each container as a tool with a simple interface:
execute(name, input) → string
Containers become cattle, not pets — interchangeable and disposable. If a container dies, the harness catches the
failure as a normal tool-call error and passes it back to Claude. The model can decide to retry; the system provisions a
fresh container with provision({resources}) and continues. No nursing failed containers back to health.
Session as Durable Log
The session log sits outside the harness. Nothing in the harness needs to survive a crash:
- New harness boots with
wake(sessionId) - Retrieves the event log with
getSession(id) - Resumes from the last recorded event
- All events are durably persisted via
emitEvent(id, event)
Further analysis: All three problems point to the same insight — state is the troublesome part; whoever holds state becomes a pet. The essence of decoupling is not “splitting a big system into small systems” (that’s just the old microservices pitch) — it’s converging state into a dedicated, highly available session log and making everything else stateless. Once you achieve this, crash recovery, security isolation, and deploy flexibility aren’t features you need to “implement” individually — they’re emergent properties of the architecture. They’re just there.
Security Boundary
In the coupled design, prompt injection needed only to convince the model to read environment variables to access tokens.
The structural fix: tokens are never reachable from the sandbox where model-generated code runs. Two patterns implement this:
- Bundled auth: Repository tokens clone repos during sandbox initialization and wire into local git remotes.
git pushandgit pullwork without exposing tokens. The agent never handles tokens directly. - Vault-based auth: MCP tools are called via a dedicated proxy. The proxy takes a session-associated token, fetches credentials from a secure vault, uses them to call the external service, and returns the result to the harness. The harness never sees the actual credentials.
Further analysis: Most security approaches are “policy-based” — narrowing permission scopes, shortening token lifetimes to reduce risk. But these approaches hide a dangerous assumption: the model isn’t smart enough to exploit limited permissions in unexpected ways. The problem is that model intelligence is evolving rapidly; today’s safety assumptions may be trivially broken tomorrow. Anthropic’s approach is structural — not restricting what the model can do, but making secrets physically unreachable. It’s like building the vault and the workshop in separate buildings, rather than adding more locks to the same one.
The Session Is Not Claude’s Context Window
Long-horizon tasks inevitably exceed the model’s context window. The key insight: the session and the context window are two different things.
The session is the complete, durable, queryable record of all events. The context window is just a subset that the
harness selects and assembles from the session before passing it to the model. The harness can query the session
flexibly through the getEvents() interface:
- Resume from where it stopped reading — slice by position to get new events
- Rewind before a specific moment — re-examine the context that led to an event
- Re-read context before a specific action — understand the reasoning behind a decision
The harness can also transform events before passing them to the model — for example, reordering messages to optimize prompt cache hit rates.
This separation enables context engineering at the infrastructure level: the harness chooses what from the session enters the context window, and how it’s organized. Storage and management are fully decoupled — when future models expand their context windows or strategies change, the session interface stays the same.
Further analysis: This design parallels the relationship between RAM and disk in operating systems. The context window is RAM — a temporary workspace where only the subset needed for the current computation is loaded. The session log is disk — the complete, durable record. The harness acts as a memory management unit (MMU), intelligently deciding what to “load” into the context window for each model call.
This produces an important cognitive shift: context compaction is not “losing memory” but “evicting cache.” The full history is always safely stored in the session, available for reload at any time. This is far more sophisticated than approaches that perform irreversible compression within the context window — once the wrong content is discarded, there’s no going back.
Many Brains, Many Hands
Scaling Brains
Once the harness moves out of the container, network peering for VPC access becomes unnecessary. More importantly, the performance improvement is dramatic:
- Previously: every session paid full container setup costs (clone repos, boot processes, fetch events) even if it never used the sandbox
- After decoupling: containers are provisioned only on-demand via tool calls. Inference starts immediately once the orchestration layer pulls pending events from the session log
Results: p50 time-to-first-token dropped ~60%, p95 dropped >90%.
Scaling Hands
Each execution environment becomes a tool with the same execute(name, input) → string interface. The harness is
agnostic about what the sandbox is — container, phone, browser, or anything else:
- No hand is coupled to any brain
- Brains can pass hands to one another
- Multiple hands can serve one brain, or one hand can serve multiple brains
This composability means the same interface supports Claude Code (general-purpose), task-specific harnesses (narrow domain optimization), and custom harnesses (whatever agent combination the task requires).
The Meta-Harness
Managed Agents is not a specific harness. It’s a meta-harness — a system of general interfaces that can accommodate many different harness implementations:
- Opinionated about interfaces: the ability to manipulate state (session) and perform computation (sandbox)
- Unopinionated about implementation: no assumptions about the number or location of brains or hands, or the specific harness Claude needs
- Designed for evolution: as model capabilities change and harness assumptions go stale, the interfaces remain stable
The challenge is timeless: designing systems for programs that don’t exist yet. Operating systems solved it by virtualizing hardware. Managed Agents solves it by virtualizing the agent’s infrastructure — creating interfaces that are general enough for unforeseen harnesses, while being specific enough to be useful today.
Further analysis: Anthropic has built an industrial-grade, reliable runtime to match increasingly powerful models. The value of this runtime may not be fully recognized today. But as agents move from demos to production, people will discover that a robust, scalable, secure infrastructure layer matters far more than a few extra percentage points on a model benchmark. This is the necessary path for AI to go from “clever” to “useful.”
Source
Scaling Managed Agents: Decoupling the Brain from the Hands — Lance Martin, Gabe Cemaj & Michael Cohen, Anthropic, April 2026.