← Writing

· 12 min read · LLMs · RAG · Fine-tuning · Structured output

Fine-tuning vs RAG: how LLMs are trained, and what I ship instead

How an LLM is trained in four stages, when fine-tuning beats RAG, and the third option that solved my own extraction problem: a stock model held to a strict schema.

Cover for Fine-tuning vs RAG, a funnel narrowing from internet-scale text to an aligned assistant

The first production extraction PlanReel ever ran came back as a single line: 400 Invalid schema: 'oneOf' is not permitted. The model hadn't misread the Medicare document. It never saw it, because the JSON schema I had generated from Zod used a keyword the API's strict mode refuses.

That was the shape of the problems on PlanReel. Fine-tuning vs RAG is the question people ask first, and on PlanReel it was the wrong question. The model that reads benefit PDFs for PlanReel is a stock model. It was never fine-tuned and it has no retrieval index. What made it reliable was a schema.

This post is the reference I wish I had: how an LLM is actually trained, what fine-tuning and retrieval-augmented generation each change, a decision table, and the third option often left out.

Steal this >
- Before you fine-tune anything, write the output you want as a JSON schema and run real documents through a stock model with strict structured output.
- If the knowledge changes, it belongs in a retrieval index, not in the weights.
- Read every field description in your schema as if it were a prompt. The model does.
- Test the whole emitted schema for forbidden keywords, not just the fields you remembered.
- Keep money and other exact values as data the model copies, never as numbers it computes.

Who this is not for: teams training foundation models. This is for engineers deciding what to do with one.

What shipping PlanReel showed

PlanReel turns a Medicare plan PDF into a narrated video. The first step is extraction: the PDF goes straight to the model with a strict JSON schema generated from the same Zod definitions the renderer and the editor use. Three things went wrong on the way to production, across extraction and script generation. None of them was a knowledge problem.

The schema was valid and still rejected. Zod's z.toJSONSchema() emits oneOf for discriminated unions. OpenAI's strict mode requires anyOf, and rejects about twenty other perfectly legal keywords. The fix was a sanitiser that rewrites the emitted schema and a test that walks the whole tree for about 24 forbidden keywords.

A document was too big to read. A 32-page plan failed with 429 Rate limit reached: Limit 30000 TPM, Requested 34983. One request exceeded the account's entire per-minute allowance, so no amount of waiting could fix it. Splitting the PDF into 12-page chunks, about 18k tokens each, and merging the results did.

The model obeyed the schema over the prompt. In script generation, the system prompt said never to tell the viewer to call the agent. The phrase kept coming back anyway, because a field's description in the schema literally said e.g. "Call me with questions." The model treated the example as an instruction.

Look at that list and ask which of the three a fine-tune would have fixed. None. A fine-tuned model still gets the same schema rejected, still can't fit 34,983 tokens into a 30,000 window, and still reads the same field descriptions. The acceptance bar was a real corpus: 20 Summary of Benefits documents from 8 carriers, 9 to 50 pages each, including one that is pure scanned images. The fixes described here were all in the schema, the chunking or the descriptions.

The model reads your schema descriptions as instructions. Audit them like prompts.

How an LLM is trained: the four-stage pipeline

Everything else in this post depends on knowing which stage you would be touching. A large language model predicts the next token from the tokens before it. Getting from that to an assistant takes four stages, each with a different dataset, a different goal and a very different cost.

LLM training pipeline in four stages: pre-training on internet text, supervised fine-tuning, reward modelling and reinforcement learning, with data and compute shrinking at each stageLLM training pipeline in four stages: pre-training on internet text, supervised fine-tuning, reward modelling and reinforcement learning, with data and compute shrinking at each stage

Almost all of the cost sits in the first box. Everything a company can realistically change sits in the last three.

1. Pre-training

Dataset. Raw internet text: trillions of words from many sources. Large, diverse and mostly low quality, which is the point. It is a general knowledge base, not a curated one.

Algorithm. Language modelling. The model predicts the next word, and in doing so learns syntax, grammar and some aspects of reasoning.

Result. A base model that can generate text but isn't yet good at any specific task.

