The Language Doesn't Matter Anymore. The Patterns Do.
The language you write in matters less than it used to. LLMs can produce working code in Python, Go, TypeScript, Rust, or C# with roughly equal competence. If you’re directing an agent to build something and your primary concern is which language it writes in, you’re optimizing the wrong variable.
What actually matters is whether you understand design patterns and when to apply them.
Design patterns are language-agnostic solutions to recurring problems. They’ve been documented since the Gang of Four published their catalog in 1994. The categories haven’t changed: creational, structural, behavioral, and architectural. What has changed is how visible the skill gap becomes when you’re working with agents.
When you’re writing code yourself, you can iterate your way to a better structure. When you’re directing an agent, you can’t. You need to know upfront what structure you want before you ask for it. If you don’t know that a Factory Method decouples object creation from the calling code, you’ll describe what you want in vague terms and get vague results. If you know the pattern by name and intent, you can say exactly what you want.
Creational patterns
The creational patterns are about controlling how objects come into existence. Singleton is the one most people know, but it’s also the one most people reach for incorrectly. A singleton works when you genuinely need one shared instance across a system, like a database connection pool. It breaks down when you use it as a convenient global variable. The Builder pattern is more commonly useful in agentic systems because you’re often constructing complex request objects or configuration structures step by step, and separating the construction logic from the representation matters when the shape of that output varies.
Structural patterns
Structural patterns are about how you connect pieces. Adapter and Facade show up constantly in agentic work because you’re integrating things: an LLM API, a tool registry, an external service. An Adapter wraps an incompatible interface so the rest of your system doesn’t have to care about it. A Facade simplifies a complex subsystem behind a single clean entry point. Both reduce the surface area your agent logic needs to reason about, which matters because agent-facing interfaces should be as narrow and clear as possible.
The Decorator pattern fits this same principle. It lets you add behavior to an object without modifying its structure. In agentic systems, this maps to adding observability, rate limiting, or retry logic around a tool call without touching the tool itself.
Behavioral patterns
Behavioral patterns are where the real complexity lives. The Observer pattern underlies most event-driven agent architectures. When one component changes state, dependent components need to know. If you’re building a multi-agent system where agents coordinate, Observer is usually how you structure that coordination. The Strategy pattern lets you swap algorithms at runtime, which is useful when you want an agent to choose between different approaches depending on context. Chain of Responsibility maps cleanly to agent routing logic, where a request passes through a sequence of handlers until one claims it.
The Command pattern deserves specific attention for agentic work. Encapsulating a request as an object means you can queue it, log it, and undo it. For agents taking actions in the real world, audit trails are not optional. Command gives you that for free.
Architectural patterns
At the architectural level, event-driven architecture and CQRS are the two most relevant patterns for serious agentic systems. Event-driven architectures let agents communicate without tight coupling. CQRS separates reads from writes, which matters when your agents are reading state frequently and writing it less often, or when the read and write load profiles differ significantly. The Circuit Breaker pattern is essential if your agents are calling external APIs that can fail. Without it, a degraded downstream service cascades into your whole system. Microservices reinforces the same principle: loose coupling and independent deployability. If your agents are tightly coupled to each other, you can’t update one without risking the others.
Knowing when to use them
The skill that separates engineers right now isn’t knowing these patterns exist. You can look them up in ten minutes. It’s knowing when to use them and when not to. Applying a pattern where the problem doesn’t warrant it adds complexity without benefit. Reaching for a Singleton because it’s familiar when you actually need a service locator is a concrete mistake with real costs. Recognizing which pattern fits a given problem requires enough exposure that the matching happens quickly, not after deliberation.
LLMs compress the feedback loop on syntax. The feedback loop on design judgment hasn’t changed. You still have to build systems, make the wrong structural call, and understand afterward why the structure failed.