LangChain Production Setup: Your AI’s Launch Checklist
The Story of the Secret Recipe Kitchen
Imagine you’re a chef opening a brand new restaurant. You have the most amazing recipes (your AI code). But before you can serve customers, you need to:
- Lock up your secret ingredients (API keys)
- Set up your kitchen properly (configuration)
- Know what to do when things go wrong (error handling)
- Have safety rules (guardrails and validation)
Let’s learn how to prepare your LangChain AI for the real world!
1. Environment and API Keys
What Are API Keys?
Think of an API key like a special password that lets your AI talk to powerful services like OpenAI or Google.
Simple Example:
- Your mom gives you a library card with YOUR name
- Only YOU can use that card to borrow books
- The library knows it’s you by checking the card
API keys work the same way!
The Secret Hiding Spot: .env Files
Never put your keys directly in your code. That’s like writing your password on a sticky note on your computer screen!
The Right Way:
# .env file (hidden, secret!)
OPENAI_API_KEY=sk-abc123xyz789
LANGCHAIN_API_KEY=ls-mykey456
# your_code.py (safe, clean!)
import os
from dotenv import load_dotenv
load_dotenv() # Load secrets
api_key = os.getenv("OPENAI_API_KEY")
Real Life Example
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
# Step 1: Load your secrets
load_dotenv()
# Step 2: Use them safely
llm = ChatOpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
model="gpt-4"
)
Golden Rules for API Keys
| Do This | Never Do This |
|---|---|
Store in .env file |
Hardcode in Python |
Add .env to .gitignore |
Push keys to GitHub |
| Use environment variables | Share keys in chat |
| Rotate keys regularly | Use same key forever |
2. Configuration Best Practices
What is Configuration?
Configuration is like setting up your TV before watching. You adjust brightness, volume, and language ONCE, then enjoy!
The Config File Approach
Instead of changing settings everywhere in your code, put them in ONE place:
# config.py - Your control center!
class LangChainConfig:
# Model settings
MODEL_NAME = "gpt-4"
TEMPERATURE = 0.7
MAX_TOKENS = 1000
# Retry settings
MAX_RETRIES = 3
TIMEOUT = 30
# Safety settings
MAX_INPUT_LENGTH = 5000
Using Your Config
from config import LangChainConfig
llm = ChatOpenAI(
model=LangChainConfig.MODEL_NAME,
temperature=LangChainConfig.TEMPERATURE,
max_tokens=LangChainConfig.MAX_TOKENS
)
Different Configs for Different Situations
Just like you wear different clothes for school vs. playground:
graph TD A["Your App"] --> B{Which Environment?} B -->|Testing| C["Low Cost Settings"] B -->|Production| D["High Quality Settings"] B -->|Development| E["Debug Settings"] C --> F["Faster Model<br>Lower Temperature"] D --> G["Best Model<br>More Retries"] E --> H["Extra Logging<br>Verbose Mode"]
3. Error Handling Patterns
Why Errors Happen
Even the best AI makes mistakes. Networks fail. Servers get busy. Your job is to catch problems gracefully.
Think of it like this:
- You’re playing catch with a friend
- Sometimes they throw too high
- You don’t cry - you just say “try again!”
The Try-Except Pattern
from langchain_openai import ChatOpenAI
import time
def safe_ai_call(prompt, retries=3):
llm = ChatOpenAI()
for attempt in range(retries):
try:
# Try to get a response
result = llm.invoke(prompt)
return result
except Exception as error:
# Something went wrong!
print(f"Oops! Attempt {attempt + 1}")
print(f"Error: {error}")
if attempt < retries - 1:
# Wait before trying again
time.sleep(2 ** attempt)
else:
# All retries failed
return "Sorry, I can't help now"
Common Errors and Fixes
| Error Type | What Happened | What To Do |
|---|---|---|
| RateLimitError | Too many requests | Wait and retry |
| AuthenticationError | Bad API key | Check your key |
| TimeoutError | Took too long | Increase timeout |
| InvalidRequestError | Bad input | Validate first |
The Retry Pattern with Backoff
from tenacity import retry, stop_after_attempt
from tenacity import wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(min=1, max=10)
)
def reliable_ai_call(prompt):
llm = ChatOpenAI()
return llm.invoke(prompt)
What’s happening:
- Try up to 3 times
- Wait 1 second, then 2, then 4… (exponential!)
- Never wait more than 10 seconds
4. Guardrails and Validation
What Are Guardrails?
Guardrails are like the bumpers in bowling - they keep the ball (your AI) from going into the gutter (doing something wrong)!
Input Validation: Check Before You Send
def validate_user_input(text):
# Rule 1: Not too long
if len(text) > 5000:
return False, "Message too long!"
# Rule 2: Not empty
if not text.strip():
return False, "Please type something!"
# Rule 3: No bad words (simple check)
bad_words = ["hack", "steal", "illegal"]
for word in bad_words:
if word in text.lower():
return False, "Please keep it nice!"
return True, "All good!"
Output Validation: Check What AI Says
def validate_ai_response(response):
# Check if response exists
if not response or not response.content:
return None, "No response received"
text = response.content
# Check minimum quality
if len(text) < 10:
return None, "Response too short"
# Check for unwanted content
if "I cannot" in text and len(text) < 50:
return None, "AI refused to help"
return text, "Success!"
The Complete Guardrail Flow
graph TD A["User Input"] --> B{Input Valid?} B -->|No| C["Show Error Message"] B -->|Yes| D["Send to AI"] D --> E["Get Response"] E --> F{Output Valid?} F -->|No| G["Try Again or Fallback"] F -->|Yes| H["Show to User"] G --> D
Using Pydantic for Strong Validation
from pydantic import BaseModel, validator
from pydantic import Field
class UserQuery(BaseModel):
question: str = Field(max_length=1000)
@validator('question')
def must_be_question(cls, v):
if not v.strip():
raise ValueError('Empty question!')
return v
# Usage
try:
query = UserQuery(question="What is AI?")
# Safe to use!
except Exception as e:
print(f"Bad input: {e}")
Putting It All Together
Here’s a production-ready LangChain setup:
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from tenacity import retry, stop_after_attempt
# 1. Load environment
load_dotenv()
# 2. Configuration
class Config:
MODEL = "gpt-4"
MAX_RETRIES = 3
MAX_INPUT = 2000
# 3. Input validation
class SafeInput(BaseModel):
text: str = Field(max_length=Config.MAX_INPUT)
# 4. Error handling with retries
@retry(stop=stop_after_attempt(Config.MAX_RETRIES))
def ask_ai(question: str) -> str:
# Validate input
safe = SafeInput(text=question)
# Call AI
llm = ChatOpenAI(
model=Config.MODEL,
api_key=os.getenv("OPENAI_API_KEY")
)
response = llm.invoke(safe.text)
# Validate output
if len(response.content) < 5:
raise ValueError("Bad response")
return response.content
Quick Recap
| Component | Purpose | Key Takeaway |
|---|---|---|
| Environment | Store secrets | Never hardcode keys |
| Configuration | Central settings | One place to change |
| Error Handling | Graceful failures | Always retry with backoff |
| Guardrails | Safety checks | Validate input AND output |
You Did It!
You now know how to prepare your LangChain AI for the real world. Just remember:
- Hide your secrets like a treasure chest
- Organize your settings in one place
- Expect problems and handle them nicely
- Build walls to keep bad things out
Your AI is ready for production! Go build something amazing!
