RealityBench: Simulated Environments to Evaluate a Vision Language Model's Ability to Document Human Physical Work
Organizations: Relantic, Inc., Columbus, OH, USA
Abstract
Augmenting worker capabilities in the physical world through guidance has been a decades-long goal for AI agents. One key supporting capability is to understand what the worker is doing, seeing through the human's camera or smart glasses, and assist them in documentation. Despite advances in vision language models, their capabilities in these settings remain uncertain and are challenging to benchmark because most physical work data is proprietary, and involves too much variability to study in a principled manner. Unlike structured settings such as kitchens and warehouses that have predictable lighting, geometry, and objects, field-facing tasks such as rooftop solar installation and vehicle repair are unconstrained and high variance. Here, we model real-world physical work in Blender across eleven environments, incorporating variants in both image acceptability and documentation. The acceptability task asks whether a particular view would be suitable proof-of-work and documentation asks whether an agent can understand the task-relevant state of the environment from that view. Across 26 vision-language models, we find that top models largely solve documentation when the answer is text in frame, but are weak at reading measurements and at judging small parts and spatial relations, such as whether a tape measure leans. Acceptability is harder to pin down because human raters disagree with each other. Measured against a scorer that agrees with the raters' majority about as often as a single rater does, the best models cannot be distinguished from a single non-author rater, at a cost within the range of a human pass. In the three environments where we can trace acceptability errors, most wrong rejections come from misreading the scene rather than the requirement. On the three documentation questions for which we have real images, model rankings on rendered frames transfer to real images.
Figures & tables
| Environment | Scene | Documentation question | Acceptability terms | Acceptable |
|---|---|---|---|---|
| rail_attachment | roof | At this roof attachment, is a lag bolt present on the L-foot, and is flashing installed under it? | attachment in frame ( 90% of it); attachment unoccluded; bolt location unoccluded ( 50% of the spot where the lag bolt sits, or would sit, visible); fills the frame (bbox 2%); not a wide shot ( 1.8 m); not scored when the lag bolt or flashing is missing | 0.12 |
| wire_adequacy | roof | Is any wire or cable touching the roof surface? | a lead wire in frame ( 50% of it); that wire’s lowest point visible; that wire unoccluded ( 30% of it); wire visible to the eye: wire pixels 0.05% of the frame; wire stands out: edge contrast 0.03; close enough to judge contact (cam within 2.5 m of that wire’s low point) | 0.39 |
| tape_gap | roof | What number is on the tape where the module frame crosses it, what is your estimate of the true perpendicular module-to-roof gap in inches, and is the tape leaning rather than standing flush? | crossing in frame; crossing unoccluded; close enough to read 1/16in ticks ( 0.65 m); tape seated flush (tilt 5 ∘ ); photographed from the front of the blade; gray: a lean over 5 ∘ that shows as at most 5 ∘ in the image | 0.17 |
| slope_gauge | roof | What does the angle gauge read, in degrees, and is it sitting on the module (glass or frame) or on bare roof? | display in frame; display unoccluded; digits legible: 14 px digit height; display readable angle (view angle 65 ∘ ); gauge on the module, not bare roof; display not blown out ( 30% saturated); gauge aligned with the slope (|yaw| 15 ∘ , else it under-reads); array context: module glass visible in frame; module edge in view to judge alignment ( 300 px of frame edge visible); text stands out in the render (Weber contrast 0.2); gray: |yaw| 15–45 ∘ | 0.25 |
| equipment_label | roof | What does it say on the equipment label (brand, model number and serial number) and what kind of equipment is it on? | label fully in frame; label unoccluded ( 95% of it); legible: 10 px per text row; barcode resolvable: 1 px per module; square-on enough to OCR (view angle 60 ∘ ); label not blown out ( 30% saturated); site context: some of the equipment/mounting in view; label lit: paper luminance 0.05; text stands out in the render (Weber contrast 0.3) | 0.06 |
| horizon_peak | roof | Is the horizon visible in this frame, and is it roughly level? | horizon in frame, in the middle 80% of the image; taken from the peak: the house’s own roof hides 10% of the horizon arc; skyline inside the frame: sky above it and the surroundings below it across 65% of the width; level (roll 10 ∘ ); own roof visible along the bottom of the frame ( 4% of the bottom quarter): proof it was taken from the peak; phone at or above the ridge line (camera height above the ridge 0 m) | 0.19 |
Appendix figures & tables12 assets
Supplementary material from the paper’s appendix.
Appendix
| Primitive | Definition |
|---|---|
| in-frame / unoccluded fraction | Sample points on the target’s surface (vertices and face interiors—corner-only sampling under-reports thin objects); project each; cast a ray from the camera; the point is visible if the first hit is the target. |
| bbox fraction | Area of the target’s projected bounding box within the frame. |
| view angle | Angle between the viewing ray to the target and the target’s surface normal ( = square-on). |
| px per unit | Pixels spanned by a unit length at the target (text row height, character cell, inch, centimeter): the legibility proxy. |
| clearance | Signed distance from a wire’s surface (beveled mesh) to the roof plane; is contact. |
| apparent reading | For a tape, the blade point that projects onto the module’s front-bottom edge from the camera (§ 3 ). |
| Environment | Requirement | Question | Keys |
|---|---|---|---|
| rail_attachment | The L-foot, its flashing and the lag bolt, close enough to judge the attachment. Reject wide array shots where the foot is a speck. | At this roof attachment, is a lag bolt present on the L-foot, and is flashing installed under it? | lag_present : bool; flashing_present : bool |
| tape_gap | Tape measure hooked at the roof surface and standing up to the module frame; the number where the frame crosses the tape must be legible, and the tape should be seated flush (perpendicular to the roof). | What number (inches) is on the tape where the module frame crosses it, what is your estimate of the true perpendicular module-to-roof gap in inches, and is the tape leaning rather than standing flush? | reading_in : number; gap_in : number; tilted : bool |
| wire_adequacy | Photograph the underside of each array close enough to judge the wiring: lead wires and trunk cable visible, so a reviewer can tell whether any wire touches the roof plane or has a hard bend. Reject photos that do not clearly show the wiring under the modules. | Is any wire or cable touching the roof surface (the shingles)? | touching : bool |
| slope_gauge | A digital angle gauge placed directly on the module glass or frame, aligned with the slope, showing its degree reading; the display must be legible with the module it sits on visible in the photo. Reject a gauge placed on bare roof instead of the module, and a shot where the display is unreadable or washed out. | What does the angle gauge read, in degrees, and is it sitting on the module (glass or frame) or on bare roof? | reading_deg : number; on_module : bool |
| equipment_label | Close-up of the equipment data label — on the back of an installed module, on a microinverter under the array, or on the inverter — with the model number, the serial number and its barcode all legible, square-on enough to read. Some of the equipment or mounting should be in view so it is clearly a label on site, not a stock image. Reject a shot where the small text is a blur, the barcode is cut off or washed out by glare. | Read the equipment data label: brand, model number and serial number, and say what the label is on. | brand : string; model : string; serial : string; on : module/microinverter/inverter |
| horizon_peak | A set of photos taken from the roof peak for the shading analysis: turning in place, each photo shows the skyline in that direction, with sky above it and the surroundings below it, and a little of this house’s own roof along the bottom as proof of where it was taken. Together the photos should go most of the way around: four or more directions with no large gap. Reject photos taken from below the peak where the roof blocks the view, photos with no roof in them at all, and sets that leave a large gap. | Is the horizon visible in this frame and roughly level, and does this house’s own roof hide part of the far view? | horizon_visible : bool; level : bool; own_roof_blocks : bool |
| defect claims (of 150) | paired change in claims vs. first | rejects | ||||||
|---|---|---|---|---|---|---|---|---|
| Model | first | last | alone | last | alone ( ) | rerun | first | alone ( ) |
| Gemini 3.8 Flash ‡ | 82 | 85 | 83 | 4/7 | 7/8 (1.00) | 8/5 | 96 | 92 (.60) |
| Gemini 3.5 Flash | 94 | 97 | 88 | 7/10 | 12/6 (.24) | 7/6 | 104 | 108 (.50) |
| Gemini 3.1 Flash Lite | 125 | 103 | 66 | 27/5 | 60/1 ( .001) | 10/6 | 125 | 133 (.13) |
| Gemma 4 31B ‡ | 92 | 96 | 78 | 5/9 | 18/4 (.004) | 8/7 | 101 | 107 (.36) |
| GPT-6 Astra ‡ | 58 | 53 | 56 | 8/3 | 9/7 (.80) | 9/6 | 76 | 73 (.65) |
| Model | FA (%) | miss (%) | P | R | F1 [95% CI] | doc. [95% CI] | gram. (%) | cost ($) | think |
| Gemini 3.8 Flash | 11 | 38 | 0.48 | 0.62 | 0.54 [0.48, 0.59] | 0.84 [0.82, 0.86] | 100 | 7.16 | 1083 |
| Gemini 3.5 Flash | 13 | 34 | 0.49 | 0.66 | 0.56 [0.51, 0.62] | 0.80 [0.78, 0.83] | 97 | 7.36 | 1114 |
| Gemini 3.1 Flash Lite | 16 | 42 | 0.39 | 0.58 | 0.47 [0.41, 0.52] | 0.73 [0.70, 0.75] | 98 | 0.73 | 0 |
| Gemma 4 31B | 15 | 37 | 0.44 | 0.63 | 0.52 [0.46, 0.57] | 0.79 [0.77, 0.81] | 100 | 0.70 | 677 |
| Gemma 4 26B-A4B | 17 | 36 | 0.39 | 0.64 | 0.48 [0.42, 0.53] | 0.77 [0.75, 0.79] | 99 | 1.24 | 1325 |
| GPT-6 Astra | 12 | 32 | 0.55 | 0.68 | 0.61 [0.56, 0.66] | 0.83 [0.81, 0.85] | 100 | 30.05 | 165 |
| F1 | GPT-6 Astra | Claude Opus 5.5 | GPT-5.6 Sol | GLM-5.3 Flash | Gemini 3.5 Flash | Claude Fable 5.1 | Claude Opus 5 | Qwen 3.8 Max | GPT-6 Sol | Muse Spark 1.3 | Qwen 3.5 397B-A17B | GPT-5.6 Terra | Qwen 3.8 27B | Grok 4.6 | Gemini 3.8 Flash | Kimi K3 | GPT-5.6 Luna | Gemma 4 31B | DeepSeek V4.1 Flash | Gemma 4 26B-A4B | Claude Sonnet 5 | Gemini 3.1 Flash Lite | LFM2.5-VL-3B § | GPT-6 Luna | Gemma 4 E4B § | |
| GPT-6 Astra | 0.61 | |||||||||||||||||||||||||
| Claude Opus 5.5 | 0.58 | 3 | ||||||||||||||||||||||||
| GPT-5.6 Sol | 0.57 | 4 | 1 | |||||||||||||||||||||||
| GLM-5.3 Flash | 0.57 | 4 | 1 | 0 | ||||||||||||||||||||||
| Gemini 3.5 Flash | 0.56 | 5 | 2 | 1 | 1 | |||||||||||||||||||||
| Claude Fable 5.1 | 0.56 | 5 | 2 | 1 | 1 | 0 |
| Model | input | output | source | read |
| Gemini 3.8 Flash | 0.75 | 3.75 | Google a | 2026-09-13 |
| Gemini 3.5 Flash | 0.75 | 3.75 | Google a | 2026-09-13 |
| Gemini 3.1 Flash Lite | 0.30 | 2.50 | Google a | 2026-09-13 |
| Gemma 4 31B † | 0.15 | 0.60 | Google Cloud (Vertex AI) b | 2026-09-20 |
| Gemma 4 26B-A4B | 0.15 | 0.60 | Google Cloud (Vertex AI) b | 2026-09-20 |
| GPT-6 Astra | 10.00 | 50.00 | OpenAI c | 2026-09-15 |
| Model | breaker | plate | car view | damage | equip. | horizon | rail | RO board | slope | tape | wire |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Gemini 3.8 Flash | 0.45 | – | 0.38 | 0.14 | 0.41 | 0.54 | 0.45 | 0.73 | 0.62 | 0.40 | 0.24 |
| Gemini 3.5 Flash | 0.41 | – | 0.53 | 0.13 | 0.39 | 0.65 | 0.60 | 0.59 | 0.71 | 0.21 | 0.47 |
| Gemini 3.1 Flash Lite | 0.34 | – | 0.49 | 0.14 | 0.28 | 0.55 | 0.31 | 0.62 | 0.37 | 0.37 | 0.43 |
| Gemma 4 31B | 0.46 | – | 0.39 | 0.08 | 0.37 | 0.60 | 0.36 | 0.66 | 0.57 | 0.16 | 0.48 |
| Gemma 4 26B-A4B | 0.38 | – | 0.25 | 0.25 | 0.35 | 0.54 | 0.55 | 0.59 | 0.50 | 0.20 | 0.34 |
| GPT-6 Astra | 0.66 | – | 0.61 | 0.26 | 0.62 | 0.63 | 0.48 | 0.73 | 0.63 | 0.72 | 0.55 |
| Model | breaker | plate | car view | damage | equip. | horizon | rail | RO board | slope | tape | wire |
| scorer-acceptable (%) | 5 | 21 | 26 | 28 | 6 | 19 | 12 | 18 | 27 | 18 | 39 |
| Gemini 3.8 Flash | 9 | – | 5 | 5 | 18 | 11 | 5 | 15 | 33 | 3 | 7 |
| Gemini 3.5 Flash | 15 | – | 8 | 6 | 20 | 12 | 3 | 29 | 20 | 1 | 11 |
| Gemini 3.1 Flash Lite | 20 | – | 12 | 3 | 32 | 21 | 11 | 26 | 8 | 4 | 20 |
| Gemma 4 31B | 9 | – | 16 | 2 | 21 | 22 | 3 | 22 | 33 | 3 | 20 |
| Gemma 4 26B-A4B | 17 | – | 8 | 18 | 23 | 26 | 8 | 29 | 33 | 1 | 8 |
| Model | in $/M | out $/M | prompt | output | thinking | prompt share | set ($) | rank by price | rank by set |
|---|---|---|---|---|---|---|---|---|---|
| GLM-5.3 Flash | 0.15 | 0.50 | 1,289 | 37 | 1,460 | 21% | 1.30 | 1 | 6 |
| GPT-6 Luna | 0.10 | 0.50 | 1,020 | 41 | 751 | 20% | 0.69 | 2 | 1 |
| Gemma 4 26B-A4B | 0.15 | 0.60 | 527 | 43 | 1,325 | 9% | 1.24 | 3 | 5 |
| Gemma 4 31B | 0.15 | 0.60 | 527 | 43 | 677 | 15% | 0.70 | 4 | 2 |
| DeepSeek V4.1 Flash | 0.30 | 1.20 | 786 | 143 | 4,903 | 4% | 8.67 | 5 | 12 |
| GPT-5.6 Luna | 0.20 | 1.20 | 1,170 | 39 | 482 | 27% | 1.18 | 6 | 4 |
| Environment | Defect reported | answers | reports defect | rejects if reported | rejected | of those, defect reported |
|---|---|---|---|---|---|---|
| tape_gap | tape is tilted | 1,688 | 75% | 99.6% | 1,296 | 97% |
| slope_gauge | gauge is not on the module | 1,950 | 19% | 96.0% | 488 | 74% |
| rail_attachment | lag bolt or flashing missing | 1,273 | 35% | 88.8% | 626 | 63% |
| Set | Frames | Raters | Ratings/frame | Agree | Scorer (held-out) | |
|---|---|---|---|---|---|---|
| breaker_label | 30 | 5 | 4.1 | 0.94 | 0.79 | 0.91 (11) |
| equipment_label | 29 | 5 | 4.3 | 0.90 | 0.58 | 0.91 (11) |
| ro_board | 30 | 5 | 4.1 | 0.98 | 0.86 | 1.00 (8) |
| rail_attachment | 30 | 5 | 4.1 | 0.88 | 0.53 | 0.80 (5) |
| car_plate † | 28 | 5 | 4.2 | 0.80 | 0.54 | – |
| wire_adequacy | 30 | 5 | 4.3 | 0.78 | 0.56 | 0.91 (11) |
| Model | tape: synthetic | tape: real | face: synthetic | face: real | severity: synthetic | severity: real |
|---|---|---|---|---|---|---|
| Claude Opus 5.5 | 0.36 [0.24, 0.48] | 0.35 [0.26, 0.47] | 1.00 [1.00, 1.00] | 0.96 [0.91, 0.99] | 0.63 [0.51, 0.73] | 0.56 [0.44, 0.68] |
| GPT-6 Sol | 0.36 [0.24, 0.48] | 0.33 [0.25, 0.41] | 0.87 [0.74, 1.00] | 0.89 [0.83, 0.94] | 0.51 [0.39, 0.63] | 0.47 [0.36, 0.61] |
| GPT-6 Astra | 0.30 [0.19, 0.40] | 0.44 [0.34, 0.53] | 0.96 [0.87, 1.00] | 0.95 [0.91, 0.98] | 0.42 [0.30, 0.54] | 0.42 [0.31, 0.54] |
| GPT-5.6 Sol | 0.27 [0.16, 0.37] | 0.33 [0.25, 0.41] | 0.74 [0.57, 0.91] | 0.79 [0.72, 0.86] | 0.46 [0.34, 0.58] | 0.42 [0.31, 0.54] |
| Gemini 3.8 Flash | 0.18 [0.09, 0.27] | 0.21 [0.13, 0.29] | 0.96 [0.87, 1.00] | 0.91 [0.85, 0.96] | 0.37 [0.27, 0.49] | 0.56 [0.42, 0.68] |
| GPT-5.6 Terra | 0.18 [0.09, 0.27] | 0.10 [0.05, 0.16] | 0.87 [0.70, 1.00] | 0.78 [0.70, 0.85] | 0.54 [0.42, 0.66] | 0.54 [0.41, 0.68] |
VLM Evaluation
Vision-language model evaluation measures multimodal systems’ perception, reasoning, grounding, robustness, and reliability across controlled and real-world tasks.
See all 999 papers