← Back to Blog
Comparisons

Unsiloed AI vs Unstract: Which Is Better in July 2026?

Unstract's LLMWhisperer and Unsiloed both read a document and give you text back, but they hand you different things. We ran the same files through both, covering every LLMWhisperer mode that applies rather than just the default, and compared the raw responses. On a scanned page, LLMWhisperer's default mode returns an empty result with a success status and a billed page. On a stained receipt, its cheap mode returns a tax registration number that is plausible and wrong.

Aman Mishra
Aman Mishra
10 min read
Unsiloed AI vs Unstract: Which Is Better in July 2026?

Unstract's LLMWhisperer and Unsiloed AI both take a document and give you text back. That's where the similarity ends.

LLMWhisperer is a text-extraction layer. The LLMWhisperer documentation describes its job as presenting document data "to LLMs in a way that they can best understand": it reads the page, returns the text, and expects a language model you supply to do the interpreting. Unsiloed does the interpreting itself. It works out what the regions on a page are, reads each one, and hands back structured values with a confidence score and a location attached.

So the question is not which one reads characters better. On a clean page, both do it well. The question is what you get back, how much work is left over, and what happens when the page is not clean.

We ran four tests on July 31, 2026, and saved every response. Unsiloed won all four.

The test Unsiloed Unstract LLMWhisperer
1. Stained receipt
12 field values, including two tax registration numbers
12 / 12
Every value correct, both tax numbers included.
10 / 12 in its best mode
Both tax numbers dropped entirely. Its cheap mode fills them in wrongly.
2. Census table
A degraded scan with no text layer, scored on the table's own arithmetic
163 / 163 (100%)
Every sum in the table holds. All 387 value cells usable as numbers.
114 / 135 (84.4%)
21 digit misreads. Only 29.3% of cells usable without cleanup. The default mode returned nothing at all.
3. Two-column page
Reading order, an embedded table, inline equations
Reading order is in the data
Columns as ordered blocks, a markdown table, 34 equations as LaTeX.
Reading order is in the whitespace
Flat-text mode fuses the columns into nonsense. No LaTeX in any mode.
4. The smaller things
Accents, word boundaries, rotated marginalia
México, Ramón
Words intact; the margin stamp filed as a header.
M´ exico, Ram´ on
11 run-together words; the margin stamp shattered through the abstract.

How We Tested Both APIs

LLMWhisperer has five processing modes and two output modes, and running only the default would be unfair. So we ran every mode that plausibly applies to each document: native_text, low_cost, high_quality, table, and form. Where LLMWhisperer has a mode built for the exact thing being tested, that mode is what we quote. On the Unsiloed side we used the endpoint that suits each job: named fields when the goal is values, document structure when the goal is a readable rendering of the page.

Every raw response was saved to disk rather than summarized, and the figures below were counted by script over those files, not by eye. Fairness in the other direction: this is a handful of documents, not a benchmark. It shows what each API hands back when a page is degraded, not a general accuracy ranking.

Round 1: A Receipt That Has Been Through Something

The kind of thing that turns up in an expense pipeline: a faded thermal receipt, photographed rather than scanned, with coffee-stain rings across the print and the paper curling at the edges. No embedded text, so everything comes off the pixels.

A faded thermal receipt with coffee-stain rings across the printed area A Malaysian hardware-store tax invoice. Its own arithmetic gives us ground truth: 50.00 − 15.90 = 34.10, and 6% of 15.00 = 0.90.

Twelve values. A field counts when the value comes back correct, ignoring letter case; every configuration was run three times and returned the same result each time.

The money came back correctly everywhere: 15.90, 15.00, 50.00, 34.10, the 0.90 tax, and the date. These are the six fields where the three disagreed:

Field On the receipt Unsiloed Unstract high_quality Unstract low_cost
Company reg no SA03711551-P (dropped) S403711551-P
GST reg no 001637511168 (dropped) 001637511166
Invoice no CS 67832 CS 67432
Merchant HOME MASTER HARDWARE HOME RASTER HARDWARE
Tax amount 0.90 0.S0
Item code 24MMx7Y 24hMa7 7
Total, all 12 fields 12 / 12 10 / 12 6 / 12

