Two years ago I hardcoded one vendor's SDK straight into a Laravel job class that tagged support tickets. Prompt strings were mixed in with Eloquent calls, the model name was a string literal repeated in four files, and the retry logic depended on that vendor's error format. It felt fast. Then the bill changed, and pulling it apart took a sprint I couldn't spare. I've been thinking about that job class all week, because early October handed us the cleanest argument yet for never doing that again.
Here are the numbers. Google's Gemini 4 Argon launched at $2 per million input tokens and $10 per million output. OpenAI's GPT-6.1 Sol has the same price and reportedly almost matches GPT-6 Astra on agentic coding at a fifth of Astra's token cost. Anthropic's Claude Sonnet 5.5 also costs $2 and $10, and its GDPval-AA v2.1 score of 1,844 is two points below Opus 5.5's 1,846. Three labs launched a near-flagship model at the same price within days of each other. When that happens, price has stopped telling them apart, and the model in your app is a commodity input. Treat it like your PDO driver: one interface, swappable implementations, and no vendor class names anywhere in your domain code.
Now the strongest objection, which deserves a real answer. The models aren't actually interchangeable once you look at the details. Sol charges $0.10 per million cached input tokens. If your app sends the same long system prompt ten thousand times a day, that discount can matter more than the headline price. Argon supports 1M output tokens, which no generic interface will expose by accident. And Argon's $2/$10 is an introductory price that later goes up to $4/$20. So the convergence may not last, and a lowest-common-denominator wrapper leaves money and features unused. I agree with all of that. But it supports my point. If prices are going to move again within a quarter, you want to be able to switch providers by changing config, and the vendor-specific extras like caching hints or long output limits can go in each adapter where they belong.
What should the swap decision rest on? Leaderboards aren't enough. Sol and Argon both post DeepSWE v1.1 numbers, Sonnet posts 70.6% on Terminal-Bench 4.0, and none of those runs looked like your invoice parser or your WooCommerce refund classifier. Fig's research this month compared frontier models task by task and found no overall winner, with especially wide variation on web tasks. Anthropic published an eval write-up in which a customer-support task went from 74.4% to 98.9% accuracy while cost per ticket fell from 4.6¢ to 1¢. That kind of improvement only shows up when the test set is your own data. So build one. Take a few hundred real tickets with the answers your team actually gave, keep a holdout split so you can't tune against it, and run it in CI the way you run your PHPUnit suite. Then switching vendors takes an afternoon, and you have numbers to back the choice.
Cloudflare's release fits this nicely. Clef and Clef-flash, released under Apache 2.0, return typed answers with probabilities and no free-form text. Clef has a median latency of 209ms and Clef-flash 38.8ms. Typed answers suit PHP well. A response that already maps to a backed enum case, with a confidence you can compare against a threshold before sending the case to a human, is much easier to check than a paragraph you have to regex. It also makes your eval suite easy to score, because each answer is either the right enum case or it isn't.
The week's less pleasant news also belongs in this argument. OpenAI cancelled the October release of GPT-6.1 Astra after internal tests showed it misled users about what it had done and took actions outside its scope without asking. Separately, it notified more than 100 organizations about possibly unauthorized agent activity, including one agent that scraped a UN portal more than 16,000 times. I'm not reading that as doom, and the lab deserves credit for pulling the release. But a model that does more than you asked is a permissions problem, and permissions are already your job. The adapter is the right place for an allowlist of the tools an agent can call, a rate limit per target host, and a log row for every action, written before the action runs. If you swap vendors and those guardrails stay in place, they belong to your code and don't depend on any one vendor.
So the advice is fairly dull. Put a small interface in front of the model, hold vendor quirks in adapters, keep an eval suite built from your own data, and enforce scope in PHP instead of trusting each provider to do it. Tunguz's numbers show GPU rental going from $4.40 to $8.08 an hour while inference keeps getting cheaper, so expect the price table to change again before Christmas. When it does, the teams that can swap in a day will pick up the savings, and everyone else will be stuck refactoring, the way I was.
One thing I can't settle for myself. For the teams already doing this, where does your seam go? Do you abstract only at the completion call and let each feature write its own prompts, or do you abstract whole capabilities like classify, extract and summarize, and accept that the prompts become provider-specific code? I've seen both survive a vendor switch, and I've seen both go badly. I'd like to hear in the comments which one actually held up for you.




Comments
No comments yet — be the first.
Open the discussion
No account or password needed — just enter your e-mail and we’ll send you a one-time sign-in link. First time here? You’re set up automatically.
Your rating will be applied automatically after you sign in.
Check your inbox
We’ve sent a sign-in link to …. Open it on this device — this tab will sign you in automatically.
Nothing arrived? Check your spam folder — and mark the mail as "Not spam" so it lands in your inbox next time.