Infrastructure. Massive: thousands of GPUs running for several months.

2. Supervised fine-tuning (SFT)

The base model is trained on high-quality labelled data: pairs of prompts and ideal responses, usually written by people to demonstrate correct behaviour.

Goal. Teach specific tasks, such as answering email or writing in a particular style, from human examples.

Result. A task-specific model that follows the rules and nuances of an application.

Infrastructure. Far smaller than pre-training: a few GPUs, days rather than months.

3. Reward modelling (RM)

The model's outputs are ranked and scored against human preferences. That feedback trains a separate model to predict which answers people actually want.

Goal. Capture what users value: clarity, relevance, tone.

Result. A reward model that scores a response by how likely it is to meet expectations.

Infrastructure. A few GPUs, training a model to predict human satisfaction.

4. Reinforcement learning (RL)

The final stage. The model is optimised against the reward model's signal, learning to produce the responses that score highest.

Goal. Generate tokens that maximise the reward, so behaviour lines up with human feedback.

Result. A refined model with a high degree of alignment to what users asked for.

Infrastructure. A small dataset, but computationally intensive: a few GPUs over days.

When someone asks to "fine-tune it on our data", they usually mean more of stage 2 on top of someone else's stages 1 to 4. That can change behaviour and style. It is a poor way to add facts.

The base model is not the product. The last stages of training shape it, and they are the realistic place for most teams to intervene.

Fine-tuning vs RAG: what each one changes

The cleanest way to hold the difference: fine-tuning changes the weights, retrieval changes the prompt.

Fine-tuning

Best for specific, consistent tasks: a fixed domain, a defined style, a format the model keeps drifting from.

What it buys. The model "remembers" the training data and applies it to every similar query without being told.

What it costs. Compute, a labelled dataset, and a retrain every time the underlying knowledge moves. What it learned is fixed at the moment training ended.

Retrieval-augmented generation (RAG)

Best for knowledge that changes: product specifications, policies, papers, anything with a date on it. The model reaches into an index at request time and answers from what it finds.

What it buys. New knowledge lands the moment it is indexed, with no retraining. Every answer can point at the chunk it came from.

What it costs. A retrieval system and the database behind it, plus a new class of bug: the right answer sitting in a chunk the retriever didn't return.

RAG request path: a query goes through a retriever to the top matching chunks, is assembled into a prompt, and the model answers; knowledge changes in the index, not the weightsRAG request path: a query goes through a retriever to the top matching chunks, is assembled into a prompt, and the model answers; knowledge changes in the index, not the weights

Every box before the model is ordinary software, which means every box before the model can be wrong in ordinary ways.

RAG is cheaper than fine-tuning until you count the retrieval bugs. Budget for them.

Timeline comparing a fine-tuned model whose knowledge stops at its training date with a RAG index that keeps updatingTimeline comparing a fine-tuned model whose knowledge stops at its training date with a RAG index that keeps updating

The fine-tuned model is not wrong on the day you ship it. It becomes wrong on a schedule you don't control.

Fine-tuning freezes today's answer into tomorrow's model.

The third option often left out

Most comparisons stop at two options. The one that solved my problem isn't either of them: structured output with schema-driven prompting. A stock model, a strict output schema, and prompts that carry the rules.

It works when the task is transformation, not knowledge. PlanReel's extraction doesn't need the model to know anything about a plan in advance. The plan is in the PDF. The job is to read it and put each figure in the right field, which is a shape problem. A schema is the cheapest way to enforce a shape, because the API refuses to return anything else.

The rules that made it hold up:

  • Money is never a float. Every cost is an integer number of cents alongside a displayAs string carrying exactly what the document printed. The model copies; it never normalises a benefit into a number it might get wrong.
  • Every prompt states its limits. Each chunk's prompt names its own page range and forbids the model from inferring anything outside the excerpt it can see.
  • The schema is shared. The model's output schema, the renderer and the editor forms all derive from the same Zod definitions, so "the model returned a field the renderer doesn't expect" can't be expressed.
  • A person approves the output. The model drafts. A human reads every number before anything reaches a client.

