---
title: "Vision model hallucinations: check each claim on its photo"
description: "A vision model can name an object its photo does not show. How Space Context asks every record again on its own frames, and what 38 of 38 and 0 of 227 mean."
lang: en
date: 2026-10-14
tags: ["ai agents", "evidence", "computer vision", "api"]
source_url: https://spacecontext.app/blog/vision-model-hallucinations-photo-check/
---

# Vision model hallucinations: check each claim on its photo

A vision model can name an object its photo does not show. How Space Context asks every record again on its own frames, and what 38 of 38 and 0 of 227 mean.

A vision model that turns a video into an inventory is generative: it can write that the kitchen has a fridge when the frame it cites shows a tall cupboard, or place an object mentioned in the narration on a frame of the hallway. Space Context does not ask you to trust that output. After the analysis, every item, issue and key location of a Space Document is asked again, as a closed question, on the frames it cites, by a second model that cannot write text. Each record comes back `verified`, `unconfirmed` or `not_visual`, with the probability and the frame that showed it best.

**In short**

- Every record cites the frames it came from; the check asks a yes-or-no question about the record on those frames only, and keeps the best probability.
- `verified` from 0.7, the threshold measured for our frame checks; `unconfirmed` below it; `not_visual` when no photo could show it (a fault, an absence, something only said in the narration).
- How the question is worded decides the result: on the demo apartment, our wording confirmed 38 of 38 items and 0 of 227 objects from other rooms.
- It is numbers only, so a key without access to sensitive values sees it too; agents get the same rule through the API, the Markdown, the Skill and the MCP server.

## Why does a vision model invent objects in a walkthrough?

A walkthrough is not one photo. A scan looks at dozens of frames, merges what they show into rooms and items, and adds what the person said while filming. Each of those steps can attach a record to the wrong picture:

- **Look-alikes**: a tall white cupboard reads as a fridge, a radiator cover as a cabinet.
- **Narration over the wrong frame**: "the kettle is by the window" becomes an item whose evidence is the frame the camera showed at that moment, the hallway.
- **Citation mistakes**: the merge step cites the frame where it thinks an object is, and sometimes picks a neighbour that does not show it. In our measurements a toilet was cited on a frame that does not show it.

None of this is unusual for a generative model, and none of it is acceptable in a check-out report or in the answer an agent gives a guest. The fix is not a better prompt for the same model: it is a second, narrower question with an answer you can measure.

## How does the photo check work?

The check runs as its own stage, `verifying`, after the document is written:

1. For every **item**, **issue** and **key location**, take up to four of the frames it cites, in the order it cites them. A frame it does not cite is never asked, and never added to it.
2. Ask one closed question per record and frame: "does this image show this?" The model answers with a probability, not with text. The same image always gets the same answer.
3. Keep the best probability over its frames. From 0.7 the record is `verified`, and the frame that showed it best moves first in its `evidence`, so the photo an agent shows first is the right one.
4. Faults and absences (`malfunction`, `missing`) are `not_visual`: a dripping tap or a missing remote is not something one still frame can confirm, so they are never asked. A record that cites no frame (it comes from the narration only) is `not_visual` too.

The result sits on the record:

```json
"verification": {
  "status": "verified",
  "probability": 0.97,
  "frame_id": "frame-12"
}
```

When the check could not run (the base level of a space while the deep pass is pending, documents made before the check existed, a check that timed out), `verification` is `null`, never a guess.

## Which question should you ask the second model?

This was the part that needed measuring. On 13 October 2026 we took the real check-out of the demo space (a small apartment in Brisbane: 38 items, 4 issues, 36 frames) and tried three wordings. The 227 "other-room" checks ask about room-specific objects (a toilet, a bed, a fridge, a sofa) on frames of rooms where they are not: every yes there is a false confirmation.

| Question asked on a cited frame | Items verified | False confirmations on frames of other rooms |
| --- | --- | --- |
| "The image clearly shows *name*" | 33 of 38 | 2 of 227 |
| The generic name alone ("a fridge") | 38 of 38 | 16 of 227 |
| "The image shows a *generic name* (described as "*name*"), even if only partly or in the background" | **38 of 38** | **0 of 227** |

The first wording is too strict: a fridge half out of shot fails. The second is too loose: a fridge-shaped cupboard passes. The third gives the model the category and the specific description together, and allows partial views, which is how objects appear in a walkthrough.

Two more findings changed the design:

- **Asking only the first cited frame missed 13 of 38 items.** Some of those were genuine citation mistakes of the analysis. Taking the best of up to four cited frames corrects them, and moves the right frame first.
- **Issues need their own wording.** "The image shows *title* (*category*), even if only partly" verified 3 of 4 issues at 0.95 to 0.96. The fourth, written by the analysis as a possibility ("Possible shower-frame darkening"), got 0.59 and stays `unconfirmed`. That is the honest answer: the frame does not settle it.

