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

# Inference parameters & sampling

> Temperature, top-k, top-p, and the other knobs that shape how a model picks each next token.

export const SamplingDistributionDiagram = () => {
  const CSS = `
  .learn-diagram .sm__chart {
    display: flex;
    align-items: flex-end;
    gap: 5px;
    height: 230px;
    padding-top: 20px;
    border-bottom: 1px solid var(--color-rule);
  }
  .learn-diagram .smbar {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
    font-family: var(--font-mono);
  }
  .learn-diagram .smbar__pct { font-size: 10px; color: var(--color-ink-mute); font-variant-numeric: tabular-nums; }
  .learn-diagram .smbar__fill {
    width: 100%;
    background: var(--tg-slate);
    border-radius: 2px 2px 0 0;
    min-height: 2px;
    transition: height var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out);
  }
  .learn-diagram .smbar.is-cut .smbar__fill { background: var(--color-paper-4); }
  .learn-diagram .smbar.is-cut .smbar__pct { color: var(--color-ink-faint); text-decoration: line-through; }
  .learn-diagram .smbar.is-pick .smbar__fill { background: var(--tg-orange); }
  .learn-diagram .sm__labels {
    display: flex;
    gap: 5px;
    margin-top: 6px;
    font-family: var(--font-mono);
  }
  .learn-diagram .sm__lab {
    flex: 1;
    min-width: 0;
    text-align: center;
    font-size: 10px;
    color: var(--color-ink-soft);
    display: grid;
    gap: 2px;
  }
  .learn-diagram .sm__lab span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .learn-diagram .sm__lab-cut { color: var(--color-ink-faint); text-decoration: line-through; }
  .learn-diagram .sm__lab-tally { color: var(--tg-orange); font-variant-numeric: tabular-nums; }
  .learn-diagram .sm__lab-tally.is-zero { color: var(--color-rule); }
  .learn-diagram .sm__sliders { display: flex; flex-wrap: wrap; gap: var(--space-sm) var(--space-md); margin-top: var(--space-md); }
  `;
  const VOCAB = [{
    t: " the",
    logit: 3.2
  }, {
    t: " a",
    logit: 2.6
  }, {
    t: " an",
    logit: 2.1
  }, {
    t: " of",
    logit: 1.7
  }, {
    t: " is",
    logit: 1.2
  }, {
    t: " was",
    logit: 0.7
  }, {
    t: " to",
    logit: 0.4
  }, {
    t: " for",
    logit: 0.0
  }, {
    t: " my",
    logit: -0.3
  }, {
    t: " our",
    logit: -0.7
  }, {
    t: " your",
    logit: -1.1
  }, {
    t: " xyz",
    logit: -1.8
  }];
  const softmax = logits => {
    const finite = logits.filter(x => isFinite(x));
    const m = finite.length ? Math.max(...finite) : 0;
    const exps = logits.map(x => isFinite(x) ? Math.exp(x - m) : 0);
    const sum = exps.reduce((a, b) => a + b, 0) || 1;
    return exps.map(x => x / sum);
  };
  const [tempRaw, setTempRaw] = useState(10);
  const [topk, setTopk] = useState(12);
  const [toppRaw, setToppRaw] = useState(100);
  const [lastPick, setLastPick] = useState(-1);
  const [tally, setTally] = useState(() => VOCAB.map(() => 0));
  const temperature = tempRaw / 10;
  const topp = toppRaw / 100;
  const T = Math.max(temperature, 0.05);
  const byLogit = VOCAB.map((v, i) => ({
    i,
    l: v.logit
  })).sort((a, b) => b.l - a.l);
  const keptK = new Set(byLogit.slice(0, topk).map(x => x.i));
  const scaled = VOCAB.map((v, i) => keptK.has(i) ? v.logit / T : -Infinity);
  const afterK = softmax(scaled);
  const keptP = new Set();
  let cum = 0;
  afterK.map((p, i) => ({
    p,
    i
  })).sort((a, b) => b.p - a.p).forEach(r => {
    if (cum < topp) {
      keptP.add(r.i);
      cum += r.p;
    }
  });
  const probs = softmax(scaled.map((x, i) => keptP.has(i) ? x : -Infinity));
  const max = Math.max(...probs);
  const kept = probs.filter(p => p > 0).length;
  const entropy = -probs.reduce((s, p) => p > 0 ? s + p * Math.log(p) : s, 0);
  const effective = Math.exp(entropy);
  const samples = tally.reduce((a, b) => a + b, 0);
  const drawOnce = counts => {
    const r = Math.random();
    let acc = 0;
    for (let i = 0; i < probs.length; i++) {
      acc += probs[i];
      if (r <= acc) {
        counts[i] += 1;
        return i;
      }
    }
    return probs.length - 1;
  };
  const sample = n => {
    const counts = tally.slice();
    let last = -1;
    for (let k = 0; k < n; k++) last = drawOnce(counts);
    setTally(counts);
    setLastPick(last);
  };
  const reset = () => {
    setTally(VOCAB.map(() => 0));
    setLastPick(-1);
  };
  return <DiagramFrame eyebrow="Sampling" title="Temperature, top-k and top-p reshape the same distribution" caption="The model emits one score per token. Temperature flattens or sharpens those scores, top-k keeps a fixed number of candidates, and top-p keeps just enough of them to cover a share of the probability mass. Sampling repeatedly shows how much of the tail actually gets used." css={CSS} controls={<div className="btn-row">
          <button className="btn btn--accent" onClick={() => sample(1)}>
            Sample once
          </button>
          <button className="btn" onClick={() => sample(50)}>
            Sample 50
          </button>
          <button className="btn" onClick={reset} disabled={samples === 0}>
            Clear
          </button>
        </div>} readout={<span>
          last pick{" "}
          <strong>{lastPick < 0 ? "none" : VOCAB[lastPick].t.trim() || "␣"}</strong> · draws{" "}
          <strong>{samples}</strong>
        </span>}>
      <div className="sm__chart">
        {VOCAB.map((v, i) => {
    const h = max > 0 ? probs[i] / max * 185 : 0;
    const cls = "smbar" + (probs[i] === 0 ? " is-cut" : "") + (i === lastPick ? " is-pick" : "");
    return <div className={cls} key={i}>
              <div className="smbar__pct">{(probs[i] * 100).toFixed(probs[i] < 0.1 ? 1 : 0)}%</div>
              <div className="smbar__fill" style={{
      height: Math.max(h, 2) + "px"
    }} />
            </div>;
  })}
      </div>
      <div className="sm__labels">
        {VOCAB.map((v, i) => <div className="sm__lab" key={i}>
            <span className={probs[i] === 0 ? "sm__lab-cut" : ""}>{v.t.trim()}</span>
            <span className={"sm__lab-tally" + (tally[i] === 0 ? " is-zero" : "")}>
              {tally[i] || "·"}
            </span>
          </div>)}
      </div>

      <div className="sm__sliders">
        <Slider label="temperature" value={tempRaw} display={temperature.toFixed(1)} min={0} max={20} onChange={setTempRaw} />
        <Slider label="top-k" value={topk} display={topk} min={1} max={12} onChange={setTopk} />
        <Slider label="top-p" value={toppRaw} display={topp.toFixed(2)} min={5} max={100} step={5} onChange={setToppRaw} />
      </div>

      <div className="stats" style={{
    marginTop: "var(--space-sm)"
  }}>
        <span>
          candidates kept: <strong>{kept}</strong> / {VOCAB.length}
        </span>
        <span>
          effective choices: <strong>{effective.toFixed(2)}</strong>
        </span>
        <span>
          most likely token: <strong>{(max * 100).toFixed(0)}%</strong>
        </span>
        <span>
          {temperature < 0.1 ? "greedy: always the top token" : "stochastic"}
        </span>
      </div>

      <Legend items={[{
    color: "#5E86AE",
    label: "candidate kept"
  }, {
    color: "#E2E4E9",
    label: "cut by top-k / top-p"
  }, {
    color: "#FC4C02",
    label: "last sampled token"
  }]} />
    </DiagramFrame>;
};

