Model or dataset
mozilla-ai/any-llm avatar
mozilla-ai/any-llm

any-llm: One Python Completion Call Across Mistral, OpenAI, Anthropic and Ollama

Communicate with an LLM provider using a single interface

2,195 stars224 forksPythonApache-2.0

At a glance

What is it?
Mozilla AI's any-llm wraps official provider SDKs behind a single completion function and an AnyLLM class, using provider extras and provider:model strings. It is a thin adapter, not a router, and its value depends on whether you need stateless scripting or a reused client.
Who is it for?
Adopt any-llm if you want one completion call shape across OpenAI, Anthropic, Mistral, Ollama and other supported providers without running a proxy, and if you are willing to install per-provider extras. Do not adopt it expecting routing, retries, budget enforcement or fallback logic: the README points to the separate otari gateway for budget management, API key management, usage analytics and multi-tenant support.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The provider lock-in problem any-llm addresses

The README states the goal plainly: communicate with any LLM provider using a single, unified interface, and switch between OpenAI, Anthropic, Azure / Microsoft Foundry, Mistral, Ollama and others without changing your code. The intended audience is Python developers who write against more than one provider, or who expect to. If your code calls one provider and will only ever call that provider, this package adds a dependency layer for no benefit. The pitch is strongest for teams that prototype on one hosted model, move to another for cost or capability reasons, and want that move to be a string change rather than a rewrite of client construction, request shaping and response parsing. The README also notes that any-llm powers any-agent, Mozilla AI's own tooling, which is the project's own claim about production use rather than an independent measurement. A second audience is LiteLLM users. The README includes a migration note stating that API keys and environment variables carry over unchanged, and shows the import changing from litellm to any_llm with model strings moving from openai/gpt-4o to openai:gpt-4o.

Two entry points: completion and AnyLLM.create

The package exposes two ways to make a call, and the README is explicit that they differ in connection handling. The direct function, imported as from any_llm import completion, creates a new client per call and is described as stateless, recommended for scripts, notebooks and single requests. The class path, AnyLLM.create("mistral", api_key="your-mistral-api-key"), reuses the client and is described as supporting connection pooling, recommended for production applications that make multiple requests. Both approaches, according to the README, support identical features: streaming, tools and the Responses API. That symmetry matters because it means you can start with the function and move to the class without changing capability, only lifecycle. The Responses API is exposed separately through responses and aresponses for providers that implement the OpenAI-style shape, and the README's example passes input_data as a list of role and content blocks and reads result.output_text from the returned object. Note that the README describes that return as an OpenAI-compatible Responses object alias, which is a compatibility claim about the surface, not a guarantee that every provider-backed call behaves identically at the edges.

Provider extras and how the model string is parsed

Installation is per provider. The README gives pip install 'any-llm-sdk[openai]' for one provider, pip install 'any-llm-sdk[mistral,ollama]' for several, and pip install 'any-llm-sdk[all]' for everything. The distribution name on PyPI is any-llm-sdk while the import name is any_llm, a mismatch worth noting when you write requirements files or lockfiles. Model selection accepts two forms. The recommended form separates the arguments: provider="mistral" with model="mistral-small-latest". The alternative combines them as model="mistral:mistral-small-latest", which the README documents as provider_id colon model_id. Both are shown in the same quickstart, so pick one convention and apply it consistently, because mixing them across a codebase is the kind of thing that produces confusing errors when a model name itself contains a colon. Credentials come from environment variables by default (MISTRAL_API_KEY, OPENAI_API_KEY and equivalents), or can be passed directly, as the AnyLLM.create example does with api_key. The README also notes that an OpenAI-compatible gateway or local server not on the provider list does not need a dedicated entry, and points to a Custom OpenAI-compatible Endpoints section of the docs for that case.

Where the thin adapter stops helping

