← Agent Frameworks 🕐 18 min read
Agent Frameworks

NVIDIA Data Flywheel Blueprint: Automated SLM Factory for Enterprise AI

> **Source credibility: MEDIUM** — vendor-produced technical documentation from NVIDIA. Apache-2.0 open-source code at `NVIDIA-AI-Blueprints/data-flywheel`.

See also (wiki): wiki/enterprise-slm-specialization.md · wiki/mlops-ai-platform-engineering.md · wiki/inference-economics.md · wiki/token-economics.md · wiki/data-readiness.md · wiki/hitl-deployment-pattern.md · wiki/agentic-ai-governance.md · wiki/slm-fine-tuning-enterprise.md


Source credibility: MEDIUM — vendor-produced technical documentation from NVIDIA. Apache-2.0 open-source code at NVIDIA-AI-Blueprints/data-flywheel. The 98.6% cost reduction figure is a real-world internal NVIDIA result from a specific, bounded use case (HR chatbot tool routing); not an industry benchmark or survey statistic. Architecture claims are reproducible via the open-source implementation. Deprecation notice: this blueprint was deprecated in April 2026. The underlying NeMo Microservices platform it demonstrates remains current; the reference implementation itself is no longer actively maintained. These case studies are vendor-published and represent selected wins with no control group and no independent verification.

TIER 2 — 2025 results; represents prior model generation tooling. Current NeMo Microservices architecture is active.


What a Data Flywheel Is

A data flywheel uses production traffic from a deployed AI application — prompt/response logs, end-user feedback, expert labels — to continuously improve that application’s models. The core insight: every production interaction is a training signal, and most enterprises are discarding it.

The high-level flow:

Your App → prompt/response logs → Log Store
Log Store → create datasets → Orchestrator
Orchestrator → Experiment #1, #2, ... #N → Results

Manual execution of this cycle requires ML engineers to make dozens of decisions per iteration: which models to try, how to curate datasets, which fine-tuning techniques to apply, which metrics to use for evaluation. At scale, this is a bottleneck — the experiments that could improve the model sit in a backlog while engineers work on other priorities.

The NeMo Microservices automation layer eliminates manual experiment design for the standard case. The flywheel automates: pull data from log store → group by task → deduplicate → create eval and fine-tuning datasets → run fine-tuning jobs → evaluate results → surface promising candidates. What took weeks of ML engineering becomes a job that runs overnight.

Critical framing: NVIDIA is explicit that this is a “discovery and promotion service” — not an autonomous deployment system. The flywheel surfaces candidates; humans decide what goes to production. This is important for enterprise governance conversations: it is a tool for accelerating the human decision, not replacing it.


Deprecation Context (April 2026)

The Data Flywheel Foundational Blueprint was deprecated in April 2026. NVIDIA’s statement: “It is no longer actively maintained, and new production use is not recommended. The blueprint is retained for reference only.”

What replaced it: The NeMo Microservices platform itself (docs.nvidia.com/nemo/microservices/). The blueprint was a reference implementation demonstrating how to orchestrate NeMo Microservices for flywheel purposes. Organizations building production flywheels in 2026 should work directly with NeMo Microservices rather than extending the deprecated blueprint code.

Why this file still matters: The blueprint documents the architectural patterns and design decisions of a production-grade flywheel in detail that NVIDIA’s general NeMo Microservices documentation does not replicate. The patterns (stratified splitting, LLM-as-judge, three experiment types, workload tagging schema) are valid regardless of which orchestration layer is used. The 98.6% cost reduction case study is real data. The deprecation affects the reference code, not the ideas.


The 98.6% Inference Cost Reduction: What It Covers and What It Doesn’t

NVIDIA’s headline figure: “using a Data Flywheel can reduce inference costs by up to 98.6%.”

The actual case: An internal NVIDIA HR chatbot used llama-3.1-70b-instruct for four tasks: chat, query rewriting for RAG, summarization, and tool calling. The flywheel identified that the tool calling task was simple enough that a fine-tuned llama-3.2-1b-instruct achieved ~98% accuracy relative to the 70B model. The cost reduction came from replacing the 70B model with the 1B model for that specific workload.

