Claude-code-plugins-plus-skills langchain-multi-env-setup
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/langchain-pack/skills/langchain-multi-env-setup" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-skills-langchain-multi-env-setup && rm -rf "$T"
manifest:
plugins/saas-packs/langchain-pack/skills/langchain-multi-env-setup/SKILL.mdsource content
LangChain Multi-Environment Setup
Overview
Configure LangChain across development, staging, and production with separate API keys, environment-specific model settings, LangSmith project isolation, and validated configuration.
Environment Strategy
| Environment | API Key Source | Model | LangSmith Project | Cache |
|---|---|---|---|---|
| Development | | gpt-4o-mini | | Off |
| Staging | CI secrets | gpt-4o-mini | | Redis |
| Production | Secret Manager | gpt-4o | | Redis |
Step 1: Configuration with Zod Validation
// config/langchain.ts import { z } from "zod"; import "dotenv/config"; const EnvironmentSchema = z.enum(["development", "staging", "production"]); const ConfigSchema = z.object({ environment: EnvironmentSchema, openaiApiKey: z.string().min(1, "OPENAI_API_KEY is required"), model: z.string().default("gpt-4o-mini"), temperature: z.number().min(0).max(2).default(0), maxRetries: z.number().default(3), timeout: z.number().default(30000), langsmith: z.object({ enabled: z.boolean(), apiKey: z.string().optional(), project: z.string(), }), cache: z.object({ enabled: z.boolean(), ttlSeconds: z.number().default(300), }), }); export type LangChainConfig = z.infer<typeof ConfigSchema>; function detectEnvironment(): z.infer<typeof EnvironmentSchema> { const env = process.env.NODE_ENV ?? "development"; if (env === "production") return "production"; if (env === "staging" || process.env.VERCEL_ENV === "preview") return "staging"; return "development"; } const ENV_CONFIGS: Record<string, Partial<z.infer<typeof ConfigSchema>>> = { development: { model: "gpt-4o-mini", temperature: 0, timeout: 60000, langsmith: { enabled: true, project: `dev-${process.env.USER ?? "local"}` }, cache: { enabled: false, ttlSeconds: 60 }, }, staging: { model: "gpt-4o-mini", temperature: 0, langsmith: { enabled: true, project: "staging" }, cache: { enabled: true, ttlSeconds: 300 }, }, production: { model: "gpt-4o", temperature: 0, maxRetries: 5, timeout: 60000, langsmith: { enabled: true, project: "production" }, cache: { enabled: true, ttlSeconds: 600 }, }, }; export function loadConfig(): LangChainConfig { const env = detectEnvironment(); const envConfig = ENV_CONFIGS[env]; const raw = { environment: env, openaiApiKey: process.env.OPENAI_API_KEY, ...envConfig, langsmith: { ...envConfig?.langsmith, apiKey: process.env.LANGSMITH_API_KEY, enabled: process.env.LANGSMITH_TRACING === "true", }, }; const config = ConfigSchema.parse(raw); console.log(`[config] Environment: ${config.environment}, Model: ${config.model}`); return config; }
Step 2: Environment Files
# .env.example (commit this) OPENAI_API_KEY= ANTHROPIC_API_KEY= LANGSMITH_API_KEY= LANGSMITH_TRACING=true NODE_ENV=development # .env.local (git-ignored, for local dev) OPENAI_API_KEY=sk-dev-... LANGSMITH_API_KEY=lsv2_pt_dev_... LANGSMITH_TRACING=true NODE_ENV=development
# .gitignore .env .env.local .env.*.local
Step 3: Secret Management
# GitHub Actions — use environments # Settings > Environments > staging > Secrets # OPENAI_API_KEY, LANGSMITH_API_KEY # GCP Secret Manager echo -n "sk-prod-..." | gcloud secrets create openai-api-key-prod --data-file=- echo -n "lsv2_..." | gcloud secrets create langsmith-api-key-prod --data-file=- # AWS Secrets Manager aws secretsmanager create-secret \ --name langchain/production/openai-key \ --secret-string "sk-prod-..."
Step 4: CI/CD with Environment Isolation
# .github/workflows/deploy.yml jobs: deploy-staging: environment: staging env: NODE_ENV: staging OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }} LANGSMITH_TRACING: "true" steps: - uses: actions/checkout@v4 - run: npm ci && npm run build - run: npm test - run: gcloud run deploy langchain-api-staging --source . deploy-production: environment: production needs: deploy-staging env: NODE_ENV: production OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }} LANGSMITH_TRACING: "true" steps: - uses: actions/checkout@v4 - run: npm ci && npm run build - run: npm test - run: gcloud run deploy langchain-api --source .
Step 5: Use Config in Application
// src/index.ts import { loadConfig } from "./config/langchain"; import { createModel } from "./infra/llm/factory"; const config = loadConfig(); // Model automatically configured for environment const model = createModel({ provider: "openai", model: config.model, temperature: config.temperature, maxRetries: config.maxRetries, timeout: config.timeout, }); // LangSmith tracing via env vars (automatic) if (config.langsmith.enabled) { process.env.LANGSMITH_TRACING = "true"; process.env.LANGSMITH_API_KEY = config.langsmith.apiKey ?? ""; process.env.LANGSMITH_PROJECT = config.langsmith.project; }
Startup Validation
// Fail fast on missing config try { const config = loadConfig(); console.log(`[startup] Config validated: ${config.environment}`); } catch (error) { console.error("[startup] Invalid configuration:", error); process.exit(1); }
Error Handling
| Issue | Cause | Fix |
|---|---|---|
| Wrong environment detected | not set | Set in deployment config |
| Secret not found | Wrong secret path | Verify in cloud console |
| Cross-env data leak | Shared API key | Use separate keys per environment |
| Config validation fail | Missing env var | Check for required vars |
Resources
Next Steps
For deployment, see
langchain-deploy-integration.