How Environment Variables Configure LLM Providers and API Keys in the Hiring Agent
The hiring-agent application reads LLM_PROVIDER, DEFAULT_MODEL, and GEMINI_API_KEY from environment variables to dynamically select between Ollama and Gemini backends without code changes.
The interviewstreet/hiring-agent repository uses a flexible configuration system that leverages environment variables to manage LLM provider selection and authentication. By externalizing provider settings into a .env file, the application enables developers to switch between local models via Ollama and cloud-based Google Gemini APIs simply by adjusting runtime variables. This approach eliminates hard-coded credentials and supports seamless deployment across development, staging, and production environments.
Loading Configuration from Environment Files
In prompt.py, the application initializes its configuration layer by calling python-dotenv's load_dotenv() function, which imports values from a local .env file into the process environment. After loading, the code accesses specific variables using os.getenv() with sensible defaults to ensure the application remains functional even when certain variables are undefined.
Core Environment Variables
The system recognizes three primary environment variables that control LLM behavior and authentication.
Selecting the LLM Provider via LLM_PROVIDER
The PROVIDER constant in prompt.py (lines 21-25) reads from the LLM_PROVIDER environment variable, validating it against the ModelProvider enum defined in models.py. If the variable is missing or contains an unrecognized value, the system forces the setting to ModelProvider.OLLAMA, ensuring the application remains operational without explicit configuration.
Configuring the Default Model with DEFAULT_MODEL
The DEFAULT_MODEL constant retrieves its value from the environment variable of the same name (line 20 in prompt.py), falling back to gemma3:4b when unspecified. This default applies when no specific model is requested during provider initialization, making it easy to standardize model usage across different deployment contexts.
Securing API Keys through GEMINI_API_KEY
For Google Gemini integration, the application retrieves the authentication token from GEMINI_API_KEY (line 67 in prompt.py), defaulting to an empty string when absent. This variable is critical for cloud-based inference; without it, the system cannot instantiate a GeminiProvider and will automatically fall back to local Ollama instances.
Runtime Provider Resolution
The llm_utils.py file contains the initialize_llm_provider function, which implements the runtime selection logic using the MODEL_PROVIDER_MAPPING dictionary (line 53) to determine the appropriate provider for a given model name. When the mapping resolves to ModelProvider.GEMINI, the function checks for a non-empty GEMINI_API_KEY; if the key is missing, it logs a warning and instantiates an OllamaProvider instead (lines 54-60), ensuring graceful degradation rather than runtime failures.
Practical Configuration Examples
Developers can configure the system by creating a .env file in the project root:
# .env configuration
LLM_PROVIDER=gemini # or "ollama"
DEFAULT_MODEL=gemini-2.5-pro
GEMINI_API_KEY=your_gemini_key_here
To initialize the LLM provider in application code:
from prompt import DEFAULT_MODEL, GEMINI_API_KEY
from llm_utils import initialize_llm_provider
# Initialize based on environment-derived settings
llm = initialize_llm_provider(DEFAULT_MODEL)
# Generate a response
response = llm.chat(
model=DEFAULT_MODEL,
messages=[{"role": "user", "content": "Explain the difference between Ollama and Gemini"}]
)
print(response)
When the Gemini key is missing, the fallback behavior activates automatically:
# Assuming LLM_PROVIDER=gemini but GEMINI_API_KEY is empty
llm = initialize_llm_provider("gemini-2.5-pro")
# Logs: "⚠️ Gemini API key not found. Falling back to Ollama."
# Returns: OllamaProvider instance
Summary
- Environment variables drive provider selection without requiring code modifications
prompt.pyloads configuration viaload_dotenv()and validates against theModelProviderenum- Three variables control behavior:
LLM_PROVIDER,DEFAULT_MODEL, andGEMINI_API_KEY - Graceful fallback to Ollama occurs when Gemini keys are missing or invalid
llm_utils.pyimplements runtime provider instantiation based on environment-derived settings and theMODEL_PROVIDER_MAPPINGlookup
Frequently Asked Questions
What happens if I don't set a Gemini API key?
If GEMINI_API_KEY is empty or unset and the provider mapping suggests Gemini, the application logs a warning message and automatically falls back to an OllamaProvider instance. This allows continued operation using local models even when cloud API credentials are unavailable.
Can I use other LLM providers beyond Ollama and Gemini?
The current implementation in models.py defines a ModelProvider enum limited to OLLAMA and GEMINI values. Adding new providers would require extending this enum and implementing corresponding provider classes in llm_utils.py, as the MODEL_PROVIDER_MAPPING dictionary expects these specific enum values.
Where should I store sensitive API keys in production?
While the .env file works for local development, production deployments should inject GEMINI_API_KEY directly through the hosting platform's secret management system or container orchestration environment variables. Never commit credentials to version control, even in private repositories.
How does the application handle invalid provider names?
In prompt.py, the code validates the LLM_PROVIDER value against the ModelProvider enum; any unrecognized or missing value automatically defaults to ModelProvider.OLLAMA. This defensive programming pattern prevents configuration errors from crashing the application and ensures local development remains friction-free.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →