First training with a real model#

Use an API endpoint to run both an acting model and the GEPA learner on nine included sentiment tasks. No external dataset, GPU, or agent CLI is needed; GEPA’s library is an installation extra. Unlike the offline walkthrough, both acting and learning make real model calls.

This is an integration smoke test: three training tasks, three validation tasks with which GEPA chooses between candidate adapters, and three held-out test tasks. There is no promised score gain. A strong model may already satisfy the judge, and a learned update can also perform worse.

1. Install and make a working copy#

Complete Installation, activate its environment, then run from the repository root:

python -m pip install -e . -r requirements-gepa.txt
mkdir -p .demo
cp -R docs/_examples/first_model .demo/first-model

All generated runs and edits stay in the copy. Use a fresh destination if you already completed it.

2. Configure the acting and learner models#

Use an endpoint that accepts chat-completions requests with system/user messages, max_tokens, temperature, text responses, and token usage. The client appends /chat/completions to the base URL.

export MODEL_BASE_URL='https://your-endpoint.example/v1'
export MODEL_NAME='your-model-id'
read -r -s MODEL_API_KEY
export MODEL_API_KEY
python .demo/first-model/configure.py

Replace the two placeholders. The read command waits for you to paste the key and press Enter without displaying it. The configuration helper writes endpoint and learner-model names into the copied YAML, never the credential.

By default both sides use MODEL_NAME. Set ACTOR_MODEL and/or LEARNER_MODEL before configuring to choose different models. Optionally set ACTOR_BASE_URL / ACTOR_API_KEY and LEARNER_BASE_URL / LEARNER_API_KEY for separate endpoints and credentials; unset values fall back to the shared settings above. Re-run the helper after changing learner settings. Keep acting settings fixed across baseline, training, and evaluation.

Side

Source of settings

Acting pipeline

Runtime environment; actor-specific endpoint/model/key override shared settings

Learner

Copied YAML’s llm section, written by the helper; credential variable name is saved, its value is not

If your model needs different request fields or a larger reasoning-token allowance, adjust the copied pipeline.py and evolver.params before running. The example’s max_tokens=256 actor setting is for a short text response; some reasoning models need more.

3. Check and measure the baseline#

hermit check --config .demo/first-model/run.yaml --no-probe
hermit check --config .demo/first-model/run.yaml
hermit eval --config .demo/first-model/run.yaml --adapter none

The first command loads components without an acting-model call. It does not authenticate the endpoint or prove that the learner works. The second sends one short request to the learner endpoint and runs one acting task; eval runs all three held-out tasks.

The judge requires exactly {"label": "positive"}, {"label": "negative"}, or {"label": "neutral"}. Invalid JSON, extra keys, prose, and wrong labels score zero. A low score without execution errors is valid feedback; connection or model errors require investigation.

4. Train and evaluate the selected adapter#

hermit train --config .demo/first-model/run.yaml
hermit eval --config .demo/first-model/run.yaml --adapter root
hermit eval --config .demo/first-model/run.yaml --adapter final

One batch of three training attempts becomes learning material. GEPA first scores the starting adapter on the three validation tasks. If a training attempt failed, it asks the learner model for a new ADAPTER.md from the attempts and the judge’s feedback, runs that version on the same three training tasks, and keeps it only if it scores higher; a kept version is then scored on the validation tasks. If all three training attempts were already correct, there is nothing to learn from and the step proposes nothing. The Trainer checks and records the result. The initial template is root; final is the candidate with the best validation score, which is root when no new version was kept.

The complete sequence makes 16 to 22 acting requests: one probe, three no-adapter tests, three training attempts, three validation tests of the starting adapter, three tests of a proposed version on the training tasks and three validation tests if it is kept, three root tests, and three final tests. There are one to three learner requests: the probe from check, then none during training when every training attempt was correct, otherwise one, with one more if the reply holds no usable instructions. HTTP retries can add provider requests.

