VisualCoding: Learning Executable Skills for Reliable Visual Reasoning
Organizations: Department of Electrical and Computer Engineering, University of British Columbia · Vector Institute
Abstract
Learning reusable skills can improve visual reasoning agents, yet applying a skill still requires the agent to implement or invoke a procedure and produce the final answer. Errors and hallucinations at these steps can prevent acquired experience from translating into reliable single-run performance. We propose VisualCoding, which combines execution-guided acquisition of reusable visual programs with direct adoption of their answers on applicable inputs. Execution-Guided Program Acquisition composes visual primitives and additional code into family-level solvers, then iteratively tests and revises them on labeled training instances. Scope-Aware Direct Execution runs a retained solver and returns its valid in-scope answer. We evaluate VisualCoding on four models across four benchmarks spanning 69 task families. VisualCoding exceeds the strongest evaluated baseline in mean accuracy by 4.45 percentage points with Gemini-3.1-Pro and by 14.78 points when reusing the frozen Pro-acquired artifacts with Flash-Lite. Ablations support execution-guided acquisition and show that direct execution outperforms textual or callable reuse of the same programs. Code is available at https://github.com/jiaq-liu/VisualCoding.
Figures & tables
| Method | TIR | MIRA | GQA | PVQA | Avg. |
|---|---|---|---|---|---|
| Direct (TF) | 48.9 | 33.3 | 68.3 | 93.6 | 61.0 |
| GEPA (TF) | 52.9 +4.0 | 35.0 +1.7 | 73.7 +5.4 | 97.8 +4.3 | 64.9 +3.8 |
| TextGrad (TF) | 54.0 +5.1 | 33.3 0.0 | 75.1 +6.8 | 96.7 +3.1 | 64.8 +3.8 |
| Tool agent | 62.9 | 37.2 | 73.3 | 93.7 | 66.8 |
| XSkill | 68.9 +6.0 | 42.4 +5.2 | 78.4 +5.1 | 96.9 +3.2 | 71.7 +4.9 |
| Trace2Skill | 65.8 +2.9 | 45.2 +8.0 | 74.9 +1.6 | 95.7 +2.0 | 70.4 +3.6 |
| Method | TIR-Bench | MIRA | GameQA | PuzzleVQA | Avg. |
|---|---|---|---|---|---|
| (a) Gemini 3.1 Flash-Lite | |||||
| Direct (TF) | 28.3 | 17.9 | 28.6 | 78.8 | 38.4 |
| GEPA (TF) | 36.3 +8.0 | 18.5 +0.6 | 40.9 +12.3 | 91.8 +12.9 | 46.9 +8.4 |
| TextGrad (TF) | 33.5 +5.2 | 16.3 -1.7 | 32.5 +3.9 | 84.4 +5.5 | 41.7 +3.3 |
| Tool agent | 39.0 | 20.9 | 30.4 | 83.4 | 43.4 |
| XSkill | 48.7 +9.7 | 28.4 +7.4 | 45.1 +14.8 | 93.0 +9.6 | 53.8 +10.4 |
| Variant | TIR-Bench | MIRA |
|---|---|---|
| Tool agent | 62.9 | 37.2 |
| (a) Acquisition | ||
| Full execution feedback | 75.9 | 46.6 |
| Independent search | 73.5 | 46.0 |
| No scope during acquisition | 68.3 | 42.0 |
| (b) Deployment | ||
Appendix figures & tables26 assets
Supplementary material from the paper’s appendix.
Appendix
| Role | Documented entries |
|---|---|
| Image preparation | arr , gray , background , fg_mask , ink_mask , hue_mask , stretch , upscale , rotate |
| Structure and geometry | components , fill_holes , holes , contour_stats , classify , min_area_rect |
| Color measurements | color_name , n_colors , color_share , mean_color |
| Spatial patterns | projection , period , panels8 , apply_variant |
| Perceptual interfaces | detect , count_objects , ask |
| Question processing | question , numbers_in |
| Criterion | High-precision tier | Gain tier |
| Minimum fitted precision | 0.95 | 0.50 |
| Minimum fitted support per route | 3 | 5 |
| Minimum pooled leave-one-out precision | 0.90 | 0.50 |
| Minimum rule stability | 0.80 | 0.50 |
| Maximum learned atoms per route | 2 | 2 |
| Minimum numeric separation | 0.02 | 0.02 |
| Method | Full panel | |||
|---|---|---|---|---|
| Task count | 194 | 211 | 341 | 746 |
| Tool agent (reference pool) | 0.00 | 52.25 | 100.00 | 60.49 |
| VisualCoding CORE | 41.75 | 62.80 | 100.00 | 74.33 |
| VisualCoding full | 50.90 | 65.76 | 97.21 | 76.27 |
| Family | Base @1 | Base @4 | Full @1 | |
|---|---|---|---|---|
| Color | 67 | 71.64 | 85.07 | 72.39 |
| Contrast | 34 | 63.24 | 79.41 | 63.97 |
| Instrument | 54 | 22.69 | 37.04 | 25.00 |
| Jigsaw | 80 | 4.38 | 11.25 | 95.00 |
| Math | 80 | 74.69 | 83.75 | 75.62 |
| Maze | 80 | 88.12 | 95.00 | 100.00 |
| Dataset | Families | Train | Test |
|---|---|---|---|
| TIR-Bench | 12 | 369 | 746 |
| MIRA | 20 | 183 | 363 |
| GameQA | 17 | 259 | 514 |
| PuzzleVQA | 20 | 663 | 1337 |
| Dataset ( ) | Tool agent | Pro policy | Pro no check | FL policy | Pro FL [95% CI] |
| TIR-Bench (746) | 39.0 | 61.5 | 65.0 | 68.5 | |
| MIRA (363) | 20.9 | 36.4 | 38.3 | 41.6 | |
| GameQA (514) | 30.4 | 52.7 | 58.6 | 65.4 | |
| PuzzleVQA (1,337) | 83.4 | 97.1 | 98.7 | 98.8 | |
| Avg. (datasets) | 43.4 | 61.9 | 65.1 | 68.6 | |
| Pooled (2,960) | 55.3 | 73.0 | 75.8 | 78.3 |
| Variant | TIR-Bench | MIRA |
|---|---|---|
| Full method | 76.3 | 47.1 |
| No text fallback | 76.0 | 46.3 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| color | 67 | 50.7 | 59.7 +9.0 | 52.2 +1.5 | 74.6 | 74.6 0.0 | 77.6 +3.0 | 73.1 -1.5 | 70.1 -4.5 |
| contrast | 34 | 64.7 | 47.1 -17.6 | 58.8 -5.9 | 64.7 | 73.5 +8.8 | 64.7 0.0 | 67.7 +2.9 | 52.9 -11.8 |
| instrument | 54 | 24.1 | 25.9 +1.9 | 24.1 0.0 | 24.1 | 25.9 +1.9 | 24.1 0.0 | 31.5 +7.4 | 25.9 +1.9 |
| jigsaw | 80 | 1.2 | 3.8 +2.5 | 5.0 +3.8 | 5.0 | 2.5 -2.5 | 7.5 +2.5 | 10.0 +5.0 | 95.0 +90.0 |
| math | 80 | 58.8 | 58.8 0.0 | 63.7 +5.0 | 77.5 | 77.5 0.0 | 72.5 -5.0 | 72.5 -5.0 | 81.2 +3.7 |
| maze | 80 | 91.2 | 98.8 +7.5 | 98.8 +7.5 | 90.0 | 97.5 +7.5 | 88.8 -1.3 | 96.2 +6.2 | 100.0 +10.0 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| color | 67 | 41.8 | 46.3 +4.5 | 52.2 +10.4 | 61.2 | 64.2 +3.0 | 68.7 +7.5 | 73.1 +11.9 | 56.7 -4.5 |
| contrast | 34 | 41.2 | 44.1 +2.9 | 47.1 +5.9 | 55.9 | 61.8 +5.9 | 64.7 +8.8 | 58.8 +2.9 | 55.9 0.0 |
| instrument | 54 | 14.8 | 20.4 +5.6 | 14.8 0.0 | 13.0 | 24.1 +11.1 | 24.1 +11.1 | 27.8 +14.8 | 16.7 +3.7 |
| jigsaw | 80 | 0.0 | 0.0 0.0 | 0.0 0.0 | 0.0 | 0.0 0.0 | 0.0 0.0 | 0.0 0.0 | 95.0 +95.0 |
| math | 80 | 33.8 | 45.0 +11.2 | 38.8 +5.0 | 51.2 | 56.2 +5.0 | 53.8 +2.5 | 55.0 +3.8 | 41.2 -10.0 |
| maze | 80 | 23.8 | 32.5 +8.8 | 23.8 0.0 | 37.5 | 35.0 -2.5 | 35.0 -2.5 | 28.7 -8.8 | 100.0 +62.5 |
| Family | DS Tool | DS VC | GPT Tool | GPT VC | |
|---|---|---|---|---|---|
| color | 67 | 74.6 | 64.2 -10.4 | 50.7 | 62.7 +11.9 |
| contrast | 34 | 58.8 | 61.8 +2.9 | 26.5 | 32.4 +5.9 |
| instrument | 54 | 14.8 | 25.9 +11.1 | 16.7 | 31.5 +14.8 |
| jigsaw | 80 | 5.0 | 95.0 +90.0 | 1.2 | 95.0 +93.8 |
| math | 80 | 81.2 | 77.5 -3.7 | 37.5 | 35.0 -2.5 |
| maze | 80 | 68.8 | 100.0 +31.2 | 57.5 | 100.0 +42.5 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| billiards | 14 | 14.3 | 28.6 +14.3 | 50.0 +35.7 | 35.7 | 64.3 +28.6 | 50.0 +14.3 | 50.0 +14.3 | 71.4 +35.7 |
| convex hull | 20 | 55.0 | 55.0 0.0 | 25.0 -30.0 | 90.0 | 90.0 0.0 | 95.0 +5.0 | 95.0 +5.0 | 90.0 0.0 |
| cubes count | 20 | 5.0 | 5.0 0.0 | 0.0 -5.0 | 5.0 | 5.0 0.0 | 5.0 0.0 | 0.0 -5.0 | 5.0 0.0 |
| cubes missing | 20 | 5.0 | 0.0 -5.0 | 5.0 0.0 | 5.0 | 0.0 -5.0 | 0.0 -5.0 | 5.0 0.0 | 0.0 -5.0 |
| defuse a bomb | 17 | 17.6 | 17.6 0.0 | 35.3 +17.6 | 23.5 | 35.3 +11.8 | 23.5 0.0 | 29.4 +5.9 | 17.6 -5.9 |
| electric charge | 14 | 78.6 | 85.7 +7.1 | 85.7 +7.1 | 78.6 | 85.7 +7.1 | 78.6 0.0 | 85.7 +7.1 | 85.7 +7.1 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| billiards | 14 | 28.6 | 0.0 -28.6 | 28.6 0.0 | 35.7 | 42.9 +7.1 | 28.6 -7.1 | 28.6 -7.1 | 71.4 +35.7 |
| convex hull | 20 | 15.0 | 20.0 +5.0 | 10.0 -5.0 | 85.0 | 90.0 +5.0 | 90.0 +5.0 | 80.0 -5.0 | 85.0 0.0 |
| cubes count | 20 | 0.0 | 0.0 0.0 | 0.0 0.0 | 0.0 | 5.0 +5.0 | 0.0 0.0 | 0.0 0.0 | 0.0 0.0 |
| cubes missing | 20 | 5.0 | 0.0 -5.0 | 0.0 -5.0 | 0.0 | 5.0 +5.0 | 0.0 0.0 | 0.0 0.0 | 5.0 +5.0 |
| defuse a bomb | 17 | 35.3 | 47.1 +11.8 | 17.6 -17.6 | 17.6 | 29.4 +11.8 | 41.2 +23.5 | 23.5 +5.9 | 11.8 -5.9 |
| electric charge | 14 | 64.3 | 57.1 -7.1 | 71.4 +7.1 | 85.7 | 64.3 -21.4 | 78.6 -7.1 | 85.7 0.0 | 78.6 -7.1 |
| Family | DS Tool | DS VC | GPT Tool | GPT VC | |
|---|---|---|---|---|---|
| billiards | 14 | 57.1 | 71.4 +14.3 | 14.3 | 71.4 +57.1 |
| convex hull | 20 | 95.0 | 90.0 -5.0 | 65.0 | 60.0 -5.0 |
| cubes count | 20 | 5.0 | 5.0 0.0 | 0.0 | 0.0 0.0 |
| cubes missing | 20 | 0.0 | 0.0 0.0 | 0.0 | 0.0 0.0 |
| defuse a bomb | 17 | 35.3 | 17.6 -17.6 | 23.5 | 29.4 +5.9 |
| electric charge | 14 | 71.4 | 71.4 0.0 | 50.0 | 64.3 +14.3 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| jewel2 q5 | 40 | 90.0 | 87.5 -2.5 | 90.0 0.0 | 87.5 | 90.0 +2.5 | 87.5 0.0 | 87.5 0.0 | 87.5 0.0 |
| jewel2 q6 | 20 | 60.0 | 65.0 +5.0 | 70.0 +10.0 | 75.0 | 75.0 0.0 | 70.0 -5.0 | 65.0 -10.0 | 80.0 +5.0 |
| maze q4 | 35 | 51.4 | 45.7 -5.7 | 60.0 +8.6 | 45.7 | 77.1 +31.4 | 60.0 +14.3 | 57.1 +11.4 | 100.0 +54.3 |
| minesweeper q5 | 40 | 87.5 | 90.0 +2.5 | 90.0 +2.5 | 90.0 | 90.0 0.0 | 90.0 0.0 | 80.0 -10.0 | 90.0 0.0 |
| pacman q1 | 20 | 20.0 | 20.0 0.0 | 15.0 -5.0 | 35.0 | 50.0 +15.0 | 45.0 +10.0 | 95.0 +60.0 | 95.0 +60.0 |
| pacman q3 | 20 | 55.0 | 60.0 +5.0 | 60.0 +5.0 | 65.0 | 90.0 +25.0 | 55.0 -10.0 | 75.0 +10.0 | 100.0 +35.0 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| jewel2 q5 | 40 | 72.5 | 62.5 -10.0 | 32.5 -40.0 | 30.0 | 57.5 +27.5 | 52.5 +22.5 | 70.0 +40.0 | 65.0 +35.0 |
| jewel2 q6 | 20 | 20.0 | 35.0 +15.0 | 30.0 +10.0 | 45.0 | 50.0 +5.0 | 45.0 0.0 | 40.0 -5.0 | 50.0 +5.0 |
| maze q4 | 35 | 20.0 | 2.9 -17.1 | 25.7 +5.7 | 14.3 | 14.3 0.0 | 8.6 -5.7 | 28.6 +14.3 | 100.0 +85.7 |
| minesweeper q5 | 40 | 50.0 | 82.5 +32.5 | 75.0 +25.0 | 55.0 | 70.0 +15.0 | 62.5 +7.5 | 72.5 +17.5 | 85.0 +30.0 |
| pacman q1 | 20 | 10.0 | 10.0 0.0 | 5.0 -5.0 | 10.0 | 20.0 +10.0 | 30.0 +20.0 | 45.0 +35.0 | 95.0 +85.0 |
| pacman q3 | 20 | 10.0 | 15.0 +5.0 | 30.0 +20.0 | 10.0 | 15.0 +5.0 | 15.0 +5.0 | 15.0 +5.0 | 100.0 +90.0 |
| Family | DS Tool | DS VC | GPT Tool | GPT VC | |
|---|---|---|---|---|---|
| jewel2 q5 | 40 | 55.0 | 65.0 +10.0 | 60.0 | 65.0 +5.0 |
| jewel2 q6 | 20 | 60.0 | 60.0 0.0 | 35.0 | 20.0 -15.0 |
| maze q4 | 35 | 97.1 | 100.0 +2.9 | 34.3 | 100.0 +65.7 |
| minesweeper q5 | 40 | 70.0 | 85.0 +15.0 | 35.0 | 72.5 +37.5 |
| pacman q1 | 20 | 95.0 | 95.0 0.0 | 5.0 | 95.0 +90.0 |
| pacman q3 | 20 | 70.0 | 100.0 +30.0 | 0.0 | 100.0 +100.0 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| circle size number | 67 | 70.1 | 95.5 +25.4 | 100.0 +29.9 | 77.6 | 100.0 +22.4 | 88.1 +10.4 | 100.0 +22.4 | 100.0 +22.4 |
| color grid | 67 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 |
| color hexagon | 67 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 |
| color number hexagon | 67 | 92.5 | 100.0 +7.5 | 97.0 +4.5 | 91.0 | 100.0 +9.0 | 100.0 +9.0 | 100.0 +9.0 | 100.0 +9.0 |
| color overlap squares | 67 | 98.5 | 100.0 +1.5 | 100.0 +1.5 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 |
| color size circle | 66 | 98.5 | 100.0 +1.5 | 100.0 +1.5 | 89.4 | 98.5 +9.1 | 87.9 -1.5 | 98.5 +9.1 | 100.0 +10.6 |
| Family | Dir. | GEPA | TG | Tool | XS | T2S | SO | VC | |
|---|---|---|---|---|---|---|---|---|---|
| circle size number | 67 | 74.6 | 100.0 +25.4 | 100.0 +25.4 | 71.6 | 92.5 +20.9 | 71.6 0.0 | 100.0 +28.4 | 100.0 +28.4 |
| color grid | 67 | 79.1 | 92.5 +13.4 | 79.1 0.0 | 95.5 | 100.0 +4.5 | 97.0 +1.5 | 100.0 +4.5 | 100.0 +4.5 |
| color hexagon | 67 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 | 100.0 0.0 |
| color number hexagon | 67 | 88.1 | 91.0 +3.0 | 86.6 -1.5 | 91.0 | 98.5 +7.5 | 95.5 +4.5 | 100.0 +9.0 | 100.0 +9.0 |
| color overlap squares | 67 | 82.1 | 100.0 +17.9 | 100.0 +17.9 | 91.0 | 100.0 +9.0 | 98.5 +7.5 | 100.0 +9.0 | 100.0 +9.0 |
| color size circle | 66 | 50.0 | 100.0 +50.0 | 89.4 +39.4 | 72.7 | 95.5 +22.7 | 69.7 -3.0 | 81.8 +9.1 | 100.0 +27.3 |
| Family | DS Tool | DS VC | GPT Tool | GPT VC | |
|---|---|---|---|---|---|
| circle size number | 67 | 74.6 | 100.0 +25.4 | 29.9 | 100.0 +70.1 |
| color grid | 67 | 95.5 | 100.0 +4.5 | 52.2 | 100.0 +47.8 |
| color hexagon | 67 | 100.0 | 98.5 -1.5 | 17.9 | 38.8 +20.9 |
| color number hexagon | 67 | 91.0 | 98.5 +7.5 | 37.3 | 97.0 +59.7 |
| color overlap squares | 67 | 82.1 | 88.1 +6.0 | 14.9 | 37.3 +22.4 |
| color size circle | 66 | 90.9 | 100.0 +9.1 | 47.0 | 100.0 +53.0 |
| Family | Tool | FULLC | IID | SCALAR | No scope | |
|---|---|---|---|---|---|---|
| color | 67 | 74.6 | 70.1 | 70.1 | 70.1 | 70.1 |
| contrast | 34 | 64.7 | 52.9 | 52.9 | 52.9 | 52.9 |
| instrument | 54 | 24.1 | 25.9 | 25.9 | 25.9 | 25.9 |
| jigsaw ∗ | 80 | 5.0 | 90.4 | 75.0 | 47.1 | 81.2 |
| math | 80 | 77.5 | 81.2 | 81.2 | 81.2 | 81.2 |
| maze ∗ | 80 | 90.0 | 96.7 | 97.1 | 90.4 | 43.8 |
| Family | Tool | Full | TEXT | CODE | INJECT | No text fallback | |
|---|---|---|---|---|---|---|---|
| color | 67 | 74.6 | 70.1 | 70.1 | 70.1 | 70.1 | 74.6 |
| contrast | 34 | 64.7 | 52.9 | 52.9 | 52.9 | 52.9 | 64.7 |
| instrument | 54 | 24.1 | 25.9 | 25.9 | 25.9 | 25.9 | 24.1 |
| jigsaw | 80 | 5.0 | 95.0 | 33.8 | 72.5 | 92.5 | 95.0 |
| math | 80 | 77.5 | 81.2 | 81.2 | 81.2 | 81.2 | 77.5 |
| maze | 80 | 90.0 | 100.0 | 97.5 | 100.0 | 100.0 | 100.0 |
| Family | Tool | FULLC | IID | SCALAR | No scope | |
|---|---|---|---|---|---|---|
| billiards ∗ | 14 | 35.7 | 47.6 | 42.9 | 61.9 | 50.0 |
| convex hull | 20 | 90.0 | 90.0 | 90.0 | 90.0 | 90.0 |
| cubes count | 20 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 |
| cubes missing | 20 | 5.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| defuse a bomb | 17 | 23.5 | 17.6 | 17.6 | 17.6 | 17.6 |
| electric charge | 14 | 78.6 | 85.7 | 85.7 | 85.7 | 85.7 |
| Family | Tool | Full | TEXT | CODE | INJECT | No text fallback | |
|---|---|---|---|---|---|---|---|
| billiards | 14 | 35.7 | 71.4 | 57.1 | 57.1 | 71.4 | 71.4 |
| convex hull | 20 | 90.0 | 90.0 | 90.0 | 90.0 | 90.0 | 90.0 |
| cubes count | 20 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 |
| cubes missing | 20 | 5.0 | 0.0 | 0.0 | 0.0 | 0.0 | 5.0 |
| defuse a bomb | 17 | 23.5 | 17.6 | 17.6 | 17.6 | 17.6 | 23.5 |
| electric charge | 14 | 78.6 | 85.7 | 85.7 | 85.7 | 85.7 | 78.6 |
| Round | Revision | Correct / 40 |
|---|---|---|
| 1 | Boundary matching with constrained Kruskal/Prim-style assembly. | 35 |
| 2 | Run Prim-style assembly from every starting piece and compare complete grids. | 37 |
| 4 | Jointly trim two boundary pixels and replace RMSE costs with MSE; rejected after regression. | 18 |
| 6 | Combine multiple cost variants and fixed-seed perturbations; rank complete grids by RMS boundary cost. | 39 |