Module 1: Models and Providers

init_chat_model and Providers

Capsule overview

init_chat_model is LangChain's universal function for initializing models from any provider. Instead of importing a different class for each provider (ChatOpenAI, ChatAnthropic, ChatGoogleGenerativeAI), you use a single function that resolves everything internally.

In this capsule you'll learn to use init_chat_model with the main providers (OpenAI, Anthropic, Google, Ollama), understand the string identifiers it uses to resolve models, and configure API keys properly. By the end, you'll be able to connect to any language model in a single line of code.

Everything you learn here is the foundation of the module's mini-project: a multi-provider chat with automatic fallback.


init_chat_model: the universal function

The problem it solves

Without init_chat_model, every provider requires its own class and initialization pattern:

# Without init_chat_model — different imports and classes per provider

from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_google_genai import ChatGoogleGenerativeAI

openai_model = ChatOpenAI(model="gpt-4.1")
anthropic_model = ChatAnthropic(model="claude-sonnet-4-20250514")
google_model = ChatGoogleGenerativeAI(model="gemini-2.0-flash")

It works, but if you want to switch providers you have to change imports, classes and possibly parameters. With init_chat_model, one function handles it all:

# With init_chat_model — one function, any provider

from langchain.chat_models import init_chat_model

openai_model = init_chat_model("openai:gpt-4.1")
anthropic_model = init_chat_model("anthropic:claude-sonnet-4-20250514")
google_model = init_chat_model("google_genai:gemini-2.0-flash")

Same function, same interface, any provider. Switching providers is switching a string.


Basic example

from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

# Initialize an OpenAI model
model = init_chat_model("openai:gpt-4.1-mini")

# Run it with invoke
response = model.invoke("What is LangChain in one sentence?")
print(response.content)
# Expected output: LangChain is an open-source framework for building
# applications with language models.

That's it. One line to initialize, one line to run.


String identifiers

init_chat_model uses a standard format to identify models:

provider:model

Examples:

String identifierProviderModel
"openai:gpt-4.1"OpenAIGPT-4.1
"openai:gpt-4.1-mini"OpenAIGPT-4.1 Mini
"openai:o3-mini"OpenAIo3-mini (reasoning)
"anthropic:claude-sonnet-4-20250514"AnthropicClaude Sonnet 4
"anthropic:claude-haiku-4-20250514"AnthropicClaude Haiku 4
"google_genai:gemini-2.0-flash"GoogleGemini 2.0 Flash
"ollama:llama3.1"Ollama (local)Llama 3.1
"ollama:mistral"Ollama (local)Mistral

Alternative format: no provider prefix

You can also pass the model and the provider separately:

# These two lines are equivalent
model = init_chat_model("openai:gpt-4.1")
model = init_chat_model("gpt-4.1", model_provider="openai")

The prefixed format ("openai:gpt-4.1") is more concise and recommended. The model_provider format is handy when the model name is dynamic (it comes from a variable or a config).

# Useful when the model comes from configuration
model_name = config.get("model_name")       # "gpt-4.1"
provider = config.get("model_provider")      # "openai"

model = init_chat_model(model_name, model_provider=provider)

Supported providers

OpenAI

Package: pip install langchain-openai API key: OPENAI_API_KEY

from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

# GPT-4.1 — the flagship model
model = init_chat_model("openai:gpt-4.1")
response = model.invoke("Explain what RAG is in 2 sentences")
print(response.content)

# GPT-4.1 Mini — faster and cheaper
model_mini = init_chat_model("openai:gpt-4.1-mini")
response = model_mini.invoke("Hello")
print(response.content)

# o3-mini — a reasoning model (it thinks before answering)
model_reasoning = init_chat_model("openai:o3-mini")
response = model_reasoning.invoke("Solve: 15 * 23 + 47")
print(response.content)

Recommended models:

  • gpt-4.1 — OpenAI's most capable model for complex tasks
  • gpt-4.1-mini — A balance of cost and capability. Ideal for most cases
  • o3-mini — For tasks that require step-by-step reasoning

Anthropic

Package: pip install langchain-anthropic API key: ANTHROPIC_API_KEY

from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

# Claude Sonnet 4 — a quality/speed balance
model = init_chat_model("anthropic:claude-sonnet-4-20250514")
response = model.invoke("Explain the difference between RAG and fine-tuning")
print(response.content)

# Claude Haiku 4 — Anthropic's fastest
model_fast = init_chat_model("anthropic:claude-haiku-4-20250514")
response = model_fast.invoke("Summarize this text in one sentence: [text]")
print(response.content)

Recommended models:

  • claude-sonnet-4-20250514 — Ideal for most tasks
  • claude-haiku-4-20250514 — Very fast, ideal for classification and simple tasks

Google (Gemini)

Package: pip install langchain-google-genai API key: GOOGLE_API_KEY

from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

# Gemini 2.0 Flash — fast, with good quality
model = init_chat_model("google_genai:gemini-2.0-flash")
response = model.invoke("What are the 3 pillars of observability?")
print(response.content)

Recommended models:

  • gemini-2.0-flash — Fast and cheap, a good option as a fallback

