Short answer: treat every table Claude extracts from a PDF as a draft. Classify the file, pull the same table out a second, independent way, reconcile row counts, column counts and totals, and reject anything that disagrees until a person has compared it with the page image. That sequence is a researcher recommendation built from vendor and library documentation. It was not run against Claude, Anthropic’s PDF skill or Claude Duet.
Status: documentation review, not hands-on tested. Sample prompts below are illustrative and are not observed output. Source dates and retrieval dates are in the provenance summary at the end. Labels used here: Vendor documentation (what the vendor says), Library documentation, Practitioner description (a creator’s own words, unverified) and Researcher recommendation (this guide’s judgement).
Why a second extraction is worth the effort
Vendor documentation. When a PDF is sent through the Claude API, “the system converts each page of the document into an image” and “the text from each page is extracted and provided alongside each page’s image.” The same page says PDF support relies on vision, so it is “subject to the same limitations and considerations as other vision tasks”, and that dense PDFs with “complex tables” can fill the context window before the page limit. At retrieval the page limit was 600 pages, or 100 when the request’s context window is under 1M tokens. That is API behaviour; the page does not describe the Claude apps or Duet.
Library documentation. pdfplumber’s README says the library works best “on machine-generated, rather than scanned, PDFs” and that by default extract_tables uses the page’s ruling lines or rectangle edges as cell separators. pypdf notes that an image-only page may yield minimal text, and suggests OCR.
Research. An arXiv abstract benchmarking 21 PDF parsers on 100 synthetic documents reports “significant performance disparities” and says rule-based metrics fail to capture semantic equivalence of table content. It is a preprint abstract on synthetic documents and does not evaluate Claude by name, so treat it as a reason not to assume any one extractor is right, not as a score for Claude.
Researcher recommendation. If extractors disagree measurably and none is guaranteed, a single extraction cannot validate itself. Compare two methods whose failure modes differ, then let a person arbitrate against the page image.
Prerequisites
- A copy of the PDF you can leave untouched, plus a separate output file for results.
- The logical page number (the number a PDF viewer shows) of every table you need.
- A named reviewer who will open the page image, and a decision on what an error costs (a board pack is different from a draft summary).
- Optional: Python with pdfplumber, if you want the deterministic comparison in step 4.
The workflow
1. Classify the file
Open it and answer three questions: Is the text selectable? Do tables have ruling lines? Are pages upright? A scanned page falls outside pdfplumber’s stated sweet spot and pypdf’s text extraction, and Anthropic’s PDF skill lists “OCR on scanned PDFs” as a separate route. Record the class: it decides how far you can trust steps 3 and 4.
2. Shrink the job
Vendor documentation recommends rotating pages upright, using logical page numbers in prompts and splitting large PDFs into chunks. Follow that, and extract one table first. A short run exposes problems that a long one would bury.
3. Extract with Claude
Illustrative prompt, not observed output:
Extract the table on PDF page 14. Keep the header row exactly as printed. Return a markdown table, the number of rows and columns, and the printed total if there is one. If a cell is unreadable or cut off, write
UNREADABLEinstead of guessing.
The last instruction is a researcher recommendation: it converts silent guesses into visible gaps.
4. Extract the same table a second way
The Anthropic PDF skill’s own example uses pdfplumber’s page.extract_tables() (skill source). An adaptation, not run:
import pdfplumber
with pdfplumber.open("document.pdf") as pdf:
tables = pdf.pages[13].extract_tables() # logical page 14
print(len(tables), [(len(t), len(t[0])) for t in tables])
pdfplumber can also overlay the detected lines and tables on the page image through debug_tablefinder, which is useful when it finds the wrong grid. Both extractors may read the same flawed text layer, so agreement raises confidence but does not prove correctness.
5. Reconcile
Normalise before comparing (strip currency symbols, thin spaces and thousands separators; match minus signs and parentheses) so formatting differences do not hide real ones. The preprint abstract’s point about string matching is the reason. Then check:
| Check | Pass condition |
|---|---|
| Row and column counts | Equal in both extractions and on the page |
| Header text | Same words and order as printed |
| Printed totals | Recomputed column sums match the printed total |
| Signs and units | Negatives, percentages, currency, scale (“in thousands”) preserved |
| Merged cells and spanning headers | Visibly attached to the right columns |
| Page breaks | A table continuing on the next page is one table, not two |
| Footnote markers | Kept, and attached to the correct cell |
6. Decide and record
Write down the file name, page numbers, file class, both methods, the disagreements and who reviewed them. Keep the original untouched.
Validation and rejection checklist
Accept the table only if every check in step 5 passes or each failure is explained and corrected by a person looking at the page image.
Reject (or send back) when:
- a recomputed total differs from the printed total;
- a cell is marked
UNREADABLEand nobody resolved it; - the two extractions disagree on any number, sign or unit;
- the file class is “scanned” and nobody did the page-image comparison;
- the reviewer cannot say which page each row came from.
Failure cases to expect
- Scanned or image-only pages. Text extraction can come back nearly empty; OCR output needs its own review.
- Tables with no ruling lines. pdfplumber’s default strategy depends on lines, so a borderless table may come back wrong or empty unless settings change.
- Dense, multi-page tables. Vendor documentation warns about context limits; chunking changes where a table gets cut.
- Confident but wrong cells. This is a researcher hypothesis, not a sourced finding: a model that sees a value that “looks off” might normalise it. Your totals check is the defence.
- Unverifiable accuracy claims. One creator’s video description says an agentic workflow keeps “verifying its own output against the source image until the data is perfect”. The description gives no data we could check, and we did not watch the video. Compare that with another creator’s description of a short Claude-to-Excel demo, which lists “spot checking the numbers against the original” and says “accuracy depends on how clean your original file is, so a quick review is always worth it.” These are practitioner descriptions, not test results; transcripts could not be retrieved.
Compatibility: Duet versus the wider Claude ecosystem
| Surface | What the documentation says | What it does not establish |
|---|---|---|
| Claude API | PDF support: pages as images plus extracted text; limits above | Accuracy on your tables |
| Anthropic PDF skill (repository) | Skill file lists extraction, merging, forms and OCR; README says to “test skills thoroughly in your own environment” | That any hosted app loads this exact version |
| Claude Code | README documents /plugin install document-skills@anthropic-agent-skills. One docs page says the pre-built document skills are not available in Claude Code; the Claude Code skills page says synced skills include built-ins “such as pdf and xlsx” |
Which statement applies to your version (the two pages disagree as retrieved) |
| Claude Duet | The announcement says Duet “carries over your memory, skills, and connected apps from your Claude account” | Any mention of PDF extraction, the PDF skill, or table accuracy in Duet. Not documented; not tested. |
Never read Claude Code or API support as Duet support. The checklist above works without any of them, because it relies on the page image and a person.