Key locations (the fuse box, the stopcock, a VIN plate) reuse the definitions of our frame check, measured on 191 hand-labelled photos: precision 1.00 at 0.7 for every type with labelled examples, except safety equipment at 0.89. The details are in [Verified evidence](https://spacecontext.app/developers/docs/guides/verified-evidence/) in the docs.

## What does it look like on a real scan?

On 14 October 2026 we ran the 36 published frames of that same Brisbane check-out through a fresh scan, without the narration. The document came back with 3 areas, 35 items and 4 issues, and this photo check:

```json
"evidence_check": { "verified": 38, "unconfirmed": 1, "not_visual": 0 }
```

The one unconfirmed record is useful to look at:

```json
{
  "id": "itm_3",
  "name": "cooktop",
  "location": "On the rear kitchen counter behind the island, toward the left side.",
  "placement": {
    "relation": "behind",
    "anchor": "kitchen island",
    "anchor_item_id": "itm_2",
    "viewpoint": "standing in the living area and facing the kitchen island",
    "detail": "on the rear counter"
  },
  "verification": { "status": "unconfirmed", … }
}
```

A cooktop in an open-plan kitchen is a reasonable inference. But none of the frames this record cites clearly shows one, so the document says so instead of presenting it as fact. An agent asked "is there a hob?" should answer "probably, behind the island, but the photos don't confirm it", and a person reviewing a check-out knows exactly which record to look at again.

The demo space itself, which any free test key reads, carries the check computed on its published frames: at check-in 34 records verified and 4 unconfirmed; at check-out 41 verified, 1 unconfirmed and 2 not visual.

## How should an AI agent use the verification?

| `status` | What it means | What the agent should do |
| --- | --- | --- |
| `verified` | One of its frames clearly shows it | Rely on it, and show its first evidence frame |
| `unconfirmed` | Its frames were checked and none clearly shows it | Say it is uncertain; never state it as fact |
| `not_visual` | No photo could show it: narration only, a fault, an absence | Say where it comes from when it matters |

The same rule reaches the agent whichever way it reads the space:

- **API**: `verification` on `items`, `issues` and `key_locations` of every [Space Document](https://spacecontext.app/developers/docs/api/space-document/).
- **Markdown and Agent Skill**: a "Photo check" line on every record and a summary ("31 of 36 records verified on photo…"), and the Skill tells the agent how to read it.
- **MCP**: `get_space` returns each record's verification and an `evidence_check` count, and the server tells the assistant to prefer verified records and hedge unconfirmed ones; `ask_space` answers say when they rest on an unconfirmed record. See [the MCP server for physical spaces](https://spacecontext.app/blog/mcp-server-for-physical-spaces/).
- **SDK**: `summarizeVerification(document)` counts verified, unconfirmed, not visual and unchecked records.
- **CLI**: `spacecontext space` prints a line such as "Evidence: 31 of 36 records verified on their photo · 3 unconfirmed · 2 not visual".

Because the result is only a status and a probability, keys that cannot read sensitive values (door codes, Wi-Fi passwords) see it too. A record withheld from them stays withheld; a hidden key location keeps its status but does not name its frame.

## What the photo check does not do

- It confirms that the **thing is in the photo**, not that every detail of the record is right: a sofa can be verified while its colour or condition is wrong.
- It never **adds** evidence: a record whose frames do not show it is marked, not moved to a frame that does.
- It never decides that something is **gone**. In a check-in/check-out comparison, an item counts as removed only when the second scan shows its place empty; "not seen" stays separate, as explained in [Check-in and check-out inventory](https://spacecontext.app/blog/check-in-check-out-inventory-comparison/).
- It is a measured filter, not a guarantee. The thresholds and wordings come from the measurements above, and we rerun them when a question changes.

## Try it on the demo

The fastest way to see verified records is a free test key, which reads the demo space at no cost:

```bash
npx spacecontext login --test
npx spacecontext space spc_demo
```

The summary ends with the evidence line, and `--json` prints the whole document, every `verification` object included. When you are ready to scan your own space, [open the console](https://spacecontext.app/developers/console/): the first live scan is free with a card on file, then $1.00 per scan, and every record of the result comes with its photo check.

## FAQ

### What does a verified record mean?

That one of the frames the record cites clearly shows it: a second model, asked a closed question about that record on that frame, answered with a probability of 0.7 or more. It confirms that the thing is in the photo, not that its brand, quantity or condition are right.

### Why not ask the same model to double-check its own answer?

Because a second generative pass is still generative: it can agree with itself in new words. The check asks a model that cannot write text a yes-or-no question and reads a probability, and the same frame always gets the same answer.

### Does the photo check make a scan slower or more expensive?

It adds a few seconds, shown as the stage verifying, and nothing to the price: a live scan costs $1.00 from prepaid credit, after a free first one with a card on file. If the check cannot run, the scan completes without it; it never makes a scan fail.

### Can I see verified records without paying?

Yes. A free test key reads the demo space spc_demo, and its records carry the same verification as a live document: at check-in 34 records verified and 4 unconfirmed, at check-out 41 verified, 1 unconfirmed and 2 not visual.

### What should an AI agent do with an unconfirmed record?

Say it is uncertain and never state it as fact. The MCP server tells assistants to prefer verified records and hedge unconfirmed ones, and the answers of ask_space say when they rest on an unconfirmed record.
