# Understanding Model Slots and Per-Analyzer Configuration in NVIDIA SkillSpector

> Learn how to use SkillSpector model slots to map analyzers to LLM models. Centralized configuration via environment variables and provider defaults simplifies per-analyzer model management.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: deep-dive
- Published: 2026-07-09

---

**Model slots in SkillSpector are named logical buckets that map specific analyzers to LLM models, with per-slot configuration managed via environment variables and provider defaults centralized in [`constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/constants.py).**

According to the NVIDIA/SkillSpector source code, the tool uses **model slots** as a flexible abstraction layer to route different security and quality analyzers to specific large language models. This architecture decouples analyzer logic from hard-coded provider IDs, allowing operators to bind specialized analyzers to optimized models without modifying source code.

## What Are Model Slots in SkillSpector?

A **model slot** is a named identifier that acts as a logical placeholder for a concrete LLM model. Rather than embedding provider-specific model IDs directly into analyzer code, SkillSpector assigns each analyzer to a slot, which is then resolved to an actual model at runtime.

The repository defines eight built-in slots in [`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py):

```python

# src/skillspector/constants.py

_MODEL_SLOTS: tuple[str, ...] = (
    "default",
    "mcp_least_privilege",
    "mcp_rug_pull",
    "mcp_tool_poisoning",
    "semantic_developer_intent",
    "semantic_quality_policy",
    "semantic_security_discovery",
    "meta_analyzer",
)

```

Each slot serves a distinct purpose:

- **default**: General-purpose analyses and fallback for analyzers without specific slot requirements
- **mcp_least_privilege**: Evaluating least-privilege MCP policies
- **mcp_rug_pull**: Detecting RUG-pull style malicious code generation
- **mcp_tool_poisoning**: Identifying tool-poisoning attacks
- **semantic_developer_intent**: Extracting semantic intent from source code
- **semantic_quality_policy**: Enforcing quality policies
- **semantic_security_discovery**: Security-focused semantic discovery
- **meta_analyzer**: Orchestrating other analyzers

## How Model Slot Resolution Works

The resolution of a slot to a concrete model ID follows a hierarchical waterfall defined in [`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py).

### The Resolution Priority Order

The `_resolve_slot_model` function implements a four-tier fallback mechanism:

1. **Per-slot environment variable**: `SKILLSPECTOR_MODEL_<SLOT>` takes highest precedence
2. **Provider slot defaults**: The active provider's `SLOT_DEFAULTS` mapping
3. **Global environment variable**: `SKILLSPECTOR_MODEL` as a generic fallback
4. **Provider default**: The provider's `DEFAULT_MODEL` constant

```python

# src/skillspector/constants.py

def _resolve_slot_model(slot: str) -> str:
    """Resolve the model for *slot* with per-slot env var override support."""
    env_key = f"SKILLSPECTOR_MODEL_{slot.upper()}"
    env_val = os.environ.get(env_key, "").strip()
    if env_val:
        return env_val
    return _provider.resolve_model(slot)

```

### Provider-Specific Slot Defaults

Each LLM provider implements `resolve_model()` with slot-aware logic. For example, the OpenAI provider in [`src/skillspector/providers/openai/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/openai/provider.py) defines:

```python

# src/skillspector/providers/openai/provider.py

def resolve_model(self, slot: str = "default") -> str:
    """Resolve model: ``SKILLSPECTOR_MODEL`` env > slot default > ``DEFAULT_MODEL``."""
    user_input = os.getenv("SKILLSPECTOR_MODEL", "").strip()
    return user_input or self.SLOT_DEFAULTS.get(slot, "") or self.DEFAULT_MODEL

```

The `SLOT_DEFAULTS` dictionary maps logical slot names to provider-specific model identifiers. Similar implementations exist for Anthropic, Bedrock, and NvBuild providers.

## Per-Analyzer Model Configuration

Analyzers bind to slots through class attributes rather than direct model references.

### Slot Binding via ANALYZER_ID

Each analyzer class specifies its preferred slot through an identifier (typically `ANALYZER_ID`). At runtime, the analyzer queries the central `MODEL_CONFIG` dictionary to retrieve the resolved model:

```python

# Pseudocode pattern used by analyzers

model_id = MODEL_CONFIG.get(self.ANALYZER_ID, MODEL_CONFIG["default"])

```

The `MODEL_CONFIG` dictionary is built at import time by mapping each slot through the resolution function:

