| name | langchain-multi-env-setup |
| description | Configure LangChain multi-environment setup for dev/staging/prod.
Use when managing multiple environments, configuring environment-specific settings,
or implementing environment promotion workflows.
Trigger with phrases like "langchain environments", "langchain staging",
"langchain dev prod", "environment configuration", "langchain env setup".
|
| allowed-tools | Read, Write, Edit |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
LangChain Multi-Environment Setup
Overview
Configure and manage LangChain applications across development, staging, and production environments.
Prerequisites
- LangChain application ready for deployment
- Access to multiple deployment environments
- Secrets management solution (e.g., GCP Secret Manager)
Instructions
Step 1: Environment Configuration Structure
config/
├── base.yaml # Shared configuration
├── development.yaml # Development overrides
├── staging.yaml # Staging overrides
├── production.yaml # Production overrides
└── settings.py # Configuration loader
Step 2: Create Base Configuration
app:
name: langchain-app
version: "1.0.0"
llm:
max_retries: 3
request_timeout: 30
logging:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
date_format: "%Y-%m-%d %H:%M:%S"
cache:
enabled: true
ttl_seconds: 3600
Step 3: Environment-Specific Overrides
extends: base
app:
debug: true
llm:
provider: openai
model: gpt-4o-mini
temperature: 0.7
logging:
level: DEBUG
cache:
type: memory
langsmith:
tracing: true
project: langchain-dev
extends: base
app:
debug: false
llm:
provider: openai
model: gpt-4o-mini
temperature: 0.5
logging:
level: INFO
cache:
type: redis
url: ${REDIS_URL}
langsmith:
tracing: true
project: langchain-staging
extends: base
app:
debug: false
llm:
provider: openai
model: gpt-4o
temperature: 0.3
max_retries: 5
request_timeout: 60
logging:
level: WARNING
cache:
type: redis
url: ${REDIS_URL}
langsmith:
tracing: true
project: langchain-production
monitoring:
prometheus: true
sentry: true
Step 4: Configuration Loader
import os
from pathlib import Path
from typing import Any, Dict, Optional
import yaml
from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings
class LLMConfig(BaseModel):
provider: str = "openai"
model: str = "gpt-4o-mini"
temperature: float = 0.7
max_retries: int = 3
request_timeout: int = 30
class CacheConfig(BaseModel):
enabled: bool = True
type: str = "memory"
url: Optional[str] = None
ttl_seconds: int = 3600
class LangSmithConfig(BaseModel):
tracing: bool = False
project: str = "default"
class Settings(BaseSettings):
environment: str = Field(default=, env=)
llm: LLMConfig = Field(default_factory=LLMConfig)
cache: CacheConfig = Field(default_factory=CacheConfig)
langsmith: LangSmithConfig = Field(default_factory=LangSmithConfig)
:
env_file =
() -> Settings:
env = environment os.environ.get(, )
config_dir = Path(__file__).parent
config = {}
base_path = config_dir /
base_path.exists():
(base_path) f:
config = yaml.safe_load(f) {}
env_path = config_dir /
env_path.exists():
(env_path) f:
env_config = yaml.safe_load(f) {}
config = deep_merge(config, env_config)
config = resolve_env_vars(config)
Settings(**config)
() -> :
result = base.copy()
key, value override.items():
key result (result[key], ) (value, ):
result[key] = deep_merge(result[key], value)
:
result[key] = value
result
() -> :
(config, ):
{k: resolve_env_vars(v) k, v config.items()}
(config, ):
[resolve_env_vars(v) v config]
(config, ) config.startswith() config.endswith():
var_name = config[:-]
os.environ.get(var_name, )
config
settings = load_config()
Step 5: Environment-Aware LLM Factory
from config.settings import settings
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_core.language_models import BaseChatModel
def create_llm() -> BaseChatModel:
"""Create LLM based on environment configuration."""
llm_config = settings.llm
if llm_config.provider == "openai":
return ChatOpenAI(
model=llm_config.model,
temperature=llm_config.temperature,
max_retries=llm_config.max_retries,
request_timeout=llm_config.request_timeout,
)
elif llm_config.provider == "anthropic":
return ChatAnthropic(
model=llm_config.model,
temperature=llm_config.temperature,
max_retries=llm_config.max_retries,
)
else:
raise ValueError(f"Unknown provider: {llm_config.provider}")
Step 6: Environment-Specific Secrets
import os
from google.cloud import secretmanager
def get_secret(secret_id: str) -> str:
"""Get secret from appropriate source based on environment."""
env = os.environ.get("ENVIRONMENT", "development")
if env == "development":
return os.environ.get(secret_id, "")
else:
client = secretmanager.SecretManagerServiceClient()
project_id = os.environ.get("GCP_PROJECT")
name = f"projects/{project_id}/secrets/{secret_id}/versions/latest"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")
openai_key = get_secret("OPENAI_API_KEY")
Step 7: Docker Compose for Local Environments
version: '3.8'
services:
app:
build: .
environment:
- ENVIRONMENT=development
- OPENAI_API_KEY=${OPENAI_API_KEY}
ports:
- "8080:8080"
volumes:
- ./src:/app/src
depends_on:
- redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
langsmith-proxy:
image: langchain/langsmith-proxy:latest
environment:
- LANGCHAIN_API_KEY=${LANGCHAIN_API_KEY}
Output
- Multi-environment configuration structure
- Environment-aware configuration loader
- Secrets management per environment
- Docker Compose for local development
Examples
Running Different Environments
ENVIRONMENT=development python main.py
ENVIRONMENT=staging python main.py
ENVIRONMENT=production python main.py
Environment Promotion Workflow
ENVIRONMENT=development pytest tests/
gcloud run deploy langchain-api-staging \
--set-env-vars="ENVIRONMENT=staging"
ENVIRONMENT=staging pytest tests/integration/
gcloud run deploy langchain-api \
--set-env-vars="ENVIRONMENT=production"
Error Handling
| Error | Cause | Solution |
|---|
| Config Not Found | Missing YAML file | Ensure environment file exists |
| Secret Missing | Not in Secret Manager | Add secret for environment |
| Env Var Not Set | Missing .env | Create .env from .env.example |
Resources
Next Steps
Use langchain-observability for environment-specific monitoring.