export const Legend = ({items}) => <ul className="legend">
    {items.map((it, i) => <li className="legend__item" key={i}>
        <span className="legend__sw" style={it.style || ({
  background: it.color
})} />
        {it.label}
      </li>)}
  </ul>;

export const Slider = ({label, value, display, min, max, step = 1, onChange}) => <label className="slider-group">
    <span className="slider-group__label">
      {label}
      <span className="slider-group__value">{display === undefined ? value : display}</span>
    </span>
    <input type="range" min={min} max={max} step={step} value={value} onChange={e => onChange(parseFloat(e.target.value))} />
  </label>;

export const DiagramFrame = ({eyebrow, title, caption, css, controls, readout, children}) => {
  const BASE_CSS = `
.learn-diagram {
  /* ── Together AI brand palette ── */
  --tg-orange: #FC4C02;
  --tg-orange-dark: #972E02;
  --tg-orange-soft: #FEE8DF;
  --tg-orange-tint: #FFDCCD;
  --tg-pink: #EF2CC1;
  --tg-pink-soft: #FDE3F6;
  --tg-purple: #A373ED;
  --tg-purple-mid: #CAAEF5;
  --tg-purple-soft: #EDE4FC;
  --tg-blue: #3D99F5;
  --tg-blue-mid: #A3D1FF;
  --tg-blue-soft: #E5F3FF;
  --tg-slate: #5E86AE;
  --tg-slate-soft: #EEF3F6;
  --tg-navy: #010120;

  /* ── Surfaces ── */
  --color-paper:   #FFFFFF;
  --color-paper-2: #F7F8FA;
  --color-paper-3: #F0F1F4;
  --color-paper-4: #E2E4E9;
  /* ── Ink ── */
  --color-ink:       #090909;
  --color-ink-soft:  #414B58;
  --color-ink-mute:  #626B84;
  --color-ink-faint: #98A0B3;
  /* ── Lines ── */
  --color-rule:        #C4C9D4;
  --color-rule-soft:   #E2E4E9;
  --color-rule-strong: #98A0B3;
  /* ── Accent ── */
  --color-accent:      var(--tg-orange);
  --color-accent-soft: var(--tg-orange-soft);
  --color-empty:       #F0F1F4;

  /* ── Type ── */
  --font-display: 'Jost', 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'The Future', 'Jost', 'Helvetica Neue', Arial, sans-serif;
  --font-mono:    'The Future Mono', ui-monospace, 'SFMono-Regular', 'Courier New', monospace;

  /* ── Spacing (4px base) ── */
  --space-3xs: 4px;
  --space-2xs: 8px;
  --space-xs:  12px;
  --space-sm:  16px;
  --space-md:  24px;
  --space-lg:  32px;

  /* ── Radius ── */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;

  /* ── Motion ── */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 120ms;
  --dur-base: 200ms;
  --dur-slow: 360ms;
  --focus-ring: 0 0 0 3px rgba(252, 76, 2, 0.35);

  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.65;
  font-weight: 400;
  color: var(--color-ink);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
  margin: 24px 0;
}
.learn-diagram, .learn-diagram * { box-sizing: border-box; }

/* ============ SHELL ============ */
.learn-diagram .diagram {
  margin: 0;
  background: var(--color-paper);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  box-shadow: 0 1px 2px rgba(9, 9, 9, 0.04), 0 2px 10px rgba(9, 9, 9, 0.03);
}
.learn-diagram .diagram__head { margin-bottom: var(--space-md); }
.learn-diagram .diagram__eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tg-orange);
  margin-bottom: 6px;
}
.learn-diagram .diagram__title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--color-ink);
  margin: 0;
}
.learn-diagram .diagram__caption {
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-ink-mute);
  margin: 6px 0 0;
  max-width: 68ch;
}
.learn-diagram .diagram__controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  align-items: center;
  margin-top: var(--space-md);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-rule-soft);
}
.learn-diagram .diagram__readout {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
  margin-left: auto;
}
.learn-diagram .diagram__readout strong {
  color: var(--tg-orange);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* ============ BUTTONS ============ */
.learn-diagram .btn {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  padding: 9px 14px;
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-md);
  background: var(--color-paper);
  color: var(--color-ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease,
              color var(--dur-fast) ease;
}
.learn-diagram .btn:hover:not([disabled]) { background: var(--color-paper-3); }
.learn-diagram .btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.learn-diagram .btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.learn-diagram .btn--accent {
  background: var(--tg-orange);
  border-color: var(--tg-orange);
  color: #fff;
}
.learn-diagram .btn--accent:hover:not([disabled]) {
  background: var(--tg-orange-dark);
  border-color: var(--tg-orange-dark);
}
.learn-diagram .btn--on {
  background: var(--tg-orange-soft);
  border-color: var(--tg-orange);
  color: var(--tg-orange-dark);
}
.learn-diagram .btn-row { display: flex; flex-wrap: wrap; gap: var(--space-2xs); flex: 0 0 auto; }

/* ============ SLIDERS ============ */
.learn-diagram .slider-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 190px;
  flex: 1 1 190px;
}
.learn-diagram .slider-group__label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
  display: flex;
  justify-content: space-between;
  gap: var(--space-2xs);
}
.learn-diagram .slider-group__value {
  color: var(--tg-orange);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-transform: none;
}
.learn-diagram input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2px;
  background: var(--color-rule);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
  margin: 8px 0 2px;
}
.learn-diagram input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  background: var(--tg-orange);
  border-radius: 50%;
  border: 2px solid var(--color-paper);
  box-shadow: 0 1px 3px rgba(9, 9, 9, 0.18);
}
.learn-diagram input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  background: var(--tg-orange);
  border-radius: 50%;
  border: 2px solid var(--color-paper);
}
.learn-diagram input[type="range"]:focus-visible { box-shadow: var(--focus-ring); }

/* ============ PANELS · STATS · LEGEND ============ */
.learn-diagram .panel {
  background: var(--color-paper-2);
  border: 1px solid var(--color-rule-soft);
  border-radius: var(--radius-md);
  padding: var(--space-sm);
}
.learn-diagram .panel__head {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
  margin-bottom: var(--space-2xs);
}
.learn-diagram .stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-md);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--color-ink-mute);
}
.learn-diagram .stats strong {
  color: var(--tg-orange);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.learn-diagram .legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-md);
  list-style: none;
  margin: var(--space-sm) 0 0;
  padding: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--color-ink-soft);
}
.learn-diagram .legend__item { display: flex; align-items: center; gap: 6px; }
.learn-diagram .legend__sw {
  width: 12px;
  height: 12px;
  border-radius: 2px;
  flex: none;
  display: inline-block;
}
.learn-diagram .tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  background: var(--color-paper-3);
  color: var(--color-ink-soft);
  white-space: nowrap;
}
.learn-diagram .tag--accent { background: var(--tg-orange-soft); color: var(--tg-orange-dark); }
.learn-diagram .tag--muted { background: transparent; border: 1px dashed var(--color-rule); color: var(--color-ink-faint); }
.learn-diagram .note {
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-ink-mute);
}
.learn-diagram code, .learn-diagram .mono { font-family: var(--font-mono); font-size: 13px; }

@media (prefers-reduced-motion: reduce) {
  .learn-diagram *, .learn-diagram *::before, .learn-diagram *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
  }
}
`;
  return <div className="learn-diagram">
    <style>{BASE_CSS}</style>
    {css ? <style>{css}</style> : null}
    <figure className="diagram">
      {(eyebrow || title || caption) && <div className="diagram__head">
          {eyebrow && <div className="diagram__eyebrow">{eyebrow}</div>}
          {title && <h3 className="diagram__title">{title}</h3>}
          {caption && <p className="diagram__caption">{caption}</p>}
        </div>}
      <div className="diagram__inner">{children}</div>
      {(controls || readout) && <div className="diagram__controls">
          {controls}
          {readout && <span className="diagram__readout">{readout}</span>}
        </div>}
    </figure>
  </div>;
};