```python

# src/skillspector/constants.py

MODEL_CONFIG: dict[str, str] = {slot: _resolve_slot_model(slot) for slot in _MODEL_SLOTS}

```

This architecture allows the `meta_analyzer` slot to use a high-capacity model while specialized security slots like `mcp_tool_poisoning` use faster, focused models.

## Environment-Based Configuration Examples

Operators configure slots via environment variables without touching code.

### Overriding Specific Slots

Set the `SKILLSPECTOR_MODEL_<SLOT>` pattern to target specific analyzers:

```bash

# Use GPT-4 for default analyses

export SKILLSPECTOR_MODEL=gpt-4

# Use Claude-Haiku for security discovery

export SKILLSPECTOR_MODEL_SEMANTIC_SECURITY_DISCOVERY=claude-haiku

```

### CI Pipeline Configuration

In automated pipelines, override specific slots for targeted analysis:

```yaml
steps:
  - name: Run SkillSpector
    env:
      SKILLSPECTOR_MODEL_MCP_RUG_PULL: meta-llama/7b
    run: |
      skillspector scan .

```

Only the `mcp_rug_pull` analyzer uses the Meta Llama model; others use the global configuration.

### Accessing Configuration Programmatically

Custom tooling can inspect the resolved configuration:

```python
from skillspector.constants import MODEL_CONFIG

# Retrieve the model for the meta_analyzer slot

meta_analyzer_model = MODEL_CONFIG["meta_analyzer"]
print(f"Meta-analyzer will run on model: {meta_analyzer_model}")

```

## Model Validation

SkillSpector validates resolved models against [`model_registry.yaml`](https://github.com/NVIDIA/SkillSpector/blob/main/model_registry.yaml), which lists known model identifiers and context lengths.

When `SKILLSPECTOR_STRICT_MODEL_VALIDATION` is set to `true`, invalid configurations raise exceptions rather than warnings:

```python

# src/skillspector/constants.py

if strict and unknown:
    raise ValueError(...)

```

This prevents runtime failures from typos or unsupported model IDs.

## Summary

- **Model slots** are logical identifiers (e.g., `mcp_rug_pull`, `semantic_security_discovery`) that decouple analyzers from specific LLM providers
- **Configuration resolution** follows a strict hierarchy: per-slot env vars → provider slot defaults → global env vars → provider defaults
- **Centralized mapping** occurs in [`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py) via the `MODEL_CONFIG` dictionary and `_resolve_slot_model()` function
- **Per-analyzer binding** happens through slot identifiers, allowing fine-grained model selection without code changes
- **Validation** against [`model_registry.yaml`](https://github.com/NVIDIA/SkillSpector/blob/main/model_registry.yaml) ensures only supported models are loaded, with strict mode available for CI/CD pipelines

## Frequently Asked Questions

### What is the default model slot in SkillSpector?

The `default` slot serves as the catch-all for analyzers that do not specify a particular slot requirement. It is also the fallback when a specific slot cannot be resolved. According to the source in [`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py), if an analyzer requests a slot not present in `MODEL_CONFIG`, the system falls back to `MODEL_CONFIG["default"]`.

### How do I override the model for a specific analyzer?

Set an environment variable following the `SKILLSPECTOR_MODEL_<SLOT>` pattern, where `<SLOT>` is the uppercase slot name. For example, `export SKILLSPECTOR_MODEL_MCP_TOOL_POISONING=gpt-4-turbo` forces the tool poisoning analyzer to use GPT-4 Turbo, regardless of provider defaults. This override takes precedence over all other configuration layers.

### Can I add custom model slots to SkillSpector?

Yes, but it requires modifying three components: first, add the slot name to the `_MODEL_SLOTS` tuple in [`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py); second, update the provider's `SLOT_DEFAULTS` dictionary (e.g., in [`src/skillspector/providers/openai/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/openai/provider.py)) to map the new slot to a default model; third, reference the new slot from your analyzer's `ANALYZER_ID` attribute. After restarting the process, the slot automatically appears in `MODEL_CONFIG`.

### Where does SkillSpector validate model identifiers?

Validation occurs in [`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py) against the [`model_registry.yaml`](https://github.com/NVIDIA/SkillSpector/blob/main/model_registry.yaml) file, which contains the canonical list of supported models and their context limits. When `SKILLSPECTOR_STRICT_MODEL_VALIDATION` is enabled, unknown model IDs raise `ValueError` exceptions immediately upon configuration loading, preventing later runtime failures during analysis execution.