8000 Add OPRO: the opro Evolver on the prompt-only template and its OfficeQA example by ruiling-smartbear · Pull Request #81 · Infini-AI-Lab/hermit · GitHub
[go: up one dir, main page]

Skip to content

Add OPRO: the opro Evolver on the prompt-only template and its OfficeQA example - #81

Open
ruiling-smartbear wants to merge 5 commits into
Infini-AI-Lab:mainfrom
ruiling-smartbear:opro
Open

ruiling-smartbear wants to merge 5 commits into
Infini-AI-Lab:mainfrom
ruiling-smartbear:opro

Conversation

@ruiling-smartbear
@ruiling-smartbear ruiling-smartbear commented Nov 6, 2026 •
Copy link
Copy Markdown
Contributor

Change

OPRO (Yang et al., ICLR 2024; google-deepmind/opro at a76bdce) as an Evolver on the existing prompt-only template, with an OfficeQA example in the GPT-5.6-Luna setting. Each step, the optimizer (the run's llm) reads the instructions scored so far in ascending order and three training problems, each with the agent's answer when judged right or the judge's feedback otherwise, and writes n_candidates new instructions; each is scored with run_agent on every training task. finalize returns the best on training, or with select: validation the best validation mean of the top_k.

Flow chart of one step
flowchart LR
  R[step rollouts:<br/>current instruction<br/>on all training tasks] --> H[history:<br/>instructions with<br/>training scores]
  H --> M[meta-prompt:<br/>best old ones, ascending<br/>+ 3 training problems]
  M --> L[llm writes<br/>n_candidates<br/>instructions]
  L --> D{new and passes<br/>template check?}
  D -- no --> S[skipped]
  D -- yes --> A[run_agent on all<br/>training tasks]
  A --> H
  H --> F[finalize: best on train,<br/>or best val of top_k]
Loading

Core and application-side changes: none.

Differences from the authors' code (the method page's table)
Dimension google-deepmind/opro This Evolver Kind
When learning happens Each step: 8 new instructions, each scored on the whole training subset The same; after the first step the Trainer's rollouts re-score the current best (one more pass, recorded, not merged) Framework
What the optimizer sees Up to 20 scored instructions, ascending; 3 training problems with gold answers The same; the agent's answer when judged right, else the judge's feedback; problems drawn from runs that did not fail Task: no gold field
The instruction One sentence One ADAPTER.md; the authors' polish_sentence runs on the whole document (removes **) Decision
Score threshold 0.0 (text-bison) or 0.3 (GPT scorers) 0.0 Decision: the scorer is an agent
Final selection None in the code; the paper reports the best on training select: train, or the best validation mean of the top top_k Decision
Failures API errors retried until they succeed One more try, then dropped or left unscored, never scored 0; budget keeps what was scored Framework
Models GPT/PaLM optimizer at temperature 1.0 The run's llm (a Codex session applies no temperature) Framework
What the acting agent sees The instruction before the question in a one-shot prompt ADAPTER.md as the agent's instructions, then the task Framework
Budget 200 steps OfficeQA: 3 steps of 4 Decision: cost
Not ported The PaLM meta-prompt, instructions_only, other exemplar criteria, the temperature schedule, few-shot evaluation of new instructions, the periodic eval-split scores, the GSM8K digit filter — Off by default or task-specific

Every difference is acceptable for this reproduction; none is open.

Validation

  • python -m pytest tests/methods/opro tests/core/test_selection.py tests/core/test_packaging.py: 43 passed. They run every stage with a scripted model, check the meta-prompt against a stored output of the authors' gen_meta_prompt, and cover the failure and budget paths and the whole loop through the Trainer.
  • Full suite on macOS: the same 11 failures as on main on this machine (no bubblewrap, /proc); test_an_interrupted_caller_stops_the_session failed once under load and passed alone five times out of five.
  • Experiment: OPRO final 0.436 against the initial skill's 0.355 on the 172 test questions, +8.1 [+1.7, +14.5] paired (24 questions better, 10 worse).
Experiment: protocol, settings, result and records

Protocol: train / test. The Evolver learns on the 50 training questions, selects on the 24 validation questions, and the frozen adapter is evaluated on the 172 test questions (exact match). The optimizer sees the judge's feedback, which names the expected answer.

Settings: gpt-5.6-luna at medium effort acting and as the optimizer on a ChatGPT login (one Codex session per optimizer call); the Codex agent, a container per session (3,600 s), four side by side; 3 steps of 4 candidates; one pass per evaluation; SkillOpt's split at 79124b3 (shuffle_seed: 42). One training, on the method code of e7d668f (later commits move two checks into setup and touch docs and tests). Training 2.4 h and 124.5 M tokens; evaluations 30 min (final) and 57 min (the initial skill).

