aisuite: one Python interface for multiple LLM providers, plus an Agents API
Simple, unified interface to multiple Generative AI providers
At a glance
- What is it?
- aisuite wraps OpenAI, Anthropic, Google, Mistral, Ollama and others behind one Chat Completions API, then layers tool calling and an Agents API on top. It suits Python teams that swap providers often and can live with manual streaming tool loops.
- Who is it for?
- Adopt aisuite if you are writing Python and want provider names to be a string you change rather than a rewrite. Skip it if your work is Node or TypeScript, or if you need a managed agent runtime with hosted state.
- Can I use it commercially?
- Yes. MIT 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 last received commits 11 days ago.
- 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 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What aisuite is for, and who should reach for it
Every provider SDK has its own request shape, its own response object, and its own idea of how a tool call is represented. If you are prototyping across models, that difference turns into glue code you maintain forever. aisuite is a lightweight Python library that removes that layer, in two parts: a unified Chat Completions API across providers, and an Agents API with tools and toolkits on top. The README describes it as a uniform access layer for LLMs, and the pyproject description says the same thing in five words.
The intended user is a Python developer who already knows which model to call and does not want the SDK to dictate the call site. The README lists OpenAI, Anthropic, Google, Mistral, Hugging Face, AWS, Cohere, Ollama and OpenRouter among the supported providers, with the promise that you swap providers by changing one string. That is the whole pitch, and it is a narrow one. This is not an orchestration framework, not a prompt manager, and not a hosted service. It is a thin translation layer plus an optional agent loop.
The project also powers OpenWorker, a desktop AI coworker, but that application now lives in its own repository at andrewyng/openworker, and the README states that a historical snapshot of its source remains in openworker-archive/. If you arrived looking for the desktop app, the README points you to the OpenWorker releases page instead.
How provider routing works: the provider:model string
The mechanism is a naming convention. Model names use the format provider:model-name, and aisuite routes the call to the right provider with the right parameters. There is no registry you configure and no adapter you register. The prefix before the colon selects the provider implementation, the rest is handed to the underlying SDK.
The client is created once and reused across models. The README example builds a list of two model strings and loops over it with the same messages and the same temperature, which is the clearest demonstration of what the abstraction buys you: the loop body does not branch on provider.
import aisuite as ai
client = ai.Client()
models = ["openai:gpt-4o", "anthropic:claude-3-5-sonnet-20240620"]
messages = [
{"role": "system", "content": "Respond in Pirate English."},
{"role": "user", "content": "Tell me a joke."},
]
for model in models:
response = client.chat.completions.create(
model=model, messages=messages, temperature=0.75
)
print(response.choices[0].message.content)The response object is OpenAI-shaped, so `response.choices[0].message.content` works regardless of which provider answered. Core parameters such as temperature, max_tokens and tools are passed in a provider-agnostic way. Where a provider does not support a parameter, the translation layer is the place that has to decide what happens, and the README does not document that behaviour, so treat unsupported-parameter handling as something to check per provider rather than assume.
Installing aisuite and making a first call
Installation is a pip install with extras. The base package ships without provider SDKs, so you either name the provider you want or pull everything. The README gives three forms.
pip install aisuite # base package, no provider SDKs
pip install 'aisuite[anthropic]' # with a specific provider's SDK
pip install 'aisuite[all]' # with all provider SDKsThe extras are declared in pyproject.toml, and they are not all one-to-one with provider names. There is an `anthropic` extra, but also `aws`, `cerebras`, `cohere`, `deepgram`, `deepseek`, `gemini`, `google` and `groq`, among others. Note that `azure` is declared with an empty list, so installing `aisuite[azure]` pulls no SDK. Python is pinned to ^3.10.
Keys come from the environment. The repository ships a .env.sample listing the variable names, including OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, MISTRAL_API_KEY, HF_TOKEN, OPENROUTER_API_KEY and the AWS trio of AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION. Google Cloud uses GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_REGION and GOOGLE_PROJECT_ID instead of a single key.
cp .env.sample .env
# fill in the keys for the providers you actually callThe README points to docs/chat-completions-quickstart.md for key setup and first calls. Once a key is set, the smallest working call is the client plus one create, and the value you should see printed is the assistant's text under response.choices[0].message.content.
Tool calling, max_turns, and the streaming restriction
The Agents layer is where aisuite stops being a translation shim. You pass plain Python functions as tools, and aisuite generates the schemas from the function signature and docstring, executes the calls, and feeds results back to the model. The docstring format matters: the README example uses a Google-style Args block with types in parentheses.
def will_it_rain(location: str, time_of_day: str):
"""Check if it will rain in a location at a given time today.
Args:
location (str): Name of the city
time_of_day (str): Time of the day in HH:MM format.
"""
return "YES"
response = client.chat.completions.create(
model="openai:gpt-4o",
messages=[{"role": "user", "content": "..."}],
tools=[will_it_rain],
max_turns=2
)Setting max_turns turns the call into a loop: aisuite sends the message, runs whatever tools the model asks for, returns the results, and repeats until the conversation completes. The full interaction history is available on response.choices[0].intermediate_messages if you want to continue the thread. Omit max_turns and you get manual mode instead: aisuite returns the model's tool-call requests as OpenAI-format JSON specs and you run the loop yourself. The README points to examples/tool_calling_abstraction.ipynb for both styles.
The constraint worth reading twice is streaming. Pass stream=True and you get an iterator of OpenAI-shaped chunks, and the async form is await client.chat.completions.acreate(..., stream=True) iterated with async for. Tool calls do stream, but as incremental delta.tool_calls fragments that you assemble and execute yourself. The README states plainly that streaming is manual tool calling and cannot be combined with max_turns. So the convenience loop and the streaming path are mutually exclusive, and choosing streaming means owning the assembly logic.
Where aisuite is the wrong tool
The abstraction is only as wide as the intersection of provider capabilities. Parameters that exist on one provider and not another have to be dropped, ignored or emulated, and the README does not document which. If your application depends on a provider-specific feature such as a particular caching mode, a reasoning control, or a response format that only one vendor offers, you will end up reaching past the abstraction, and at that point the uniform interface is overhead rather than help.
The second limit is language. The package is Python, pinned to ^3.10. There is an aisuite-js/ directory at the top level of the repository, but the README does not document a JavaScript client, so it is not something to plan an adoption around. If your stack is TypeScript, this is not the library for you.
The third is the agent runtime itself. max_turns is a bounded back-and-forth counter, not a durable execution engine. There is no documented checkpointing, resumption or crash recovery for an in-flight agent loop, and intermediate_messages is returned to you rather than persisted. Long-running work that must survive a process restart needs state you build yourself. The README also does not document rollback behaviour for tool execution, so a tool that writes to disk or sends a message has no undo provided by the library.
aisuite compared with LangChain
The honest comparison is with LangChain, because both sit between your code and multiple model providers. The difference is in what each one owns. LangChain is a framework: chains, retrievers, memory abstractions, vector store integrations, and a large surface of its own concepts to learn. aisuite deliberately has almost no concepts. You get a client, a create call, and optionally tools and a turn limit. The README's framing is that you focus on logic rather than SDK differences, and that framing is the design constraint, not a marketing line.
That makes aisuite easier to read end to end and easier to remove. If you decide the abstraction is not worth it, you replace the client call with the provider SDK directly and the rest of your code is unchanged, because aisuite did not ask you to structure your application around it. The trade is that anything LangChain gives you as a built-in, such as document loaders or a retrieval pipeline, you write yourself here. The repository does include examples such as examples/QnA_with_pdf.ipynb, so patterns exist, but they are examples rather than framework components.
The Agents API narrows the gap somewhat. Toolkits for files, git and shell are described in the README, and MCP servers can be attached, with examples including examples/mcp_config_dict_example.py and examples/mcp_http_example.py. Tool policies are mentioned as a governance mechanism. Those are real agent-building primitives, and they are the part of the library most likely to grow.
Licence, maintenance and the cost of upgrading
aisuite is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is permissive and imposes no copyleft obligation on your application. Nothing here is legal advice; check the LICENSE file in the repository for the exact terms before you rely on it.
The repository is not archived, and the last push was on 2026-09-18, three days before this article's reference point, so the project is being worked on. The most recent release listed is v0.1.3 (OpenWorker 0.1.3) from 2026-07-20, while pyproject.toml declares version 0.2.0, so the package version and the release tags do not line up cleanly. That is worth knowing before you pin a version, because a pin to a release tag may not match what the main branch installs.
Upgrade cost is dominated by provider SDKs rather than aisuite itself. The optional dependencies carry version ranges, for example anthropic >=0.40.0,<1.0.0, openai ^1.107.0, cohere ^5.12.0 and google-genai ^2.10.0. Installing aisuite[all] resolves all of them at once, which means one provider's breaking major release can force a resolution change across your environment. Installing per-provider extras keeps that blast radius small, and is the reason to prefer aisuite[anthropic] over aisuite[all] in a pinned production image.
Editorial conclusion
Adopt aisuite if you are writing Python and want provider names to be a string you change rather than a rewrite. Skip it if your work is Node or TypeScript, or if you need a managed agent runtime with hosted state. Before committing, verify that your chosen provider appears in the pyproject extras, that the model names you plan to use follow the provider:model format, and that streaming tool calls fit your loop, because the README states streaming cannot be combined with max_turns.
Frequently asked questions
How do I install aisuite?
Install it with pip, choosing the extras for the providers you call: pip install aisuite for the base package, pip install 'aisuite[anthropic]' for one provider's SDK, or pip install 'aisuite[all]' for every provider SDK. You also need API keys for the providers you use, and the README points to docs/chat-completions-quickstart.md for key setup.
How do I use aisuite for a first call?
Create a client with ai.Client(), then call client.chat.completions.create with a model string in the provider:model-name format, a messages list, and parameters such as temperature. The response is OpenAI-shaped, so the assistant text is at response.choices[0].message.content regardless of which provider answered.
How does aisuite compare with LangChain?
aisuite is a thin layer: a unified Chat Completions API plus an Agents API with tools and toolkits, and almost no framework concepts of its own. LangChain is a broader framework with chains, retrievers and integrations, so anything LangChain provides as a built-in you would write yourself on top of aisuite.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/andrewyng-aisuite)