*A highly complicated archaeological bibliography, turned into 40,628 structured rows with provenance.*
**Summary:** GLM OCR preserves layout, a deterministic parser routes rows, an LLM does only what LLMs are good at, and rules carry the rest of the load.
**Status:** active · **Year:** 2024 - ongoing **Tags:** AI Systems, Digital Humanities, Data Engineering, OCR, Multilingual
---
The Nova Bibliografia Pompeiana is a huge bibliography of work on Pompeii and Herculaneum. It was valuable, but it was still basically trapped as a book: pages, columns, headings, and citations that humans could read but software could not reliably sort. To turn it into data, the pipeline had to understand the words alongside the layout, author inheritance, cross-references, and source location. That is why the problem stayed stuck for so long.
 *SOURCE — A raw page from the Nova Bibliografia Pompeiana.*
 *OVERVIEW — The same bibliography varies by language, authors, places, dates, series, and level of detail. Color overlay maps each axis of variation onto a real two-column page.*
German title in an Italian-language bibliography. Title-case rules differ.
RM is Mitteilungen des Deutschen Archäologischen Instituts. No universal registry maps it.
"v. anche" = "see also." A pointer, never a standalone record. Has a number, still isn’t one.
Same number, different volumes, different authors, different years. The number alone fails as an ID.
Model matches the page exactly. Strict scoring marks it wrong because it doesn’t match the normalized gold.
The breakthrough was GLM OCR. It preserved enough of the page structure, columns, headings, and citation numbers to make the rest of the pipeline possible. From there, the system could parse rows, classify fragments, send real standalone citations to Qwen 3.6 Plus, and keep risky rows out of the clean import path. The final pipeline is not one prompt, it is a full production system with parsing, routing, extraction, cleanup, IDs, and review tiers.
**Pipeline:**
1. **Source PDF** (input) — Nova Bibliografia Pompeiana, scanned pages and columns. 2. **GLM OCR** (process) — Layout-preserving read of pages, columns and citation numbers. 3. **OCR parser** (process) — Segments rows and tracks each row back to its page and column. 4. **Row classifier** (rule) — Decides if a row is a standalone citation or a fragment like 'v. anche'. 5. **Qwen 3.6 Plus** (process) — Structured field extraction on standalone citations only. 6. **Fragment rules** (rule) — Keeps the raw row, marks it for review, never invents fields. 7. **Postprocess** (process) — Normalizes whitespace, dates, ranges and inherited authors. 8. **Deep-sweep audit** (process) — Fixed 12,503 cells, every change logged with a reason. 9. **NBP_UI_UID** (process) — Collision-safe ID built from source, page, column and hash. 10. **Final split** (output) — Zotero-ready rows on one side, need-review rows on the other.
Each stage has one job. The LLM only sees rows the rule layer has already declared safe; everything risky stays in a separate, fully traceable lane until a human signs off.
*Genuine model-error rate after text-evidence verification: ~1.5%.*
For years, this was possible in theory but not practical in reality. OCR could read some text, but it usually lost the layout that made the bibliography understandable. LLMs were either too expensive, too inconsistent, or not good enough to run across tens of thousands of messy citations. In 2024 to 2026, the missing pieces finally started arriving close together.
*Sources: Sources: Zhipu AI (GLM-4.5V, GLM-OCR), Alibaba Cloud Model Studio (Qwen Plus pricing), OmniDocBench v1.5 leaderboard*
What matters is that the exact things this project needed all crossed the quality and price line at almost the same time. Earlier, this pipeline would have been technically possible but economically unreasonable. Now it became something I could actually build, test, rerun, and verify.
I started working on this seriously in mid-2024. The first approach was the obvious one: give a frontier model a very detailed system prompt and ask it to sort citations directly. That helped me write the rulebook, but it did not produce a stable enough dataset. Each later attempt got closer, but each one failed for a different reason.
The pipeline shape was already right from the first attempt: parse the citation, apply rules, preserve uncertainty, and verify the result. What changed was that model quality, OCR quality, and inference cost finally caught up to the design. Sometimes the right engineering move is knowing when not to force a weak system to ship.
The final file is a structured bibliography with authors, titles, object types, years, pages, source locations, stable IDs, and review labels. The safe rows can move toward Zotero and website search, while uncertain rows are clearly separated for human review. That means future work can focus on the hard remaining cases instead of redoing the whole bibliography by hand.
**Future work:**