# How to Configure API Keys for Different LLM Providers: A Complete Guide

> Learn to configure API keys for various LLM providers like OpenAI, Moonshot, and Ark. Easily set environment variables and select your active provider for seamless integration.

- Repository: [Bojie Li/ai-agent-book](https://github.com/bojieli/ai-agent-book)
- Tags: how-to-guide
- Published: 2026-08-22

---

**You can configure API keys for different LLM providers by setting provider-specific environment variables such as `OPENAI_API_KEY`, `MOONSHOT_API_KEY`, or `ARK_API_KEY`, and selecting your active provider using the `LLM_PROVIDER` variable in [`chapter9/prompt-auto-optimization/config.py`](https://github.com/bojieli/ai-agent-book/blob/main/chapter9/prompt-auto-optimization/config.py).**

The `bojieli/ai-agent-book` repository simplifies multi-provider LLM access through a centralized, environment-variable-driven configuration system. By leveraging [`chapter9/prompt-auto-optimization/config.py`](https://github.com/bojieli/ai-agent-book/blob/main/chapter9/prompt-auto-optimization/config.py) and Python's `dotenv.load_dotenv()` implementation, you can seamlessly switch between OpenAI, Moonshot, ARK, and OpenRouter without modifying application logic. This approach allows you to configure API keys for different LLM providers using standard shell exports or a local `.env` file.

## Supported LLM Providers and Required Environment Variables

The configuration system supports four distinct providers, each requiring specific environment variables for authentication:

| Provider | Required Environment Variable | Default Model | Base URL |
|----------|------------------------------|---------------|----------|
| **OpenAI** | `OPENAI_API_KEY` | `gpt-5.6-luna` | OpenAI SDK default |
| **Moonshot** | `MOONSHOT_API_KEY` | `kimi-k3` | `https://api.moonshot.cn/v1` |
| **ARK** | `ARK_API_KEY` (and optional `ARK_MODEL`) | `doubao-seed-1-6-250615` | `https://ark.cn-beijing.volces.com/api/v3` |
| **OpenRouter** | `OPENROUTER_API_KEY` (fallback) | `openai/gpt-4o-mini` | `https://openrouter.ai/api/v1` |

The system reads these variables via `dotenv.load_dotenv()`, enabling configuration through either shell exports or a project-level `.env` file placed at the repository root.

## Centralized Configuration Architecture

In [`chapter9/prompt-auto-optimization/config.py`](https://github.com/bojieli/ai-agent-book/blob/main/chapter9/prompt-auto-optimization/config.py), the configuration logic abstracts provider-specific implementations through several key functions:

- **`get_provider()`** – Reads the `LLM_PROVIDER` environment variable (defaults to `openai`).
- **`get_model()`** – Resolves the target model name, applying internal `_to_openrouter_model` mapping when routing through OpenRouter.
- **`get_client()`** – Returns an OpenAI-compatible client instance, automatically handling the `_use_openrouter` fallback logic.
- **`get_temperature()`** – Returns `0` for deterministic models or `1` for reasoning models (e.g., `gpt-5.x`, `kimi-k3`, `o1`), unless explicitly overridden by `LLM_TEMPERATURE`.

This architecture ensures that when you configure API keys for different LLM providers, the application code remains provider-agnostic and maintains consistent interfaces regardless of the backend service.

## Step-by-Step Configuration Guide

### 1. Create Your Environment File

Place a `.env` file at your project root with your chosen provider and corresponding API keys:

```text

# Select the active provider

LLM_PROVIDER=openai          # Options: openai, moonshot, ark

# Provider-specific API keys

OPENAI_API_KEY=your-openai-key
MOONSHOT_API_KEY=your-moonshot-key
ARK_API_KEY=your-ark-key
ARK_MODEL=doubao-seed-1-6-250615   # Optional: overrides ARK default

# Universal fallback option

OPENROUTER_API_KEY=your-openrouter-key

# Optional overrides

LLM_MODEL=gpt-4o-mini       # Overrides the provider's default model

LLM_TEMPERATURE=0.7         # Overrides automatic temperature selection

```

### 2. Select Your Provider and Model

Set `LLM_PROVIDER` to activate a specific configuration:

- **`openai`**: Uses `OPENAI_API_KEY` and defaults to `gpt-5.6-luna`.
- **`moonshot`**: Uses `MOONSHOT_API_KEY` and defaults to `kimi-k3`.
- **`ark`**: Uses `ARK_API_KEY` and defaults to `doubao-seed-1-6-250615` (unless `ARK_MODEL` is set).

Use `LLM_MODEL` to override the default model for any provider, regardless of the selected backend.

### 3. Runtime Provider Switching

Switch providers without editing files by exporting variables in your shell:

```bash
export LLM_PROVIDER=moonshot
export MOONSHOT_API_KEY=sk-xxxxxx
python your_script.py

```

This approach allows you to configure API keys for different LLM providers dynamically across development, staging, and production environments.

## Automatic OpenRouter Fallback

The configuration implements intelligent fallback logic via internal `_use_openrouter` checks within `get_client()`. If the selected provider's specific key is missing (e.g., no `OPENAI_API_KEY` set) but `OPENROUTER_API_KEY` is present, the client automatically routes requests through OpenRouter.

Additionally, the system forces OpenRouter routing when detecting "reasoning" models (such as `gpt-5.x`, `kimi-k3`, or `o1`). These models require a higher temperature setting (defaulting to `1`), which OpenRouter handles through specialized routing infrastructure.

## Accessing Configured Clients in Python

Once you configure API keys for different LLM providers, use the following pattern to instantiate clients in your application:

```python
from chapter9.prompt_auto_optimization.config import get_client, get_model, get_temperature

client = get_client()           # Returns OpenAI-compatible client for selected provider

model = get_model()             # Resolves to final model string (with OpenRouter mapping if needed)

temperature = get_temperature() # Returns 0 (deterministic) or 1 (reasoning), or custom value

response = client.chat.completions.create(
    model=model,
    messages=[{"role": "user", "content": "Explain quantum entanglement"}],
    temperature=temperature,
)
print(response.choices[0].message.content)

```

The `get_client()` function automatically selects the correct base URL and authentication headers based on your environment configuration.

## Summary

- **Environment Variables**: Configure API keys for different LLM providers using `OPENAI_API_KEY`, `MOONSHOT_API_KEY`, `ARK_API_KEY`, or `OPENROUTER_API_KEY` according to the target service.
- **Centralized Config**: All provider logic resides in [`chapter9/prompt-auto-optimization/config.py`](https://github.com/bojieli/ai-agent-book/blob/main/chapter9/prompt-auto-optimization/config.py), utilizing `dotenv.load_dotenv()` for secure variable injection.
- **Provider Selection**: Use `LLM_PROVIDER` to switch between openai, moonshot, and ark modes without code changes.
- **Automatic Fallback**: The `_use_openrouter` logic ensures continuity if primary provider keys are missing but `OPENROUTER_API_KEY` is available.
- **Model Overrides**: Customize behavior with `LLM_MODEL` and `LLM_TEMPERATURE` environment variables to override defaults.

## Frequently Asked Questions

### What environment variables do I need to configure API keys for different LLM providers?

You need provider-specific keys: `OPENAI_API_KEY` for OpenAI, `MOONSHOT_API_KEY` for Moonshot, and `ARK_API_KEY` for ARK. Optionally, set `OPENROUTER_API_KEY` as a universal fallback. The `LLM_PROVIDER` variable determines which configuration is active, defaulting to `openai` if unset.

### How does the OpenRouter fallback work when a provider key is missing?

The system checks `_use_openrouter` logic in `get_client()`. If your selected provider's key is unset (e.g., missing `OPENAI_API_KEY`) but `OPENROUTER_API_KEY` exists, the client automatically routes requests to OpenRouter. This also occurs automatically for reasoning models like `gpt-5.x` or `o1` to ensure proper temperature handling.

### Can I override default models and temperature settings?

Yes. Set `LLM_MODEL` to override any provider's default model. Set `LLM_TEMPERATURE` to override the automatic selection, which normally returns `0` for standard models and `1` for reasoning models detected via internal `_to_openrouter_model` mapping.

### Where is the LLM configuration centralized in the repository?

All configuration logic is centralized in [`chapter9/prompt-auto-optimization/config.py`](https://github.com/bojieli/ai-agent-book/blob/main/chapter9/prompt-auto-optimization/config.py) within the `bojieli/ai-agent-book` repository. This file contains `get_provider()`, `get_model()`, `get_client()`, and `get_temperature()` functions that manage provider selection, model resolution, and client instantiation.