Now booking Q3 project slots for Singapore SMEs
AI Automation

Why We Don't Default to OpenAI for Every AI Feature We Build

Most AI development tooling assumes you'll use a handful of major providers and stops there. Here's what it actually takes to plug a different model, like a Southeast Asia-trained LLM, into a real product instead.

4 August 2026 · 5 min read

Most AI development frameworks quietly assume you'll be using one of a handful of major providers, and some actively reject anything else with validation errors, even when the alternative model speaks the exact same API format under the hood. Concretely: a framework's default provider often checks the requested model name against an internal list of ones it recognizes, and simply refuses to send the request if the name doesn't match, regardless of whether the endpoint you're pointing at would actually respond correctly. We wanted to know what it actually takes to get past that and plug in a different model on purpose.

The problem: most AI frameworks assume there's only one kind of model worth using

The "best" model for a given business isn't always the most talked-about one. Sometimes it's a regional model trained with more relevant local context, sometimes it's a self-hosted model chosen for cost or data residency reasons, since keeping data within a specific jurisdiction can be a genuine compliance requirement, not just a preference. Sometimes it's simply cheaper per token for the volume a business actually needs, without a meaningful drop in quality for the specific task at hand. Standard AI SDK tooling often doesn't expect that choice and blocks it by default, not out of malice, but because supporting every possible model isn't where a framework's maintainers focus their testing effort.

This isn't a hypothetical concern. A business handling customer data under Singapore's PDPA, or one that's simply promised clients their information stays within a specific region, can find that the most convenient default provider is quietly the wrong choice on compliance grounds alone, independent of how good the model itself is.

Why frameworks default to lock-in in the first place

It's worth being fair to the framework here. Defaulting to a small set of well-tested, heavily used providers is a reasonable trade-off for the majority of developers who just want something that works reliably out of the box, and validating the model name catches a whole category of accidental misconfiguration before it becomes a confusing runtime error. The friction only shows up for the smaller group of people who have a deliberate reason to point somewhere else, and for them, the default protection becomes the obstacle.

What we built

Rather than forcing an alternative model through a framework's default assumptions, we built a small custom configuration layer that explicitly told the framework where to send requests and how to authenticate, bypassing the built-in restrictions entirely. Concretely, that meant configuring a base URL, the authentication headers, and the model identifier by hand instead of letting the framework infer or validate them against its own internal list, using a compatibility layer designed for exactly this purpose rather than fighting the default provider directly.

That layer sat underneath a normal chat interface with streaming responses, meaning text appears token by token as the model generates it, the way most people now expect a chat product to feel, rather than waiting for a full response to arrive all at once. Getting streaming to keep working correctly regardless of which model was actually answering was the part that mattered: the rest of the application, the interface, the conversation history, the UI state, didn't need to know or care which model was behind the response.

The approach generalizes further than just one model. Any model server that speaks the same OpenAI-compatible request and response shape, whether that's a hosted regional model, a self-hosted model running through a serving layer, or a local model running through something like Ollama, can be plugged into the same override, changing only the address and the credentials, not the surrounding application code.

What actually broke while we were testing this

Bypassing the framework's validation removes a safety net along with the restriction, and it's worth being honest that this cuts both ways. Without the framework checking things on your behalf, small mistakes, a slightly wrong header, a mistyped model identifier, an authentication token in the wrong format, surface as confusing errors from the model server instead of a clear, early warning from the framework itself. Most of the actual debugging time on this project went into working through those unclear failures one at a time, not into the override mechanism itself, which was comparatively simple once it was working.

Why this matters for a business choosing AI tools

The same approach works for any model that follows a compatible API shape, which means a business isn't locked into a single AI provider by default. Picture a realistic path: a product gets prototyped quickly against a well-known global provider because it's the fastest way to validate the idea, and later, once it's live, the business wants to move to a regional model for cost reasons, or needs to satisfy a data residency requirement that the original provider can't meet. With this pattern, that's a configuration change, not a rebuild of the application around a new SDK.

That optionality has a real cost implication too. Being able to compare providers on price and performance for your actual workload, instead of being structurally stuck with whichever one you happened to start with, is part of what keeps an AI feature's ongoing running cost in check rather than locked to whatever a single vendor decides to charge. It's the same efficiency-first thinking behind pairing a smaller, traditional machine learning model with an LLM only where language understanding is genuinely the bottleneck: use the tool that actually fits the job and its cost, not whichever one is easiest to reach for by default.

The result

A working chat application answering through a Southeast Asia-trained model instead of a default global provider, with streaming responses working exactly as they would with any major provider, using an approach general enough to apply to any similarly compatible model. That's the actual point: not one specific model, but not being structurally stuck with whichever one happens to be the default.

The broader habit this reflects is one we apply before any AI feature gets built for a client: pick the model based on what the task, the budget, and any data residency requirements actually demand, then build the integration to fit that choice, rather than defaulting to whichever provider happens to have the most name recognition and adjusting the business requirements to match it afterward.