# How to Configure Model Tier Selection (1x/10x/30x Cost Factors) in Ouroboros

> Learn how to configure Model Tier selection in Ouroboros. Easily set 1x, 10x, or 30x cost factors by editing config.yaml or programmatically using the Tier enum.

- Repository: [Q00/ouroboros](https://github.com/Q00/ouroboros)
- Tags: how-to-guide
- Published: 2026-03-14

---

**Configure Model Tier selection in Ouroboros by editing the `economics.tiers` section in `~/.ouroboros/config.yaml`, where `frugal` (1×), `standard` (10×), and `frontier` (30×) tiers map to specific LLM providers and models, or programmatically select tiers using the `Tier` enum with `get_model_for_tier()`.**

Ouroboros implements a **Progressive Adaptive LLM (PAL)** routing system that balances computational cost against model capability through three distinct pricing tiers. Understanding how to configure these Model Tier selections allows you to optimize the trade-off between inference speed, accuracy, and API costs when running autonomous coding workflows.

## Understanding the Three-Tier Cost Structure

The PAL system categorizes every LLM request into one of three tiers, each defined by a specific **cost multiplier** relative to the base tier:

- **Frugal (1×)**: Fast, inexpensive models for routine tasks like log analysis, syntax fixes, and Stage 1 code generation.
- **Standard (10×)**: Balanced capability for logic design, Stage 2 evaluation, and refactoring operations.
- **Frontier (30×)**: Most capable models reserved for consensus building, lateral thinking, and "big-bang" synthesis tasks.

These multipliers are enforced by the `Tier` **enum** located in [`src/ouroboros/routing/tiers.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/routing/tiers.py), which exposes the `cost_multiplier` property to ensure runtime consistency【/cache/repos/github.com/Q00/ouroboros/main/src/ouroboros/routing/tiers.py#L38-L62】.

## Configuration Schema and Default Settings

Tier definitions reside within the **economics** section of the central configuration model. The schema is defined by `TierConfig` in [`src/ouroboros/config/models.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/config/models.py), which contains:

- `cost_factor`: The integer multiplier (1, 10, or 30)
- `models`: A list of `ModelConfig` objects specifying provider and model name pairs【/cache/repos/github.com/Q00/ouroboros/main/src/ouroboros/config/models.py#L40-L53】

The function `get_default_config()` in the same file generates the complete default configuration including all three tiers with their standard cost factors and model assignments【/cache/repos/github.com/Q00/ouroboros/main/src/ouroboros/config/models.py#L81-L124】.

## Customizing Model Tiers in config.yaml

Override default behavior by editing `~/.ouroboros/config.yaml`. The `economics.tiers` section maps tier names to their configurations.

### Modifying Cost Factors

Each tier expects a specific cost factor. Changing `frugal` to anything other than `1`, `standard` from `10`, or `frontier` from `30` triggers a validation error.

Example configuration:

```yaml
economics:
  tiers:
    frugal:
      cost_factor: 1  # Must be 1 for frugal tier

      models:
        - provider: openai
          model: gpt-4o-mini
    standard:
      cost_factor: 10  # Must be 10 for standard tier

      models:
        - provider: anthropic
          model: claude-sonnet-4-6
    frontier:
      cost_factor: 30  # Must be 30 for frontier tier

      models:
        - provider: openai
          model: o3

```

Attempting to set `cost_factor: 2` under `frugal` results in a `ConfigError` during startup validation.

### Adding or Removing Models

Customize which LLM providers and models are available within each tier by editing the `models` list. Each entry requires `provider` and `model` keys.

Example adding Google Gemini to the standard tier:

```yaml
economics:
  tiers:
    standard:
      cost_factor: 10
      models:
        - provider: openai
          model: gpt-4o
        - provider: google
          model: gemini-2.5-pro

```

### Setting the Default Tier

Control which tier Ouroboros uses when no specific tier is requested by setting `default_tier` under `economics`:

```yaml
economics:
  default_tier: frugal  # Options: frugal, standard, frontier

  tiers:
    # ... tier definitions

```

## Selecting Tiers Programmatically

For dynamic tier selection within Python code, use the `Tier` enum and `get_model_for_tier()` function from [`src/ouroboros/routing/tiers.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/routing/tiers.py).

The function signature is:

```python
def get_model_for_tier(tier: Tier, config: OuroborosConfig) -> Result[ModelConfig, ConfigError]:

```

This performs three steps:
1. Validates the tier exists via `get_tier_config`
2. Confirms the `cost_factor` matches `Tier.cost_multiplier` (1, 10, or 30)
3. Returns a random model from the tier's `models` list for load balancing【/cache/repos/github.com/Q00/ouroboros/main/src/ouroboros/routing/tiers.py#L66-L127】

Example usage:

```python
from ouroboros.routing.tiers import Tier, get_model_for_tier
from ouroboros.config.models import get_default_config

config = get_default_config()

# Select frontier tier (30x)

result = get_model_for_tier(Tier.FRONTIER, config)

if result.is_ok:
    model = result.value
    print(f"Selected {model.provider}/{model.model} from frontier tier")
else:
    print(f"Configuration error: {result.error}")

```

## Validation and Error Handling

Ouroboros validates tier configuration at startup to prevent runtime failures. The `validate_tier_configuration` function in [`src/ouroboros/routing/tiers.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/routing/tiers.py) ensures:

- All three tiers (frugal, standard, frontier) are present
- Each tier's `cost_factor` matches the expected multiplier (1, 10, 30)
- Each tier contains at least one valid model configuration【/cache/repos/github.com/Q00/ouroboros/main/src/ouroboros/routing/tiers.py#L200-L247】

If validation fails, a `ConfigError` is raised immediately, preventing the system from starting with misconfigured economics.

## Summary

- Ouroboros uses a **three-tier PAL system** with fixed cost multipliers: **Frugal (1×)**, **Standard (10×)**, and **Frontier (30×)**.
- Configure tiers in `~/.ouroboros/config.yaml` under the `economics.tiers` section, specifying `cost_factor` and `models` lists.
- Use the `Tier` enum (`FRUGAL`, `STANDARD`, `FRONTIER`) with `get_model_for_tier()` to programmatically select models.
- All configurations are validated at startup; mismatched cost factors trigger immediate `ConfigError` exceptions.

## Frequently Asked Questions

### What happens if I set the wrong cost factor for a tier?

Ouroboros validates tier configurations at startup via `validate_tier_configuration`. If you set a `cost_factor` that doesn't match the tier's expected multiplier (e.g., setting `2` instead of `1` for the frugal tier), the system raises a `ConfigError` and refuses to start, preventing runtime billing mismatches.

### Can I add custom tiers beyond the three default ones?

The current implementation in [`src/ouroboros/routing/tiers.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/routing/tiers.py) defines a fixed `Tier` enum with three variants: `FRUGAL`, `STANDARD`, and `FRONTIER`. The validation logic expects exactly these three tiers to be present. While you can customize the models within each tier, adding entirely new tier categories would require modifying the source code enum and validation functions.

### How does Ouroboros handle model selection when multiple models are configured in one tier?

When you call `get_model_for_tier()`, the function retrieves the tier configuration and performs a random selection from the `models` list. This provides simple load balancing across providers or model variants within the same cost tier, as implemented in [`src/ouroboros/routing/tiers.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/routing/tiers.py) lines 87-95.

### Where is the default configuration generated if I don't have a config file?

The default configuration is generated by the `get_default_config()` function in [`src/ouroboros/config/models.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/config/models.py). This function creates the standard three-tier setup with predefined models and cost factors (1×, 10×, 30×) when no user configuration exists, serving as the base for any user overrides.