Ollama (local models)

Package: pip install langchain-ollama Requirement: Ollama installed and running locally

# Install Ollama: https://ollama.ai
# Pull a model
ollama pull llama3.1
ollama pull mistral
from langchain.chat_models import init_chat_model

# No API key needed — it runs on your machine
model = init_chat_model("ollama:llama3.1")
response = model.invoke("What is a vector database?")
print(response.content)

# Mistral — a lightweight alternative
model_mistral = init_chat_model("ollama:mistral")
response = model_mistral.invoke("Hello")
print(response.content)

Advantages of local models:

  • ✅ No cost per use (it runs on your machine)
  • ✅ No network latency
  • ✅ Data never leaves your machine (privacy)

Downsides:

  • ❌ Lower quality than GPT-4.1 or Claude Sonnet
  • ❌ Needs a powerful GPU for large models
  • ❌ Slower on limited hardware

Azure OpenAI

Package: pip install langchain-openai API key: AZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT

from langchain.chat_models import init_chat_model

model = init_chat_model(
    "openai:gpt-4.1",
    model_provider="azure_openai",
    azure_endpoint="https://your-resource.openai.azure.com/",
    api_version="2024-12-01-preview"
)
response = model.invoke("Hello from Azure")
print(response.content)

Azure OpenAI is useful in enterprise environments where the organization already has contracts with Microsoft.


Direct initialization vs init_chat_model

Both work. Pick based on your case:

Criterioninit_chat_modelDirect class (ChatOpenAI)
Simplicity✅ One function for everything❌ A different class per provider
Switching providers✅ Change one string❌ Change import + class
Configurable models✅ Native via configurable_fields❌ Requires custom code
IDE autocomplete⚠️ Returns a generic type✅ The IDE knows the methods
Provider-specific params⚠️ Via kwargs✅ Documented on the class

Recommendation: Use init_chat_model as your default. Only reach for direct classes if you need advanced IDE autocomplete for provider-specific parameters.

# Recommended for most cases
model = init_chat_model("openai:gpt-4.1")

# The alternative, when you need very provider-specific parameters
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
    model="gpt-4.1",
    organization="org-abc123",
    default_headers={"X-Custom-Header": "value"}
)

Configure API keys properly

Recommended approach: a .env file

# .env (at the root of your project)
OPENAI_API_KEY=sk-proj-your-key-here
ANTHROPIC_API_KEY=sk-ant-your-key-here
GOOGLE_API_KEY=your-key-here
from dotenv import load_dotenv
load_dotenv()  # Loads the variables from .env

from langchain.chat_models import init_chat_model

# LangChain's packages look for these variables automatically
model = init_chat_model("openai:gpt-4.1")  # Uses OPENAI_API_KEY

Alternative approach: pass it explicitly

model = init_chat_model("openai:gpt-4.1", api_key="sk-proj-...")

Not recommended for code you share or push to git. Useful only for quick testing.

Environment variables per provider

ProviderEnvironment variable
OpenAIOPENAI_API_KEY
AnthropicANTHROPIC_API_KEY
GoogleGOOGLE_API_KEY
Azure OpenAIAZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT
OllamaNot required (local)

Connection to the project