The design choice that makes any-llm small is that it wraps official provider SDKs rather than reimplementing HTTP calls. The README lists this as a benefit, since it means compatibility tracks whatever the vendor ships. The consequence is that the lowest common denominator is whatever the providers share, and anything provider-specific has to be reached some other way. The README does not document an escape hatch for passing through arbitrary provider-specific parameters, so if you need a feature that only one vendor offers, verify before adopting that it is expressible through the unified call. A second limitation is scope. The README directs readers to the separate otari gateway for budget management, API key management, usage analytics and multi-tenant support. That is a clear boundary: any-llm is a client-side adapter, not a control plane. If your requirement is spend caps per team, centralized key rotation, or per-tenant accounting, this package alone does not provide it, and the README says so by pointing elsewhere. Finally, the project requires Python 3.11 or newer, which rules it out for codebases pinned to older interpreters.

any-llm against LiteLLM and against a direct SDK

The README frames LiteLLM as the closest comparable, and the migration note is the most concrete comparison in the material: environment variables carry over, the import changes, and model strings move from a slash separator to a colon separator. That tells you the two projects occupy similar ground, with any-llm positioning itself as the thinner option that delegates to official SDKs. The practical difference to check is feature coverage per provider, since a thinner adapter will expose fewer provider-specific knobs. The other alternative is no abstraction at all: import the vendor SDK you actually use and call it directly. That gives you every parameter, every new feature on release day, and one fewer dependency to track, at the cost of rewriting call sites when you change vendors. The honest split is that the direct SDK wins when you have one provider and want its full surface, LiteLLM or any-llm win when you have several, and between those two the deciding question is whether you need the gateway-style features that any-llm deliberately leaves to otari.

Release cadence, licence and upgrade cost

The repository shows a fast release rhythm: 1.27.1 on 2026-09-04, 1.27.0 on 2026-09-03, and 1.26.0 on 2026-08-17, with the last push to main on 2026-09-09. Frequent minor releases on a pre-2.0 version number mean the project is still moving, and pinning a version in your lockfile is the reasonable default rather than tracking the latest. The licence is Apache-2.0, a permissive licence that permits commercial use and modification and includes a patent grant. That is a summary of the identifier, not legal advice; if you redistribute the package or ship it inside a product, read the licence text and your own compliance requirements. Upgrade cost is hard to estimate from the material alone. The README does not include a changelog or deprecation policy, so the way to judge risk is to read the release notes for the versions between the one you pin and the one you are moving to. The dependency surface is also worth a look before you adopt: the [all] extra pulls in every supported provider SDK, so installing it to save a decision means carrying the transitive dependencies of vendors you may never call.

What to verify before you commit

Three checks are worth doing first. Confirm that every provider you depend on is listed on the supported providers page, since the README names OpenAI, Anthropic, Azure / Microsoft Foundry, Mistral and Ollama but does not enumerate the full set. Confirm that your existing model strings map to the provider colon model format, because the migration example demonstrates exactly one case, openai/gpt-4o to openai:gpt-4o, and a string that does not map cleanly will fail at call time rather than at import time. And confirm your Python version, since 3.11 is the floor. If you use an OpenAI-compatible endpoint that is not on the provider list, the README says you do not need a dedicated provider entry and points to the Custom OpenAI-compatible Endpoints documentation, which is the section to read before writing your own wrapper. None of these checks requires installing the package; they are all answerable from the docs and the repository.

Editorial conclusion

Adopt any-llm if you want one completion call shape across OpenAI, Anthropic, Mistral, Ollama and other supported providers without running a proxy, and if you are willing to install per-provider extras. Do not adopt it expecting routing, retries, budget enforcement or fallback logic: the README points to the separate otari gateway for budget management, API key management, usage analytics and multi-tenant support. Before committing, verify that every provider you need appears on the supported providers page, confirm the model string format for each one (the README shows both provider="mistral" with model="mistral-small-latest" and the combined "mistral:mistral-small-latest"), and check whether your existing LiteLLM model strings map cleanly, since the migration example only demonstrates openai/gpt-4o becoming openai:gpt-4o.

Official sources

  1. License: Apache-2.0
  2. mozilla-ai/any-llm on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes