Why "One API for All LLMs" Is a Bad Design Decision

"Don't write frameworks for dummies."

That sentence stuck with me while reading Domain-Driven Design: Tackling Complexity in the Heart of Software. I didn't fully understand it at first - but after building (and then redesigning) an AI orchestration framework, I do now.

Where We Started

When we began building a framework for orchestrating AI agents, one of the first features we introduced was a unified request interface across multiple LLM providers.

At first, it felt like a great design decision.

One interface.

Multiple providers.

Clean abstraction.

Simple.

But that simplicity turned out to be misleading.

Why 'One API for All LLMs' Is a Bad Design Decision

The Problem with "Unified" Abstractions

Over time, cracks started to show:

All models looked the same to developers

By flattening everything into a single interface, we erased the differences between models. Developers stopped thinking about capabilities and limitations - which is exactly what they should be thinking about.

Adding new models became harder, not easier

New models come with new capabilities, parameters, and behaviors. A "unified" interface either:

Neither is good design.

The ubiquitous language was wrong

The API didn't reflect the domain. It reflected our attempt to simplify it. That meant the language of the library didn't express real model capabilities.

We enabled misuse by design

The worst part: the abstraction allowed developers to make mistakes easily - and only discover them at runtime.

For example:

passing reasoning_effort="high" to a model that doesn't support reasoning.

The system didn't prevent it. It allowed it.

That's not just a bad developer experience - it's a failure in design. The abstraction wasn't helping developers. It was hiding the truth.

The Redesign

So we changed direction.

Instead of forcing a unified interface, we started modeling each LLM separately, along with its capabilities and constraints.

Metaphor for the Redesign of the Mozaik LLM Orchestration Framework

Why This Is the Right Move

Advanced users can extract more value

Power users are no longer limited by a lowest-common-denominator API.

Models are not the same - and that matters

Treating them as identical leads to misuse. Embracing differences leads to better outcomes.

Invalid configurations are caught early

Instead of runtime surprises, errors are surfaced immediately.

Better developer experience (DX)

Clear APIs, explicit capabilities, fewer hidden assumptions.

Most importantly: the library expresses domain knowledge correctly

The design now reflects reality - not an oversimplified version of it.

Looking Forward

We're not done yet.

We haven't fully committed the redesign - but we've started moving in this direction, and the changes will roll out in the next versions of Mozaik.

The goal is simple:

This is still evolving, and we'll likely learn more (and fix more mistakes) along the way.

But one thing is already clear:

We're no longer trying to hide the complexity of LLMs.

We're designing for it.

Miodrag Vilotijević

Miodrag Vilotijević

Co-founder @ JigJoy

Building the future of software development with AI-driven architecture

"Don't write frameworks for dummies. Team divisions that assume some developers are not smart enough to design are likely to fail because they underestimate the difficulty of application development. If those people are not smart enough to design, they shouldn't be assigned to develop software."