Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Builds and maintains configuration-based evaluations on a workflow with the eval-config tool. Use when the user asks to set up, add, view, change, or remove an evaluation, score, grade, or judge a workflow's output, or measure answer quality against a test dataset. This is the only eval form Instance AI handles — it does not touch on-canvas evaluation nodes.
.claude/skills/n8n-io-config-evals/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 56% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 1% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 14% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 9% | 0% |
Use this skill to attach a configuration-based evaluation to a workflow with the eval-config tool. A config eval pairs a workflow with a name, a start node, an end node, one or more judged metrics, and a Data Table dataset. Nothing is added to the canvas — the config lives off-canvas via the evaluation-config API.
Config evals are the only evaluation form you work with. Do not add, read, rewire, or reason about on-canvas evaluation nodes (EvaluationTrigger, Evaluation/checkIfEvaluating/setOutputs/setMetrics). If the user asks for those, build a config eval instead and briefly say that is how you set up evaluations.
name — a human-readable evaluation name.startNodeName — the node where a run begins; it is fed one test-input row.Must be a node with an incoming connection — never a trigger (see step 2).
endNodeName — the node whose output is judged.dataTableId — a Data Table holding the test dataset. Create and populate itwith the data-tables tool first, then link it here by id.
metrics — one or more judged metrics (see below).the node that produces the answer.
startNodeName is the first node after the trigger — the node thatreceives the input the dataset varies. Never use the trigger itself: an eval run swaps the trigger for a dataset-driven one, so the start node must have an incoming connection or the run fails to compile. For a chat/agent workflow this is usually the agent node (often the same as endNodeName).
endNodeName is the node whose output you want scored (usually the AI agentor the final response node).
data-tables(action="list") to find an existingdataset, or create and seed one with data-tables before creating the config. Never invent a dataTableId; use one returned by data-tables.
actualAnswer / expectedAnswer / userQueryexpressions (see Metrics).
eval-config (action="create"), or update when changing an existingconfig. The tool shows an approval card automatically — call it and respect the result; do not ask for chat approval first.
id, and the metrics configured.
Each metric is LLM-judged and needs a judge model: a credentialId, a model, and an outputType (numeric, the default, or boolean). Reuse an LLM credential the workflow already uses when one fits.
Do not set provider unless you know the exact chat-model node type — it is derived automatically from the credential you pass (each credential type maps to one provider). Just pick the credential and the model.
Two presets are available:
correctness — compares the produced answer to a ground-truth answer.Requires expectedAnswer (an n8n expression resolving to the ground-truth value, typically a dataset column, e.g. ={{ $json.expected_output }}).
helpfulness — judges the produced answer against the user's query.Requires userQuery (an n8n expression for the input the user asked, e.g. ={{ $json.input }}).
Every metric also needs actualAnswer: an n8n expression resolving to the workflow's produced answer at the end node, e.g. ={{ $json.output }}.
userQuery and expectedAnswer name dataset columns (the input the user asked; the ground-truth answer). actualAnswer names a field of the workflow's produced output. Write all of them as ={{ $json.<name> }} — the evaluation reads dataset columns from the dataset row and actualAnswer from the end node automatically. Do not reference the trigger or any node by name.
=actualAnswer, userQuery, and expectedAnswer are n8n expressions — they read a value out of each test row at runtime. The leading = is what tells n8n to evaluate the {{ … }} template. Without it the string is stored as literal text: the field shows {{ $json.output }} verbatim and the judge scores that raw string instead of the resolved value.
={{ $json.output }}, ={{ $json.expected_output }}{{ $json.output }} (no = → treated as fixed text)Only add = when the value references workflow data via {{ … }}. A genuinely fixed constant (rare for these fields) is written as plain text without =.
Pick correctness when the dataset has a known right answer to compare against; pick helpfulness when there is no single ground truth and quality is judged relative to the request. Use prompt only to override the default judge prompt.
data-tables tool: one column for each input theevaluation varies, plus a ground-truth column when using correctness.
dataTableId; the eval-config tooldoes not create or populate rows. If no suitable dataset exists, create one first, then create the config.
the metrics, or ask the user for the expected answers.
Use references/config-eval-playbook.md for tool-call recipes, worked examples, and output shapes.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 35,236 | 21,075 | -40% | 1 | 1 | 0% | 2,089 | 1,872 | -10% | 0 | 0 | — |
case-02 | fail→fail | 56,413 | 13,843 | -75% | 1 | 1 | 0% | 2,860 | 1,711 | -40% | 0 | 0 | — |
case-03 | fail→fail | 10,427 | 18,239 | +75% | 1 | 1 | 0% | 1,929 | 1,811 | -6% | 0 | 0 | — |
case-04 | pass→pass | 90,830 | 26,033 | -71% | 1 | 1 | 0% | 2,371 | 4,452 | +88% | 0 | 0 | — |
case-05 | pass→pass | 164,393 | 12,165 | -93% | 1 | 1 | 0% | 2,501 | 3,336 | +33% | 0 | 0 | — |
case-06 | pass→pass | 29,062 | 12,332 | -58% | 1 | 1 | 0% | 2,140 | 3,398 | +59% | 0 | 0 | — |
case-07 | fail→pass | 15,085 | 11,852 | -21% | 1 | 1 | 0% | 1,260 | 1,966 | +56% | 0 | 0 | — |
case-08 | pass→pass | 7,425 | 10,402 | +40% | 1 | 1 | 0% | 989 | 1,824 | +84% | 0 | 0 | — |
case-09 | fail→pass | 9,890 | 4,831 | -51% | 1 | 1 | 0% | 1,462 | 1,838 | +26% | 0 | 0 | — |
case-10 | fail→fail | 16,051 | 22,744 | +42% | 1 | 1 | 0% | 3,152 | 2,077 | -34% | 0 | 0 | — |
case-11 | fail→pass | 47,851 | 14,716 | -69% | 1 | 1 | 0% | 3,258 | 3,288 | +1% | 0 | 0 | — |
case-12 | fail→fail | 6,464 | 32,603 | +404% | 1 | 1 | 0% | 734 | 3,019 | +311% | 0 | 0 | — |
case-13 | fail→pass | 25,926 | 4,208 | -84% | 1 | 1 | 0% | 1,724 | 1,963 | +14% | 0 | 0 | — |
case-14 | fail→pass | 14,827 | 8,068 | -46% | 1 | 1 | 0% | 1,903 | 2,066 | +9% | 0 | 0 | — |
case-15 | fail→pass | 20,726 | 9,443 | -54% | 1 | 1 | 0% | 1,353 | 2,022 | +49% | 0 | 0 | — |
case-16 | fail→fail | 4,020 | 6,304 | +57% | 1 | 1 | 0% | 411 | 2,030 | +394% | 0 | 0 | — |
case-17 | fail→pass | 9,502 | 5,169 | -46% | 1 | 1 | 0% | 1,236 | 2,030 | +64% | 0 | 0 | — |
case-18 | fail→pass | 11,217 | 4,263 | -62% | 1 | 1 | 0% | 1,344 | 1,994 | +48% | 0 | 0 | — |
case-19 | fail→pass | 46,342 | 5,602 | -88% | 1 | 1 | 0% | 1,989 | 2,056 | +3% | 0 | 0 | — |
case-20 | fail→fail | 15,140 | 3,356 | -78% | 1 | 1 | 0% | 928 | 1,746 | +88% | 0 | 0 | — |
case-21 | fail→pass | 6,197 | 2,799 | -55% | 1 | 1 | 0% | 883 | 1,643 | +86% | 0 | 0 | — |
case-22 | pass→fail | 7,587 | 9,828 | +30% | 1 | 1 | 0% | 1,152 | 2,931 | +154% | 0 | 0 | — |
case-23 | pass→pass | 12,568 | 4,038 | -68% | 1 | 1 | 0% | 1,611 | 1,826 | +13% | 0 | 0 | — |
case-24 | pass→pass | 29,350 | 7,544 | -74% | 1 | 1 | 0% | 2,053 | 2,546 | +24% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted, and 19 counted toward the lift figure. The other 5 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +38 percentage points is the difference between those two pass rates over the 19 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.