How to Configure API Keys for Multiple LLM Providers in aisuite

aisuite resolves API keys through a cascading priority system: explicit arguments first, then environment variables, then SecretStore entries, allowing seamless multi-provider workflows without hardcoded secrets.

The aisuite library from the andrewyng/aisuite repository provides a unified interface for interacting with diverse large language model (LLM) providers. To configure API keys for multiple LLM providers in aisuite, you leverage a hierarchical resolution system that prioritizes security and flexibility. Each provider implements a resolver function that searches for credentials in three distinct layers before making API calls.

Understanding the API Key Resolution Hierarchy

Every provider in aisuite follows a standardized credential lookup pattern implemented in resolver functions. The resolution order is:

  1. Explicit argument passed directly to the provider configuration (api_key="sk-...")
  2. Environment variable specific to each provider (e.g., OPENAI_API_KEY, ANTHROPIC_API_KEY)
  3. SecretStore entry under the provider:<name> profile, typically managed through the Settings UI

This design ensures that sensitive credentials never need to be hardcoded in source files while supporting dynamic configuration across development and production environments.

Provider-Specific Configuration Sources

OpenAI Provider Configuration

In platform/coworker/providers/openai_provider.py, the resolve_api_key function (lines 23-38) first checks for an explicitly passed API key, then falls back to the OPENAI_API_KEY environment variable, and finally queries the SecretStore for provider:openai according to the andrewyng/aisuite source code.

Anthropic Provider Configuration

The Anthropic resolver in platform/coworker/providers/anthropic_provider.py (lines 62-75) searches for ANTHROPIC_API_KEY in the environment before checking secrets.get("provider:anthropic") as implemented in andrewyng/aisuite.

Gemini Provider Configuration

For Google's Gemini, platform/coworker/providers/gemini_provider.py (lines 81-92) implements a dual environment variable check: it prefers GEMINI_API_KEY but accepts GOOGLE_API_KEY as a fallback before resorting to the SecretStore entry provider:gemini.

Initializing the Client with Multiple Providers

The Client class in aisuite/client.py manages provider configurations through the provider_configs parameter. When you instantiate the client with Client(provider_configs={...}) or call client.configure(...), aisuite stores these configurations and lazily initializes provider instances via Client._resolve_provider (lines 52-74 and 99-104).

Each provider entry in the configuration dictionary supports an api_key field. When set to None, aisuite triggers the resolver chain to locate credentials automatically from environment variables or the SecretStore.

Practical Multi-Provider Setup

Create a .env file in your project root using the variables defined in .env.sample (which lists all supported variables for OpenAI, Anthropic, Gemini, Azure, AWS, and others), then load it automatically via python-dotenv:

import aisuite as ai

# Create a client capable of routing to multiple providers

client = ai.Client(
    provider_configs={
        "openai": {"api_key": None},      # Resolves via OPENAI_API_KEY

        "anthropic": {"api_key": None},   # Resolves via ANTHROPIC_API_KEY

        "gemini": {"api_key": None},      # Resolves via GEMINI_API_KEY

    }
)

# Route to OpenAI

response = client.chat.completions.create(
    model="openai:gpt-4-turbo",
    messages=[{"role": "user", "content": "Explain polymorphism."}]
)
print(f"OpenAI: {response.choices[0].message.content}")

# Route to Anthropic

response = client.chat.completions.create(
    model="anthropic:claude-3-sonnet-20240229",
    messages=[{"role": "user", "content": "Explain inheritance."}]
)
print(f"Anthropic: {response.choices[0].message.content}")

# Route to Gemini

response = client.chat.completions.create(
    model="gemini:gemini-1.5-flash",
    messages=[{"role": "user", "content": "Explain encapsulation."}]
)
print(f"Gemini: {response.choices[0].message.content}")

Each request automatically resolves the appropriate API key based on the provider prefix in the model identifier (e.g., "openai:", "anthropic:", "gemini:").

Summary

  • aisuite uses a three-tier resolution system: explicit arguments override environment variables, which override SecretStore entries.
  • Provider resolvers live in platform/coworker/providers/ with each module implementing a resolve_api_key function following the pattern established in openai_provider.py, anthropic_provider.py, and gemini_provider.py.
  • Environment variables follow naming conventions: OPENAI_API_KEY, ANTHROPIC_API_KEY, and GEMINI_API_KEY (or GOOGLE_API_KEY as fallback).
  • The Client class in aisuite/client.py lazily initializes providers and triggers key resolution via Client._resolve_provider.
  • Reference .env.sample for the complete list of supported environment variables across all integrated platforms.

Frequently Asked Questions

What is the exact priority order for API key resolution in aisuite?

aisuite checks credentials in the following strict order: first, any explicit api_key argument passed in the provider configuration; second, the provider-specific environment variable (such as OPENAI_API_KEY); third, the SecretStore entry under the provider:<name> profile. This hierarchy ensures maximum flexibility while preventing accidental credential leakage in version control.

Can I mix explicit API keys and environment variables for different providers?

Yes. The provider_configs dictionary accepts None for providers that should resolve via environment variables or SecretStore, while simultaneously accepting explicit strings for other providers. This allows you to hardcode keys for experimental providers while keeping production credentials in environment variables.

How does aisuite handle the Gemini API key versus the Google API key?

According to the source in platform/coworker/providers/gemini_provider.py, the resolver prefers GEMINI_API_KEY but automatically falls back to GOOGLE_API_KEY if the primary variable is unset. This dual-check pattern accommodates users migrating from the older Google AI SDK to the newer Gemini-specific endpoints.

Where should I store API keys for the aisuite Settings UI to find them?

When using the graphical Settings interface, keys are stored in the internal SecretStore under the profile key provider:<name> (e.g., provider:openai, provider:anthropic). These entries are checked last in the resolution chain and provide a secure alternative to environment variables for desktop applications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →