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.


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ónWords intact; the margin stamp filed as a header. |
✗ M´ exico, Ram´ on11 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 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
1940spans four sub-columns - Dotted leader lines running from each row label to its first value
- Around 60 rows of comma-separated figures
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:
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 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.
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.


