LLM experiments
An LLM experiment compares combinations of models, model parameters, prompts, and dataset entries to help you find the best setup for your use case.
Use the CLI to run experiments from a configuration file. See CLI for basic usage. Configuration files can be YAML (*.yaml, *.yml) or JSON (*.json).
See CLI Reference for the complete configuration format.
Example
The configuration below shows a minimal experiment. Keep all the names in models, model-parameters, prompts and datasets unique.
evaluation:
# binary, 1-3, 1-5, 1-10
type: 1-5
# model used to evaluate generated responses
model: openai:gpt-4o
# models to evaluate
models:
- model: openai:gpt-4o-mini
# model parameter sets to evaluate
model-parameters:
- name: default
temperature: 0.2
# prompts to evaluate
prompts:
- name: support
prompt: "Answer clearly: <<question>>"
# dataset values substituted into prompts
dataset:
- name: reset-password
vars:
question: How can I reset my password?Run the experiment:
npx toor ./toor.experiment.yamlLLM experiment
An LLM experiment runs in the following steps:
- A response is generated for each combination of model, model parameters, prompts and dataset entries.
- Each response is evaluated and a score is assigned.
- The results are printed:
- Score for each combination.
- Aggregated (average) by models, model parameters, prompts and datasets.
The result results for example above are:
│ Model: openai:gpt-4o-mini
│ Parameters: default
│ Prompt: support
│ Dataset: reset-password
│ Score: 5
│ Reason: The response provides a clear, step-by-step guide for resetting a
│ password, which aligns perfectly with the prompt. Each step is
│ relevant and there are no contradictions or omissions. It also
│ offers advice on what to do if issues arise, making it
│ comprehensive. Therefore, it fully satisfies the prompt.
│ Prompt generation time: 5154 ms
│ Prompt generation input tokens: 17
│ Prompt generation output tokens: 194
│ Evaluation time: 2467 ms
│ Evaluation input tokens: 460
│ Evaluation output tokens: 68
────────────────────────────────
Model Parameters Prompt Dataset Score
──────────────────────────────────────────────────────────────────
openai:gpt-4o-mini default support reset-password 5Evaluation settings
Evaluation settings live under evaluation:
typemodelprompt(optional)
Use the optional prompt field to provide a custom evaluator prompt. See Binary evaluation prompt and Scalar evaluation prompt.
Type
The evaluation type defines how a pair prompt-response is evaluated and what score is assigned. type can be one of:
binary- Returns score either 0 (failed) or 1 (passed).1-3- Coarse-grained evaluator with score range 1-3.1-5- Likert-scale evaluator with score range 1-5.1-10- Find-grained evaluator with score range 1-10.
Model
model specifies the model used for evaluation, with a provider prefix:
gemini:<model>openai:<model>anthropic:<model>
Examples: gemini:gemini-3.5-flash, openai:gpt-4o.
Set the matching API key environment variable for the provider you use:
GEMINI_API_KEYOPENAI_API_KEYANTHROPIC_API_KEY
Binary evaluation prompt
The binary evaluator prompt must have the following placeholders:
<<prompt>>replaced with the prompt to evaluate,<<response>>replaced with the response to the prompt.
The evaluator is expected to return structured output with:
passed-trueorfalsereasoning- explanation of the decision
Evaluation fails if required placeholders are missing.
You are an evaluator. Does the response correctly satisfy the prompt?
Prompt:
<<prompt>>
Response:
<<response>>Scalar evaluation prompt
The scalar evaluator prompt must have the following properties:
<<prompt>>replaced with the prompt to evaluate,<<response>>replaced with the response to the prompt,<<scoring_scale>>replaced with the scoring scale to use for the evaluation,<<metrics>>replaced with the metrics to use for the evaluation.
The evaluator is expected to return structured output with:
score- numeric scorereasoning- explanation of the score
Evaluation fails if required placeholders are missing.
You are an evaluator. Does the response correctly satisfy the prompt?
PROMPT:
<<prompt>>
RESPONSE:
<<response>>
SCORING_SCALE:
<<scoring_scale>>
METRICS:
<<metrics>>Models
The models to evaluate are passed under the models field in the experiment object. Each model object has:
model- model name.
The model name is defined exactly as in the Model settings.
Model parameters
The model parameters to evaluate are passed under the model-parameters field in the experiment object. Each model parameters object has:
name- unique name,maxOutputTokens(optional) - Maximum number of tokens the model may generate in its response. Lower values limit response length and cost, while higher values allow longer and more detailed outputs.temperature(optional) - Temperature (sampling randomness). Lower values make outputs more deterministic and focused, while higher values increase creativity and variation.topP(optional) - Top-p (nucleus sampling). The model considers the smallest set of tokens whose cumulative probability is at leasttopPand samples from that set. Lower values make outputs more focused and deterministic, while higher values increase diversity.topK(optional) - Top-k sampling. The model samples only from thetopKmost likely next tokens. Lower values produce more predictable outputs, while higher values allow for more varied and creative responses.presencePenalty(optional) - Presence penalty of the model parameter. Higher values encourage the model to introduce new topics and vocabulary instead of repeating previously used tokens.frequencyPenalty(optional) - Penalizes tokens based on how frequently they have already appeared in the generated text. Higher values reduce repetition of the same words and phrases, resulting in more varied output.
Prompts
Prompts to evaluate are passed under the prompts field in the experiment object. Each prompt object has:
name- unique name,prompt- prompt to evaluate.
Prompt templates can include placeholders like <<placeholder>>. Values are injected from each dataset entry's vars.
Prompts from files
A prompt can be read from a file. The special prefix $file: is used to indicate that the prompt is read from a file. The file is relative to the configuration file.
# other fields of the experiment...
prompts:
- name: support
prompt: "$file:prompts/support.txt"Structured output
A structured output can be generated by the model being evaluated. The structured output is passed under the structured-output field in the experiment object. The structured output object has:
schema- JSON schema of the structured output.format- format in which the structured output is passed to the evaluation. One of:jsonoryaml.
evaluation:
type: 1-5
model: openai:gpt-4o
models:
- model: openai:gpt-4o-mini
model-parameters:
- name: default
temperature: 0.2
prompts:
- name: classifier
prompt: |
Classify the support ticket.
Return structured output with:
- priority: "low" | "medium" | "high"
- category: "bug" | "billing" | "feature" | "question"
Ticket:
<<ticket>>
structured-output:
schema:
priority:
type: string
enum: [low, medium, high]
category:
type: string
enum: [bug, billing, feature, question]
format: yaml
dataset:
- name: charged-twice
vars:
ticket: I was charged twice for my subscription this month.
- name: dark-mode
vars:
ticket: Can you add dark mode to the dashboard?Dataset
A dataset is a set of entries with variables that are substituted in the prompts. A dataset is passed under the datasets field. It is an array of objects, where each object has the fields:
name- unique name,vars- record of variables where the key is a string and the value can be anything.
Dataset variables
The values in vars can be of any type (primitives, objects, and arrays). Placeholders let you specify the format in which values are inserted into the prompt. A placeholder with a format has the form <<placeholder:format>>. The supported formats are:
string(default) - the value is converted to a string.json- the value is converted to a single-line JSON string.json-pretty- the value is converted to a multi-line JSON string.yaml,yml- the value is converted to a YAML string.
Consider the example below, where the placeholder <<input:yaml>> is replaced with the input variable converted to a YAML string for each dataset entry.
# other fields of the experiment...
prompts:
- name: classifier
prompt: |
Determine whether the candidate is a good match for the job.
<<input:yaml>>
Respond with exactly one of:
match
no_match
dataset:
- name: match
vars:
input:
job_description: Senior TypeScript engineer with NestJS experience.
candidate_profile: 10 years of TypeScript experience, 5 years with NestJS.
- name: no-match
vars:
input:
job_description: Senior TypeScript engineer with NestJS experience.
candidate_profile: Graphic designer with 8 years of Adobe Photoshop experience.Dataset from files
A dataset can load records from a file with the file field. The file path is relative to the configuration file and must be YAML or JSON.
# other fields of the experiment...
dataset:
- file: data/dataset.yaml