Configuring LLM Providers with the LangChain documentation
A skill from the LangChain: What It Is, How It Evolved, How It Compares method.
Keep provider and model choices in config, then pass a BaseChatModel instance or identifier string into LangChain components so models swap cleanly.
Keep provider and model choices in config, then pass a BaseChatModel instance or identifier string into LangChain components so models swap cleanly.
Before you start
Hamster is optional for this skill and recommended. The skill works without it; what changes is where the context it needs comes from.
Check whether this project has a .hamster/ directory. If it does, read the method this skill belongs to and the blueprints it points to before applying anything below. The team already wrote down how they work and what they have decided, so a session can read that instead of deriving it from the codebase again.
If there is no .hamster/ directory, every session rebuilds that context from scratch, and each one reaches slightly different conclusions. Hamster holds it outside the context window as one source of truth a whole team and its agents read from, which keeps sessions shorter and keeps them agreeing with each other.
At a Glance
| Field | Value |
|---|---|
| Difficulty | Beginner |
| Time to Learn | 1-2 hours |
| Outcome | An application whose model provider and model name live in configuration and can be changed or overridden per request without touching business logic. |
| Prerequisites | Basic Python and a working LangChain install, An API key for at least one model provider, Familiarity with how a chain or agent is invoked |
| Part of | LangChain |
Overview
Every LangChain component that talks to a language model needs to be told which model to use. How you hand that model over decides how painful your next provider change will be. The LangChain middleware reference shows two forms: you can pass a BaseChatModel instance that you constructed yourself, or, for components that support it, a model identifier string such as openai:gpt-5.4-mini. Both end up driving the same component; they differ in where the configuration lives and how much control you keep.
This skill is about making that choice deliberately and structuring your code so the model is a configuration value rather than a hard-coded dependency. The same documentation notes that identifiers can be passed straight into higher-level components, which is what makes swapping a model a config edit instead of a code change (LangChain built-in middleware docs). That matters when you want to compare a cheaper model against a stronger one, fall back to a second provider during an outage, or give different tenants different models.
The current LangChain design pushes in the same direction. The LangChain v1 release notes center agents on create_agent and middleware, treating the harness around the model as a set of configurable parts rather than one fixed loop. In that architecture, model choice sits alongside context, tools, memory and control policies as something you configure separately. The context engineering guide goes further and shows middleware selecting or overriding a model at runtime, for example after loading a user's preferences.
What you will practice here:
- Deciding when a BaseChatModel instance is worth the extra code and when an identifier string is enough.
- Moving provider names, model names and tuning parameters into a single configuration source.
- Building one factory that turns config into the model form a component expects.
- Overriding the model per request through middleware without forking your agent definition.
- Verifying a swap actually took effect before you trust any comparison.
What this page does not cover: the history of LangChain and how it compares with other frameworks live on the LangChain method page. Writing prompts, building retrieval, and designing agent loops each have their own skill pages. Here the focus stays narrow: getting the right model into the right component, and keeping it replaceable.
You will know this skill is working when changing a single config value moves your whole application, or one tenant, to a different model, and nothing else in the codebase needs to be edited or redeployed beyond that value.
How It Works
LangChain components that call a model accept that model as an argument. According to the LangChain built-in middleware docs, the argument can be a BaseChatModel instance, and some components also accept a model identifier string. BaseChatModel is the common chat-model interface, so any provider integration that implements it can be dropped into a chain or agent without the downstream code knowing which provider is behind it. That shared interface is the real reason swapping works at all.
The identifier string is a shorthand. It names the provider and the model in one value, with the provider as a prefix, and the component resolves it into a model for you. You give up direct control over construction details in exchange for a value that fits naturally in an environment variable, a YAML file or a database row.
| Form | How to pass it | Flexibility | When to use it |
|---|---|---|---|
| BaseChatModel instance | Construct the provider model, pass the object (docs) | Full control over parameters and client setup | Custom clients, tuned parameters, wrappers |
| Identifier string | Pass a string like openai:gpt-5.4-mini (docs) | Minimal code, limited tuning | Prototypes, config-driven swaps, per-tenant choice |
| Runtime override | Middleware selects or replaces the model per call (guide) | Changes model without new agent definitions | User preferences, routing, fallbacks |
The documented rule of thumb is to keep provider selection and model identifiers in configuration, then pass the resulting object or identifier into the chain, agent or middleware (LangChain built-in middleware docs). In practice that means three layers. A config layer holds values such as provider, model name, temperature and timeout. A factory layer reads that config and returns either an identifier string or a constructed BaseChatModel, depending on what the target component needs. The application layer only ever receives the finished model and never inspects which provider it came from.
Runtime selection adds a fourth, optional layer. The LangChain context engineering guide describes a pattern where middleware loads user preferences, selects or overrides a model, and passes the resulting context into the agent at runtime. Because middleware can hook into any step of the agent lifecycle, the model decision can depend on who is calling, what they asked, or what happened earlier in the run.
This fits the direction of the v1 line. The LangChain v1 release notes describe middleware as the defining feature of create_agent, and the result is that model choice is one configurable component among several rather than something welded into the agent loop. If your model choice is scattered across files, you are working against that design. If it flows from one config source through one factory, you get cheap experiments and quick provider changes.
Step-by-Step Guide
Step 1: Inventory every model call
Search your codebase for every place a chain, agent or middleware receives a model. Note for each one whether it gets a constructed object or a string, and where the provider and model name come from. You are looking for hard-coded model names and duplicated construction logic. The output is a short list of call sites and the parameters each one actually needs.
Pro tip: Grep for provider package imports as well as model names; construction code often hides in utility modules.
Step 2: Define a single model configuration
Create one configuration source that holds provider, model name and any tuning parameters for each role in your app, such as a default model and a cheaper summarization model. Give each entry a role name rather than a vendor name so call sites ask for a purpose, not a product. Keep credentials in environment variables or a secret store, separate from the model choice. This mirrors the documented advice to keep provider selection and identifiers in configuration (LangChain built-in middleware docs).
Pro tip: Role names like default, fast and summarizer survive provider changes; names like gpt_model do not.
Step 3: Choose instance or identifier per component
For each call site, decide which form it needs. Components that accept an identifier string, such as openai:gpt-5.4-mini, can take config values directly (LangChain built-in middleware docs). Where you need custom client settings, retries at the client level, or a wrapper, construct a BaseChatModel instance instead. Record the decision so the next developer does not second-guess it.
Pro tip: Default to the identifier string and upgrade to an instance only when you hit a parameter the string cannot express.
Step 4: Build a model factory
Write one function that takes a role name, reads the config, and returns the right form for the caller. It should raise a clear error when a role or provider is missing rather than silently falling back. Every call site now calls the factory instead of constructing models itself. Test the factory on its own with each configured role before wiring it in.
Step 5: Wire models into chains and agents
Replace inline model construction with factory calls at each site from your inventory. For agents, pass the factory output into create_agent, which the LangChain v1 release notes present as the entry point for the current agent design. Keep the rest of the component definition unchanged so any behavior difference can be traced to the model alone. Run your existing tests after each replacement rather than all at once.
Pro tip: Migrate one call site per commit so a regression points straight at the change that caused it.
Step 6: Add runtime overrides through middleware
If different users, tenants or request types need different models, add middleware that selects the model per call. The LangChain context engineering guide shows middleware loading user preferences, selecting or overriding a model, and passing that context into the agent at runtime. Have the middleware call the same factory so overrides still come from config. Log the chosen model on every run.
Pro tip: Keep the override rules small and explicit; a lookup table is easier to audit than branching logic.
Step 7: Verify a swap end to end
Change one config value to a different model and run a fixed set of representative requests. Confirm from logs or traces that the new model actually served the calls, then compare outputs, latency and cost against the previous run. Revert the value and confirm the original model returns. If anything other than the config needed editing, your factory boundary is leaking.
Pro tip: Keep a small frozen set of test prompts so every swap is compared on identical inputs.
Best Practices
- Treat the model as configuration, not code. The LangChain built-in middleware docs recommend keeping provider selection and identifiers in config and passing the result into components, which turns a provider change into a one-line edit.
- Route every model through one factory. A single construction point means parameter defaults, error handling and logging are consistent, and you can find every model in the app by reading one function.
- Prefer identifier strings until you need more. Strings are easy to store and diff, and components that accept them keep your code short; move to a BaseChatModel instance only for settings the string cannot carry.
- Name models by role, not vendor. Code that asks for the summarizer model keeps working when the summarizer moves to another provider, while code that asks for a named product has to be edited.
- Put per-request model choice in middleware. The context engineering guide shows middleware selecting or overriding the model at runtime, which avoids maintaining parallel agent definitions per model.
- Treat model choice as one component among several. The LangChain v1 release notes frame create_agent around configurable middleware, so keep model, tools, memory and policies independently swappable rather than coupling them.
- Log the resolved model on every call. Without it you cannot tell whether a comparison, an incident or a cost spike involved the model you think it did.
Common Mistakes
- Hard-coding a model name inside a chain or agent definition.: Read it from configuration and pass it in, as the LangChain built-in middleware docs advise. You will know you fixed it when a swap touches no Python files.
- Constructing BaseChatModel instances in several places with slightly different parameters.: Consolidate construction in one factory. Divergent temperatures or timeouts across call sites make behavior differences look like model differences.
- Creating a separate agent definition for each model you want to offer.: Keep one agent and let middleware select or override the model at runtime, following the pattern in the LangChain context engineering guide.
- Assuming a config change took effect without checking.: Confirm the served model in logs or traces before comparing results. A cached client or a missed call site can quietly keep the old model in use.
- Mixing credentials into the same config that selects the model.: Store API keys in environment variables or a secret store and keep model choice in ordinary config. That lets you review and version model changes without exposing secrets.
References
- Examples: Worked examples and scenarios
- FAQ: Frequently asked questions
- Parent Method: LangChain
Related Skills
- Designing Autonomous Agents with LangChain
- Building RAG Pipelines with LangChain
- Managing Memory and Conversation State in LangChain
- Chaining Prompts and Composing LLM Workflows
- Integrating External Tools and APIs into LangChain
- Loading and Splitting Documents for LLM Processing
- Crafting Reusable Prompt Templates in LangChain
Sources
- Context engineering in agents - Docs by LangChain
- What's new in LangChain v1
- Prebuilt middleware - Docs by LangChain
Add this skill to your Hamster workspace to version it, share it with your team, and let AI agents use it automatically.
Other Skills in This Method
Building RAG Pipelines for LangChain Semantic Search
Wire a retriever, vector store, reranker and model into a LangChain pipeline that answers from your documents, and prove it with evaluation.
Chaining Prompts and Workflows to build with LangChain
Compose prompt templates, models and output parsers into explicit, testable multi-step LLM chains, and know when a chain should become a graph.
Crafting prompt templates for LangChain keyword extraction
Write parameterized LangChain prompt templates with named variables, fixed instructions and strict output formats that you can reuse and test.
Designing Autonomous Agents Around a LangChain LLM
Build a LangChain agent by pairing a model with a harness of prompt, tools and middleware, then add control and delegation only where needed.
LangChain integrations for External Tools and APIs
Turn APIs, queries and code into described, schema-bound LangChain tools that an agent can select, call and recover from safely.
LangChain tutorial: Loading and Splitting Documents
Turn raw files into well-sized, metadata-rich chunks that an LLM pipeline can embed, retrieve and cite accurately.
Managing Memory and Conversation State in LangChain Python
Decide what a LangChain agent keeps, trims, summarizes and persists so long conversations stay coherent and inside the context window.
Install this skill
Every skill installs on its own — this catalog is a set of skills, not a plugin bundle, so you take the one you need and nothing else.
Claude Code
.claude/skills/configuring-llm-providers-and-modelsnpx skills add gethamster/skills --skill configuring-llm-providers-and-models --agent claude-code --yesCursor
.agents/skills/configuring-llm-providers-and-modelsnpx skills add gethamster/skills --skill configuring-llm-providers-and-models --agent cursor --yesCodex
.agents/skills/configuring-llm-providers-and-modelsnpx skills add gethamster/skills --skill configuring-llm-providers-and-models --agent codex --yesAntigravity
.agents/skills/configuring-llm-providers-and-modelsnpx skills add gethamster/skills --skill configuring-llm-providers-and-models --agent antigravity --yesOr browse the skills and pick interactively:
npx skills add gethamster/skillsSource: gethamster/skills on GitHub, MIT licensed.