The commands on this page, request by request.
Training/Evolution Loop first-model walkthrough · example scores 1hermit checkRuns the first training task with no adapter, and sends one short requestto the learner model. Both only test the connections.+1 acting+1 learnerThe command before it, check --no-probe, only loads components: no requests. 2hermit eval --adapter noneRuns the 3 test tasks with no adapter. This is the baseline score.Evaluation only measures: nothing goes to the learning side.+3 acting 3hermit train· rolloutsThe acting agent runs the 3 training tasks with root, the starting adapter.The answers and the judge's feedback become learning material for GEPA.+3 acting 3hermit train· GEPA scores rootGEPA has the acting agent run root on the 3 validation tasks.It keeps only the scores: root becomes candidate #0 in its pool.+3 actingThe learner model never sees the validation tasks. 3hermit train· reflectionA training answer was wrong, so GEPA sends the attempts and the judge'sfeedback to the learner model, which writes a new ADAPTER.md.+1 learner(one more if the reply holds no usable instructions)If all 3 training answers had been right: nothing to learn, 16 requests in total. 3hermit train· test the new versionIt passes the specification check, then reruns the same 3 training tasks.Example: 3/3 beats root's 2/3, so GEPA keeps it.+3 actingNot higher than root? GEPA discards it: 19 requests in total. 3hermit train· score it on validationThe kept version runs the 3 validation tasks (example: 3/3)and joins the pool as candidate #1.+3 acting 3hermit train· hand back and recordGEPA hands back its pick; the Trainer checks it and records the version.final = the candidate with the best validation score: #1 here, else root.no model requests 4hermit eval --adapter rootRuns the 3 test tasks with root. Training never used these tasks.+3 acting 5hermit eval --adapter finalRuns the same 3 test tasks with final, to compare with root's score.+3 acting Total: 22 acting + 2 learner requestsThis run tested and kept a new version, which gives the maximum.16 if no new version is tested · 19 if it is tested but not kept.Learner: 1 to 3 (one more if a reply holds no usable instructions) Acting agent(s) actobserveaccess outputs / feedbackupdate GEPA test runs Task data1 training task3 test tasks3 training tasks3 test tasks Original harness Harness adapter nonerootnewfinalrootfinal Specification checkLearning material3 answers + feedbackEvolver· GEPAEvolver state: emptypool: #0 root 2/3#0 root 2/3 · #1 new 3/3Validation learner model Environmentnot used in this exampleHumanfeedback Model requests, command by command acting requests 012345678910111213141516171819202122 learner requests 012 none · 1 train probeprobe +1 → 1 learner probeprobe +1 → 1 none · 3 test score 1/3 +3 → 4 root · 3 train score 2/3 +3 → 7 root · 3 val score 2/3 +3 → 10 learner reflectreflect +1 → 2 new · 3 train only if testedscore 3/3 +3 → 13 new · 3 val only if keptscore 3/3 +3 → 16 root · 3 test score 2/3 +3 → 19 final · 3 test score 3/3 +3 → 22 1 check 2 eval none 3 train 4 eval root 5 eval final Dashed cells run only on some paths: 16 requests if no new version is tested · 19 if it is tested but not kept · 22 if it is kept.
Animated, about 50 seconds per loop. Dashed cells run only on some paths; scores are illustrative.

See more about training at Evolving an adapter.

The YAML uses token and time budgets; prices are not invented, so dollar cost is reported as unknown. Add verified llm.price settings for learner dollars and acting-client prices in the copied pipeline if you need dollar accounting. Probe and test calls are outside the training budget; GEPA’s candidate tests during training count toward it. Training can overshoot during in-flight requests; use endpoint-side spending controls when needed.

5. Inspect what was learned#

cat .demo/first-model/runs/first-model/checkout/ADAPTER.md
cat .demo/first-model/runs/first-model/steps.jsonl
cat .demo/first-model/runs/first-model/eval/final/summary.json
cat .demo/first-model/runs/first-model/step_0001/output/report.md
cat .demo/first-model/runs/first-model/step_0001/state/gepa.json

report.md says what GEPA did with the step: kept a new version, rejected it, or skipped. gepa.json holds the candidate pool with each candidate’s validation scores.

Look for a general classification/formatting rule, not copied training reviews. The feedback explicitly discloses training labels in this protocol, and the learner model sees only the training attempts and their feedback. GEPA’s code receives the validation results and keeps only their scores; the feedback of a wrong validation answer names its label, and the run’s tools.jsonl records it. Test labels stay in judge-owned code. This in-process, sandbox-disabled example does not create a security boundary around those files.

Require errors: 0 when comparing scores. mean_score is the fraction of correct task attempts here. Three test tasks do not establish a reliable improvement. The final adapter can be deployed using the deployment tutorial.

For another completed experiment, use a new trainer.run_name on every related command. To change the task or judge, continue with Bring your task. For larger model experiments, use the recipe catalog.