> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runapprentice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Using the console

> The map of the Apprentice console: one pipeline from your data to an optimized prompt, and later a replacement model. Know your next step and why it matters.

The console is one pipeline. Get your data in, verify it, optimize the prompt, then later replace the model. This page is the map, so you always know what the next step is and why. It is not a set of instructions. For those, start with the [quickstart](/quickstart).

## The pipeline

Every task moves through the same stages, in order. You do not have to finish all of them. Most teams stop after the optimized prompt and ship that.

<div className="not-prose my-6 grid grid-cols-2 gap-px overflow-hidden rounded-2xl border border-gray-200 bg-gray-200 sm:grid-cols-5 dark:border-gray-800 dark:bg-gray-800">
  {[
      { n: "01", t: "Examples", d: "Your input and output pairs, uploaded or captured." },
      { n: "02", t: "Review", d: "Verify rows so the score can be trusted." },
      { n: "03", t: "Optimize", d: "GEPA rewrites the prompt against your data." },
      { n: "04", t: "Result", d: "Baseline vs optimized on a held-out slice." },
      { n: "05", t: "Replace", soon: true, d: "Train a small model to take over, eval-gated." },
    ].map((s) => (
      <div key={s.n} className="bg-white p-4 dark:bg-gray-900">
        <div className="font-mono text-xs font-semibold tracking-widest" style={{ color: "#1FA97B" }}>{s.n}</div>
        <div className="mt-1.5 text-sm font-semibold text-gray-900 dark:text-white">
          {s.t}
          {s.soon && <span className="ml-1 text-xs font-normal text-gray-400">(soon)</span>}
        </div>
        <div className="mt-1 text-xs leading-snug text-gray-500 dark:text-gray-400">{s.d}</div>
      </div>
    ))}
</div>

The task hub mirrors this exactly. The one active stage is always your next step, and each stage tells you what unlocks the next.

## Two ways to get data in

Every task starts with examples, and there are two doors. Pick the one that fits how you work.

<Columns cols={2}>
  <Card title="Upload a dataset" icon="upload" href="/quickstart">
    **Fastest path to a score.** You already have a CSV or JSONL of inputs and the outputs you want back. Upload it and optimize in the same step.
  </Card>

  <Card title="Connect the SDK" icon="plug" href="/how-to/capture-langchain">
    You have a live app. Wire the `runapprentice` SDK once and it captures real requests as examples over time. Best for learning from production traffic.
  </Card>
</Columns>

Both feed the same pipeline. Upload is faster to a first result; capture is better for keeping a task learning from what your app actually sees.

## What "verified" means

Every row carries a tier. The tier decides what a row is allowed to do, so a score is never built on data no one checked.

<div className="not-prose my-6 overflow-hidden rounded-2xl border border-gray-200 dark:border-gray-800">
  {[
      { name: "Gold", metal: "#D4A94A", d: "Human-verified. The only tier that certifies quality and the only tier that trains a model." },
      { name: "Silver", metal: "#A8AEB5", d: "Passed a deterministic check, or you uploaded it. Counts toward optimization, not training." },
      { name: "Raw", metal: "#B0714A", d: "Captured live, unverified. A candidate for review, never counted." },
    ].map((r, i) => (
      <div key={r.name} className={`flex items-baseline gap-4 px-4 py-3.5 ${i > 0 ? "border-t border-gray-200 dark:border-gray-800" : ""}`}>
        <span className="flex w-24 shrink-0 items-center gap-2.5 text-sm font-semibold text-gray-900 dark:text-gray-100">
          <span
            className="inline-block h-2.5 w-2.5 rounded-full"
            style={{ backgroundColor: r.metal, boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.18)" }}
          />
          {r.name}
        </span>
        <span className="text-sm text-gray-600 dark:text-gray-300">{r.d}</span>
      </div>
    ))}
</div>

This split is why the two stages unlock at different points. **Optimization** runs on verified rows, which is gold plus silver. **Training** runs on gold only. Optimizing improves the prompt, so silver is trusted enough. Training and promoting a model is a quality claim, so it uses human-verified rows alone. For the full reasoning, see [data tiers](/concepts/data-tiers).

<Note>
  You never get a number Apprentice cannot back up. Scores are measured on rows the optimizer never saw, and a run that does not improve is reported as it is, not hidden. A real result you can trust beats a flattering one you cannot.
</Note>

## Where to go next

<CardGroup cols={2}>
  <Card title="JSON extraction, end to end" icon="brackets-curly" href="/how-to/json-extraction">
    Run the whole pipeline on a real dataset and pull the optimized prompt back into your code.
  </Card>

  <Card title="Why replacement is eval-gated" icon="shield-check" href="/concepts/eval-gated-replacement">
    The reasoning behind the model swap: switched only when your evals prove no quality regression.
  </Card>
</CardGroup>