Caveats the documentation explicitly lists:

  1. Task type matters: Tool calling with a small, fixed set of tools is structurally simpler than open-ended generation, RAG, or summarization. The 1B model succeeded because the routing decision had low complexity — it had to choose among a small set of known tools, not generate creative responses.

  2. Single-turn, not multi-agent: The flywheel evaluates individual prompt/completion pairs. It does not evaluate multi-step agent chains where errors compound. A model that achieves 98% accuracy on individual turns may perform significantly worse in a 10-step agent chain (cumulative reliability effect, documented separately in the enterprise agent operations research).

  3. Not all workloads compress: In the same HR chatbot example, chat, query rewriting, and summarization were not candidates for model replacement. The flywheel surfaces candidates; “no good candidate” is a valid and common result.

  4. Model accuracy is relative, not absolute: Evaluation scores are LLM-as-judge similarity metrics (1–10 scale) comparing the candidate model’s output to the production model’s output — not ground truth. A score of 9/10 means the small model’s output is nearly identical to the large model’s output, not that both models are correct.

  5. Smaller models may generate longer outputs: NVIDIA explicitly flags that test-time compute is not just a function of model size — smaller models may require more tokens to reach a similar conclusion. Cost reduction from model size can be partially offset by increased token count. Benchmark your specific workload before claiming cost savings.

Second example from the documentation: Qwen-2.5-32b-coder matched llama-3.1-70b-instruct on a specific workload with no fine-tuning required — just a model swap. This shows that the flywheel’s value is not only fine-tuning; it can identify that a different-architecture model already performs comparably, eliminating training cost entirely.


NeMo Microservices Components

The flywheel orchestrates five NeMo Microservices:

NeMo Datastore

Dataset management and storage. The flywheel writes evaluation datasets, fine-tuning datasets, and LoRA adapter artifacts to the Datastore. All downstream services (Customizer, Evaluator) pull from Datastore by name/namespace.

Dataset naming convention: {namespace}/{dataset_name} — consistent with Customizer config naming. The nmp_namespace config parameter isolates flywheel datasets from other workloads in shared NeMo deployments.

NeMo Customizer

Fine-tuning via parameter-efficient techniques. Default: LoRA (Low-Rank Adaptation). Configuration per model:

customizer_config:
  gpus: <count>
  num_nodes: 1
  tensor_parallel_size: <count>
  data_parallel_size: <count>
  use_sequence_parallel: false
  micro_batch_size: <size>
  max_seq_length: 32768
  training_precision: bf16

LoRA hyperparameters:

  • adapter_dim: rank of the LoRA adapter (typical range: 8–64)
  • adapter_dropout: regularization dropout on the adapter

Training job lifecycle: create_customizer_configstart_training_job → poll status → retrieve adapter. The flywheel creates a reusable config_name per (base model, customizer config) combination to avoid recreating configs for repeated fine-tuning runs.

Output artifacts: Fine-tuned models stored as LoRA adapters at {namespace}/{output_model_name}. Adapters can be extracted post-flywheel for deployment via the LoRA extraction docs (docs/12-lora-model-extraction.md).

NeMo Evaluator

LLM-as-judge evaluation. Two evaluation modes:

For general Q&A workloads: LLM judge scores similarity on a 1–10 scale using a defined rubric:

  • 10: Nearly identical meaning; wording differences only
  • 8–9: Same key info, maybe one minor detail off
  • 6–7: Rough overlap but missing several points
  • 4–5: Some relation but wrong on most core content
  • 2–3: Largely irrelevant or incorrect
  • 1: Completely irrelevant or empty

For tool-calling workloads: Two complementary signals:

  • Programmatic: function_name accuracy (0–1), function_name_and_args_accuracy (0–1)
  • LLM judge: tool_calling_correctness (0 or 1) — strict evaluation against criteria:
    • Prediction must not be null/empty/structurally invalid
    • function.name must exactly match ground truth
    • All required arguments must be present
    • Short identifier arguments (user_id, product_id): must match exactly
    • Longer natural-language arguments (queries, messages): semantic similarity acceptable
    • Any argument failure → rating 0

Judge model configuration: Default in the reference implementation is an LLM judge deployed via NeMo Deployment Manager. For resource-constrained setups, a remote judge (external API) is supported; the auto-cleanup system explicitly notes it does not shut down remote judges during cleanup, only local ones.

NeMo Deployment Manager (DMS)