The default mode, native_text, returned nothing at all: 0 / 12.

The two misses are a tax invoice's most consequential fields. The high_quality and form modes return the labels with nothing after them (Company Reg No. : and GST Reg No. :), while low_cost fills them in with plausible wrong numbers.

Round 2: A Dense Table on a Degraded Scan

A page from the 1951 US Census, with several things working against a reader:

  • No text layer
  • A header where 1940 spans four sub-columns
  • Dotted leader lines running from each row label to its first value
  • Around 60 rows of comma-separated figures

The 1951 census population table: a degraded scan with nested headers and dotted leader lines The dotted leader lines are the hazard here: they invite a reader to drift one row up or down.

The Default Mode Reads Nothing

The default and cheapest mode, native_text, returns this:

'\n\n<<<\x0c'

Six characters: a page separator and a form feed. No error, no warning: the request succeeded, the job reported itself processed, and the page was billed. A pipeline left on the default silently ingests nothing from every scan you send it.

Where the Numbers Went Wrong

The table mode does read the page, and renders the nested header creditably. The problem is the figures. Here's one row as printed:

The Male 5 to 9 years row of the census table, enlarged Male, 5 to 9 years. The 1940 columns read 5,418,823 total: 4,744,537 white plus 674,286 nonwhite.

Cell On the scan Unsiloed Unstract table mode
5 to 9 years, nonwhite 674,286 67,428
40 to 44 years, nonwhite 423,945 423,045
Under 5 years, 1910 5,380,596 5,380,598
The row label itself 5 to 9 years 5 to 0 years

The printed table is its own answer key: white plus nonwhite must equal the 1940 total, and male plus female must equal the total for each age band. A failed sum means a misread digit.

Numeric cells returned Sums that hold
Unsiloed 387 163 / 163 (100%)
Unstract table mode 387 114 / 135 (84.4%)

Both returned the same 387 cells, so neither is scoring well by returning fewer. Twenty-one sums fail on LLMWhisperer's output. Unstract also has fewer checkable rows (135 against 163) because mangled labels like 5 to 0 years cannot be matched against their counterparts in the male and female sections.

Then there's the formatting. Spaces get injected inside the numbers, inconsistently:

| Total              | 91, 972, 266 | 105, 710, 620 | 122, 775, 046 |
| Under 5 years      | 10,631,364   | 11,573,230    | 11, 444, 890  |
| 15 to 19 years     | 9,063, 603   | 9, 430, 556   | 11, 552; 115  |

One cell reads 91, 972, 266 and the next reads 10,631,364, and one uses a semicolon for a thousands separator. Only 29.3% of its value cells would survive being handed straight to a program that expects a number.

Every Value Knows Where It Came From

Unsiloed returns each figure with a confidence score and the rectangle it was read from:

{
  "value": "9,229,505",
  "score": { "grounding_score": 0.97, "extraction_score": 0.98 },
  "citation": { "page": 1, "bbox": [273, 156, 307, 166] }
}

Drawn back onto the scan, that box lands here:

The census table with the returned bounding box drawn around the value 9,229,505 The citation for 9,229,505 (Under 5 years, 1940 White). Every one of the 387 values carries one.

On a 60-row scan of 1951 print, that's the difference between a number you can audit and a number you have to trust.

Round 3: A Two-Column Page

A MATEC conference paper: two columns of prose, an embedded table with a merged header, and inline equations.

The two-column MATEC conference page with an embedded table and inline equations Nothing separates the columns but a gap, so a reader has to infer where the left one ends.

What Unstract Returned

Here the output mode decides everything. In flat-text mode, the two columns are read straight across the page:

This can be explained by the relative high damping in electric potential at the conductor terminals with respect
the suspension of the coil (see Figure 5) combined with to the bemf constant.
the relative small force introduced into the shaker by the We study a system which on the one hand generates
impact hammer, leading to a totally damped acceleration a force due to an applied current and on the other hand

Every line is two unrelated fragments: the opening of a sentence from column one welded to the middle of a sentence from column two. Embed that and you have indexed text that means nothing.

The layout_preserving mode handles this much better, keeping the columns apart with horizontal whitespace so a reader can follow each one down the page:

    This can be explained by the relative high damping in          electric potential at the conductor terminals with respect
    the suspension of the coil (see Figure 5) combined  with        to the bemf constant.

