Multi-Provider Agents

Build agents that work with OpenAI, Anthropic, Google, and 30+ LLM providers

Switch between any LLM provider — OpenAI, Anthropic, Google, and more — without changing your agent code.

Diagram

Multi-Provider Routing

openai/…

anthropic/…

google/…

other/…

🤖 Agent

🔀 Router

🟢 OpenAI

🟣 Anthropic

🔵 Google

âš¡ Any Provider

Quick Start

  1. Simple Usage
    bash
    npm install praisonai
  2. With Configuration
    typescript
    import { Agent } from 'praisonai';
    
    const agent = new Agent({
      instructions: 'You are a helpful assistant.',
      llm: 'openai/gpt-4o-mini'
    });
    
    const response = await agent.chat('Hello, how are you?');
    console.log(response);
  3. Switch Providers with One Line
    typescript
    import { Agent } from 'praisonai';
    
    const agent = new Agent({
      instructions: 'You are a helpful assistant.',
      llm: 'anthropic/claude-3-5-sonnet-latest'
    });
    
    const response = await agent.chat('Explain AI in one sentence');
    console.log(response);

How It Works

Diagram
LLM ProviderBackend RouterAgentUserLLM ProviderBackend RouterAgentUserchat(“question”)Resolve backend for llm stringAI SDK or Native providerAPI requestResponseAnswer

Model String Resolution

PraisonAI resolves a model string in three tiers: explicit prefix > prefix inference > OpenAI fallback.

llm stringbaseURL set?Resolved providerBackend used
gpt-4o-mininoopenaiOpenAI (native)
claude-3-5-sonnet-latestnoanthropicAI SDK
gemini-2.0-flashnogoogleAI SDK
openai/gpt-4onoopenaiOpenAI (native)
anthropic/claude-3-5-sonnet-latestnoanthropicAI SDK
claude-3-5-sonnet-latestyesopenaiOpenAI-compatible (baseURL)
anthropic/claude-3-5-sonnet-latestyesanthropicAI SDK (explicit prefix wins)

A bare name plus a custom baseURL stays on the OpenAI-compatible path — see The baseURL exception.


Supported Providers

ProviderModel StringExample
OpenAIopenai/modelopenai/gpt-4o, openai/gpt-4o-mini
Anthropicanthropic/modelanthropic/claude-3-5-sonnet-latest
Googlegoogle/modelgoogle/gemini-2.0-flash
Groqgroq/modelgroq/llama-3.3-70b-versatile
Mistralmistral/modelmistral/mistral-large-latest
Coherecohere/modelcohere/command-r-plus
DeepSeekdeepseek/modeldeepseek/deepseek-chat
xAIxai/modelxai/grok-2

Common Patterns

Agent with Tools

typescript
import { Agent } from 'praisonai';

function getWeather(city: string): string {
  return JSON.stringify({ city, temperature: 22, condition: 'sunny' });
}

const agent = new Agent({
  instructions: 'You help users check the weather.',
  llm: 'anthropic/claude-3-5-sonnet-latest',
  tools: [getWeather]
});

const response = await agent.chat('What is the weather in Paris?');
console.log(response);

Tools work identically on every provider — swap the llm string (openai/..., google/..., groq/..., ollama/...) with no other code change.

Structured Output

outputSchema takes a JSON Schema object (not a Zod schema) and constrains the model to matching JSON on every provider. OpenAI uses native response_format: json_schema; other providers (Anthropic, Google, Groq, Mistral, Ollama, …) route through the AI SDK backend’s generateObject({ schema }). See Structured Output.

typescript
import { Agent } from 'praisonai';

const agent = new Agent({
  instructions: 'Extract person information from text.',
  llm: 'openai/gpt-4o-mini',
  outputSchema: {
    type: 'object',
    properties: {
      name: { type: 'string' },
      age: { type: 'number' },
      city: { type: 'string' },
    },
    required: ['name', 'age', 'city']
  },
  outputSchemaName: 'Person'  // names the schema in the response_format payload
});

const result = await agent.chat('John is 30 years old and lives in Paris');
// '{"name":"John","age":30,"city":"Paris"}'

Multi-Agent Pipeline

typescript
import { Agent } from 'praisonai';

const researcher = new Agent({
  name: 'researcher',
  instructions: 'Research topics thoroughly.',
  llm: 'anthropic/claude-3-5-sonnet-latest'
});

const writer = new Agent({
  name: 'writer',
  instructions: 'Write engaging content based on research.',
  llm: 'openai/gpt-4o'
});

const research = await researcher.chat('Research the history of AI');
const article = await writer.chat(`Write an article based on: ${research}`);
console.log(article);

Environment Variables

bash
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
export GOOGLE_API_KEY=AIza...
export GROQ_API_KEY=gsk_...

# Or pass apiKey per-agent (as of PR #4483, honoured across all providers)

# Override backend resolver
export PRAISONAI_BACKEND=ai-sdk   # Force AI SDK for all providers
export PRAISONAI_BACKEND=native   # Force native providers only
export PRAISONAI_BACKEND=auto     # Auto-select (default)

Best Practices

Use the provider/model string format

Always use "provider/model" strings ("openai/gpt-4o-mini") rather than provider-specific config objects. Switching providers is a one-line change.

Install provider packages only when needed

Core PraisonAI bundles OpenAI support. For other providers install @ai-sdk/anthropic, @ai-sdk/google, etc. only when you use them.

Match model to task

For quick tasks use openai/gpt-4o-mini or google/gemini-2.0-flash. For complex reasoning use anthropic/claude-3-5-sonnet-latest or openai/gpt-4o. Mix providers across agents in multi-agent workflows.

Store API keys in environment variables

Never hard-code API keys. Use environment variables (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.). For production deployments use a secrets manager.


Related