Dynamically spins NIMs up and down during evaluation to avoid running every candidate NIM simultaneously. This is critical for the economics of the flywheel: if you test 10 candidate models, you don’t need 10 NIM instances running in parallel. DMS starts a NIM for each experiment, runs evaluations, then stops it.

Resource efficiency pattern: The flywheel documentation calls this “scale across any number of NIMs by using NeMo Deployment Manager to dynamically start and stop NIMs as needed, so you don’t have to keep every NIM running at all times.”

Cleanup on shutdown: The CleanupManager activates on Celery worker shutdown (SIGTERM, SIGINT, container stop, system restart). It:

  1. Finds all flywheel runs in PENDING or RUNNING state
  2. Identifies active NIM deployments
  3. Cancels active customization jobs (NeMo Customizer)
  4. Stops all running NIM deployments (DMS)
  5. Marks all resources as CANCELLED in MongoDB

This prevents resource leaks from crashed workers — a common operational problem in long-running ML experiment pipelines.

NeMo Data Service (Embedding)

Text embedding generation for ICL (in-context learning) example selection. When icl_config uses semantic similarity for example selection (as opposed to random selection), the embedding service computes similarity between the test query and candidate ICL examples from the training set.


Three Experiment Types Per Model

For each candidate NIM, the flywheel runs three experiment types:

1. Base Evaluation (base-eval)

  • Dataset: Held-out production-like data, no ICL examples
  • Model: Out-of-the-box (no fine-tuning)
  • Purpose: Establishes baseline — what does this model do right now with no adaptation?

2. ICL Evaluation (icl-eval)

  • Dataset: Same held-out data, but each test example has ICL examples injected into the system message
  • Model: Out-of-the-box (no fine-tuning)
  • Purpose: Measures few-shot adaptation — can prompt engineering alone close the gap with the production model?

ICL example selection: Either random or semantic similarity (using NeMo Embedding Service). Semantic selection finds examples from the training set that are similar to the test query — a stronger signal but higher cost.

Configuration: icl_config in config.yaml controls:

  • max_context_length: Maximum tokens for the full ICL-augmented prompt
  • reserved_tokens: Tokens reserved for the model response
  • Number of ICL examples to inject

Operational insight: ICL evaluation often produces the cheapest path to improvement — no fine-tuning cost, no adapter deployment complexity. When a base model’s ICL score is close to the production model’s performance, few-shot prompting may be sufficient without fine-tuning.

3. Customized Evaluation (customized-eval)

  • Dataset: Same held-out base data (no ICL examples)
  • Model: LoRA fine-tuned on training split of production traffic
  • Purpose: Measures the actual impact of supervised fine-tuning

This is the most expensive experiment type (requires fine-tuning job + re-evaluation) and also the one that can produce the largest accuracy improvements for task-specific workloads.

Result interpretation: Compare base-eval, icl-eval, and customized-eval scores across candidate models. Look for:

  • A small model with high customized-eval score → strong fine-tuning candidate
  • A small model with high base-eval score → no fine-tuning needed (like the Qwen-2.5-32b-coder example)
  • A small model where icl-eval score approaches production model score → prompt engineering may suffice

Production Traffic Ingestion Architecture

Log Schema

Every production inference call must be logged in a specific schema:

Field Type Description
timestamp int (epoch seconds) Request time
workload_id str Stable identifier for the logical task/route/agent node
client_id str Identifier of the application or deployment
request dict Exact openai.ChatCompletion.create payload
response dict Exact ChatCompletion response

Why the full request/response? Keeping the complete payload allows the flywheel to:

  • Replay prompts exactly for evaluation
  • Build few-shot demonstrations from real examples
  • Fine-tune without lossy format conversions
  • Preserve tool call structure for tool-calling workloads

Workload Tagging — the Most Important Design Decision

workload_id is the primary key for all data operations. It must be:

  • Stable: the same logical operation must always emit the same workload_id
  • Granular: each distinct node in an agent chain must have its own workload_id
  • Consistent: mixing workloads under one ID produces unreliable datasets

Why granularity matters: If an agent has five nodes (intent classifier, retrieval, reranker, generator, citation formatter), all five must have separate workload_id values. If they share an ID, the flywheel cannot:

  • Evaluate them independently
  • Build appropriately scoped training datasets
  • Identify which specific node is the cost reduction opportunity

client_id: Identifies the application or deployment that generated the traffic. Multiple workloads share the same client_id. Used for multi-tenancy — isolating one customer’s traffic from another’s in a shared deployment.