None of that needed a training run, and all of it can change in a pull request.

Before asking for a fine-tune, check whether a retrieval index or a JSON schema does the job.

Which to choose: the decision table

Four questions settle most cases. Ask them in order.

Question

If yes

If no

Does the knowledge change after you ship?

RAG. Keep facts out of the weights.

Next question.

Must every answer point to its source?

RAG, with the retrieved chunk kept alongside the answer.

Next question.

Is the output a fixed shape (fields, types, enums)?

Structured output with schema-driven prompting.

Next question.

Do you need a style or behaviour the prompt can't hold, and do you have labelled examples of it?

Fine-tune.

Better prompts first. You have nothing to train on yet.

Real systems can answer yes to more than one. A support assistant can need retrieval for the policies, a schema for the ticket it files, and a fine-tune for the house tone. That is all three, and it is fine, as long as each one is doing the job only it can do.

Decision tree for fine-tuning vs RAG vs structured prompting: changing knowledge or a need to cite sources leads to RAG, a fixed output shape leads to structured prompting, and only a style with labelled examples leads to fine-tuningDecision tree for fine-tuning vs RAG vs structured prompting: changing knowledge or a need to cite sources leads to RAG, a fixed output shape leads to structured prompting, and only a style with labelled examples leads to fine-tuning

Fine-tuning is the last branch, not the first. It is the only one that needs a dataset before you can start.

Rules I enforce when LLMs touch production

These replace the "best practices" list this post used to end with. They are rules, not suggestions.

  1. Nothing reaches a user without a person reading it when the output carries money, health, legal or contractual weight.
  2. Exact values are copied, never computed. Prices, dates, identifiers and quotes travel as strings from the source.
  3. The output has a schema, and the schema is tested whole. Assert the absence of what the provider forbids, not only the presence of what you remembered.
  4. Schema descriptions and examples get the same review as prompts.
  5. A request that can never fit is an architecture problem. Retry on 429 cannot fix a request larger than the limit. Chunk it.
  6. Know what leaves the building. Be deliberate about which code and data go to an external model, and send nothing sensitive that hasn't been approved for external processing.
  7. Read generated code before merging it. The model is a tool, not a reviewer of its own work. I wrote up how I do that in my AI coding workflow.

Where LLMs help in day-to-day development

Code generation, review, debugging, documentation and test writing are all real uses, and I use models for each. The pattern that makes them work is the same one as extraction: a narrow task, a defined output, and a person who reads the result before it ships.

FAQ

What is the difference between fine-tuning and RAG?

Fine-tuning changes the model's weights by training it further on labelled examples, so the behaviour is built in. RAG leaves the weights alone and adds retrieved documents to the prompt at request time, so the knowledge can change without retraining.

When should I fine-tune an LLM instead of using RAG?

When you need a consistent style or behaviour that prompting can't hold, the underlying knowledge doesn't change often, and you have labelled examples of the output you want. If the knowledge changes, use retrieval.

What is structured output, and is it an alternative to fine-tuning?

Structured output constrains the model to return JSON that matches a schema you supply. For transformation tasks such as extracting fields from a document, a stock model with a strict schema can do the job a fine-tune was proposed for, with no training data and no retraining.

What are the four stages of LLM training?

Pre-training on large amounts of raw text, supervised fine-tuning on labelled prompt and response pairs, reward modelling from human rankings, and reinforcement learning against that reward model.

Can I combine fine-tuning, RAG and structured output?

Yes. A system can use retrieval for changing knowledge, a schema for the output shape, and a fine-tune for tone. Each should do the job only it can do.

Why does my LLM ignore the system prompt?

One cause worth checking first: the model also reads your schema's field descriptions and examples. On PlanReel an example in a description overrode an explicit rule in the system prompt. Audit descriptions like prompts.

Shape first

An earlier, shorter version of this post appeared on the Eaglix blog.

Try this this week: take the feature someone wants to fine-tune for, write its output as a JSON schema, and run real documents through a stock model with strict structured output before anyone books a GPU. If you want a pipeline like this built for your team, get in touch.

Train the model last. Shape the output first.

Keep reading