I Showed Cloudflare's Clef an Image of a Document (in English) and Had It Find Errors in the OCR Results

I Showed Cloudflare's Clef an Image of a Document (in English) and Had It Find Errors in the OCR Results

Verifying VLM output in OCR that extracts numbers and text from documents has been a challenge. I tested whether Cloudflare Workers AI's new decision model, Clef, can detect errors in extraction results using the image.
2026.10.04

This page has been translated by machine translation. View original

Hello, I'm Keima.

For OCR processing of documents on AWS, one approach is to host an OCR model on Amazon SageMaker to extract text, then use a downstream LLM to structure keys and values while making use of the character recognition confidence scores.
However, hosting a model on SageMaker around the clock tends to get expensive, and because multiple services are combined, the architecture also tends to become heavy.

Recently, the character recognition accuracy of VLMs themselves has improved, so a setup where a VLM alone handles everything through extraction has become practical.
However, the confidence scores an LLM outputs tend to be self-reported, and it can give high scores even to misread values, so they are a weak basis for judgment that cannot be fully trusted.
On the other hand, calling yet another LLM just for verification would add further cost.

Clef, released on Cloudflare Workers AI on October 1, 2026, is a decision model that supports image input and returns probabilities directly in response to questions.
Because it runs lightweight and at low cost, I thought it might be suitable for independently checking extraction results.

So in this article, I pass a document image and its extraction results to Clef, have it judge "Is this value exactly as in the image?", and test whether it can find errors in OCR results.

1. Test conditions

First, I had Claude Haiku 4.5 extract fields from English quotes, invoices, and receipts (3 documents, 91 fields in total), trying to detect naturally occurring errors.
However, Haiku turned out to be better than expected and extracted every field correctly, so for this test I intentionally injected 3 patterns of errors (12 each, 36 in total).

The breakdown of the injected errors is as follows.

  • Digit change (12): change just one digit of an amount or date ($1,150.00 → $1,160.00, 09/18/2026 → 09/19/2026, etc.)

  • Change to a similar character (12): replace with a character easily confused in OCR (0 → O, 1 → l, m → rn, etc.)

  • Replacement with a different value (12): replace with another word that is not unnatural in context (SAMPLE MART → FRESH MARKET, Service → Hardware, etc.)

The judgment and verification conditions are as follows.

  • Judgment method: pass one document image and the extraction results, and for each field ask with noul (a question that returns the probability of yes) "Is this value exactly as printed in the image?" A probability below 0.5 is judged as an "error"

  • Models: clef (27B) and clef-flash (9B)

{
  "model": "clef",
  "images": ["data:image/png;base64,..."],
  // state: premise for the judgment (an OCR system read the invoice image and extracted keys and values)
  "state": {
    "task": "An OCR system read the attached invoice image ...",
    "extracted": { "invoice_no": "INV-2026-0042" }
  },
  "questions": {
    "field.invoice_no": {
      "type": "noul", // a yes/no question. Returns the probability of yes
      // instructions: judgment instructions (Does the extracted invoice_no value match the string printed in the document image exactly, character for character?)
      "instructions": "Is the extracted value of \"invoice_no\" (\"INV-2026-0042\") exactly what is printed in the document image, character for character?"
    }
  }
}

Sample invoice image
The invoice used in the test

2. Results

2.1 Could it find the errors?

Clef returns, for each field, the "probability that the value matches the image."
Fields with a probability below 0.5 were judged as "errors," and I counted the results from the following two perspectives.

  • Error detection: Of the 36 injected errors, the number correctly judged as "errors"

  • Correct values judged as errors: The number of values that were actually correct but were judged as "errors" (false positives).

Condition Error detection (out of 36) Correct values judged as errors (out of 237)
clef 36 0
clef-flash 36 3

clef detected all of the injected errors and had 0 false positives.
On the other hand, clef-flash had 3 false positives, where fields that should have been correct were wrongly judged as "errors (probability below 0.5)." The fields involved were as follows, and all of them were amount-related fields such as the total amount.

Document Field Value actually entered (correct, as in the image) Probability judged by clef-flash
Quote Total amount (Total) $5,820.12 0.17 to 0.19
Receipt Price of line item 1 4.29 0.34
  • The quote's Total was falsely flagged in each of two trials, so the count is 3 in total, but the fields themselves are the two kinds above.

The match probabilities for all 36 injected errors are as follows.
These values represent "the probability that the extracted value is correct according to the image," so the lower the number, the more strongly the model suspects that it "does not match the image (is an error)."

