Understanding Model Slots and Per-Analyzer Configuration in NVIDIA SkillSpector
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.
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:
# 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.
The Resolution Priority Order
The _resolve_slot_model function implements a four-tier fallback mechanism:
- Per-slot environment variable:
SKILLSPECTOR_MODEL_<SLOT>takes highest precedence - Provider slot defaults: The active provider's
SLOT_DEFAULTSmapping - Global environment variable:
SKILLSPECTOR_MODELas a generic fallback - Provider default: The provider's
DEFAULT_MODELconstant
# 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 defines:
# 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:
# 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:
# 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:
# 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:
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:
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, which lists known model identifiers and context lengths.
When SKILLSPECTOR_STRICT_MODEL_VALIDATION is set to true, invalid configurations raise exceptions rather than warnings:
# 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.pyvia theMODEL_CONFIGdictionary and_resolve_slot_model()function - Per-analyzer binding happens through slot identifiers, allowing fine-grained model selection without code changes
- Validation against
model_registry.yamlensures 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, 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; second, update the provider's SLOT_DEFAULTS dictionary (e.g., in 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 against the 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.
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 →