HERO: Harnessing Evidence for Test-time Refinement and Prompt Optimization in Program Generation
Organizations: University of Washington · Microsoft Research · Recursion
Abstract
Harness optimization improves LLMs by refining reusable prompts and scaffolding, yet requires further adaptation for program generation tasks such as text-to-SQL and text-to-Python. Existing methods often rely on LLM reflectors to propose harness updates, which can fix observed failures but also disrupt previously correct behavior. Text-to-code tasks offer a natural way to mitigate this issue: we can execute generated outputs, allowing us to evaluate and verify the effects of proposed updates directly. Building on this signal, we introduce HERO Harnessing Evidence for Refinement and Optimization), which combines offline and test-time harness optimization. At the first stage, HERO learns reusable prompt updates from execution-verified successes and failures and validates candidate revisions before adoption. At test time, we treat the generated code as an instance-specific harness and refine it using execution feedback. Across four SQL, Cypher, and Python benchmarks, HERO achieves the best offline performance, improving pass@1 by 7.6 points over the initial prompt, while test-time refinement adds another 2.0 points and improves execution efficiency.
Figures & tables
| Baseline | Offline Prompt Optimization | Test-Time Adaptation | Harness Optimization | ||||||||
| Dataset | Seed | HERO-O | SkillOpt | GEPA | MIPROv2 | ACE | DC-Cu | HERO-O+T | HERO-O + ReAct | HERO-O + DC-Cu | Meta- Harness |
| BIRD DEV | 59.39 (0.32) | 63.55 (0.21) | 61.31 (1.19) | 62.59 (0.59) | 60.87 (0.57) | 60.87 (0.10) | 60.22 (0.79) | 64.81 (0.21) | 63.12 (1.03) | 62.44 (1.43) | 58.24 (2.18) |
| BigCodeBench | 47.93 (0.74) | 52.59 (0.31) | 51.81 (0.47) | 50.13 (1.00) | 50.65 (0.59) | 51.96 (1.25) | 44.79 (0.83) | 53.79 (0.33) | 52.64 (0.24) | 51.70 (0.89) | 45.26 (2.52) |
| DSCodeBench | 44.74 (0.24) | 54.84 (1.87) | 51.87 (1.50) | 52.14 (1.99) | 51.73 (1.76) | 51.31 (0.43) | 42.81 (0.24) | 56.04 (1.87) | 56.22 (2.87) | 54.70 (0.87) | 45.99 (0.52) |
| CypherBench | 74.00 (0.44) | 85.50 (1.40) | 84.10 (1.30) | 78.73 (1.53) | 78.27 (3.04) | 77.13 (1.74) | 77.13 (1.74) | 89.93 (1.46) | 87.00 (0.21) | 81.77 (2.98) | 77.03 (2.59) |
| Method | Tokens/call (K) | Prompt length (tokens) |
| ACE | 31.89 (1.17) | 35,881 (7,563) |
| MIPROv2 | 3.47 (0.02) | 2,704 (70) |
| SkillOpt | 2.87 (0.10) | 2,021 (628) |
| GEPA | 2.47 (0.24) | 2,003 (541) |
| HERO-O (Ours) | 2.79 (0.18) | 1,949 (389) |
| Method | BIRD | BigCodeBench | DSCodeBench | CypherBench |
| Seed prompt | 79.1 (5.0) | 61.2 (3.6) | 48.7 (0.5) | 85.6 (1.5) |
| Stage Offline Harness Optimization | ||||
| GEPA | 73.1 (3.6) | 69.1 (3.9) | 56.0 (2.2) | 86.7 (3.8) |
| MIPROv2 | 77.9 (7.1) | 69.7 (2.7) | 55.4 (1.3) | 86.5 (3.2) |
| ACE | 72.3 (2.2) | 71.3 (2.5) | 55.3 (0.5) | 103.8 (15.2) |
| SkillOpt | 75.9 (4.0) | 69.7 (1.0) | 54.8 (1.0) | 137.7 (50.8) |
Appendix figures & tables9 assets
Supplementary material from the paper’s appendix.
Appendix
| Dataset | Task | Rollout budget | ||||
| BIRD-SQL | Text-to-SQL | 500 | 250 | 1,400 | 1,530 | 5,400 |
| CypherBench | Text-to-Cypher | 250 | 250 | 250 | 1,000 | 3,700 |
| BigCodeBench | Python | 250 | 250 | 250 | 637 | 5,400 |
| DSCodeBench | Python | 250 | 250 | 250 | 482 | 3,600 |
| Method | BIRD-SQL | BigCodeBench | CypherBench | DSCodeBench |
| Tokens per call (K) | ||||
| ACE | 38.46 1.06 | 31.51 6.16 | 20.84 1.66 | 36.63 1.97 |
| MIPROv2 | 2.17 0.11 | 2.41 0.33 | 1.82 0.10 | 7.47 0.12 |
| SkillOpt | 3.17 0.43 | 2.52 0.19 | 2.36 0.43 | 3.41 0.40 |
| GEPA | 2.42 0.29 | 1.86 0.12 | 2.24 0.22 | 3.36 0.49 |
| Ours | 3.10 0.48 | 2.10 0.18 | 2.57 0.09 | 3.36 0.18 |
| Hyperparameter | Value | BIRD-SQL | BigCodeBench |
| Candidates per round | 63.55 (0.21) | 51.96 (0.00) | |
| 6 | 61.90 (1.25) | 52.07 (0.66) | |
| 8 | 62.39 (1.52) | 51.38 (0.55) | |
| 10 | 61.74 (1.61) | 51.65 (1.41) | |
| 12 | 62.83 (0.81) | 51.81 (1.34) | |
| Search rounds | 3 | 61.66 (1.52) | 51.86 (0.81) |
| Setting | BIRD-SQL | BigCodeBench | DSCodeBench | CypherBench | Mean |
| Full | 3.01 | 1.61 | 1.70 | 2.06 | 2.10 |
| Failure-only | 2.61 | 1.71 | 1.49 | 1.41 | 1.81 |
| Refinement budget | ReAct | |||||||
| Dataset | Metric | 0 | 2 | 4 | 6 | 8 | ||
| BIRD-SQL | Pass@1 (%) | 62.53 (1.82) | 63.38 (1.83) | 63.59 (1.43) | 63.53 (1.53) | 63.77 (1.47) | 64.05 (1.57) | 63.12 (1.02) |
| Env. actions | 0 | 1.35 | 1.59 | 1.66 | 1.76 | 1.78 | 0.79 | |
| LLM calls | 0 | 3.15 | 3.33 | 3.40 | 3.46 | 3.43 | 1.93 | |
| BigCodeBench | Pass@1 (%) | 52.59 (0.31) | 53.38 (0.87) | 53.79 (0.33) | 53.95 (0.74) | 54.06 (0.33) | 53.85 (0.31) | 52.64 (0.24) |
| Env. actions | 0 | 1.88 | 2.31 | 2.40 | 2.49 | 2.50 | 1.91 | |
| Baseline | Offline Prompt Optimization | Test-Time Adaptation | Harness Optimization | ||||||||
| Dataset | Seed | Ours | SkillOpt | GEPA | MIPROv2 | ACE | DC-Cu | Ours + Refine | Ours + ReAct | Ours + DC-Cu | Meta- Harness |
| BIRD DEV | 58.91 (0.44) | 63.66 (1.18) | 64.38 (1.21) | 63.01 (1.30) | 63.03 (0.84) | 63.36 (1.57) | 62.14 (0.27) | 65.38 (1.13) | 63.57 (1.10) | 64.12 (0.69) | 58.52 (0.72) |
| BigCodeBench | 52.22 (0.77) | 52.43 (0.57) | 52.96 (0.36) | 52.69 (0.48) | 52.54 (1.94) | 52.49 (0.36) | 50.71 (1.77) | 52.59 (0.57) | 53.48 (0.50) | 53.38 (1.13) | 51.49 (0.28) |
| DSCodeBench | 50.83 (0.55) | 55.39 (1.70) | 54.56 (0.72) | 53.94 (0.55) | 54.84 (0.94) | 55.26 (1.22) | 45.09 (1.69) | 54.63 (0.32) | 54.08 (0.43) | 54.49 (0.21) | 50.14 (2.80) |
| CypherBench | 73.13 (0.45) | 83.67 (1.10) | 79.00 (1.37) | 76.87 (2.05) | 79.37 (2.36) | 82.17 (2.10) | 73.83 (1.01) | 88.63 (2.02) | 87.87 (1.42) | 81.13 (3.20) | 82.47 (1.96) |
Automatic Prompt Optimization
Automatic prompt optimization uses model or task feedback to revise instructions for stronger, more reliable language-model performance.
See all 103 papers