Match probabilities for the 36 injected errors (click to expand)
Document Set Field Correct value Injected value Pattern clef clef-flash
Quote A item1_unit_price $1,150.00 $1,160.00 Digit 0.02 0.02
Quote A tax $431.12 $431.72 Digit 0.23 0.05
Quote A quote_no Q-2026-0187 Q-2026-O187 Similar character 0.06 0.10
Quote A item3_amount $435.00 $435.0O Similar character 0.02 0.16
Quote A item4_name Office suite license Project management tool Replacement 0.02 0.02
Quote A item6_category Service Hardware Replacement 0.01 0.03
Quote B date 09/18/2026 09/19/2026 Digit 0.02 0.03
Quote B item3_qty 3 5 Digit 0.03 0.02
Quote B total $5,820.12 $5,82O.12 Similar character 0.07 0.10
Quote B item1_name Laptop computer Laptop cornputer Similar character 0.03 0.08
Quote B item2_amount $840.00 $1,240.00 Replacement 0.03 0.11
Quote B note Prices are valid for 30 days from the quote date. Prices include free shipping. Replacement 0.02 0.02
Invoice A invoice_no INV-2026-0042 INV-2026-0045 Digit 0.02 0.02
Invoice A item2_qty 5 6 Digit 0.06 0.03
Invoice A vendor_address_line2 Columbus, OH 43004 Columbus, OH 43OO4 Similar character 0.05 0.04
Invoice A bill_to_address_line1 88 Innovation Way B8 Innovation Way Similar character 0.13 0.04
Invoice A bill_to_name Example Robotics Inc. Example Logistics LLC Replacement 0.03 0.02
Invoice A payment_terms Net 30 Due on receipt Replacement 0.02 0.02
Invoice B due_date 10/15/2026 10/16/2026 Digit 0.08 0.02
Invoice B amount_due $1,234.50 $1,284.50 Digit 0.07 0.04
Invoice B po_number PO-7781 PO-778l Similar character 0.07 0.08
Invoice B vendor_email billing@sample-supply.example billing@sarnple-supply.example Similar character 0.03 0.03
Invoice B item3_description Pallet wrap film Bubble wrap roll Replacement 0.03 0.02
Invoice B shipping $14.37 $0.00 Replacement 0.02 0.02
Receipt A item2_price 3.49 3.48 Digit 0.11 0.02
Receipt A time 14:32 14:52 Digit 0.04 0.01
Receipt A receipt_no #0815 #O815 Similar character 0.07 0.13
Receipt A total 28.94 2B.94 Similar character 0.04 0.01
Receipt A item4_name APPLES 2LB BANANAS 3LB Replacement 0.03 0.01
Receipt A store_name SAMPLE MART FRESH MARKET Replacement 0.02 0.01
Receipt B date 09/21/2026 09/27/2026 Digit 0.03 0.01
Receipt B item5_price 11.99 17.99 Digit 0.03 0.01
Receipt B store_address_line2 Portland, OR 97201 Portland, OR 972O1 Similar character 0.06 0.05
Receipt B payment_card VISA ****0000 VISA ****OOOO Similar character 0.09 0.12
Receipt B item1_name MILK 1GAL ORANGE JUICE Replacement 0.02 0.01
Receipt B subtotal 28.94 31.50 Replacement 0.03 0.01

2.2 How the probabilities separate

To see where the threshold should be set, I summarized the spread of the "probability that the value matches the image" assigned to the error fields (36) and the correct fields (237).
The bottom 5% and top 5% are the values at the 5% and 95% positions from the bottom when the probabilities are sorted from lowest to highest.

Condition Target Min Bottom 5% Median Top 5% Max
clef Errors 0.012 0.016 0.030 0.112 0.227
clef Correct values 0.622 0.769 0.914 0.974 0.983
clef-flash Errors 0.009 0.012 0.023 0.122 0.162
clef-flash Correct values 0.166 0.645 0.940 0.973 0.981

For the correct fields, both models gave high probabilities with medians in the 0.9s (clef: 0.914, clef-flash: 0.940).
Looking at the bottom 5%, clef was at 0.769 and clef-flash at 0.645, so some fields came out somewhat low.

The results when changing the threshold are as follows.

Threshold clef: error detection clef: false positives clef-flash: error detection clef-flash: false positives
0.5 36/36 0/237 36/36 3/237
0.6 36/36 0/237 36/36 8/237
0.7 36/36 5/237 36/36 18/237
0.8 36/36 23/237 36/36 50/237

At every threshold, both models caught all 36 injected errors.
The difference was in the number of false positives: the higher the threshold, the more correct values get sent to human review.
With clef, there were 0 false positives at 0.5 to 0.6, but at 0.8 about 10% of the correct values (23) would be sent to human review.
clef-flash had 3 false positives even at 0.5, and at 0.8 it reaches about 20% (50), so clef is better suited if you want to keep the review effort down.
However, since the error data is only 36 cases, for actual operation I recommend collecting similar statistics on the documents you handle and deciding the threshold from them.

2.3 Time and cost

The requests to Clef were made once per document.
In each request, I sent one image together with the questions for all fields of that document (21 to 38 questions).

Condition Time per request (median) Total time for 9 requests Total cost for 9 requests
clef 1.737 s (1,737 ms) 14.46 s $0.0103 (about 1.55 yen)
clef-flash 0.953 s (953 ms) 8.69 s $0.0039 (about 0.58 yen)

Times are measured values when calling the REST API from within Japan, and costs are converted at 150 yen per dollar.
Extraction by Haiku takes about 10 to 13 seconds per document, so adding this check barely changes the overall processing time.

3. Summary

As far as I tested with three English documents, clef, given the images, detected all the injected errors and had no false positives.
However, the errors this time were injected artificially, so I have not confirmed performance against the kinds of misreadings Haiku itself makes.

If you incorporate this into a document extraction check, rather than having the VLM self-report the correctness of its own extraction results, an effective setup is to pass the results together with the image to a lightweight decision model like Clef and have it double-check.

References


Claudeならクラスメソッドにお任せください

クラスメソッドは、Anthropic社とリセラー契約を締結しています。各種製品ガイドから、業種別の活用法、フェーズごとのお悩み解決などサービス支援ページにまとめております。まずはご覧いただき、お気軽にご相談ください。

サービス詳細を見る

Share this article

AI白書