Recommended Paid
Use each provider's official SDK to call models
Call each model provider through its own official SDK, inside one module of your own. Add a shared abstraction only when you call two or more providers.
Cost
Paid. The SDKs are open source, but each provider charges for every call to its model API. Use one only when no open-weight model passes your evals.
How to do it
A hosted model is a paid service, so pick one only after the open-weight test above fails. Each provider updates its SDK with its API, so new features and fixes land there first. On 21 October 2026 the Python packages openai (Apache-2.0), anthropic (MIT) and google-genai (Apache-2.0) each had a release in the past week. Each had over 36 million weekly PyPI downloads. All three fail the five-year test. openai reached 1.0 in November 2023 and anthropic in August 2026. The TypeScript @anthropic-ai/sdk was still at 0.137. Pin exact versions, because these SDKs change often. A third-party wrapper framework adds a second release cycle between you and the API. LangChain, the most downloaded one, reached 1.0 in October 2025. Keep every call behind one module, as Call models through one module says. Choose something else when you call two or more providers. Then a thin module of your own, or a hosted gateway, maps one request shape onto each official SDK.
Examples
Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.
TypeScript example
import OpenAI from 'openai';
const TIMEOUT_MS = 30_000;
const client = new OpenAI({ timeout: TIMEOUT_MS, maxRetries: 2 });
export async function generate(prompt: string): Promise<string> {
const response = await client.responses.create({ model: process.env.MODEL_NAME!, input: prompt });
return response.output_text;
}
Python example
import os
import anthropic
TIMEOUT_SECONDS = 30.0
MAX_TOKENS = 1024
client = anthropic.Anthropic(timeout=TIMEOUT_SECONDS, max_retries=2)
def generate(prompt: str) -> str:
message = client.messages.create(
model=os.environ["MODEL_NAME"],
max_tokens=MAX_TOKENS,
messages=[{"role": "user", "content": prompt}],
)
return "".join(block.text for block in message.content if block.type == "text")
How to check
A script lists every model package in the dependency files. Each one is the official SDK of a provider the project calls, and only files inside the model module import it.
Related rules
- Call models through one module in AI features
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. Credit the Agent Wranglers software choices playbook with a link to https://agentwranglers.se/playbook/stack/ai-software/official-model-sdk. Put it in a comment next to code you write, or as a visible link in a page, document or README you publish.