AI data preparation.

Most AI answer quality problems start upstream, in a scanned PDF with no text layer or a policy that was superseded last year. Data preparation is the pipeline that stops them reaching the model.

Engineering guide7 min readUpdated 19 October 2026

Short answer

Data preparation for AI turns raw business documents and records into clean, current, traceable inputs a model can use. It covers extraction, normalisation, deduplication, versioning, privacy filtering and chunking, with a quality check at every stage. For most business AI systems it matters more than model choice. Build it as a versioned pipeline with automated gates, so every answer traces back to a specific source.

  • Every stage of ingestion needs a check and a defined action when the check fails.
  • Normalise Unicode to NFC so te reo Māori macrons match in search.
  • Superseded versions and duplicates are the most common cause of wrong answers.
  • Detect New Zealand identifiers such as IRD and bank account numbers before indexing.
  • Publish versioned snapshots so evaluations and incidents can name the exact data.

What data preparation means for AI systems

Data preparation for language model systems is mostly document engineering. The inputs are PDFs, Word files, emails, spreadsheets and web pages, and the outputs serve three different consumers: a retrieval corpus the system searches at run time, evaluation sets that measure it, and occasionally a fine-tuning set. Each needs the same core pipeline and different final checks.

The goal is traceability as much as cleanliness. When an answer is wrong, you should be able to name the source file, its version, the chunk that was retrieved and the pipeline run that produced it. Without that, every bad answer becomes an argument about whether the model or the data is at fault.

The ingestion pipeline, stage by stage

Build ingestion as discrete stages, each with an automated check and a defined action when the check fails.

Stage Check Action on failure
Inventory Every source has an owner, a purpose and access rules Do not ingest a source nobody owns
Extract Text length against page count; replacement characters; tables detected Route to OCR or manual review
Normalise Unicode NFC; whitespace; dates parsed to ISO 8601; amounts tagged with currency and GST basis Reject unparseable dates rather than guess
Deduplicate Exact content hash, then near-duplicate similarity Keep one canonical copy, link the others
Version Effective date and status: current, superseded or draft Exclude superseded and draft versions from the live corpus
Privacy Personal information detection, including New Zealand identifiers Mask, restrict or exclude
Chunk Size distribution; every chunk carries source, page and section Fix the splitter; reject chunks without provenance
Publish Snapshot ID, document counts and diff against the last snapshot Block if the diff is unexpectedly large

The AI data inventory template is a good starting point for the first stage. Scanned documents with no text layer are the most common extraction failure; the choice between OCR and vision models is covered in OCR versus vision models.

Automated quality checks

Write checks as code that runs on every batch, and gate publication on the failure rate. A document that fails a check is queued for review; a batch where too many fail is not published at all.

import hashlib
import re
import unicodedata

NZ_BANK_ACCOUNT = re.compile(r"\b\d{2}-\d{4}-\d{7}-\d{2,3}\b")

def normalise(text: str) -> str:
    text = unicodedata.normalize("NFC", text)   # one form for macrons
    text = text.replace(" ", " ")          # non-breaking spaces from Word and PDFs
    return re.sub(r"[ \t]+", " ", text).strip()

def content_id(text: str) -> str:
    return hashlib.sha256(normalise(text).encode("utf-8")).hexdigest()

def check_document(doc) -> list[str]:
    problems = []
    if doc.page_count and len(doc.text) / doc.page_count < 200:
        problems.append("little text per page: scanned without OCR?")
    if "�" in doc.text:
        problems.append("replacement characters: encoding damage")
    if not doc.meta.get("owner") or not doc.meta.get("effective_date"):
        problems.append("missing owner or effective date")
    if NZ_BANK_ACCOUNT.search(doc.text) and not doc.meta.get("privacy_reviewed"):
        problems.append("bank account number present without privacy review")
    return problems

def gate(batch, max_failure_rate=0.02):
    flagged = {d.id: p for d in batch if (p := check_document(d))}
    rate = len(flagged) / max(len(batch), 1)
    if rate > max_failure_rate:
        raise RuntimeError(f"{rate:.1%} of documents failed checks; snapshot not published")
    return flagged  # publish, and send flagged documents to review

The thresholds are starting points. Tune them on your own corpus after looking at what each check actually catches.

Normalisation details that change answers

Small encoding differences break search in ways that look like model errors.

  • Macrons. The letter ā can be stored as one precomposed character or as a plain a followed by a combining macron. The two look identical and do not match in keyword search or exact comparisons. Normalising to NFC, as defined in Unicode Normalization Forms, makes Māori, Whangārei and Ōtautahi match however they were typed.
  • Dates. New Zealand documents use day-first dates, and 03/04/2026 is 3 April, not 4 March. Parse with an explicit day-first rule and store ISO 8601. Never let a model infer the format.
  • Money. Record whether amounts include GST. A supplier quote and an invoice for the same job can differ by exactly 15% for that reason alone.
  • Repeated boilerplate. Headers, footers and confidentiality notices repeated on every page dominate retrieval if left in. Strip them before chunking.
  • Spreadsheets. Merged cells, hidden rows, formulas and multiple tables on one sheet do not survive naive text conversion. Extract each table with its header row repeated on every chunk, and record the sheet name and cell range as provenance.

Deduplication and versioning

