Skip to main content

Crosscheck

A second opinion for AI photo descriptions. Several vision models, running on your own computer, describe the same photo. Crosscheck tells you what they all agree on, and, first and most clearly, where they disagree.

Built for blind and low-vision people, who use AI descriptions for labels, medicine, mail and screens but have no easy way to tell when a description is wrong.

Why

A single AI description sounds equally confident when it is right and when it is wrong. A study at ASSETS 2025, Surfacing Variations to Calibrate Perceived Reliability of MLLM-generated Image Descriptions (Meng Chen, Akhil Iyer, Amy Pavel), found that when blind and low-vision participants were shown where several models' descriptions varied, they spotted 4.9 times as many unreliable claims as with a single description (2.62 against 0.53 per image). 11 of 15 participants ranked that presentation as their favourite, and all of them wanted to use it in the future.

Crosscheck brings that idea to models that run locally through Ollama: free, offline, and the photo never leaves your computer.

How it works

  1. Each model lists what it sees as short, separate facts, and quotes any text it can read.

  2. Facts that say the same thing are merged. Facts that differ in a number or quoted text ("Ibuprofen 200 mg" against "400 mg") are kept apart, because that is where errors hide.

  3. Every model looks at the photo again and judges each fact the others stated: yes, no, or unsure.

  4. If you asked a question, each model also answers it in a few words, and the models judge each other's answers the same way. "Cannot tell" counts as not answering, not as disagreeing.

  5. You hear a short summary first, for example:

    A pill bottle on a wooden table. The 3 models agree on 6 of 9 details. They disagree about: The label says "Ibuprofen 200 mg"; The label says "Ibuprofen 400 mg".

    Then, on demand: what every model agrees on, where they disagree (and which model said what), and details not every model could judge.

Agreement is not proof. Models can make the same mistake. For medicine, money or safety, confirm with a person or another trusted source. Crosscheck never says "verified".

Install

  1. Install Ollama and pull three vision models from different families (different families make different mistakes):

    ollama pull qwen3-vl:4b-instruct
    ollama pull gemma4:e4b
    ollama pull ministral-3:3b
    
  2. Install and start Crosscheck (Python 3.10+, no other dependencies):

    uv tool install crosscheck-vision      # or: pipx install crosscheck-vision
    crosscheck serve
    

    It opens http://127.0.0.1:8765 in your browser.

Choose other models with --models a,b,c (or CROSSCHECK_MODELS). With a 12–16 GB GPU, expect about 30–90 seconds per photo while Ollama swaps the models in and out; a CPU works, slowly.

Using it

  • Web app: choose a photo, optionally ask a question ("What does the label say?"), press Check photo. Progress is announced; when the result is ready, focus moves to it. Everything works with the keyboard and a screen reader. A checkbox can also read the result aloud with the browser's own voice.
  • Terminal: crosscheck describe photo.jpg --question "What does the label say?", or --json for the full result.

The web app shrinks the photo in your browser before sending it, which also removes metadata such as GPS location.

Evaluation

eval/modal_eval.py runs Crosscheck on 100 photos taken by blind people, from the VizWiz-VQA validation set (CC BY 4.0), each with the question its photographer asked and ten crowd answers. eval/rescore.py then grades every answer against the crowd answers with a separate text model (Qwen3-8B), because word matching misjudges free-form answers. Results on one NVIDIA L4, all three default models loaded (eval/results/vizwiz-judged.json):

Result
Correct, single model (Qwen3-VL 4B / Gemma 4 E4B / Ministral 3 3B) 56% / 55% / 45%
Correct, Crosscheck's combined answer 63%
Wrong when the models disagree 45%
Wrong when all models agree 33%
Wrong answers that were flagged as a disagreement 38%
Time per photo (median / 90th percentile) 13 s / 42 s

What this means:

  • Combining three small models gives a better answer than any one of them.
  • Disagreement is a real warning sign (errors are more common), but agreement does not mean the answer is right: a third of agreed answers were still wrong. VizWiz photos are often blurry, dark or badly framed, which is exactly when blind users most need help and when small models are weakest.
  • An earlier version compared answers by their words and used Granite 3.2 Vision, which refused 38% of photos; it flagged almost everything and told users nothing. Its results are kept in eval/results/vizwiz-v1-granite-lexical.json.

The ASSETS '25 study used large cloud models; we have not yet measured how much bigger local models (for example on a 24 GB GPU) improve these numbers.

Privacy and security

  • Runs on 127.0.0.1 only. Photos stay in memory and go only to your Ollama. Nothing is logged.
  • Requests must come from the app itself: a non-local Host (DNS rebinding) or a foreign Origin (another website) is refused. A strict Content-Security-Policy blocks outside content.
  • Model output is shown as text, never as HTML.

Status and limits

  • v0.1, for desktop browsers on the same computer. Using a phone camera over Wi-Fi needs HTTPS and is planned for v0.2.
  • Merging facts across models uses word overlap, so two phrasings of one fact are sometimes listed separately; each still gets judged.
  • Small local models are weaker than the cloud models in the study, and their agreement is a weaker signal (see Evaluation). Treat "the models agree" as encouraging, never as proof.

Feedback from blind and low-vision users matters most: please open an issue or email admin@rushlabs.ai.

Development

python -m unittest discover -s tests -v

Tests run against a fake Ollama: merging and judging, a failing model, the web app's security checks, the job queue and the CLI.

Licence

Apache-2.0. Built by Rush Labs, an applied AI lab. The models keep their own licences (all three defaults are Apache-2.0).

Metadata

Release files for crosscheck-vision 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for crosscheck-vision 0.2.0
File Size Uploaded Provenance Actions
crosscheck_vision-0.2.0.tar.gz 23.6 kB With provenance Details for crosscheck_vision-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for crosscheck-vision 0.2.0
File Interpreter ABI Platform Actions
crosscheck_vision-0.2.0-py3-none-any.whl Python 3 none any Details for crosscheck_vision-0.2.0-py3-none-any.whl

Total release size: 50.2 kB

Release files / crosscheck_vision-0.2.0.tar.gz

Download URL crosscheck_vision-0.2.0.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b2956d82e8c357a1a99adbd23381f613aeaf0814ea51af1260e3538abd09e2ba
BLAKE2b-256 checksum
How to use checksums
04a0a1ef0c8f172aa12dacbb2e3ab4a149c0c696abc507eb667b2a4bb4a051e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.

Transparency log

Release files / crosscheck_vision-0.2.0-py3-none-any.whl

Download URL crosscheck_vision-0.2.0-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
58a0563b03b1d6c0e5ab3201aef48df6a684c7805c02cabd1fabc4375d3b3c3a
BLAKE2b-256 checksum
How to use checksums
679d432b05da143f48645228fccbcacc7f62d041d99c90b40e7a51801b3ddbf1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.

Transparency log

Security for crosscheck-vision 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for crosscheck_vision-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page