**TL;DR:** At every step of generation, the model produces a probability for every possible next token in its vocabulary. Sampling is the process of picking one of those tokens to actually use. Temperature, top-k, top-p, and a few penalty controls are different ways of shaping that probability distribution before you pick from it. They do not change the model itself, they only change how you draw a token from the model's output distribution.

## Why sampling exists at all

Imagine the model is choosing the next word in this sentence: "The capital of France is \_\_\_". The model assigns very high probability to "Paris", lower probability to "France", "Lyon", "Marseille", and "Brussels", and very small slivers of probability to the rest of its \~200,000-token vocabulary.

You could pick "Paris" every single time. This works perfectly well for factual questions where there is one obvious correct answer. But if you try the same strategy on a prompt like "Write me a poem about loneliness \_\_\_", you will get the same stale rhymes that the model assigns the highest probability to, every single time. The "right" word in creative or open-ended writing is rarely the highest-probability word, because the highest-probability word is the most predictable one and predictable writing is usually boring.

Sampling lets you choose between two extremes. On one end is textbook mode, where you always pick the most probable word. On the other is a more creative mode, where you sometimes pick a less expected word to get more variety. The controls in this section move you between those two ends.

<SamplingDistributionDiagram />

## Greedy decoding

The most basic sampling strategy is to pick the highest-probability token every single time. This is called **greedy decoding** and on most APIs it is equivalent to setting `temperature = 0`. Greedy decoding can be repetitive or bland. Because you always pick the top option, the model never tries any of the moderately likely alternatives, and the output can read as generic.

Greedy decoding is the right default for tasks like information extraction, classification, and any task where there is clear single correct answer.

## Temperature

Temperature is the most commonly used sampling parameter. It works by dividing the logits by a temperature value before the softmax converts them into probabilities. The effect on the resulting distribution looks like this:

* `temperature = 0` is equivalent to greedy decoding. The model always picks the maximum value token.
* `temperature = 1.0` gives you the model's unaltered distribution. This is the distribution the model would naturally produce based on its training.
* `temperature < 1` sharpens the distribution. The most likely tokens become even more likely, and the long tail of unlikely tokens gets suppressed. The output becomes more focused and less surprising.
* `temperature > 1` flattens the distribution toward uniform. The output becomes more creative and more random, but also more likely to go off the rails.

As a rough starting point, you might use `0` for anything factual, `0.7` for general chat, and `0.9 to 1.2` for creative writing. Above about `1.5`, the model tends to produce strange outputs regardless of the prompt, so it is rarely worth going any higher. Model providers usually publish recommended defaults for temperature and the controls below—when they do, stick to those values for optimal results.

## Top-k and top-p

Even with a sensible temperature, a 200K-token vocabulary has a very long tail of very unlikely tokens. Sampling can occasionally land on one of those tail tokens, which might make the output go somewhere strange. Top-k and top-p are two different ways to ignore the tail before sampling, so that the model can only pick from a reasonable shortlist.