Duplicates and superseded versions cause more wrong answers in business corpora than any model limitation. The same policy saved in three folders gets three times the retrieval weight; last year’s version of a pricing schedule answers questions as confidently as this year’s.

Deduplicate in two passes: exact matches on a normalised content hash, then near-duplicates by text similarity, keeping one canonical copy. Duplication also matters for evaluation. Research on deduplicating training data found train-test overlap affecting over 4% of the validation sets of standard datasets, which inflates measured performance. The same thing happens when an evaluation question is answered by a near-copy of a document used to write the prompt’s examples.

For versions, store an effective date and a status on every document, keep only current versions in the live corpus, and keep superseded versions in an archive that can be searched deliberately (“what did the policy say in 2024?”).

Personal information and purpose

Detect personal information before indexing, then mask, restrict or exclude it depending on whether the task needs it. Open-source tools such as Microsoft’s Presidio detect and redact common categories and accept custom recognisers. Add New Zealand patterns yourself: IRD numbers, NHI numbers, NZ driver licence numbers and bank account numbers in the 2-4-7-2 digit format.

Purpose matters as much as detection. Under the Privacy Act 2020, IPP10 limits using personal information for purposes other than the one it was collected for, and IPP9 limits how long it can be kept. Reusing years of customer emails to build an evaluation set can raise both questions. Our lesson on protecting customer information when using AI covers the practical steps, and building private AI search covers carrying source permissions into the index.

Evaluation and training sets need extra care

Evaluation data needs the same pipeline plus three rules:

  1. Split by time or entity. Hold out later months, or whole customers and suppliers, so near-identical cases do not appear on both sides of the split.
  2. Deduplicate across splits. Run the near-duplicate pass over training, development and test sets together.
  3. Document the dataset. Record motivation, composition, collection process and recommended uses, as proposed in Datasheets for Datasets, and version it with the system that uses it. See versioning prompts and evaluations.

Where real examples are scarce, generated ones can fill gaps, with limits covered in testing AI with synthetic data.

Where data preparation goes wrong

Failure Symptom in the AI system Detection
Scanned PDFs with no text layer “I could not find that” for documents that exist Text-per-page check at extraction
Tables flattened into prose Wrong numbers attributed to wrong rows Table detection rate; spot checks on table-heavy files
Superseded versions live Confident answers from last year’s policy Status and effective date required on every document
Duplicates One document dominates results Duplicate cluster report per snapshot
Encoding damage Missing macrons, garbled names Replacement character and normalisation checks
Personal information in logs Pipeline debug output stores raw text Scan logs with the same PII detectors
Silent connector failure Corpus stops growing; answers go stale Alert on snapshot diff size and last-modified dates

Retrieval quality is the downstream test of all of this; measure it as described in RAG retrieval evaluation. Document-heavy pipelines are the core of our AI document processing work.

  • Every source has an owner, a purpose and access rules recorded before ingestion
  • Extraction checks text per page and routes low-text documents to OCR or review
  • Text is normalised to Unicode NFC; dates are parsed day-first and stored as ISO 8601
  • Amounts record currency and whether GST is included
  • Exact and near-duplicates are removed, with one canonical copy kept
  • Every document has an effective date and status; superseded versions are excluded from the live corpus
  • Personal information detection includes New Zealand identifiers, with an action for each type
  • Every chunk carries source, version, page and section
  • Batches are gated on failure rate, and snapshots are versioned with a diff report
  • Evaluation sets are split by time or entity, deduplicated across splits and documented

Sources

  1. Unicode Normalization Forms (UAX #15), Unicode Consortium, 2026
  2. Deduplicating Training Data Makes Language Models Better, arXiv (Lee et al.), 2021
  3. Datasheets for Datasets, arXiv (Gebru et al.), 2018
  4. Presidio, GitHub (Microsoft), 2026
  5. Privacy Act 2020, New Zealand Legislation, 2020

Written by the Levy Street team in Wellington. Last updated 19 October 2026.

Questions people ask

What is data preparation for AI?

It is the work of getting source material into a state an AI system can use reliably: extracting text from documents, cleaning and standardising it, removing duplicates and outdated versions, protecting personal information, splitting it into retrievable pieces and recording where each piece came from. For language model systems it mostly concerns documents and emails rather than the tidy tables of classic machine learning.

Do we need clean data before starting an AI project?

No, but you need to know which mess matters. Start with one workflow, inventory the sources it depends on, and measure the problems that change answers: missing text, duplicates, superseded versions, unparseable dates. Fix those in the pipeline rather than by hand, so the fixes keep working as new documents arrive.

How should documents be chunked for retrieval?

Split along the document’s own structure, such as headings, clauses or table boundaries, rather than at fixed character counts, and keep each chunk’s title, section and page with it. Check the size distribution: very small chunks lose context and very large ones dilute relevance. Then measure retrieval quality on real questions, because the best settings depend on your documents.

Should personal information be removed before data goes to an AI model?

Remove or mask it whenever the task does not need it, and restrict it when it does. Detection tools find common patterns, but New Zealand identifiers such as IRD numbers, NHI numbers and bank account numbers need custom rules. Under the Privacy Act 2020, using information collected for one purpose to build AI datasets can raise purpose and retention questions, so check before you reuse it.

Building something that has to hold up?

We design, evaluate and run AI systems in production. Tell us what you are building and where it hurts.