Adapter accuracy [95% CI] − the initial skill, points questions better / worse
the initial skill 0.355 [0.285, 0.424]
OPRO final (candidate 2 of 13, validation 0.625) 0.436 [0.366, 0.512] +8.1 [+1.7, +14.5] 24 / 10

Paired per question, 95% bootstrap; 0 errors in either evaluation. The gain is the answer's form: long or Markdown answers fall from 55 to 13, while answers containing the reference value are 118 and 112. The final instruction and its card are in examples/officeqa/opro/adapter/; the run records are local (examples/officeqa/opro/runs/luna-opro).

A first evaluation of final (0.419) lost 10 answers to the shared-layer fault fixed in #73; it was discarded and both evaluations were run again on that fix. The training met the fault once, and that rollout was run again.

Checked in the records: the 9 exemplars' right / wrong labels match the judge; a fresh judge agrees with all 150 training answers and both evaluations; no validation or test question appears in a meta-prompt; every evaluation session deployed the selected instruction.

Left out and not verified: the table's "Not ported" row, the no-adapter baseline, the GLM 5.3 Flash column, repeated trainings, and Linux.

Review

  • Tests and documentation cover the affected behavior, where applicable: as listed under Change; the tests follow the test checklist (tests/methods/opro/, selected by pytest --changed, stand-ins only for the model and the agent, no network or CLI).
  • Commands, defaults, and public interfaces are consistent: every evolver.yaml parameter is used; a run without llm or with an unknown select stops in setup, before its first rollouts.
  • Shared logs and examples contain no credentials or private data: adapter/ holds the instruction, its card and the template's files, with no local paths.
  • Documentation-only: not applicable.
  • Core changes. None.
  • Implementation correctness and failures. A failed optimizer call is tried once more, then dropped; an instruction whose rollouts fail twice is left unscored, never scored 0; at the hard budget the scored instructions are kept. Follow-up, not in this PR: Trainer.train runs the bootstrap outside its budget try.
  • Real execution paths and tests. One test runs the whole loop through the Trainer; the measured run went through hermit train and hermit eval, which read the adapter finalize returned.
  • Adapter template, Evolver, Upstream fidelity and adaptations. The existing prompt-only template; a new opro Evolver; the differences and their kinds in the table under Change.
  • Learning information and evaluation boundaries. The optimizer sees training questions and the judge's feedback; validation is used only by finalize, the test split only by hermit eval; the judge runs outside the session.
  • Experiments. Under Validation.
  • Agent three-layer abstraction. Optimizer calls go through ask(ctx.agent) (one codex Base Agent session per call), rollouts through run_agent; no method-specific execution, timeout or usage code.
  • This description. Read end to end against the code and the run records.
  • Independent review (post-PR audit). Two rounds by separate agents. The first (e7d668f) confirmed the verbatim meta-prompt, the numbers, the exemplar labels and the splits, and its findings are fixed in 59ca92c (left open: the 55→13 answer-form count is a heuristic reading; its own gave 62→21); the second (59ca92c) found no defects, and its two wording points are fixed in 938e554.

…QA example

- hermit/agent/evolver/methods/opro/: OPRO (Yang et al., ICLR 2024; google-deepmind/opro at a76bdce), one
  OPRO step per training step, the authors' meta-prompt verbatim and their reply parsing and md5 de-duplication
  ported; the optimizer is the run's llm tool, candidates are scored with run_agent on every training task;
  final is the best on training or the best validation mean of the top top_k.
- tests/methods/opro/, with its group in tests/selection.py and tests/README.md.
- examples/officeqa/opro/: smoke and run configs in the GPT-5.6-Luna setting, and adapter/ with the measured
  run's final instruction and its card.
- docs/methods/opro.md (flow chart, differences from the authors' code, what it is not); OfficeQA recipe section,
  OfficeQA README row, methods index, README method lists, CHANGELOG.
…differences table

From the post-PR audit:
- setup refuses a run without llm or with an unknown select, before the first rollouts; the step keeps its
  check for a resume. A Trainer test holds it.
- The method page's table adds the Trainer's extra pass per step, the exemplar draw, polish_sentence on a whole
  document, where reruns are recorded and the setup check; "What it is not" counts the extra pass.
- The recipe gives both evaluation times and no longer names the container image.
@ruiling-smartbear
ruiling-smartbear marked this pull request as ready for review November 6, 2026 05:12

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0