This is the mode LLMWhisperer is built around, and for its stated purpose it works. The catch is that column one and column two occupy the same lines: any consumer that normalizes whitespace (most chunkers, most embedding pipelines) collapses this straight back into the interleaved version above. The structure is real, but it's a rendering, and it survives only as long as nothing touches the spacing.

What Unsiloed Returned

The two columns come back as separate blocks in reading order, so the sequence is part of the data:

This can be explained by the relative high damping in the suspension of the coil
(see Figure 5) combined with the relative small force introduced into the shaker by
the impact hammer, leading to a totally damped acceleration response of the table.

The embedded table came back as markdown, with the merged Values header preserved as a sub-header row and the exponents intact:

| Modal parameter | Symbol | Values | |
| --- | --- | --- | --- |
|  |  | Calculated | Determined experimentally |
| Modal mass of the vibrating table | m₁ | 77.2 g | 18.2 g |
| Modal damping of the isolation studs | c₂ | 196.15 kg/s | 76 kg/s |
| Modal stiffness of the suspension of the coil | k₁ | 12.3·10³ kg/s² | 28.02·10³ kg/s² |

The equations came back as LaTeX rather than as an attempt at plain text:

$\overline{F}_q = q\left(\overline{E} + \left(\overline{v} \times \overline{B}\right)\right)$

Across this page, Unsiloed returned 34 mathematical expressions marked up as LaTeX and a seven-row markdown table. LLMWhisperer returned neither, in any mode.

The Smaller Things

None of these decide a purchase on their own. They're the kind of defect that quietly degrades a search index or an audit trail, and they showed up consistently.

Accented characters never compose. On an arXiv title page with Spanish affiliations, LLMWhisperer left every diacritic stranded as its own character, in both output modes:

Ram´ on H. Ruiz-Medina*
Centro Universitario de Ciencias Exactas e Ingenier´ıas,
Universidad de Guadalajara, Guadalajara, M´ exico.

Searching that text for "Ramón" or "México" returns nothing. Unsiloed returned Ramón, Ingenierías, and México.

Word boundaries collapse in flat-text mode. On that same page there are 11 places where words run together into strings of 25 characters or more:

CentroUniversitariodeCienciasExactaseIngenier´ıas,
equivariantfunctions,knownasfixingelementarycollapsings. Alloftheseresultsare

A language model reading that has to re-segment the words before it can use them.

Rotated marginalia becomes body text. The arXiv identifier printed vertically up the left edge of the page came back shattered into single characters and interleaved into the abstract:

5                                    Centro Universitario de Ciencias Exactas e Ingenier´ıas,
0 2                                    Universidad de Guadalajara, Guadalajara, M´ exico.
r 2
a
M

Unsiloed returned the same stamp whole, filed as a header rather than as content, which is what lets a retrieval-augmented generation pipeline drop it instead of indexing it.

Small glyph substitutions. On the receipt, the multiplication sign × came back as ¥, the trademark TQ™ as TOM, and the label Cashier # as Cashler #. Unsiloed returned x, TQ™, and Cashier, respectively.

The Verdict

LLMWhisperer handles the easy end of the range, and handles it accurately. The trouble is how quickly "easy" runs out. A second column was enough to fuse sentences together. A scan with no text layer was enough to return nothing at all, with a success status and a billed page. Faded print was enough to lose two tax registration numbers in one mode and corrupt them in another. A table of figures was enough that 70% of the numbers needed cleaning before anything could add them up. Each of those is an ordinary document, and the mode that copes with one is not the mode that copes with the next.

Unsiloed's advantage is what lands in the response. Values rather than a rendering: markdown tables a standard parser reads, LaTeX for equations, reading order carried in the data instead of in whitespace that any chunker flattens. A confidence score and a location on every one of those values, so checking a doubtful number is a comparison rather than a hunt. And one endpoint, with no mode to predict in advance.

Choose Unsiloed when the structured output is the deliverable, when documents arrive in whatever condition the world sends them, and when a wrong value needs to arrive marked as uncertain rather than looking exactly like a right one.

Continue reading