Instrumentation Pattern

doc = {
    "timestamp": int(time.time()),
    "workload_id": WORKLOADS["tool_router"],
    "client_id": CLIENT_ID,
    "request": {
        "model": response.model,
        "messages": messages,
        "temperature": 0.3,
        "max_tokens": 1024,
    },
    "response": response.model_dump(),
}
es.index(index=ES_INDEX, document=doc, id=str(uuid.uuid4()))

Streaming responses: If the application uses streaming mode, the application must buffer the stream and reconstruct a full response object before indexing. The flywheel importer cannot reconstruct responses from streaming chunks.

Log store: Elasticsearch 8.12.2 in the reference implementation. The flywheel API queries Elasticsearch to pull data for dataset creation. Operators can substitute other stores by modifying the importer, as long as the document schema is preserved.


Class-Aware Stratified Splitting

One of the most technically precise components of the flywheel. When creating evaluation and fine-tuning datasets from production traffic, naive random splitting produces imbalanced datasets — if 90% of traffic is one tool call type and 10% is another, a random 10% eval split may have zero examples of the minority class.

Stratification variable: Tool name, extracted via get_tool_name() analysis of the response field. Each unique tool call target becomes a “class.”

Splitting algorithm:

  1. Group records by workload_id and tool name
  2. Apply class-aware stratified splitting using scikit-learn’s StratifiedShuffleSplit
  3. Ensure balanced representation across tool types in both eval and fine-tuning splits

Configuration parameters:

Parameter Purpose
eval_size Number of records in the evaluation split
val_ratio Proportion of remaining data held out for validation
min_total_records Minimum records required to attempt stratification
random_seed Seed for reproducibility (set to 42 for reproducible splits)

Fallback logic (when stratification fails — from src/lib/flywheel/util.py:133-141):

  • Number of classes > eval_size
  • Any class has only 1 sample
  • Insufficient total samples

In fallback mode, the system uses random splitting. This degrades dataset quality for imbalanced workloads — operators should monitor class distribution and increase dataset size or reduce eval_size to maintain stratification.

Performance characteristics:

  • Small datasets (< 100 records): minimal overhead
  • Large datasets (> 10,000 records): may require limit parameter tuning
  • Highly imbalanced classes: consider adjusting eval_size relative to smallest class

Why this matters for tool-calling agents: Agentic workloads frequently have imbalanced tool call distributions. A customer service agent might route 70% of calls to a FAQ lookup and 30% across five specialized tools. Without stratification, the fine-tuning dataset over-optimizes for the majority tool and under-represents the rare tools — exactly the failure mode that produces agents that handle common cases well but break on edge cases.


LLM-as-Judge Evaluation Methodology

The flywheel does not require human-labeled ground truth for evaluation. Instead, it uses the production model’s responses as the reference standard and judges candidate models against that reference.

Core assumptions (explicitly stated in NVIDIA’s documentation as intentional):

  1. Production logs are used directly without PII removal
  2. Evaluation datasets have no ground truth other than what the production model responds with
  3. No hand-labeling of data

Rationale: The goal is model distillation — finding a smaller model that replicates the production model’s behavior at lower cost. The production model’s output is therefore the correct reference, not external ground truth. This is a deliberate inversion of standard evaluation methodology.

Risks the documentation acknowledges:

  • A high accuracy score (e.g., 95%) indicates alignment with the production model but does not guarantee safety or correctness. The remaining 5% of divergent cases may include critical or policy-violating errors.
  • LLM judges are non-deterministic. Setting random_seed: 42 in config improves reproducibility of data splits but does not fully control judge variance.
  • Data leakage: the flywheel includes deduplication to reduce train/eval overlap, but operators must verify no overlap exists, especially when datasets are updated or re-used.

Tool-calling judge (strict evaluation):

The tool-calling judge prompt is detailed and strict:

Evaluation Rules:
1. If the prediction is null, empty, or structurally invalid → rating 0
2. function.name must exactly match ground truth function.name
3. function.arguments must be valid JSON
4. Strict-match arguments (short identifiers): must match exactly
5. Semantic-match arguments (longer strings): semantic similarity acceptable
6. Any required argument missing or failing → rating 0
7. Rating 1 only if: name matches AND all arguments correct

