Model training & fine-tuning
Teach a base model your format, tone and judgement calls, then put it on any agent in a crew. LoopLlama runs supervised fine-tuning on the provider, tracks the job, and makes the resulting model routable in your workflows — at the provider's list price for training and inference, with no markup.
When to fine-tune#
Prompting gets most agents there. Fine-tuning is for the agent that runs thousands of times a month on a narrow, repeatable task — classifying submissions, drafting the same kind of email, extracting fields from the same document type — where you want a smaller, cheaper model to match the quality of a frontier model, cut the system prompt down to a line, or lock in a house style. The usual pattern is to run the agent on a strong model first, review its outputs, and then train a small model on the runs you were happy with.
Base models#
Supervised fine-tuning is available on these catalog models. Rates are the providers' list prices per 1M tokens.
| Model | Provider | Training | Fine-tuned input | Fine-tuned output |
|---|---|---|---|---|
| gpt-4.1 | OpenAI | $25.00 | $3.00 | $12.00 |
| gpt-4.1-mini | OpenAI | $5.00 | $0.80 | $3.20 |
| mistral-small-latest | Mistral | $2.00 | $0.15 | $0.60 |
| codestral-latest | Mistral | $3.00 | $0.30 | $0.90 |
Training data#
A training set is a list of examples; each example is a short conversation ending in the answer you want the model to give. There are two ways to build one.
From your workflow runs
Every completed step a workflow has produced is already an example: the agent's system prompt, the input it received, and the output it produced. Choose a workflow and an agent role, and LoopLlama assembles the set from the newest completed runs (failed runs and errored steps are skipped, up to 2,000 examples). Review the workflow's run history first — the model learns the outputs exactly as they were, so delete or re-run anything you wouldn't want repeated.
Upload a JSONL file
One JSON object per line, in the chat format both providers accept, or the shorter {"input", "output"} form (with an optional system), which LoopLlama rewrites to messages. Sets need at least 10 examples; a few hundred is where quality usually starts to move. Files are validated line by line before upload, so a malformed example is reported with its line number rather than failing at the provider.
{"messages":[{"role":"system","content":"Classify the broker submission."},{"role":"user","content":"Subject: New deal — Joe's Auto Body, $85k, 6 months in business…"},{"role":"assistant","content":"{\"decision\":\"decline\",\"reason\":\"time_in_business\"}"}]}
{"input":"Subject: Renewal — Harbor Dental, paid 80% of prior advance…","output":"{\"decision\":\"approve\",\"reason\":\"renewal_eligible\"}"}Start a job#
From the dashboard, Model training → Train a model. Over the API, create a job with the same fields; it returns immediately with status queued while the provider validates the file and trains.
import { LoopLlama } from "@loopllama/sdk";
const ll = new LoopLlama({ apiKey: process.env.LOOPLLAMA_API_KEY });
// Train on the "classifier" agent's completed steps in a workflow
const job = await ll.fineTunes.create({
name: "Submission classifier",
base_model: "gpt-4.1-mini",
source: "runs",
workflow_id: "wf_…",
role: "classifier",
});
const done = await ll.fineTunes.poll(job.id); // resolves when succeeded / failed / cancelled
console.log(done.fine_tuned_model); // → "ft:gpt-4.1-mini-2025-04-14:acme::abc123"Job lifecycle
queuedstatusoptionalvalidatingstatusoptionalrunningstatusoptionalsucceededstatusoptionalfine_tuned_model is set, trained_tokens and cost_usd are recorded, and the model is routable in your workflows.failedstatusoptionalerror carries the provider's message (usually a data-validation problem).cancelledstatusoptionalStatus is refreshed from the provider whenever you read the job and once a minute in the background, so a job completes whether or not anyone is watching. Each job's provider event log is available under /fine-tunes/:id/events.
Use the model in a workflow#
A finished job's fine_tuned_model works anywhere a catalog id does: as a workflow's default model, on a single agent in the crew, or on an Agent Hub template. It appears in the dashboard's model pickers under Your fine-tuned models. Tool calling, approvals, checkpoints and web-hooks behave exactly as they do for the base model.
{
"name": "Submission triage",
"model": "claude-sonnet-4-6",
"crew": [
{ "role": "classifier", "model": "ft:gpt-4.1-mini-2025-04-14:acme::abc123",
"systemPrompt": "Classify the broker submission." },
{ "role": "responder", "systemPrompt": "Draft the reply for the decision above." }
]
}400 at save time. Deleting a job record makes its model unroutable from your workflows (the model itself stays at the provider until you delete it there).Hyperparameters#
- OpenAI —
epochs(1–50). Leave unset to let OpenAI choose from the set size. - Mistral —
training_stepsandlearning_rate(default 0.0001). Leave unset for the provider defaults. suffix(letters, numbers, hyphens; up to 18 characters) is embedded in the provider's model id so you can recognise it in provider dashboards.
Self-hosting#
Fine-tuning uses the same provider keys as inference: set OPENAI_API_KEY and/or MISTRAL_API_KEY and the corresponding base models become trainable. With no provider configured at all, jobs complete instantly in stub mode with a placeholder model id, mirroring stub runs. Training and fine-tuned inference prices can be corrected without a deploy through MODEL_PRICING_OVERRIDES, e.g. {"gpt-4.1-mini":{"fineTune":{"train":5,"in":0.8,"out":3.2}}}.
See the Fine-tunes API reference for every field, and Models & providers for how routing and at-cost billing work.