In the Multi-Provider Chat with Fallback (this module's project):

  • You'll use init_chat_model to initialize 3 different providers
  • The string identifier will let you switch providers with a simple config change
  • The automatic fallback will try provider 1 → provider 2 → provider 3

Everything you learn here applies directly in Capsule 08.


Troubleshooting

Problem 1: ImportError: cannot import name 'init_chat_model'

Cause: Your langchain version is too old. Fix:

pip install --upgrade langchain langchain-core

Problem 2: ValueError: Could not find chat model provider for ...

Cause: The provider's package isn't installed. Fix:

# For OpenAI
pip install langchain-openai

# For Anthropic
pip install langchain-anthropic

# For Google
pip install langchain-google-genai

Problem 3: AuthenticationError or Invalid API Key

Cause: The API key is missing, wrong, or not loaded. Fix:

# Check that the key exists
import os
from dotenv import load_dotenv
load_dotenv()

print(os.getenv("OPENAI_API_KEY"))  # Should print your key
# If it prints None, check your .env file

Problem 4: Ollama doesn't respond

Cause: Ollama isn't running, or the model isn't downloaded. Fix:

# Check that Ollama is running
ollama list

# If the model isn't listed, pull it
ollama pull llama3.1

# Check that the server responds
curl http://localhost:11434/api/tags

Exercises

Exercise 1: Your first model (Easy)

Initialize an OpenAI model with init_chat_model and ask it a simple question. Print the response.

See solution
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

model = init_chat_model("openai:gpt-4.1-mini")
response = model.invoke("What is the capital of France?")
print(response.content)
# Expected output: The capital of France is Paris.

Explanation: init_chat_model detects the provider from the string identifier "openai:...", looks for the API key in OPENAI_API_KEY, and returns a ready-to-use instance.

Exercise 2: Switch providers (Easy)

Change the previous exercise to use Anthropic instead of OpenAI. You should only need to change one line.

See solution
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

# Only the string identifier changes
model = init_chat_model("anthropic:claude-haiku-4-20250514")
response = model.invoke("What is the capital of France?")
print(response.content)
# Expected output: The capital of France is Paris.

Explanation: The interface is identical. Only the string identifier changes. The rest of the code is exactly the same.

Exercise 3: Multiple providers (Medium)

Write a function ask_model(provider, question) that takes a provider name ("openai", "anthropic", "google") and a question, initializes the right model, and returns the response.

See solution
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

MODELS = {
    "openai": "openai:gpt-4.1-mini",
    "anthropic": "anthropic:claude-haiku-4-20250514",
    "google": "google_genai:gemini-2.0-flash",
}

def ask_model(provider: str, question: str) -> str:
    """Initializes the model for the given provider and returns the response."""
    if provider not in MODELS:
        raise ValueError(f"Unsupported provider: {provider}")
    
    model = init_chat_model(MODELS[provider])
    response = model.invoke(question)
    return response.content

# Usage
print(ask_model("openai", "Say hello in Japanese"))
print(ask_model("anthropic", "Say hello in Japanese"))
# Expected output: こんにちは (Konnichiwa) — or variants

Explanation: The MODELS dictionary maps simple names to full string identifiers. The function is provider-agnostic because init_chat_model unifies the interface.

Exercise 4: Compare responses (Medium)

Write a script that asks the same question to 2 different providers and compares their responses side by side. Print the provider, its response, and the type of object returned.

See solution
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

providers = {
    "OpenAI": "openai:gpt-4.1-mini",
    "Anthropic": "anthropic:claude-haiku-4-20250514",
}

question = "What is an embedding, in one sentence?"

for name, model_id in providers.items():
    model = init_chat_model(model_id)
    response = model.invoke(question)
    
    print(f"--- {name} ---")
    print(f"Response: {response.content}")
    print(f"Type: {type(response)}")
    print(f"Metadata: {response.response_metadata.get('model_name', 'N/A')}")
    print()

# Expected output:
# --- OpenAI ---
# Response: An embedding is a numerical representation...
# Type: <class 'langchain_core.messages.ai.AIMessage'>
# Metadata: gpt-4.1-mini
#
# --- Anthropic ---
# Response: An embedding is a numerical vector...
# Type: <class 'langchain_core.messages.ai.AIMessage'>
# Metadata: N/A

Explanation: Both providers return the same type (AIMessage), which confirms the interface is unified. The specific content varies, but the structure is identical.

Exercise 5: Dynamic model from config (Hard)

Build a system where the model is configured from a configuration dictionary (simulating a config file). The function should take the config dict, initialize the model, and return the response along with metadata about the provider used.

See solution
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model

def chat_with_config(config: dict, question: str) -> dict:
    """
    Initializes a model based on config and returns the response with metadata.
    
    Expected config:
    {
        "model": "gpt-4.1-mini",
        "provider": "openai",
        "temperature": 0.7
    }
    """
    model = init_chat_model(
        config["model"],
        model_provider=config["provider"],
        temperature=config.get("temperature", 0.7)
    )
    
    response = model.invoke(question)
    
    return {
        "answer": response.content,
        "provider": config["provider"],
        "model": config["model"],
        "tokens": response.usage_metadata if hasattr(response, "usage_metadata") else None
    }

# Production config
prod_config = {
    "model": "gpt-4.1-mini",
    "provider": "openai",
    "temperature": 0.3
}

# Development config (cheaper)
dev_config = {
    "model": "gpt-4.1-nano",
    "provider": "openai",
    "temperature": 0.7
}

result = chat_with_config(prod_config, "What is LangChain?")
print(f"Provider: {result['provider']}")
print(f"Model: {result['model']}")
print(f"Response: {result['answer'][:100]}...")

Explanation: The config-dict pattern is common in real applications where configuration comes from YAML files, environment variables, or databases. init_chat_model with model_provider accepts the values separately, which makes this pattern straightforward.


Summary

In this capsule you learned:

  • init_chat_model is the universal function for initializing models from any provider
  • String identifiers follow the format provider:model (e.g. "openai:gpt-4.1")
  • You can split model and provider using the model_provider parameter
  • The main providers are OpenAI, Anthropic, Google (cloud) and Ollama (local)
  • Each provider needs its package (langchain-openai, etc.) and its API key
  • The interface is identical across providers — switching providers = switching a string
  • Use .env + python-dotenv to handle API keys safely

Next capsule: Parameters and configuration — you'll learn to tune the model's behavior with temperature, max_tokens, timeout, and models configurable at runtime.


Additional resources

  1. init_chat_model API Reference - Full documentation for the function
  2. Chat Models Universal Init - The official how-to guide
  3. LangChain Integrations: Chat Models - Complete list of supported providers
  4. OpenAI Models Documentation - Models available from OpenAI
  5. Anthropic Models Documentation - Models available from Anthropic
  6. Ollama Library - Models available for local execution
  7. python-dotenv Documentation - Handling environment variables

Module 1 — LangChain & LangGraph: From Chains to Agents