Combining OpenRouter with LangChain, CrewAI, and LlamaIndex
Most agent frameworks already speak OpenAI-compatible chat APIs.
Search across all documentation pages
Most agent frameworks already speak OpenAI-compatible chat APIs.
OpenRouter exposes that shape at https://openrouter.ai/api/v1, so you can keep LangChain, CrewAI, or LlamaIndex orchestration and swap only the model backend.
This page gives working wiring patterns and the production rules that stop "works in the tutorial" setups from leaking keys or hardcoding SKUs.
Construct each framework's chat model once through a shared factory: OpenRouter base URL, API key, model slug, and optional headers.
Do not configure OpenRouter differently in every agent class.
export OPENROUTER_API_KEY=sk-or-...
export OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
export AGENT_MODEL_DEFAULT=openai/gpt-4o-miniMap logical roles (default, planner, researcher) to slugs in one module.
Every framework entrypoint calls get_chat_model(role) rather than constructing clients inline.
LangChain ChatOpenAI, LlamaIndex OpenAI-compatible LLMs, and CrewAI/LiteLLM OpenRouter routes all work from the same idea: custom base_url + key + model.
Let the framework bind tools; keep OpenRouter as transport.
A model that streams fine may still fail structured tool calls inside a given integration version.
When quality drops, you need both the graph node and the resolved OpenRouter model.
Shared factory (conceptual; pin package APIs at build):
import os
from functools import lru_cache
OPENROUTER_BASE = os.getenv(
"OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1"
)
API_KEY = os.environ["OPENROUTER_API_KEY"]
REGISTRY = {
"default": os.getenv("AGENT_MODEL_DEFAULT", "openai/gpt-4o-mini"),
"planner": os.getenv("AGENT_MODEL_PLANNER", "anthropic/claude-sonnet-4"),
}
HEADERS = {
"HTTP-Referer": os.getenv("APP_URL", "https://example.com"),
"X-Title": os.getenv("APP_NAME", "agent-prod"),
}
@lru_cache
def model_id(role: str = "default") -> str:
return REGISTRY[role]LangChain / LangGraph (langchain-openai; verify imports for your version):
from langchain_openai import ChatOpenAI
def lc_model(role: str = "default") -> ChatOpenAI:
return ChatOpenAI(
model=model_id(role),
api_key=API_KEY,
base_url=OPENROUTER_BASE,
default_headers=HEADERS,
temperature=0,
)LlamaIndex (OpenAI-compatible pattern; verify class names at build):
from llama_index.llms.openai import OpenAI as LlamaOpenAI
def li_model(role: str = "default") -> LlamaOpenAI:
return LlamaOpenAI(
model=model_id(role),
api_key=API_KEY,
api_base=OPENROUTER_BASE,
default_headers=HEADERS,
)CrewAI (often via LiteLLM-style model strings; verify current CrewAI docs):
from crewai import Agent, LLM
def crew_llm(role: str = "default") -> LLM:
# Many setups use openrouter/<slug> with OPENROUTER_API_KEY set
return LLM(
model=f"openrouter/{model_id(role)}",
api_key=API_KEY,
base_url=OPENROUTER_BASE,
)
researcher = Agent(
role="Researcher",
goal="Find grounded facts",
backstory="Careful analyst",
llm=crew_llm("default"),
verbose=False,
)If your CrewAI version expects a different LLM shape, keep the same principle: one factory, OpenRouter base, registry slug.
Frameworks own orchestration: graphs, crews, agents, memory hooks, tool binders.
OpenRouter owns model access: multi-provider inventory, unified auth, optional provider routing and fallbacks.
That split matches Architecting an Agent Around a Model-Agnostic Gateway.
| Framework | Typical integration | Watch-outs |
|---|---|---|
| LangChain / LangGraph | ChatOpenAI + base_url | Bind tools on the model instance used by the node; do not recreate clients per token |
| LlamaIndex | OpenAI-compatible LLM classes | Align chat vs complete APIs; agent runners need tool-calling models |
| CrewAI | LLM / LiteLLM openrouter/... | Hierarchical crews multiply calls - set budgets; pin model per agent role |
Use role-based registry entries:
Wire roles in config, not by forking agent code.
All three ecosystems support streaming to varying degrees.
Test streaming + tool calls together; some paths buffer tool calls until the stream segment completes.
Framework packages move quickly.
Pin langchain-*, llama-index-*, and crewai versions in the app lockfile, and re-verify OpenRouter base URL parameters after upgrades (verify at build).
OPENAI_API_KEY only - Some libs read OpenAI env vars by default. Set the key you pass explicitly to OpenRouter's key./api/v1 or trailing-slash mismatches cause confusing 404s.vendor/model form for many models.| Approach | Strength | Weakness | Best fit |
|---|---|---|---|
| Framework + OpenRouter | Fast multi-model orchestration | Two version surfaces | Most product teams |
| Framework + direct OpenAI/Anthropic | Native SDK features | Harder multi-provider | Single-provider mandate |
| Framework-free + OpenRouter client | Maximum control | You build memory/tools | Small custom runtimes |
| LiteLLM proxy in front of everything | Central policy | Extra network hop | Platform teams |
Yes.
Share the key and factory; isolate only if you need separate spend caps or environments.
No.
OpenRouter works with any OpenAI-compatible client. Frameworks are optional orchestration.
Pass extra body fields supported by your chat model wrapper (for example extra_body on OpenAI-compatible clients). Verify field names against OpenRouter docs at build.
Only when roles differ in difficulty or risk. Start with one default; split when evals or cost data justify it.
No.
You can use OpenRouter (or another provider) for the chat LLM and a different embeddings provider. Keep configs explicit.
Change base_url, key, and model strings to OpenRouter slugs; run tool and RAG evals; then add fallbacks.
For demos, often yes. For tool-using production agents, only if they pass your tool evals and rate limits.
In the shared factory default headers so every framework path attributes traffic consistently.
Yes.
Resolve model_id from a flag or experiment assignment before building or selecting the node model. See A/B Testing Models in Production via OpenRouter.
Import paths, tool binding helpers, and message content block shapes. Keep a thin adapter and a smoke test.
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026