Configuration Profiles for Dev and Prod
Environment-specific configs, feature flags, and staged deployments.
Configuration Profiles for Dev and Prod is a free AI Agents lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Config Profiles Matter
A production agent and a development agent should behave differently: different logging levels, different model tiers (cost vs. quality), different databases, different rate limits. Configuration profiles make this automatic — one environment variable switches all settings at once.
Environment Detection with ENV Variable
The standard pattern is to read an ENV (or ENVIRONMENT) variable that identifies the current deployment context. Your code then selects the appropriate configuration profile based on this value.
import os
# Read the environment identifier
ENV = os.getenv('ENV', 'development').lower()
if ENV not in ('development', 'staging', 'production'):
raise ValueError(
f'Invalid ENV value: "{ENV}". '
f'Must be: development, staging, or production'
)
print(f'Running in {ENV} mode')
# Usage:
# ENV=development python agent.py -> dev settings
# ENV=staging python agent.py -> staging settings
# ENV=production python agent.py -> prod settings
# python agent.py -> defaults to developmentConfig Classes Per Environment
Define a base config class and subclasses for each environment. Each subclass overrides the values that differ. This is more readable and type-safe than a large dictionary of conditionals.
import os
class BaseConfig:
OPENAI_API_KEY: str = os.environ.get('OPENAI_API_KEY', '')
MAX_STEPS: int = 20
LOG_LEVEL: str = 'INFO'
CACHE_ENABLED: bool = True
CACHE_TTL_SECONDS: int = 3600
class DevelopmentConfig(BaseConfig):
MODEL: str = 'gpt-4o-mini' # cheaper in dev
LOG_LEVEL: str = 'DEBUG' # verbose logging in dev
CACHE_ENABLED: bool = False # fresh results in dev
MAX_STEPS: int = 10 # shorter loops in dev
class StagingConfig(BaseConfig):
MODEL: str = 'gpt-4o-mini'
LOG_LEVEL: str = 'INFO'
MAX_STEPS: int = 20
class ProductionConfig(BaseConfig):
MODEL: str = 'gpt-4o' # best quality in prod
LOG_LEVEL: str = 'WARNING' # less noise in prod
MAX_STEPS: int = 30 # more steps allowed in prod
if __name__ == '__main__':
for cls in (DevelopmentConfig, StagingConfig, ProductionConfig):
c = cls()
print(f'{cls.__name__}: model={c.MODEL} log_level={c.LOG_LEVEL} max_steps={c.MAX_STEPS} cache={c.CACHE_ENABLED}')
Config Factory: Selecting the Right Profile
A config factory function reads the ENV variable and returns the appropriate config class. This single function is the only place that knows about the environment switch logic.
import os
def get_config():
env = os.getenv('ENV', 'development').lower()
configs = {
'development': DevelopmentConfig,
'staging': StagingConfig,
'production': ProductionConfig
}
config_class = configs.get(env)
if not config_class:
raise ValueError(f'Unknown environment: {env}')
return config_class()
# Usage throughout your agent:
config = get_config()
print(f'Model: {config.MODEL}')
print(f'Max steps: {config.MAX_STEPS}')
print(f'Log level: {config.LOG_LEVEL}')
# All code uses config.MODEL, config.LOG_LEVEL etc.
# Switching environments requires only changing ENV variablePydantic Settings for Typed Configuration
pydantic-settings provides a powerful, type-safe way to define configuration. It auto-reads environment variables, validates types, and can load from .env files. Install with pip install pydantic-settings.
# pip install pydantic-settings
from pydantic_settings import BaseSettings
from pydantic import Field
from typing import Literal
class AgentSettings(BaseSettings):
# Required fields — raise error if not set
openai_api_key: str
search_api_key: str
# Optional with defaults
env: Literal['development', 'staging', 'production'] = 'development'
model: str = 'gpt-4o-mini'
max_steps: int = Field(default=20, ge=1, le=100) # validated range
log_level: str = 'INFO'
cache_enabled: bool = True
cache_ttl_seconds: int = Field(default=3600, ge=60)
class Config:
env_file = '.env'
case_sensitive = False # OPENAI_API_KEY -> openai_api_key
# settings = AgentSettings() # raises ValidationError if required vars missingPydantic Settings with Environment-Specific Overrides
Combine Pydantic Settings with computed properties to apply environment-specific defaults that can still be overridden by environment variables.
from pydantic_settings import BaseSettings
from pydantic import model_validator
import os
class AgentSettings(BaseSettings):
openai_api_key: str
env: str = 'development'
model: str = ''
log_level: str = ''
max_steps: int = 0
@model_validator(mode='after')
def apply_env_defaults(self) -> 'AgentSettings':
env_defaults = {
'development': {'model': 'gpt-4o-mini', 'log_level': 'DEBUG', 'max_steps': 10},
'staging': {'model': 'gpt-4o-mini', 'log_level': 'INFO', 'max_steps': 20},
'production': {'model': 'gpt-4o', 'log_level': 'WARNING', 'max_steps': 30}
}
defaults = env_defaults.get(self.env, env_defaults['development'])
if not self.model: self.model = defaults['model']
if not self.log_level: self.log_level = defaults['log_level']
if not self.max_steps: self.max_steps = defaults['max_steps']
return self
class Config:
env_file = '.env'Feature Flags Per Environment
Use config profiles to enable or disable features per environment. For example, enable debug UI only in development, use real payments only in production, and point to sandboxed services in staging.
import os
class AgentFeatureFlags:
env = os.getenv('ENV', 'development')
# Enable memory persistence (requires DB)
MEMORY_ENABLED: bool = env in ('staging', 'production')
# Use real payment processing
REAL_PAYMENTS: bool = env == 'production'
# Enable verbose step-by-step output
VERBOSE_STEPS: bool = env == 'development'
# Use cheap model for unit test runs
FORCE_MINI_MODEL: bool = os.getenv('CI') == 'true'
flags = AgentFeatureFlags()
print(f'Memory: {flags.MEMORY_ENABLED}')
print(f'Verbose: {flags.VERBOSE_STEPS}')
print(f'Payments: {flags.REAL_PAYMENTS}')Configuration Validation at Startup
Validate all configuration at startup and print a summary so operators can verify the agent is configured correctly before it begins processing. This avoids silent misconfiguration in production.
import os
import sys
def validate_and_print_config(config) -> None:
print(f'=== Agent Configuration ===')
print(f'Environment : {config.env}')
print(f'Model : {config.model}')
print(f'Max steps : {config.max_steps}')
print(f'Log level : {config.log_level}')
print(f'Cache : {"enabled" if config.cache_enabled else "disabled"}')
print(f'OpenAI key : ...{config.openai_api_key[-4:]}')
print('===========================')
# Critical validations
if config.env == 'production' and config.log_level == 'DEBUG':
print('WARNING: DEBUG logging in production exposes sensitive data!')
if not config.openai_api_key:
print('FATAL: OPENAI_API_KEY not set')
sys.exit(1)
print('Configuration validated.')
if __name__ == '__main__':
from types import SimpleNamespace
demo_config = SimpleNamespace(
env='development', model='gpt-4o-mini', max_steps=10,
log_level='DEBUG', cache_enabled=False, openai_api_key='sk-demo-1234'
)
validate_and_print_config(demo_config)
Overriding Config Values per Environment
In CI/CD pipelines, override specific config values without changing the entire profile. Pass individual variables alongside the ENV variable to customize settings for a specific deployment.
# Staging deployment with custom model override:
# ENV=staging AGENT_MODEL=gpt-4o python agent.py
# Production with reduced max_steps for cost control:
# ENV=production AGENT_MAX_STEPS=15 python agent.py
# CI test run — use production profile but with cheap model:
# ENV=production AGENT_MODEL=gpt-4o-mini CI=true python agent.py
# The config class reads ENV first for the profile,
# then individual overrides take precedence:
import os
env = os.getenv('ENV', 'development')
config = get_config() # loads base profile for env
# Individual overrides applied on top:
if os.getenv('AGENT_MODEL'):
config.MODEL = os.getenv('AGENT_MODEL')
if os.getenv('AGENT_MAX_STEPS'):
config.MAX_STEPS = int(os.getenv('AGENT_MAX_STEPS'))
print(f'Final model: {config.MODEL}')Documenting Config Profiles for Teammates
Document your configuration profiles clearly — in code comments, README, or both. New developers need to understand what changes between environments to deploy confidently.
# config_profiles.py — Configuration per environment
#
# | Setting | development | staging | production |
# |----------------|----------------|----------------|-------------|
# | MODEL | gpt-4o-mini | gpt-4o-mini | gpt-4o |
# | MAX_STEPS | 10 | 20 | 30 |
# | LOG_LEVEL | DEBUG | INFO | WARNING |
# | CACHE_ENABLED | False | True | True |
# | MEMORY_DB | SQLite (local) | PostgreSQL | PostgreSQL |
#
# To switch environments:
# ENV=staging python agent.py
#
# To override a single setting:
# ENV=production AGENT_MAX_STEPS=15 python agent.py
print('Config profile table documents all per-environment differences')Config in Tests: Forced Test Profile
Tests should always run with a specific test configuration — never production settings. Create a test config fixture that applies the appropriate settings and prevents any accidental production API calls.
import os
import pytest
@pytest.fixture(autouse=True)
def test_environment(monkeypatch):
'Force test configuration for all tests'
monkeypatch.setenv('ENV', 'test')
monkeypatch.setenv('AGENT_MODEL', 'gpt-4o-mini')
monkeypatch.setenv('AGENT_MAX_STEPS', '5') # short loops in tests
monkeypatch.setenv('LOG_LEVEL', 'DEBUG')
monkeypatch.setenv('CACHE_ENABLED', 'false')
# Use a fake API key — tests should mock all LLM calls
monkeypatch.setenv('OPENAI_API_KEY', 'test-key-not-real')
# This fixture runs before every test automatically
# Tests cannot accidentally use production settingsKnowledge Check: Configuration Profiles
Test your understanding of environment-specific configuration profiles.
Recap: Configuration Profiles for Dev and Prod
You now have a complete configuration management strategy for agents across environments:
- Use an
ENVvariable to identify the deployment context - Define config classes per environment with appropriate defaults
- Use a config factory to select the right profile automatically
- Use
pydantic-settingsfor type-safe, validated configuration - Use feature flags to enable/disable features per environment
- Validate and print config at startup so operators can verify settings
- Force a test configuration in pytest fixtures to prevent production calls
Good configuration management is what makes the same codebase safely deployable to development, staging, and production.
Frequently asked questions
Is the “Configuration Profiles for Dev and Prod” lesson free?
Yes — the full text of “Configuration Profiles for Dev and Prod” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.
What will I learn in “Configuration Profiles for Dev and Prod”?
Environment-specific configs, feature flags, and staged deployments. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start AI Agents?
No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Configuration Profiles for Dev and Prod” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this AI Agents lesson?
Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Environment Variables for Agents
- .env Files and python-dotenv
- Secrets Rotation and Security
- Configuration Profiles for Dev and Prod