This strictness is appropriate for tool-calling evaluation — a tool call with a correct function name but wrong arguments is a failure, not a partial success.

LLM judge system prompt for Q&A similarity (1–10 scale):

The judge evaluates similarity between candidate and reference using a rubric that penalizes missing key information but accepts wording differences. Return format: single integer, no other text. This minimalist response format prevents the judge from hedging or adding qualitative commentary that complicates parsing.


Infrastructure Components

Component Version Role
Elasticsearch 8.12.2 Log storage for production traffic
MongoDB 7.0 API data persistence (job state, flywheel run metadata, LLM judge run records)
Redis 7.2 Task queue for Celery workers
FastAPI REST API layer
Celery Background task processing (dataset creation, NeMo Microservices orchestration)

MongoDB collections: flywheel_runs, llm_judge_runs. Historical job results are retained by design — model improvements are not monotonic, and historical results are needed for regression detection and root cause analysis.

Minimum GPU requirements:

  • Self-hosted LLM judge: 6× NVIDIA H100 or A100 GPUs
  • Remote LLM judge: 2× NVIDIA H100 or A100 GPUs
  • Disk: 200 GB minimum free

Single-node constraint: The reference implementation runs on a single-node Linux GPU cluster. Kubernetes is documented as a deployment target for production scale.

Task serialization safeguard: The blueprint includes an explicit safeguard against concurrent NeMo Microservices calls that could saturate GPU resources. Celery worker concurrency must be configured to respect GPU availability. The documentation calls this the “Task Serialization Safeguard” — a reminder that the flywheel’s job submission rate must be bounded by available GPU capacity.


Workflow Orchestration

Celery task graph (simplified):

create_datasets (Celery task)
  → pull from Elasticsearch
  → deduplicate
  → stratified split
  → write to NeMo Datastore
  → for each NIM:
      → DMS: spin up NIM
      → Customizer: start fine-tuning job
      → monitor fine-tuning
      → Evaluator: base eval
      → Evaluator: ICL eval
      → Evaluator: customized eval
      → DMS: stop NIM
      → write results to MongoDB

Job scheduling options:

  • Always-on service: flywheel runs continuously against new traffic
  • Ad-hoc: spin up on-demand, run against a traffic slice, shut down
  • Scheduled: daily/weekly via cron or workflow scheduler

Off-peak scheduling recommendation (explicitly documented): For shared infrastructure, run flywheel jobs during off-peak hours to reduce contention. The async Celery architecture makes scheduled execution straightforward.


Human-in-the-Loop Architecture

The flywheel is explicitly designed with HITL at the promotion step:

“Think of the Flywheel as a flashlight, not an autopilot. Promotion to production — as well as any deeper evaluation or dataset curation — remains a human decision.”

What the flywheel automates:

  • Data ingestion from Elasticsearch
  • Dataset creation and splitting
  • Fine-tuning job submission and monitoring
  • Evaluation execution (base, ICL, customized)
  • Results aggregation and ranking

What requires human decision:

  • Whether a surfaced candidate is actually acceptable for production
  • Domain-specific acceptance testing beyond the automated metrics
  • Load testing under realistic production conditions
  • Security and compliance review
  • LoRA adapter extraction and deployment to the production serving stack

Recommended verification steps before promotion (from NVIDIA’s documentation):

Step Purpose
Human spot-check of divergent answers Detect hidden flaws or policy violations
Domain-specific eval suite Confirm task-level metrics (BLEU, ROUGE, code tests)
Load test under production traffic Ensure latency and capacity targets
Security & compliance review Verify no new data handling risks

This is a meaningful HITL checkpoint for enterprise governance: the flywheel surfaces candidates, but the production gate still requires human sign-off and domain-specific testing that automated metrics cannot fully capture.


Enterprise Adoption Patterns

Pattern 1: Tool Routing Compression (Highest ROI)

The validated use case: replace a large model used for tool routing with a fine-tuned small model. This works because tool routing is structurally simpler than other LLM tasks — the output space is bounded, the correct answer is deterministic, and fine-tuning can distill the routing logic into a 1B–3B model.

Prerequisite: The application must already log tool calls with workload IDs. Retrofit for existing applications requires instrumenting the logging layer.

Pattern 2: No-Fine-Tuning Model Swap

The Qwen-2.5-32b-coder example: flywheel identifies that a different architecture model already matches the production model without fine-tuning. Instant cost and latency reduction with no training cost.

