# Tell a Model to Aim at the Floor and Half Its Drafts Fall Under It

> When the length target and the throw floor are the same number, the model clusters at it. Separating aim, expansion threshold, throw floor and ceiling fixed the distribution.

- Author: Dil Ahdan (https://dil.dev/)
- Published: 2026-10-14
- Updated: 2026-10-14
- Tags: llm, content-pipeline, n8n, prompt-engineering
- Canonical: https://dil.dev/notes/llm-length-target-was-the-floor/

## Key takeaways

- Setting the aim and the floor to the same number collapses the model's distribution onto that number.
- Four of ten published guides landed within 100 words of the 1,200 floor; one execution wrote 1,005 words and killed the run entirely.
- The fix is four separate knobs: a 1,650 aim, a 1,400 expansion threshold, a 1,200 throw floor and a 2,000 hard ceiling.
- A false threat in the prompt claiming short drafts waste the run was pushing padding rather than genuine length.
- Removing the false threat and separating the knobs are two distinct changes; conflating them makes it impossible to know which one helped.

When the aim and the floor are the same number, the model treats the floor as the target and writes to it. That is the whole finding. The rest of this note is the evidence, the mechanism and the four-knob fix.

## What the Pipeline Looked Like Before

The article pipeline for an electrical contractor client used a single instruction in the Generate Article prompt: aim for 1,400 to 1,800 words, never under 1,400.

The lower bound of the range and the never-under figure were identical. There was no separate expansion pass, no distinct throw floor and no ceiling stated anywhere else in the flow.

## What the Published Guides Actually Showed

The commit on 2026-09-16 documents body word counts for ten published guides. The picture is not pretty:

- **Lowest count:** 1,203 words, which is three words over what became the 1,200 throw floor.
- **Four guides** landed within 100 words of that floor.
- **One execution** wrote 1,005 words and killed the run entirely, because the pipeline had no expansion pass to catch it.

That last one is the clearest signal. The model did not just cluster near the floor, it fell through it. A prompt that says "never under 1,400" did not prevent a 1,005-word draft. It just meant the run died with nothing published.

## Why the Model Clusters at the Floor

The model reads a range like 1,400 to 1,800 and treats the lower bound as the satisficing point. Writing 1,400 words satisfies the constraint. Writing 1,800 words also satisfies it, but requires more tokens and more decisions about what to include.

Without an upward pull, the model gravitates toward the minimum. This is not a bug in the model. It is a predictable consequence of how the constraint is framed.

The same logic applies to the never-under phrasing. It sets a floor but gives the model no reason to aim above it.

## The False Threat Making Things Worse

The old prompt also contained a line claiming that a short draft "is rejected by the system and wastes the run." That was not true. At the time the line was written, there was no expansion loop. By the time the commit landed, there was. The line was stale and factually wrong.

A false threat like that does one of two things. Either the model ignores it, in which case it does nothing. Or the model responds to it by padding, adding filler sentences to hit the number without adding substance. Neither outcome is good.

Removing the line is a separate change from fixing the length knobs. It is worth keeping them separate in your own head, because conflating them makes it impossible to know which change did the work.

## The Four-Knob Fix

The commit introduces a document, `docs/runbooks/article-length-rule.md`, that defines four distinct values and where each one lives in the pipeline:

- **1,650 aim:** sits in the Generate Article prompt. This is the number the model is told to write toward. It is not a floor and not a ceiling.
- **1,400 expansion threshold:** sits in the Too Short? IF node. If the draft comes in below 1,400, the pipeline sends it through one expansion pass asking for more detail. One pass only.
- **1,200 throw floor:** sits in Compose Draft. If the draft is still below 1,200 after the expansion pass, the run aborts. Nothing gets published.
- **2,000 hard ceiling:** also in the prompt. Drafts above this are trimmed or flagged depending on how far over they go.

The gap between the aim (1,650) and the throw floor (1,200) is 450 words. Normal model variance on a guide-length article is well inside that gap, so a draft that falls a bit short of the aim still has room to clear the floor without needing the expansion pass.

The expansion threshold at 1,400 sits between them as a catch. A draft that lands between 1,200 and 1,400 gets one more attempt before the pipeline decides whether to abort.

## Verifying the Live Prompt

One thing worth noting from the commit: the verification step included a live readback of the n8n prompt node inside the running workflow. Not the file on disk. Not the version in source control. The actual prompt the workflow was executing.

This matters because n8n workflows can drift from what you think you deployed. If you fix the prompt in your editor and forget to save it back into the workflow, the pipeline keeps running the old version. The live readback is the only way to be certain.

## What the Commit Does Not Claim

The commit does not include a post-fix word-count distribution. There is no table showing that the new prompt produces guides averaging 1,650 words. That data does not exist yet, because the change was made on 2026-09-16 and the guides take time to accumulate.

It would be easy to write a sentence here claiming the fix worked. It would also be invented. The honest position is: the mechanism is sound, the old prompt was provably broken, and the new one should perform better. Whether it does is a question for a future commit.

## What I'd do differently

- **Instrument word counts from the start.** Ten guides published before anyone noticed the clustering. A simple log of body word count per run would have flagged it after two or three.
- **Separate the knobs before the first deployment.** The four-knob structure is not complicated. It just requires thinking about aim, expansion, floor and ceiling as distinct concerns rather than collapsing them into one range.
- **Audit prompt claims for accuracy.** The false threat about wasting the run was in the prompt for long enough to affect published content. A prompt is a specification. Stale specs cause bugs the same way stale code does.
- **Keep the expansion pass to one attempt.** The current setup does this correctly. More than one expansion pass risks a loop that inflates the article with padding rather than substance, which is exactly the behaviour the false threat was accidentally encouraging.

## Quick answers

**Why does telling a model a minimum length make it write exactly that length?**

The model treats the constraint as a target. If the floor and the aim are the same number, there is no upward pull, so the model satisfies the constraint with the least effort and stops. Separating the aim from the floor gives the model a genuine centre to write toward.

**What is an expansion threshold in an article pipeline?**

It is a word-count check after the first draft. If the draft falls below the threshold, the pipeline sends it through one more generation pass asking for additional detail. It sits between the aim and the throw floor so the model has room to fall short without immediately failing.

**What happens when a draft hits the throw floor?**

The pipeline aborts that run rather than publishing a short article. In this case the throw floor is 1,200 words. One draft came in at 1,005 words and triggered exactly that abort.

**Is it safe to remove a warning from a prompt if it was factually wrong?**

Yes, but treat it as a separate change from the length-target change. A false threat can cause padding behaviour that looks like length compliance. Removing it may shorten drafts slightly, which is why the expansion threshold exists as a safety net.

**How do you verify the prompt a live n8n workflow is actually using?**

Do a live readback of the prompt node inside the running workflow, not from the file you think you deployed. The commit here included that readback as part of the verification step.

**What word count should I aim for if my floor is 1,200 and my ceiling is 2,000?**

Somewhere around 1,600 to 1,700 puts the aim roughly in the middle of the acceptable range. This pipeline uses 1,650. The exact number matters less than the gap between aim and floor being large enough that normal model variance does not routinely breach the floor.
