model.py.
This page shows the full loop:
- Declare the variables your benchmark reads (owner, on the Environment tab).
- Read them in your ingestion/scoring code from
os.environ. - Run a model. The runner fills in only what you exposed, on the Evaluate screen.
- Verify the injected values shaped the run, in the results.
Who does what. The benchmark owner declares every variable and decides what runners can
see and change. The runner picks a model and fills in the exposed values. They change
values only, never keys.
How it works
Each variable has a source that decides where its value comes from:1. Open the benchmark
From Eval → Environments, open the benchmark you own and want to configure. Env-var-first benchmarks describe their run contract right on the Overview tab.
model.py required.

2. Declare your variables
Click Edit, then open the Environment tab. This is where you declare every credential and config your benchmark reads from its container. Nothing is added for you. You decide what exists, what runners see, and what they can change.1
Set an optional prefix
A prefix like
GK pre-fills new key names as GK_… so they group together. Every key stays
fully editable.2
Add each variable
For every variable, set its Key, Label, Source, and, where relevant, the Model
field it maps to. Toggle Required, Secret, and Hidden / Visible to runners.

3. Read them in your benchmark
Your ingestion and scoring code reads these straight fromos.environ. The Environment tab shows
a copyable snippet of exactly the keys you declared:

There is no
model.py to edit. The same values are injected for both the ingestion step
and the scoring step, so an LLM-as-judge can read its own *_JUDGE_* keys the same way.4. Preview what runners will see
The Preview on the Environment tab mirrors the Evaluate screen. Only variables you mark Visible to runners appear here. Model-sourced values show as read-only chips (“auto-filled from selected model”); runner-provided values show as editable fields.
GK_SYSTEM_PROMPT and GK_MAX_QUESTIONS; everything
else is auto-filled from the model they pick.
5. Run a model against it
Open the Evaluate tab, choose a model source (Platform, Running, Trained, HuggingFace, or External API), and pick a model. Expand Advanced: model environment & parameters to see the env panel you designed.- Model (under test) chips are auto-filled from the selected model (
GK_TEMPERATURE,GK_MAX_TOKENS, …). - You provide these are the runner-exposed fields.
- Sampling parameters (Temperature, Max tokens, Top P, Timeout) feed the model-sourced keys.

6. Verify it worked
Open the run from Results. The injected system prompt clearly shaped the model’s behaviour: every answer in the Model column isC, and the run only scores on questions where C
happened to be the correct answer.

This confirms the loop end-to-end: a value the runner typed on the Evaluate screen was injected as
an environment variable, read by the benchmark from
os.environ, and visibly changed the model’s
outputs. You can inspect the exact variables a run used under Run configuration → View.
Reference
Runtime precedence
When more than one source could set the same key, the value is resolved deterministically:- From model: mapped from the runner’s selected model (not runner-overridable).
- Fixed + hidden: the owner’s baked value (secret values injected server-side).
- Fixed + visible: runner value if provided, otherwise the baked value.
- Runner provides: the runner’s value.
- Undeclared keys: free-form passthrough from the advanced editor.
Variable flags
Next steps
- Run a benchmark: the full run workflow.
- Read results: interpret the score breakdown and detailed table.
- Create a custom environment: package your own env-var-first bundle.