This requires running base evaluations across multiple candidate NIMs. The flywheel’s value is automating this candidate search — without it, discovering that Qwen already matches requires a manual evaluation campaign.

Pattern 3: Query Rewriting and Summarization (Lower Confidence)

NVIDIA’s documentation notes that in the HR chatbot example, chat, query rewriting, and summarization did NOT compress successfully. These tasks have higher complexity and more variable output spaces. The flywheel will still evaluate them, but operators should have lower expectations for cost reduction in these workload types.

Pattern 4: Multi-Workload Agent

For agents with multiple distinct nodes (the primary design target), the flywheel evaluates each node independently. An agent with 5 nodes might find that 2 of them can be compressed and 3 cannot — a partial optimization that still delivers meaningful cost reduction.

The key prerequisite: Every node must have a unique, stable workload_id. This must be designed into the application before deploying the flywheel — retrofitting workload IDs into an existing agent that does not distinguish nodes requires application changes.


What This Means for Enterprise AI Strategy

Inference Cost Is Now the Growth Constraint

The broader context for the flywheel: as organizations scale from pilots to production, inference cost scales with transaction volume. A model that costs $0.50 per research report at 100 reports/month costs $50,000/month at 100,000 reports/month. Model compression at the workload level is a cost governance strategy, not just a technical optimization.

The data flywheel automates the search for compression opportunities across the model portfolio. Without it, identifying and validating compression candidates is a manual ML engineering project per workload.

The Automation Insight

The central value proposition, stated directly in NVIDIA’s documentation:

“Rather than having ML engineers manage each experiment, you can automate the exploration of various configurations using sensible defaults, and then present the most promising candidates to a research engineer or machine learning engineer for further analysis.”

This shifts ML engineering time from experiment execution to result interpretation. The flywheel runs the experiments; the engineer decides which candidates to promote. This is a meaningful leverage multiplier: one ML engineer can oversee flywheel runs across dozens of workloads simultaneously instead of managing each experiment manually.

Data Readiness Is the Real Prerequisite

The flywheel assumes:

  1. Production traffic is being logged with workload IDs
  2. The log schema matches the required format
  3. Sufficient traffic volume per workload to produce statistically meaningful training and eval datasets

Most enterprise AI deployments in 2026 are not logging at this level of granularity. Implementing the flywheel requires instrumenting the application first — which is a data engineering project, not an ML engineering project.

Minimum data requirement: min_total_records must be satisfied per workload before stratified splitting can proceed. NVIDIA’s documentation does not specify the minimum for reliable results, but the fallback logic (random split when stratification fails) suggests that very small workloads (< 10 per class) will produce unreliable evaluation results.

The Deprecation’s Strategic Message

The April 2026 deprecation of the blueprint in favor of using NeMo Microservices directly reflects NVIDIA’s view that the flywheel pattern is now sufficiently understood that a reference implementation is unnecessary — organizations should build production flywheels directly on NeMo Microservices with their own orchestration logic. The blueprint served its educational purpose.

For enterprises not yet using NeMo Microservices, the blueprint remains the best detailed documentation of what a production flywheel looks like end-to-end, even if the code itself is no longer maintained.


Operational Constraints

PII in production logs: The blueprint explicitly acknowledges routing production traffic into fine-tuning without PII removal. This is a compliance risk for regulated industries (HIPAA, GDPR, CCPA). Organizations in regulated verticals must add a PII redaction layer before logs reach Elasticsearch. The blueprint does not include this layer.

No user feedback integration: The flywheel exclusively relies on production logs and automated judge models. Thumbs-up/thumbs-down signals, user ratings, and expert labels have no effect on evaluation or training. This is intentional — the design avoids requiring ongoing user feedback collection — but means the flywheel cannot optimize for user-perceived quality unless the production model’s output correlates with user satisfaction.

Single-turn optimization: The flywheel evaluates individual prompt/completion pairs. Agentic workflows where quality emerges from multi-turn interactions are not directly supported. Operators must decompose multi-turn workflows into single-turn workloads (individual agent nodes) for the flywheel to be applicable.

No automatic promotion: A high accuracy score does not automatically deploy the candidate model. Operators must extract LoRA adapters, run additional testing, and update deployment configuration manually. The flywheel is the beginning of the promotion process, not the end.