### Top-k

Top-k works by sorting all of the tokens by probability, keeping the top *k* of them, and throwing away the rest. After truncating to the top *k* tokens, the remaining probabilities are renormalized to sum to 1, and you sample from that shortened distribution. Setting `top_k = 20` means "only ever consider the 20 most likely next tokens".

Top-k is straightforward and reliable. The downside is that the "right" number of plausible tokens varies a lot from step to step. Sometimes there are only 3 obvious candidates and many noisy ones, in which case top-k is keeping more than you need. Other times there are 200 reasonable candidates and your top-k of 20 has thrown away 180 of them.

### Top-p (nucleus sampling)

Top-p works a little differently. You sort the tokens by probability, then keep the smallest set of tokens whose probabilities together add up to *p*. You sample from that set. Setting `top_p = 0.9` means "consider the smallest group of tokens that together hold 90% of the probability".

Top-p adapts to the shape of the distribution at each step. When the model is very sure about the next token, the set that adds up to 90% is small. When the model is uncertain, the set grows to include more candidates. This adaptive behavior often makes top-p a better default than top-k.

You can use both together. Most APIs let you set either parameter independently, and some platforms apply top-k first and then top-p.

## Repetition, presence, frequency penalties, and logit bias

Models sometimes get stuck repeating the same phrase or word over and over. There are several controls that let you influence the token distribution during generation, including penalties and direct logit biasing:

* **Frequency penalty:** Each occurrence of a token in the output so far reduces that token's logit a little. The more times you have used the word "however", the less likely "however" is to come up again on the next step.
* **Presence penalty:** Any token that has appeared at all gets its logit reduced by a fixed amount. Presence penalty does not care how many times the token appeared—it only checks whether it's appeared at all.
* **Repetition penalty:** This is the same idea applied multiplicatively to the logits rather than additively. Repetition penalty is more common in open-source models than in OpenAI-style APIs.
* **Logit bias:** This parameter lets you directly adjust the likelihood of specific tokens appearing in the generated output. For example, you can strongly encourage or almost entirely ban certain words or pieces of text from appearing by pushing their probabilities up or down before sampling. This can be done alongside penalties or on its own.

All of these controls should be used sparingly. If you apply too much penalty or bias, the model will strain to avoid common or important words, hurting fluency in ways worse than the original repetition. For logit bias, start with small adjustments unless you are intentionally trying to force or block a token entirely. If the output starts feeling forced or unnatural, dial the penalties and biases back.

## Seed and determinism

Sampling uses a random number generator under the hood. If you fix the seed, the same input produces the same output across runs. This is useful for testing, debugging, and reproducible evaluation runs.

An important caveat worth knowing is that even with a fixed seed, hardware and batching can introduce small amounts of non-determinism. Different concurrent requests can subtly affect floating-point order, which means "deterministic" in practice means "deterministic most of the time but not always". In practice, the same call repeated several times can return slightly different logits.

## What changes for reasoning models

Modern **reasoning/hybrid models** produce a long internal chain of thought before they give you a final answer. Most of these models ship with recommended sampling settings, which you should almost certainly use. Performance degrades noticeably when you override the provider's recommendations.

The exact behavior varies significantly across models, so it is worth checking the model card before you tune these controls on a hybrid or reasoning model.

## What to pick for what

Here are reasonable starting points by task. For the exact request fields, see [inference parameters](/docs/inference/chat/parameters).

* **Extraction, classification, structured output:** Use `temperature = 0`. You want one right answer and you want it to be reproducible.
* **General chat or assistant tasks:** Use `temperature = 0.7` and `top_p = 0.9`. This is a safe middle ground for most use cases.
* **Creative writing or brainstorming:** Use `temperature = 0.9 to 1.1` and `top_p = 0.95`. Let the model breathe a bit and explore less predictable options.
* **Code generation:** Use `temperature = 0.1 to 0.3`. Coding demands precision. A little randomness can help when the model is stuck, but most of the time you want the model's best guess rather than a creative one.
* **Reasoning/hybrid models:** Check to see if the model provider recommends a setting for the sampling parameters in reasoning and non-reasoning modes.

<Tip>
  If your output is bad, the first thing to check is the prompt, not the sampling. Sampling controls are a small intervention compared to the prompt itself. You should get the prompt right first, then tune sampling only if you have a specific complaint about the output (too repetitive, too random, too generic).
</Tip>

## Next steps

<CardGroup cols={3}>
  <Card title="Context engineering" icon="messages" href="/learn/prompt-engineering">
    The biggest lever on output quality.
  </Card>

  <Card title="Structured outputs & JSON mode" icon="braces" href="/learn/structured-outputs">
    Constrain outputs to a schema.
  </Card>

  <Card title="How LLMs work" icon="cpu" href="/learn/how-llms-work">
    Where logits come from in the first place.
  </Card>
</CardGroup>
