{"slug": "aisuite-andrew-ng-s-unified-chat-completions-and-agents-api-for-python", "title": "aisuite: Andrew Ng's Unified Chat Completions and Agents API for Python", "summary": "Andrew Ng's aisuite, a MIT-licensed Python library with 15,876 GitHub stars, provides a unified OpenAI-style Chat Completions API across OpenAI, Anthropic, Google, Ollama, and other providers, plus an Agents API with tools, toolkits, and native MCP support. The library, updated as recently as July 25, 2026, also serves as the engine behind the OpenWorker desktop app, which has moved to its own repository. aisuite standardizes the interface for multiple LLM providers, requiring users to supply their own API keys.", "body_md": "# aisuite: Andrew Ng's Unified Chat Completions and Agents API for Python\n\naisuite is Andrew Ng's MIT-licensed Python library for building with LLMs, giving you one OpenAI-style Chat Completions API across OpenAI, Anthropic, Google, Ollama, and more, plus a first-class Agents API with tools, toolkits, policies, and native MCP support — and the engine behind the OpenWorker desktop app.\n\n- ⭐ 15876\n- Python\n- MIT\n- Updated 2026-08-02\n\n[LiteLLM — Unified OpenAI-Compatible API for 100+ LLM Providers](https://dibi8.com/resources/llm-frameworks/litellm/) •\n[LLM Gateway: Portkey vs LiteLLM vs OpenRouter](https://dibi8.com/resources/llm-frameworks/llm-gateway-portkey-litellm-openrouter-comparison-2026/)\n\n## What Is aisuite? [#](#what-is-aisuite)\n\n**aisuite** is a lightweight, MIT-licensed Python library from Andrew Ng’s team for building with LLMs, structured in two layers: a unified **Chat Completions API** across providers, and an **Agents API** with tools, toolkits, and MCP support on top of it. It’s also the engine behind **OpenWorker**, a separate desktop AI-coworker app now developed in [its own repository](https://github.com/andrewyng/openworker) — the aisuite README still carries a snapshot of OpenWorker’s old in-repo source under `platform/`\n\n, but active OpenWorker development has moved out.\n\n🔗 **GitHub**: [https://github.com/andrewyng/aisuite](https://github.com/andrewyng/aisuite)\n📦 **PyPI**: [https://pypi.org/project/aisuite](https://pypi.org/project/aisuite/)\n\nAt **15,800+ GitHub stars**, MIT licensed, with a commit as recent as **July 25, 2026**, and carrying Andrew Ng’s name (Coursera/deeplearning.ai co-founder, one of the most recognized figures in applied ML education), it’s a credible, actively maintained entry in an increasingly crowded “one API for every LLM provider” category.\n\nThe project’s own architecture diagram, reproduced from the README:\n\n```\n┌───────────────────────────────────────────────┐\n│          OpenWorker  (separate repo)          │   agent harness for doing everyday tasks\n├───────────────────────────────────────────────┤\n│        Agents API  ·  Toolkits  ·  MCP        │   build agents across multiple LLMs\n├───────────────────────────────────────────────┤\n│             Chat Completions API              │   one API across multiple LLM providers\n├────────┬───────────┬────────┬────────┬────────┤\n│ OpenAI │ Anthropic │ Google │ Ollama │ Others │\n└────────┴───────────┴────────┴────────┴────────┘\n```\n\n## Installation [#](#installation)\n\n```\npip install aisuite               # base package, no provider SDKs\npip install 'aisuite[anthropic]'  # with a specific provider's SDK\npip install 'aisuite[all]'        # with all provider SDKs\n```\n\nYou’ll still need your own API keys for whichever providers you call — aisuite doesn’t proxy billing or provide free access, it just standardizes the interface.\n\n## Chat Completions: One API Across Providers [#](#chat-completions-one-api-across-providers)\n\nThe Chat Completions layer is a high-level abstraction over model calls — it supports the common parameters (`temperature`\n\n, `max_tokens`\n\n, `tools`\n\n, etc.) in a provider-agnostic way and normalizes request/response shapes so provider-specific SDK differences don’t leak into your application code.\n\nModels are addressed as `<provider>:<model-name>`\n\n, and aisuite routes each call to the right provider with the right parameters:\n\n``` python\nimport aisuite as ai\nclient = ai.Client()\n\nmodels = [\"openai:gpt-4o\", \"anthropic:claude-3-5-sonnet-20240620\"]\n\nmessages = [\n    {\"role\": \"system\", \"content\": \"Respond in Pirate English.\"},\n    {\"role\": \"user\", \"content\": \"Tell me a joke.\"},\n]\n\nfor model in models:\n    response = client.chat.completions.create(\n        model=model,\n        messages=messages,\n        temperature=0.75\n    )\n    print(response.choices[0].message.content)\n```\n\n### Streaming [#](#streaming)\n\n```\nfor chunk in client.chat.completions.create(model=model, messages=messages, stream=True):\n    print(chunk.choices[0].delta.content or \"\", end=\"\", flush=True)\n```\n\nStreaming works across OpenAI, Anthropic, Ollama, and OpenAI-compatible endpoints, with an async variant (`await client.chat.completions.acreate(...)`\n\n, iterated with `async for`\n\n). Tool calls stream too, as incremental `delta.tool_calls`\n\nfragments — but note that streamed tool calling is manual only; it can’t be combined with the automatic `max_turns`\n\nloop described below.\n\n## Agents API: Tools, Toolkits, and Policies [#](#agents-api-tools-toolkits-and-policies)\n\naisuite turns tool calling into passing plain Python functions — it generates the schema, executes the call, and feeds the result back to the model for you.\n\n### Automatic tool-call loop with `max_turns`\n\n[#](#automatic-tool-call-loop-with-max_turns)\n\n``` python\ndef will_it_rain(location: str, time_of_day: str):\n    \"\"\"Check if it will rain in a location at a given time today.\n\n    Args:\n        location (str): Name of the city\n        time_of_day (str): Time of the day in HH:MM format.\n    \"\"\"\n    return \"YES\"\n\nclient = ai.Client()\nresponse = client.chat.completions.create(\n    model=\"openai:gpt-4o\",\n    messages=[{\n        \"role\": \"user\",\n        \"content\": \"I live in San Francisco. Can you check for weather \"\n                   \"and plan an outdoor picnic for me at 2pm?\"\n    }],\n    tools=[will_it_rain],\n    max_turns=2  # Maximum number of back-and-forth tool calls\n)\nprint(response.choices[0].message.content)\n```\n\nWith `max_turns`\n\nset, aisuite sends the message, executes any tool calls the model requests, feeds results back, and repeats until the conversation completes — `response.choices[0].intermediate_messages`\n\ncarries the full tool-interaction history. Omit `max_turns`\n\nfor full manual control: aisuite then just returns the model’s tool-call requests and you drive the loop yourself.\n\n### The structured Agents API [#](#the-structured-agents-api)\n\nFor longer-running, multi-step work, aisuite has a first-class `Agent`\n\n/ `Runner`\n\nAPI with prebuilt **toolkits**:\n\n``` python\nimport aisuite as ai\nfrom aisuite import Agent, Runner\n\nagent = Agent(\n    name=\"repo-helper\",\n    model=\"anthropic:claude-sonnet-4-6\",\n    instructions=\"You are a careful repo assistant. Use your tools to answer from the code.\",\n    tools=[*ai.toolkits.files(root=\".\"), *ai.toolkits.git(root=\".\")],\n)\n\nresult = Runner.run(agent, \"What changed in the last commit? Summarize in 3 bullets.\")\nprint(result.final_output)\n```\n\nThis layer is where aisuite reaches beyond a pure API-routing library toward a production agent harness:\n\n**Tool policies**—`RequireApprovalPolicy`\n\n, allow/deny lists, or a custom callable deciding which tool calls are permitted to run**State stores**— persist and resume agent runs in memory, a file, or Postgres, continuing conversations across separate process runs** Artifacts & tracing**— capture what an agent produced and the steps it took to get there\n\n### MCP tools, natively [#](#mcp-tools-natively)\n\n```\nclient = ai.Client()\nresponse = client.chat.completions.create(\n    model=\"openai:gpt-4o\",\n    messages=[{\"role\": \"user\", \"content\": \"List the files in the current directory\"}],\n    tools=[{\n        \"type\": \"mcp\",\n        \"name\": \"filesystem\",\n        \"command\": \"npx\",\n        \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/path/to/directory\"]\n    }],\n    max_turns=3\n)\nprint(response.choices[0].message.content)\n```\n\nInstalled via `pip install 'aisuite[mcp]'`\n\n, MCP servers’ tools can be handed to any model with no manual schema wiring. For reusable connections, security filters, and tool-name prefixing across multiple MCP servers, aisuite exposes an explicit `MCPClient`\n\n.\n\n## Extending aisuite: Adding a Provider [#](#extending-aisuite-adding-a-provider)\n\nNew providers plug in through a lightweight adapter with a fixed naming convention for automatic discovery:\n\n| Element | Convention |\n|---|---|\n| Module file | `<provider>_provider.py` |\n| Class name | `<Provider>Provider` (capitalized) |\n\n```\n# providers/openai_provider.py\nclass OpenaiProvider(BaseProvider):\n    ...\n```\n\n## aisuite vs. LiteLLM vs. a Direct SDK [#](#aisuite-vs-litellm-vs-a-direct-sdk)\n\n| Aspect | aisuite | LiteLLM | Direct provider SDK |\n|---|---|---|---|\nUnified chat API | Yes | Yes | No — one SDK per provider |\nStructured Agents API (Runner, toolkits, policies) | Yes | No (routing-focused) | No |\nNative MCP tool support | Yes | Partial (proxy-dependent) | No |\nState stores for resumable agents | Yes (memory/file/Postgres) | No | No |\nPowers a shipped desktop app | Yes (OpenWorker) | No | N/A |\nLicense | MIT | MIT | Varies by provider |\nMaintainer profile | Andrew Ng’s team | BerriAI | Provider itself |\n\nThe practical distinction: if you only need “call whichever LLM with one interface,” aisuite and LiteLLM solve the same problem in roughly the same shape. If you need an actual agent — tools, multi-turn execution, approval policies, resumable state — aisuite has that as a first-class layer rather than something you’d bolt on yourself.\n\n## Use Cases [#](#use-cases)\n\n### 1. Provider-Agnostic Application Code [#](#1-provider-agnostic-application-code)\n\nWrite your chat logic once against `client.chat.completions.create(...)`\n\nand swap `model=\"openai:gpt-4o\"`\n\nfor `model=\"anthropic:claude-sonnet-4-6\"`\n\nwithout touching call sites — useful for A/B testing models or avoiding vendor lock-in.\n\n### 2. Tool-Using Agents With Governance [#](#2-tool-using-agents-with-governance)\n\nThe `RequireApprovalPolicy`\n\nand allow/deny-list tool policies matter once an agent has access to real tools (git, shell, files) — this is the layer that lets you grant capability without granting unchecked autonomy.\n\n### 3. Resumable, Long-Running Agent Tasks [#](#3-resumable-long-running-agent-tasks)\n\nPostgres-backed state stores mean an agent run can persist across process restarts — relevant for anything that shouldn’t lose progress if the host process dies mid-task.\n\n### 4. Bridging Existing MCP Servers Into Any Model [#](#4-bridging-existing-mcp-servers-into-any-model)\n\nIf you already run MCP servers (filesystem, custom internal tools), the native `tools=[{\"type\": \"mcp\", ...}]`\n\nsupport means you don’t need a separate adapter layer to expose them to whichever LLM you’re calling that day.\n\n## Related Repositories [#](#related-repositories)\n\n| Repository | Purpose |\n|---|---|\n|\n\n[Model Context Protocol](https://modelcontextprotocol.io/docs/getting-started/intro)## Related Articles [#](#related-articles)\n\n[LiteLLM — Unified OpenAI-Compatible API for 100+ LLM Providers](https://dibi8.com/resources/llm-frameworks/litellm/)— the closest direct comparison for the Chat Completions layer alone[LLM Gateway: Portkey vs LiteLLM vs OpenRouter](https://dibi8.com/resources/llm-frameworks/llm-gateway-portkey-litellm-openrouter-comparison-2026/)— for weighing aisuite against the broader gateway/proxy category\n\n## Conclusion [#](#conclusion)\n\n**aisuite** covers familiar ground with its Chat Completions layer — provider abstraction is a crowded category — but backs it with a genuinely structured Agents API: tool policies, resumable state stores, and native MCP support, rather than routing alone. Built by Andrew Ng’s team, MIT licensed, actively committed to as of late July 2026, and validated by powering a real shipped product (OpenWorker), it’s a reasonable default if you want the provider-swapping convenience of a LiteLLM-style library but expect to grow into actual tool-using agents rather than staying at single-turn chat completions.\n\n**Best for**: Python developers who want one interface across LLM providers today, with a credible growth path into governed, resumable agents without switching libraries later.\n\n**GitHub**: [https://github.com/andrewyng/aisuite](https://github.com/andrewyng/aisuite)\n\n*Last updated: 2026-08-02*", "url": "https://wpnews.pro/news/aisuite-andrew-ng-s-unified-chat-completions-and-agents-api-for-python", "canonical_source": "https://dibi8.com/resources/llm-frameworks/aisuite-unified-llm-agents-api-2026/", "published_at": "2026-08-02 12:30:00+00:00", "updated_at": "2026-08-02 13:35:36.171788+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-agents", "developer-tools", "ai-infrastructure"], "entities": ["Andrew Ng", "aisuite", "OpenAI", "Anthropic", "Google", "Ollama", "OpenWorker", "deeplearning.ai"], "alternates": {"html": "https://wpnews.pro/news/aisuite-andrew-ng-s-unified-chat-completions-and-agents-api-for-python", "markdown": "https://wpnews.pro/news/aisuite-andrew-ng-s-unified-chat-completions-and-agents-api-for-python.md", "text": "https://wpnews.pro/news/aisuite-andrew-ng-s-unified-chat-completions-and-agents-api-for-python.txt", "jsonld": "https://wpnews.pro/news/aisuite-andrew-ng-s-unified-chat-completions-and-agents-api-for-python.jsonld"}}