> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Routing

> How PraisonAI decides which vendor your model string reaches

PraisonAI picks the vendor from your model string, so `claude-3-5-sonnet-latest` goes to Anthropic and `gemini-2.0-flash` goes to Google — no prefix required.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    I1[gpt-4o-mini] --> OpenAI[🟢 OpenAI]
    I2[claude-3-5-sonnet-latest] --> Anthropic[🟣 Anthropic]
    I3[gemini-2.0-flash] --> Google[🔵 Google]
    I4[anthropic/claude-3-5-sonnet-latest] --> Anthropic

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef openai fill:#10B981,stroke:#7C90A0,color:#fff
    classDef vendor fill:#189AB4,stroke:#7C90A0,color:#fff

    class I1,I2,I3,I4 input
    class OpenAI openai
    class Anthropic,Google vendor
```

## Quick Start

**1. Just name the model**

Name the model and PraisonAI routes it to the right vendor.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { Agent } from 'praisonai';

const openai = new Agent({ instructions: 'x', llm: 'gpt-4o-mini' });
const claude = new Agent({ instructions: 'x', llm: 'claude-3-5-sonnet-latest' });
const gemini = new Agent({ instructions: 'x', llm: 'gemini-2.0-flash' });

await claude.chat('Hello!');
```

**2. Be explicit when the name isn't enough**

Add a `provider/` prefix for custom-named or gateway models the bare name would not resolve.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { Agent } from 'praisonai';

const anthropic = new Agent({ instructions: 'x', llm: 'anthropic/my-custom-claude' });
const openai    = new Agent({ instructions: 'x', llm: 'openai/gpt-4o' });
const google    = new Agent({ instructions: 'x', llm: 'google/gemini-2.0-flash' });
```

***

## How It Works

PraisonAI runs four checks in order to resolve every model string.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Start[📝 llm string] --> Slash{Contains '/' ?}
    Slash -->|yes| Explicit[✅ Use explicit prefix]
    Slash -->|no| Prefix{Known prefix?<br/>claude- / gemini- / gpt-}
    Prefix -->|yes| Infer[✅ Infer provider]
    Prefix -->|no| Base{Custom baseURL set?}
    Base -->|yes| Compat[✅ OpenAI-compatible path]
    Base -->|no| Fallback[✅ Default to OpenAI]

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff

    class Start input
    class Slash,Prefix,Base decision
    class Explicit,Infer,Compat,Fallback result
```

An explicit `provider/model` prefix wins over everything, including a custom `baseURL`.

***

## Routing Decision Table

This table is the single source of truth for user-visible routing behaviour.

| `llm` string | `baseURL` set? | Resolved provider | Backend used |
| - | - | - | - |
| `gpt-4o-mini` | no | openai | OpenAI (native) |
| `claude-3-5-sonnet-latest` | no | **anthropic** | **AI SDK** |
| `gemini-2.0-flash` | no | **google** | **AI SDK** |
| `some-local-model` (unknown bare) | no | openai | OpenAI (native) |
| `openai/gpt-4o` | no | openai | OpenAI (native) |
| `anthropic/claude-3-5-sonnet-latest` | no | anthropic | AI SDK |
| `claude-3-5-sonnet-latest` | **yes** | openai | OpenAI-compatible (baseURL) |
| `anthropic/claude-3-5-sonnet-latest` | **yes** | **anthropic** | AI SDK (explicit prefix wins) |

***

## The baseURL Exception

> [!NOTE]
>
> Pointing at a proxy that serves `claude-*` over an OpenAI-shaped API is a real deployment, so a **bare** name plus a custom `baseURL` stays on the OpenAI-compatible path — prefix inference would otherwise route it away from the endpoint you explicitly asked for. An **explicit** `provider/model` prefix still wins, because that request is unambiguous.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { Agent } from 'praisonai';

// Bare name + baseURL → stays OpenAI-compatible (proxy case)
new Agent({ llm: 'claude-3-5-sonnet-latest',
            baseURL: 'https://my-gateway.example/v1' });

// Explicit prefix + baseURL → explicit prefix wins (unambiguous)
new Agent({ llm: 'anthropic/claude-3-5-sonnet-latest',
            baseURL: 'https://my-gateway.example/v1' });
```

***

## Per-Agent Credentials

Pass `apiKey` on the agent and PraisonAI honours it for whichever provider the model routes to.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { Agent } from 'praisonai';

const agent = new Agent({
  instructions: 'You are helpful.',
  llm: 'claude-3-5-sonnet-latest',
  apiKey: process.env.MY_ANTHROPIC_KEY,   // no ANTHROPIC_API_KEY needed
});
```

A programmatically-passed `apiKey` is honoured for every provider — env vars are optional, not required.

***

## Best Practices

> [accordion] Prefer the bare name for major models
>
> `claude-3-5-sonnet-latest` reads more clearly than `anthropic/claude-3-5-sonnet-latest` and routes the same way.

> [accordion] Add the provider/ prefix when you're using a gateway
>
> A `baseURL` keeps a bare name on the OpenAI-compatible path; an explicit `provider/model` prefix overrides that.

> [accordion] Pass apiKey per agent when running multiple tenants
>
> No env-var juggling, no cross-tenant leakage — each agent carries its own key.

> [accordion] Do not name your own model claude-... or gemini-... unless you mean it
>
> The prefix inference is deliberate — a custom model with that name will route to Anthropic or Google.

***

## Related

> [card] [Providers](https://praison.ai/docs/js/providers.md)
>
> Full provider reference and configuration

> [card] [Multi-Provider Agents (AI SDK)](https://praison.ai/docs/js/ai-sdk.md)
>
> Build agents across 30+ providers


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.