Refactoring Monolithic Agent Configs Into Composable Units
Breaking monolithic configs into independent, single-responsibility units prevents sprawl.

Monolithic agent configs fail in a predictable order. What starts as one file, one agent, and fast iteration turns into a sprawling document nobody can safely touch, and the fix teams reach for first, usually a "supervisor agent" that routes everything, doesn't solve the problem. It just gives the monolith a new name. The actual fix is decomposition: breaking a config apart the way software engineers already break apart code, into single-responsibility units with explicit interfaces and independent deployment paths.
The early stage is rational. A prototype with one agent, one config, and a short list of tools is the fastest way to get something working, and there's no reason to over-engineer it. But configs grow the way most software does under deadline pressure: a new task gets added, a new tool gets listed, a new block of prompt logic gets pasted in, and the environment variables multiply. The pattern is consistent: what begins as a supervisor and three helper agents becomes ten agents, then twenty, all still living inside the same deployment unit. Each new use case gets grafted onto the existing config instead of being pulled out into something separate, because grafting is faster in the moment and extraction always feels like it can wait. Ellipsis, a cloud runtime for YAML-defined coding agents, treats each config as a discrete, versioned unit from the start rather than letting that boundary erode.
OpenHands V0 is a documented case of where that waiting leads. The project crossed tens of thousands of GitHub stars within 18 months, and its architecture assumed every execution would happen inside a sandbox. That assumption held fine until the project needed to support local execution through a CLI, at which point the sandbox-only design forced special-case handling in the CLI runtime and duplicated local implementations of MCP and tool logic that already existed elsewhere in the codebase. The failure arc is consistent across teams and frameworks: rigid execution assumptions lead to sprawling mutable configuration, which leads to tight coupling between concerns that were never supposed to be coupled, which eventually forces a full redesign because there's no smaller fix left to try.
This isn't a story about one team's bad habits. A prevalence study covering thousands of public GitHub repositories found that 10.1% of tracked agent config paths were exact duplicates across independent repositories, even after accounting for forks, and 75.5% of those duplicate pairs crossed organizational boundaries entirely. That means shared, undeclared components are already propagating across the ecosystem at scale, outside anyone's review process. Config sprawl is a structural property of how monolithic agent configs evolve, not a discipline problem specific to any one engineering culture.
Why a "supervisor agent" consolidation makes the problem worse, not better
The instinct once sprawl becomes unmanageable is to build a supervisor agent: one entry point that routes requests, unifies context, and gives the illusion of order. The goals behind it are legitimate. Consistency, reuse, and central control are all things engineering teams should want.
The failure is structural, not aspirational. All the agents the supervisor routes to still live inside the same deployment unit, so the supervisor doesn't eliminate the monolith, it just wraps a new interface around it. Frameworks like LangGraph and CrewAI make this especially easy to fall into, because wiring agents together into a graph takes very little code. That ease hides the actual infrastructure problem: a deeply nested graph of agents, all running in one tightly coupled environment, where a change to any node risks affecting every other node in ways that are hard to trace.
What changes is the shape of the mess, not its presence. Scattered one-off builds get traded for a single hard-to-test, hard-to-deploy system that's arguably worse, because now the coupling is hidden behind a clean-looking router instead of being visible as a pile of separate scripts. Without explicit interfaces between agents, every new agent added to the graph potentially couples to every other agent already in it, and that dependency count grows rapidly as the system scales. Composable design replaces that quadratic mess with a linear set of well-defined connections.
The diagnostic question that cuts through all of this is simple to ask and uncomfortable to answer honestly: can each agent in the system be deployed and tested on its own, or does it only function because it happens to share a runtime with everything else? If the answer is the latter, consolidation hasn't solved anything.
What decomposition actually means for agent configs
Single responsibility, borrowed directly from software engineering, means each config unit owns one clearly bounded job: retrieval, classification, code execution, or review, not the entire workflow end to end. That sounds obvious stated plainly, yet it's the principle most sprawling configs violate first, because it's always easier to add one more responsibility to an existing agent than to stand up a new one.
Explicit interfaces are what make decomposition actually work rather than just look tidy. Each unit needs a defined answer to two questions: what does it listen for, and what does it emit? Those answers should exist as event contracts the unit adheres to, not as assumptions baked into shared state that only make sense if you already know how the whole system is wired.
Reusable modules follow from there. Tool lists, credential scopes, and guard rules can be written once and composed across multiple agents instead of copy-pasted into every config that needs something similar, which is exactly the kind of duplication the 10,008-repository study caught happening across organizations with no shared review process governing the code they were both running.
Google's Titanium project offers a concrete before-and-after. A monolithic Python script got rebuilt as a SequentialAgent pipeline with five specialized nodes: Company Researcher, Search Planner, Case Study Researcher, Selector, and Email Drafter, each one narrow enough to describe in a sentence. Failures now isolate to a specific node instead of cascading through the whole pipeline, and each node can be tested and improved independently without touching the others. Google's Agent Bake-Off teams, cited in MLflow's 2026 production guide, reported cutting processing time from an hour down to ten minutes after adopting this sub-agent decomposition pattern.
None of this argues for splitting everything regardless of complexity. A simple retrieval task or a basic Q&A bot is usually faster, cheaper, and easier to debug as a single config, and forcing decomposition onto something that small just adds coordination overhead with no payoff. Composable patterns earn their place once coordination, delegation, or reasoning across multiple tools becomes unavoidable, not before.
A concrete pattern for breaking apart a sprawling agent config
The right starting point isn't a full rewrite. Pick one self-contained use case, ideally the sub-task with the cleanest input and output boundary, and untangle that one first.
Step one is an audit. List every tool permission, every environment variable, and every section of prompt logic in the monolith, then sort them by what actually belongs together by responsibility versus what's just sitting next to each other by accident of how the file grew.
Step two comes before any structural change: define event contracts. What does the unit consume, and what does it produce? Write that down as an explicit interface before touching the config's structure, because retrofitting an interface onto code that's already been split tends to just recreate the coupling in a new location.
Step three is extraction into typed, versioned config files. Each unit becomes its own YAML file (or equivalent), checked into the repository, reviewed the same way code gets reviewed, with a declared scope of credentials and tools attached to it rather than inherited from somewhere else.
YAML keeps showing up here for good reason. CrewAI's YAML-based "crews" let roles like Planner, Coder, and Reviewer work together sequentially or hierarchically, a pattern that's already standard practice in coding workflows, legal review, and marketing operations. Guard rules are moving into the same encoding: one documented guard engine built on Claude Code's PreToolUse hook system pattern-matches commands against YAML-structured lessons with typed fields for severity and trigger conditions. Codex applies a related idea with AGENTS.md files that align agent behavior with a repository's own conventions. Different tools, same underlying principle: version-controlled configuration instead of logic buried inline.
Step four scopes credentials per unit. Each config gets exactly the permissions its one responsibility requires, and nothing more, with no ambient credentials inherited from a shared runtime that happens to have broader access than the task calls for.
Step five adds retries, timeouts, and graceful failure handling at the unit level, because an extracted config needs to behave like a real service from day one, not like a fragment of a script that only worked because it was embedded in something larger.
The migration works incrementally by design. One extracted unit running cleanly in production is the proof of concept, and the rest of the monolith follows the same five steps at whatever pace the team can sustain.
Version control and review as the governance layer for composable configs
A single massive config file resists meaningful review. Changes to one section can have effects on another section that no reviewer, however careful, is likely to catch just by reading a diff, because the file's structure doesn't correspond to any actual boundary in the system's behavior.
Composable units fix this by making the diff legible. A change to one agent's tool list or prompt scope can be reviewed on its own terms, without the reviewer needing to hold the entire system in their head first.
The stakes here aren't hypothetical. That same 10,008-repository study found 75.5% of duplicate config pairs crossing organizational boundaries, meaning undeclared components are propagating between companies that have no formal relationship and no shared review process governing the code they're both running.
Version-controlled YAML config is the structural answer: agents-as-code, put through the same pull request, approval, and audit trail that any other infrastructure change goes through. Each config unit should carry, at minimum, its declared tool permissions, its credential scope, a budget cap, and the specific trigger or event that activates it, all readable by an engineer who had nothing to do with writing it.
Composition also allows differentiated governance in a way consolidation never can. A config with production database access can carry a stricter review requirement than a config that only does read-only search, without needing one blanket policy to cover both. A 2026 KPMG survey of large-enterprise leaders found that 75% cite security, compliance, and auditability as the most critical requirements for deploying agents in production. Version-controlled, composable configs are the structural mechanism that actually satisfies that requirement, rather than a policy document asserting that it's satisfied.
Isolating each unit's execution to contain blast radius
Decomposing a config on paper doesn't guarantee decomposed execution. If every agent still runs inside one shared runtime, with one shared credential set and one shared execution context, the system is a monolith again in every way that matters, regardless of how clean the YAML files look sitting in the repository.
Sandboxed execution per unit closes that gap. Each agent config should map to its own isolated execution environment, with credentials minted specifically for that session and revoked the moment it ends, so no unit can reach into resources its config never declared.
OpenHands V1 illustrates the shift in practice. It moved away from mandatory shared sandboxing toward opt-in isolation across four decoupled packages, and production deployment data shows V1 substantially reducing system-attributable failures compared to V0's architecture.
The security consequences of skipping this step are documented, not speculative. Documented attacks on agentic CI/CD pipelines have shown how a single compromised entry point, with no input sanitization or execution isolation in place, can propagate through shared infrastructure and reach publishing credentials. Every link in that chain depended on the agent having shell access without input sanitization or execution isolation standing in the way.
Scoped credentials are the structural control that breaks a chain like that before it starts. A unit that can only reach the tools its own config declares cannot be redirected into touching tools it was never given a reason to know about. IBM's 2026 Institute for Business Value study found 94% of enterprises report that AI sprawl is raising both security risk and operational complexity, and isolated execution per composable unit is the direct architectural response to that finding, not a general best practice offered on faith.
Budget caps belong at the unit level too, not just as a global organization-wide dashboard someone checks after the fact. A spend ceiling attached to each config fires before the session ends, which is the only point at which it can actually prevent overspend rather than just report it.
Testing composable units independently before wiring them together
End-to-end tests of a monolithic config test everything at once or effectively nothing, because a failure anywhere in the run stops the whole thing and implicates every component equally, whether or not it had anything to do with the actual bug.
Independent testability changes what's possible. Each unit can be evaluated against a fixed input and output contract on its own, so a regression test on the Search Planner never has to run the Email Drafter to get a meaningful result.
MLflow's 2026 production guide describes embedding evaluation probes directly inside workflows, rather than relying solely on offline batch analysis, as the path to real-time auditability. That approach only becomes tractable once a workflow is decomposed into units with defined boundaries; a monolith has no seams to put a probe at.
Metrics can attach to a single unit instead of getting smeared across an entire agent run. Latency, token cost, and error rate become attributable to the specific config that produced them, not folded into one aggregate number that tells a team something went wrong without saying where.
This is also what makes upgrading a system tractable over time. Multi-agent architectures let individual sub-agents get replaced or upgraded as models improve, so swapping one unit's model configuration doesn't require touching the rest of the pipeline at all. That's the practical payoff of decomposition, not an abstract architectural preference: less has to change to make a meaningful improvement.
At the interface level, tests should confirm two things. Does the unit emit the event schema it promised, and does it handle its documented failure modes without falling over? Those tests travel with the config in the repository, so they run every time the config changes, not just when someone remembers to check.
When something breaks in production, isolated execution turns "the agent did something" into a specific config version, a specific tool call, and a specific token window that a team can actually investigate.
Observability across a composable pipeline requires deliberate design
Composability solves the testing and governance problems, but it introduces a new one. A monolith produces one log. A pipeline of five composable units produces five, and correlating them into a coherent picture of what happened requires deliberate design, not something that falls out for free once the units exist.
Real observability in a composable system means every tool call, every diff, and every token is attributable to a specific config unit, a specific trigger, and a specific session, traceable back through the pipeline rather than lost in an aggregate.
Google's Titanium rebuild added OpenTelemetry instrumentation as part of the same effort that split the monolithic script into five nodes. Individual sub-agents now carry distinct performance metrics, and a failure is isolable to a specific node instead of the entire pipeline reading as one undifferentiated black box.
The scale of the gap this closes is worth sitting with. Mean monitoring coverage across deployed agents runs at roughly half, which means, put plainly, that something close to half of all AI agents running in production today are unsecured and unobserved. Composable units with per-unit logging are the structural path to actually closing that gap, not a monitoring dashboard bolted on after the architecture is already set.
Trace correlation needs to be part of the interface design from the start. Each unit should emit a shared session or pipeline ID alongside its own logs, so a distributed trace across the whole pipeline can be reconstructed after the fact. That's a decision that belongs in the event contract defined during step two of the decomposition, not something patched in once the pipeline is already running.
Audit requirements are catching up to this reality in regulation, not just in engineering practice. The EU AI Act's Articles 12, 19, and 72 create explicit traceability and post-market monitoring duties for high-risk AI systems. Per-unit logs attributable to a specific person or trigger satisfy that kind of requirement in a way a single monolithic run log simply cannot, because the monolithic log was never designed to answer "who triggered this and what did it touch."
Observability also closes the loop on improvement. Per-unit metrics show which component is degrading, which is running over budget, and which is producing malformed output, and that's the information a team actually needs to make the next round of changes.
Running composable agent configs on managed infrastructure rather than assembling it yourself
Well-structured YAML configs still need somewhere to run, and that's where a lot of the efficiency gained from decomposition can quietly disappear. Building sandboxes, rotating credentials, enforcing budgets, and generating audit logs from scratch is its own substantial engineering project, one that competes directly with the time saved by refactoring the configs in the first place.
Managed infrastructure needs to supply a short list of things for composable configs to actually work as designed. Per-session isolated sandboxes, not one shared VM serving every agent in the pipeline. Credentials minted per session and revoked automatically on completion, not ambient secrets sitting in a shared environment indefinitely. Budget caps enforceable at the unit, developer, and time-period level, firing before a session ends rather than showing up as a surprise on a monthly invoice. A complete log of every tool call and every diff, attributable to the exact config version and trigger that produced it.
Gartner projects that 40% of enterprise applications will feature task-specific AI agents by 2026, up from under 5% in 2025. Teams building toward that shift need governed execution environments to run in, not just cleaner config files sitting in a repository with nowhere disciplined to run.
Independently testable units, running in isolated sandboxes, with observability built in at the unit level, is what separates a governed agentic engineering workflow from a prototype someone is quietly hoping doesn't break in front of a customer. Neither half is optional. The config refactoring gives a team something worth deploying, and the infrastructure underneath is what makes deploying it safe.
Sources
- The OpenHands Software Agent SDK: A Composable and Extensible Foundation for Production Agents
- Building Production-Ready AI Agents in 2026 | MLflow
- Google: Refactoring a Monolithic AI Sales Agent for Production Reliability - ZenML LLMOps Database
- Production-Ready AI Agents: 5 Lessons from Refactoring a Monolith- Google Developers Blog
- The Supervisor Pattern: Stop Writing Monolithic Agents and Start Orchestrating Teams
- Understanding Enterprise AI Agents: The 2026 Guide to Deployment, Governance, and Scale
- Best practices for Mastering AI Agents, Subagents, Skills & MCP
- arxiv.org


