Cloud / Google Cloud Document AI Interview questions
Last updated
1. What is Google Cloud Document AI?
Document AI is a Google Cloud service that turns unstructured and semi-structured documents, such as scans, PDFs, and photos, into structured data. You send a file to a processor and get back text, layout, and extracted fields as JSON.
It is built on top of Vertex AI with generative AI, so newer processor versions use foundation models rather than only classic OCR and template models. Typical uses are invoice capture, KYC onboarding, claims intake, and feeding clean text into search or RAG systems.
flowchart LR A["Scanned file or PDF"] --> B[Processor] B --> C["Document JSON: text, layout, entities"] C --> D["BigQuery, app, or search index"]
Take quiz
Only a cleaned-up copy of the original PDF
A list of Cloud Storage bucket permissions
Text, layout, and extracted fields in a Document JSON
A retrained model file you download and host yourself
Autoscaling a web tier during traffic spikes
Capturing supplier name and totals from scanned invoices
Streaming sensor readings into time-series storage
Transcribing live phone calls to text
2. What are the main processor categories in Document AI?
Document AI groups processors by the job they do: digitize, extract, and classify or split. Choosing the right category is the first design decision in any pipeline.
| Category | What it does | Examples |
| Digitize | Pulls text and layout out of pages | Enterprise Document OCR |
| Extract | Returns fields, tables, or structure | Form Parser, Layout Parser, Custom Extractor, Invoice Parser |
| Classify / split | Identifies document type or boundaries | Custom Classifier, Custom Splitter |
Every processor also returns text and layout, so extraction processors include the digitize step internally.
Take quiz
Invoice Parser
Form Parser
Layout Parser
Custom Classifier
Classify, using Custom Splitter
Extract, using Custom Extractor
Digitize, using Enterprise Document OCR
Split, using Layout Parser
3. What is a processor in Document AI?
A processor is the Document AI resource that does the actual work. It is created in a specific project and location, has a type such as OCR_PROCESSOR or FORM_PARSER_PROCESSOR, and exposes an endpoint you send documents to.
Its resource name looks like projects/{project}/locations/{location}/processors/{id}. A processor holds one or more processor versions, and requests go to the default version unless you target a specific one.
Think of it as a managed model endpoint that already knows how to read a certain kind of document.
Take quiz
Project, location, and processor ID
Cluster name, node pool, and zone
Dataset name, table name, and partition
Bucket name, object name, and generation
The processor's default version
A version chosen at random for load balancing
The oldest version that still exists
Always the newest release candidate
4. What is Enterprise Document OCR used for?
Enterprise Document OCR digitizes documents. It detects and extracts printed and handwritten text from scans and PDFs in more than 200 languages, and returns pages, blocks, paragraphs, lines, and tokens with bounding boxes.
It also scores each page for readability, which helps you spot blurry or skewed uploads early. Optional add-ons cover math formulas, font style, and checkbox detection.
Use it when you need clean text and coordinates but do not need named fields. Downstream code, search indexing, or an LLM can then work with that text.
Take quiz
A document type label only
Typed invoice fields mapped to a fixed schema
A signed contract with validated clauses
Text with page layout and bounding boxes
The Cloud Storage storage class
The per-page image quality score
The IAM role of the caller
The processor location setting
5. What is the Form Parser in Document AI?
The Form Parser is a general-purpose extractor that needs no training. It detects key-value pairs, tables, and checkboxes in forms and returns them along with the OCR text.
It works well for surveys, applications, and questionnaires where the printed labels are the field names. The keys come from whatever is on the page, so you do not define a schema.
If you need specific, consistently named fields, such as policy_number, a Custom Extractor is the better fit.
Take quiz
It asks the caller to pass a JSON schema per request
You must upload a labeled training set first
It reads the printed labels on the page as keys
It uses a fixed list of invoice fields
Cloud Storage object versions
Database foreign keys
Tables and checkboxes
Audio transcripts
Enterprise Document OCR
Custom Splitter
Form Parser
Custom Extractor
6. What is the Layout Parser in Document AI?
The Layout Parser reads the structure of a document: text blocks, tables, lists, titles, headings, and page headers or footers. It accepts HTML and PDF input.
Its standout feature is context-aware chunking. It splits a document into chunks that follow the heading hierarchy, so all text in a chunk comes from the same layout entity such as a heading or list.
That makes it a common first step for retrieval-augmented generation and enterprise search, where cutting text at arbitrary character counts hurts answer quality.
Take quiz
They are sorted alphabetically by first word
They contain only table cells
They follow the document's heading and layout hierarchy
They are always exactly 100 characters long
HTML and PDF
Only JPEG photos
Only CSV exports
Only audio files
7. What is a Custom Extractor in Document AI?
A Custom Extractor pulls fields you define from documents Google has no pretrained parser for, such as a company-specific purchase order or a lab report.
You create a schema of labels, then pick an approach: a generative AI version built on a foundation model (usable zero-shot, with few-shot examples, or fine-tuned), a custom model trained on labeled documents, or a template-based version for fixed layouts.
Every version is evaluated on a test set before you deploy it, and deployed versions can be set as the default for the processor.
Take quiz
When you want to rotate scanned pages
When you need to merge two PDFs
When no pretrained parser matches your document type
When you only need page-level OCR text
Use a generative AI foundation model, optionally fine-tuned
Write regex rules in the console only
Copy a version from the Invoice Parser
Upload a spreadsheet of expected totals
8. What are the pretrained specialized parsers in Document AI?
Specialized parsers are pretrained for a specific document type, so you can extract fields with no training. The documented set includes:
- Invoice Parser and Expense Parser for AP and receipts
- Bank Statement Parser, Pay Slip Parser, and W2 Parser for financial paperwork
- US Driver License, US Passport, and Identity Document Proofing parsers for identity checks
- Utility Parser for utility bills
They return typed entities such as invoice_id or total_amount with confidence scores. Availability differs by region, so check the processor list before designing around one.
Take quiz
Utility Parser
Pay Slip Parser
Invoice Parser
US Passport Parser
It extracts typed fields without any training on your side
It stores documents permanently in BigQuery
It removes the need for a Google Cloud project
It guarantees 100 percent accuracy on every layout
9. What is a Custom Classifier in Document AI?
A Custom Classifier looks at a document and decides which type it is, for example invoice, bank statement, or contract. The result comes back as an entity whose type is the predicted class, with a confidence score.
It is normally used as a router. Once a file is classified, your pipeline sends it to the matching extractor instead of running every extractor on every file.
You define the classes, supply labeled sample documents, train and evaluate a version, then deploy it. A generative AI foundation model can also back classifier versions.
Take quiz
The OCR language of each line
The bounding box of every word
The predicted document class with a confidence score
A merged multi-page PDF
To encrypt files before upload
To delete low quality scans automatically
To route each file to the right extractor
To resize images to a fixed width
10. What is a Custom Splitter in Document AI?
A Custom Splitter finds where one document ends and the next begins inside a single multi-page file, such as a scanned stack of loan paperwork.
It does not cut the PDF for you. It returns entities with page references that mark each sub-document, and your code uses those page ranges to split the file.
A common pattern is splitter first, then classifier on each piece, then the right extractor per class.
Accuracy depends on how distinct the first page of each document looks, so train it on samples that include the awkward cases: cover sheets, blank separator pages, and documents that start mid-stack.
Take quiz
Entities with page ranges marking each sub-document
Physically separated PDF files in a bucket
A list of duplicate pages to delete
A translated copy of every page
One scan that bundles several different documents
A CSV export of invoices
An HTML web page
A single-page receipt photo
11. What file types can Document AI process?
Document AI accepts common document and image formats: PDF, TIFF, GIF, JPEG, PNG, BMP, and WebP. Layout Parser additionally accepts HTML.
You must pass the correct mime_type with every request, for example application/pdf or image/png. A wrong or missing value is a frequent cause of INVALID_ARGUMENT errors.
Size also matters. Online requests are capped at 40 MB per file and batch requests at 1 GB, and each processor has its own page limits.
Take quiz
mime_type
output_bucket_class
processor_display_name
billing_account_id
No limit at all
40 MB
5 KB
1 GB
12. What is the Document object returned by Document AI?
The Document is the JSON (or protobuf) message every processor returns. It is the single container for everything the processor found.
| Field | What it holds |
text |
All recognized text as one string |
pages |
Per-page layout: blocks, paragraphs, lines, tokens, tables, form fields |
entities |
Extracted or classified items with type, value, and confidence |
shard_info |
Present when a large result is split across several files |
Positions in pages point back into text through text anchors, so you read text once and reference it by index.
Take quiz
In one top-level text string
In a separate image file per word
In Cloud Logging entries
Inside each entity only
shard_info
entities
mime_type
uri
13. What is an entity in Document AI output?
An entity is one extracted or classified item, such as an invoice date, a supplier name, or a document class. It lives in document.entities.
The useful properties are type_ (the field name), mention_text (text as printed), normalized_value (typed value for dates, money, or addresses), confidence, and page_anchor for location.
Some entities are nested. A line_item entity, for instance, carries child properties for description, quantity, and amount.
Always check that a property exists before reading it. A missing optional field simply produces no entity, so code that assumes every key is present will fail on real traffic.
Take quiz
shard_info
mention_text
type_
page_anchor
As a CSV attachment
As a plain string in the text field
As a separate Document per row
As a parent entity with child properties like description and amount
14. What is a confidence score in Document AI?
The confidence score is a value from 0 to 1 that tells you how sure the model is about an entity or a recognized element. Higher means more certain.
It is not a probability of being correct in a strict statistical sense, so treat it as a ranking signal and calibrate it against labeled samples from your own documents.
In practice you set thresholds per field. A document whose critical fields all clear the threshold flows straight through, and the rest go to a human review queue.
Take quiz
1 to 10
0 to 1
-1 to 1
0 to 255
Choosing the Cloud Storage region
Deciding which documents need human review
Compressing the output JSON
Selecting the OCR language automatically
15. How do you create a Document AI processor?
You can create one from the console or through the API. The console route is the quickest way to try things out.
- Enable the Document AI API (
documentai.googleapis.com) in your project. - Open Document AI and browse the processor gallery.
- Pick a processor type, name it, and choose a location such as
usoreu. - Copy the processor ID and use it in your
processrequests.
parent = client.common_location_path("my-project", "us") processor = client.create_processor( parent=parent, processor=documentai.Processor( display_name="invoice-prod", type_="INVOICE_PROCESSOR", ), ) print(processor.name)
Custom processors need extra steps afterward: dataset, labeling, training, and deployment.
Keep a separate processor ID for each environment, such as dev and prod, so test traffic never touches production versions or quotas.
Take quiz
A Compute Engine machine type
A VPC subnet range
A BigQuery table name
A location such as us or eu
Dataset, labeling, training, and deployment of a version
Nothing, it is ready immediately
Exporting the model to Cloud Run
Manual installation of Tesseract
16. How do you process a document with the Document AI Python client?
Create a DocumentProcessorServiceClient pointed at the endpoint for your processor's location, build the processor name, wrap the file bytes in a RawDocument, and call process_document.
from google.api_core.client_options import ClientOptions from google.cloud import documentai client = documentai.DocumentProcessorServiceClient( client_options=ClientOptions(api_endpoint="us-documentai.googleapis.com")) name = client.processor_path("my-project", "us", "PROCESSOR_ID") with open("invoice.pdf", "rb") as f: raw = documentai.RawDocument(content=f.read(), mime_type="application/pdf") result = client.process_document( request=documentai.ProcessRequest(name=name, raw_document=raw)) for e in result.document.entities: print(e.type_, e.mention_text, round(e.confidence, 2))
The endpoint prefix must match the processor location. A us processor called through the eu endpoint will fail.
For many files or very large ones, prefer batch processing instead, and wrap the call in retries for transient errors such as RESOURCE_EXHAUSTED. Reuse one client object across requests instead of creating a new one per file, and always read the document.error or exception details when a call fails, since they usually name the exact problem.
Take quiz
The Python version
The PDF file name
The API endpoint prefix
The Cloud Run service name
GcsPrefix
RawDocument
ProcessorVersion
BatchProcessRequest
17. What is a processor version in Document AI?
A processor version is a specific model release inside a processor. Pretrained versions have IDs like pretrained-layout-parser-v1.0-2024-06-03, while custom versions are ones you train or fine-tune.
A processor can hold several versions at once, and exactly one is the default. Calls to the processor use the default, and calls to the versioned resource name pin an exact version.
Versions have lifecycles. Older ones get deprecation dates, so production code should not assume a version lives forever.
Treat a version change like a code release. Evaluate it on a sample and then promote it, because even a minor model update can shift extracted values.
Take quiz
One per file type
Unlimited
Exactly one
One per caller
Change the Cloud Storage bucket
Rename the processor
Call the versioned resource name directly
Add a label to the PDF
18. What is the Document AI Toolbox?
The Document AI Toolbox is an open-source Python library that wraps the raw Document message in friendlier objects. It saves you from hand-rolling code for anchors, shards, and exports.
Common helpers include loading sharded batch output straight from Cloud Storage, searching pages for a string, reading entities and tables as plain Python objects, and exporting results to BigQuery. It also has helpers for splitting a PDF using splitter output.
Use it to cut boilerplate, but keep the raw Document JSON in storage as the source of truth.
Take quiz
Provisioning VPC networks
Training foundation models from scratch
Billing reports for all Google Cloud services
Handling raw Document output such as shards and anchors more easily
Changing the processor location
Creating IAM custom roles
Rebooting the processor
Loading sharded output JSON from Cloud Storage
19. What IAM roles control access to Document AI?
Document AI uses predefined roles that map to what a caller needs to do:
| Role | Typical use |
roles/documentai.apiUser |
Send documents to a processor |
roles/documentai.viewer |
Read processors, versions, and datasets |
roles/documentai.editor |
Create and manage processors, datasets, versions |
roles/documentai.admin |
Full control, including IAM-sensitive actions |
Give pipeline service accounts apiUser only, plus read and write access to the specific buckets. Keep editor and admin for people who build and train processors.
Storage permissions are separate from these roles. A batch job also needs read access to the input bucket and write access to the output bucket.
Take quiz
roles/documentai.apiUser
roles/documentai.admin
roles/documentai.editor
roles/owner
Anonymous callers
Every end user of the app
The production ingestion service account
Engineers who create and train processors
20. What is the difference between online and batch processing in Document AI?
Online processing is a synchronous call: you send one document and wait for the Document in the response. Batch processing is asynchronous: you point at files in Cloud Storage, get a long-running operation back, and results are written to an output bucket.
| Aspect | Online | Batch |
| Call style | Synchronous process_document |
Long-running batch_process_documents |
| Input | Bytes in the request | Cloud Storage files or prefix |
| Size cap | 40 MB per file | 1 GB per file |
| Output | Returned in the response | JSON written to Cloud Storage |
| Best for | User-facing, low-latency flows | Backlogs and scheduled loads |
Page limits per document are higher for batch and differ by processor, so check the limits page for the processor you use.
Take quiz
Directly in the HTTP response body
In a Cloud SQL table automatically
In an email attachment
As JSON files in a Cloud Storage output location
Online processing in a tight loop
Custom Splitter only
Form Parser with manual uploads
Batch processing
21. What is the difference between the Form Parser and a Custom Extractor?
The Form Parser is generic and schema-less. A Custom Extractor is schema-driven and returns exactly the fields you defined.
| Point | Form Parser | Custom Extractor |
| Setup | None, ready to use | Schema, samples, evaluation, deployment |
| Field names | Whatever labels print on the page | Names you choose, such as claim_id |
| Output shape | Key-value pairs and tables | Typed entities, nested if needed |
| Best for | Exploring unknown forms quickly | Stable pipelines that feed other systems |
A frequent path is to prototype with the Form Parser, then move to a Custom Extractor once downstream code needs fixed field names and types.
In practice many teams use both: online for the user waiting on a screen, and batch for everything that can wait.
Take quiz
Custom Splitter
Form Parser
Enterprise Document OCR
Custom Extractor
Form Parser only works in one region
Custom Extractor is free of evaluation steps
Downstream code needs fixed, typed field names
Form Parser cannot read PDFs
22. Which is better for a Custom Extractor: generative AI or a custom model?
It depends on how much labeled data you have and how varied your layouts are. Generative AI versions work from the first sample because the foundation model already understands documents. Custom model-based versions learn only from your labeled set.
| Factor | Generative AI | Custom model-based |
| Data needed | None for zero-shot, a few for few-shot or fine-tuning | Labeled training and test sets, around 10 per label at minimum |
| Layout variety | Handles unseen layouts well | Best when layouts are consistent |
| Foundation model dependence | Base versions are retired over time | Your trained version is independent of foundation releases |
A sensible default is to start with generative AI, measure on a test set, and fine-tune. Choose a custom model if you have lots of consistent, labeled documents and want predictable behavior.
Take quiz
Splitter retraining
Template-based extraction
Generative AI zero-shot
Custom model-based training
You only need OCR text
You have no samples at all
Every layout is completely different
You have many consistent, labeled documents
23. How do text anchors link entities and layout to the document text?
Document AI stores all recognized text once in document.text. Every other element, whether a token, line, table cell, or entity, points into that string through a text_anchor.
A text anchor holds one or more text_segments, each with a start_index and end_index. To read an element's text you slice document.text between those indexes and join the segments.
def layout_text(layout, text): return "".join( text[int(s.start_index):int(s.end_index)] for s in layout.text_anchor.text_segments ).strip()
This design avoids duplicating text per element, and it means a single entity can cover several disjoint pieces of text.
Whichever you pick, evaluate both on the same test set so the comparison is fair, and look at latency and cost as well as F1.
Take quiz
page_number and column
left and right margin
x_min and y_min
start_index and end_index
To force the use of batch mode
Because pages cannot hold text
To keep entities from having confidence
Elements reference it by index instead of duplicating it
24. How do you read table data from a Document AI response?
Tables live under each page as page.tables. A table has header_rows and body_rows, each made of cells, and every cell has a layout whose text anchor points into document.text.
def cell_text(cell, text): return "".join( text[int(s.start_index):int(s.end_index)] for s in cell.layout.text_anchor.text_segments).strip() doc = result.document for page in doc.pages: for table in page.tables: header = [cell_text(c, doc.text) for c in table.header_rows[0].cells] rows = [[cell_text(c, doc.text) for c in r.cells] for r in table.body_rows] print(header, rows)
Guard against tables with no header row. Also remember that a table split across pages arrives as separate table objects that you may need to stitch together.
The same mechanism applies to entities, so mention_text is only a convenience copy of what the anchor points to. When an entity wraps across lines, expect several segments rather than one. That is why you should never search the final text for a value and guess its position. Follow the anchor and the geometry stays correct.
Take quiz
In the top-level mime_type
In page.tables, split into header_rows and body_rows
In shard_info
In the uri field
One combined table object always
Duplicate entities for every cell
Separate table objects per page that may need merging
No table output at all
25. How do you run a batch processing job from Cloud Storage?
Build a BatchProcessRequest with an input location, either a prefix or an explicit list of files, and an output Cloud Storage path. The call returns a long-running operation you wait on or poll.
input_cfg = documentai.BatchDocumentsInputConfig( gcs_prefix=documentai.GcsPrefix(gcs_uri_prefix="gs://my-bucket/incoming/")) output_cfg = documentai.DocumentOutputConfig( gcs_output_config=documentai.DocumentOutputConfig.GcsOutputConfig( gcs_uri="gs://my-bucket/results/")) op = client.batch_process_documents( request=documentai.BatchProcessRequest( name=name, input_documents=input_cfg, document_output_config=output_cfg)) op.result(timeout=3600)
Make sure the identity running the job can read the input bucket and write the output bucket. When the operation finishes, read the metadata for per-file status, because one bad file does not fail the whole batch.
Use the Form Parser or a Custom Extractor with child labels when you need meaningful columns such as quantity or unit price. Raw OCR tables only give you positional cells.
Take quiz
The extracted fields directly
A long-running operation
A new processor version
A signed URL to the PDF
The processor display name
The operation metadata with per-document status
The IAM policy of the project
The Cloud Storage storage class
26. How do the Enterprise Document OCR add-ons improve results?
Enterprise Document OCR has optional features you switch on through OcrConfig. Each one adds data to the output, and each can affect cost, so enable only what you read downstream.
- Image quality scores flag blurry, noisy, or skewed pages.
- Selection mark detection reports checkbox and radio states.
- Font style info returns bold, italic, and size, useful for spotting headings.
- Math OCR recognizes formulas as LaTeX.
- Native PDF parsing reads embedded text directly instead of OCRing it.
opts = documentai.ProcessOptions(ocr_config=documentai.OcrConfig( enable_native_pdf_parsing=True, enable_image_quality_scores=True, premium_features=documentai.OcrConfig.PremiumFeatures( enable_selection_mark_detection=True, compute_style_info=True)))
Pass opts as process_options on the request.
Use a prefix to process a whole folder, and an explicit file list when only certain files should run. Give each run a unique output prefix, such as a date or run ID, so results from different jobs never mix.
Take quiz
Image quality scores
Selection mark detection
Math OCR
Native PDF parsing
Splits the PDF by document type
Converts PDFs into JPEG
Encrypts the PDF
Reads embedded PDF text directly instead of OCRing it
27. How do you define a schema for a Custom Extractor?
The schema is the list of labels the extractor must return. Each label has a name, a data type, and an occurrence.
- Data type: plain text, number, money, datetime, address, or checkbox. Typed labels populate
normalized_value. - Occurrence: required once, optional once, required multiple, or optional multiple.
- Parent and child labels: use a parent such as
line_itemwith children for description, quantity, and amount to capture repeating rows.
Keep names snake_case and unambiguous. Avoid two labels that could both match the same text, such as date and invoice_date, because the labeling noise hurts accuracy. Start with the fields you actually use downstream and add more later.
Take quiz
A second processor per row
A larger confidence threshold
A bigger Cloud Storage bucket
A parent label with child labels
Labels must all be plain text
Only one label is allowed per page
Datetime labels are not supported
They can match the same text and make labeling inconsistent
28. How do you evaluate a processor version in Document AI?
Evaluation runs a version against a test set of labeled documents that were kept out of training. The result reports precision, recall, and F1, overall and per label.
Read the per-label numbers rather than only the headline F1. A strong overall score can hide a weak label such as tax_id. You can also move the confidence threshold to see how precision and recall trade off, and compare two versions side by side before promoting one.
Toggle fuzzy matching only when small formatting differences, such as spacing or punctuation, are acceptable in your downstream use. The same evaluation is available through the API with evaluate_processor_version.
Take quiz
Labels are evaluated in different regions
Per-label results are free but overall results are billed
Overall F1 is never produced
A good overall F1 can hide one weak label
A labeled test set held out from training
Only the first page of each file
The same documents used for training
Unlabeled production scans
29. When should you use Layout Parser instead of Enterprise Document OCR?
Use Layout Parser when the structure of the document matters, not just its characters. It identifies headings, lists, tables, and paragraphs and can chunk by that hierarchy.
Use Enterprise Document OCR when you want faithful text and word-level geometry, such as for highlighting, redaction, or feeding your own post-processing.
| Need | Better choice |
| Chunks for RAG or search | Layout Parser |
| Heading hierarchy of HTML or PDF | Layout Parser |
| Handwriting and checkbox detection | Enterprise Document OCR |
| Token boxes for redaction | Enterprise Document OCR |
Rerun the evaluation after every change to the schema or the test set, because scores from earlier runs are no longer comparable.
Take quiz
Passport Parser
Layout Parser
Custom Splitter
Enterprise Document OCR alone
Word-level boxes for redaction
Splitting a bundle
Classifying a file type
Heading-aware chunking
30. How does Layout Parser chunking support RAG pipelines?
Layout Parser produces chunks that respect the document's structure, so each chunk comes from one layout entity such as a section or list. That keeps related sentences together, which improves what an embedding captures.
With include_ancestor_headings on, each chunk also carries the headings above it. A paragraph under Refund policy then still says it belongs to that section, even when retrieved alone.
opts = documentai.ProcessOptions( layout_config=documentai.ProcessOptions.LayoutConfig( chunking_config=documentai.ProcessOptions.LayoutConfig.ChunkingConfig( chunk_size=500, include_ancestor_headings=True)))
flowchart LR A["PDF or HTML"] --> B["Layout Parser"] B --> C["Chunks with headings"] C --> D["Embedding model"] D --> E["Vector index"] E --> F["Retrieval for the LLM"]
The two also combine well. Some teams use OCR for geometry-heavy tasks and Layout Parser for the structured copy used in retrieval. A quick test is to ask what the next step consumes: raw characters and boxes point to OCR, while sections and headings point to Layout Parser.
Take quiz
A summary written by an LLM
The headings above the chunk's text
The page image as base64
The original file's checksum
They remove all tables
Related text stays together in one chunk
They avoid the need for embeddings
They shrink every chunk to one word
31. How do you choose confidence thresholds for auto-approval?
Set thresholds per field, based on the cost of a wrong value, and calibrate them on labeled samples from your own documents.
- Run a representative labeled sample through the processor.
- For each field, plot precision against confidence threshold.
- Pick the lowest threshold that meets your error budget for that field.
- Decide document pass or fail from the critical fields, not the average.
| Field | Risk if wrong | Example policy |
total_amount |
Payment error | Strict threshold, plus totals check |
invoice_date |
Late-fee confusion | Moderate threshold |
notes |
Low | Accept as is |
Track the straight-through rate and the error rate after launch, and revisit thresholds when document mix changes.
Take quiz
On file size
On the upload time
On the average confidence of every token
On the critical fields' confidence
Page count against file size
Precision against confidence threshold on labeled samples
Cost against region
Latency against bucket name
32. When would you choose a classifier plus a splitter in one pipeline?
Use both when incoming files are a mix of unknown types and some are bundles. The splitter first cuts a scanned stack into logical documents by page range. The classifier then labels each piece, and the label picks the extractor.
If every upload is a single document of unknown type, you only need the classifier. If every upload is a bundle of known types, the splitter alone may be enough, because its output labels can already hint at the document type.
Add a fallback route for low-confidence classes, such as a manual queue, so a wrongly routed document does not produce confident but wrong fields.
Take quiz
Encrypts each page
Chooses the Cloud Storage bucket
Finds page ranges of the logical documents
Extracts invoice totals
Every file is already classified
Every file is a bundle of 40 documents
No files have text
Each file is a single document of unknown type
33. How do you handle normalized values for dates and money in Document AI?
Typed entities carry a normalized_value next to the printed mention_text. Use the normalized value for logic and keep the mention text for audit and display.
for e in doc.entities: nv = e.normalized_value if e.type_ == "total_amount" and nv.money_value.currency_code: m = nv.money_value print(m.currency_code, m.units + m.nanos / 1e9) elif e.type_ == "invoice_date" and nv.date_value.year: d = nv.date_value print(f"{d.year}-{d.month:02d}-{d.day:02d}")
Money is split into units and nanos, so combine them carefully, ideally with Decimal. Ambiguous dates like 03/04/2026 depend on the parser's reading, so validate them against business rules.
Measure each router stage separately. A splitter that cuts a page too early can look like a classifier failure later, which makes debugging confusing. Also keep the routing thresholds in configuration, not code, so you can tighten them without a redeploy when misroutes appear.
Take quiz
shard_info
mention_text
page_anchor
normalized_value
As currency_code plus units and nanos
As a single float string only
As a currency symbol glyph
As a base64 image
34. How do you pin and deploy processor versions safely in production?
Pretrained processors serve the default version, and calling the versioned resource name pins a specific one. Custom versions follow a train, evaluate, deploy, then set-default flow.
- Train or fine-tune a new version and evaluate it on the test set.
- Deploy it and send staging traffic by calling its version name directly.
- Compare outputs against the current default on real samples.
- Set it as default only after it clears your acceptance bar.
- Keep the previous version deployed until you are sure you can roll back.
Watch the deprecation list. Versions have shutdown dates, and a pinned version that retires will start to fail. Undeploy test versions you no longer need, since deployed custom versions can add hosting cost.
Take quiz
Rename the processor
Call its version name from staging before making it default
Delete the old version first
Change the OCR language
To double the confidence score
To avoid billing entirely
So you can roll back by setting it as default again
Because only two versions are allowed
35. Why does the processor location matter in Document AI?
A processor is a regional resource. Documents are processed and data is stored in the location you pick, which matters for data residency and compliance.
The multi-region locations are us and eu. A handful of single regions, such as europe-west2 or asia-south1, have limited support and need an access request. Not every processor version exists in every location.
You cannot move a processor later. Changing location means recreating it and, for custom processors, re-importing the dataset and retraining. Call the matching endpoint, such as eu-documentai.googleapis.com, and keep Cloud Storage buckets in the same geography to avoid latency and egress surprises.
Take quiz
us and eu
asia and africa
global and local
uk and ca
Running a rename command
Creating a new processor in the new location
Editing its display name
Nothing, location is a label
36. How do you add human review now that HITL is deprecated?
Document AI Human-in-the-Loop and Document AI Warehouse were deprecated on January 16, 2024, with shutdown scheduled for January 16, 2025. Human review is now something you build around the processor, or get from a partner.
- Auto-approve documents whose critical fields clear their confidence thresholds.
- Send the rest to a review queue, for example Pub/Sub plus Firestore.
- Show the original page in a small review UI and draw boxes from each entity's
page_anchor. - Store the corrected values with the reviewer and timestamp.
Feed the corrected documents back into your training or test dataset. That is how a custom processor improves over time on the layouts that actually fail.
Take quiz
Use the output bucket name
Use the processor ID
Use the entity's page_anchor bounding box
Use the file's MIME type
Into the Cloud Billing export
Into the VPC flow logs
Into IAM policy bindings
Back into the training or test dataset
37. How can you reduce Document AI processing cost?
Document AI bills mainly per page processed, and rates differ by processor, so cost control starts with sending fewer and cheaper pages.
- Use Enterprise Document OCR when text is enough, rather than a specialized parser.
- Select only needed pages with the page selector, for example just the first pages for classification.
- Turn on only the OCR add-ons you really use.
- Cache results in Cloud Storage keyed by a file hash so identical files are not reprocessed.
- Undeploy unused custom versions, since deployed versions can add hosting cost.
- Prefilter obvious junk, such as blank or unreadable pages, before sending.
Check the current pricing page for exact rates, since they change.
Take quiz
Cache results keyed by a file hash
Rename the file before upload
Switch the processor location
Increase the confidence threshold
Deployment locks the schema
Only deployed versions can be evaluated
Undeployed versions score higher
Deployed versions can add hosting cost
38. How does Document AI deal with handwriting and low-quality scans?
Enterprise Document OCR recognizes handwritten text as well as print, and it returns a quality assessment per page so you can see when input is poor. Handwriting accuracy still drops with messy writing, low resolution, and heavy skew.
Use the image quality scores to branch: pass good pages through, and send poor ones to a re-scan request or a review queue. Per-token confidence helps you target the specific words that are shaky.
Improve inputs when you can. Scan at a reasonable resolution, avoid shadows, and keep pages upright. Cleaning images upstream is usually cheaper than fixing wrong extractions later.
Measure cost per successfully processed document, not only per page, since reprocessing and review time add up.
Take quiz
The processor ID
The MIME type string
The output bucket path
The per-page image quality score
Using batch mode
Using the us location
Having too many IAM roles
Low resolution, skew, and messy writing
39. Explain the execution flow of an event-driven Document AI pipeline?
A common design reacts to file uploads instead of polling. The flow is fully asynchronous, so a slow document never blocks the next one.
flowchart TD
A["File lands in GCS inbox"] --> B["Eventarc trigger"]
B --> C["Cloud Run service"]
C --> D{Small file?}
D -- Yes --> E["Online process_document"]
D -- No --> F["Batch process with LRO"]
E --> G["Save Document JSON to GCS"]
F --> G
G --> H["Publish processed message to Pub/Sub"]
H --> I["Validation service"]
I --> J{Critical fields pass?}
J -- Yes --> K["Write to BigQuery or ERP"]
J -- No --> L["Review queue"]
- The upload fires a Cloud Storage event, and Eventarc invokes a Cloud Run service.
- The service picks online or batch mode by file size and page count.
- The raw Document JSON is written to Cloud Storage before anything else, so the result can be replayed.
- A Pub/Sub message triggers validation, which either loads the data or opens a review task.
Make every step idempotent, for example by keying on the file hash, because Eventarc and Pub/Sub deliver at least once.
Add a dead-letter topic for failed messages so one poison file cannot block the queue, and alert on its size for early warning.
Take quiz
Because Pub/Sub cannot carry text
To make confidence scores larger
To skip IAM checks
So results can be replayed or re-validated without reprocessing
Document AI only runs once per day
Cloud Run cannot scale
Event and message delivery can repeat
BigQuery rejects all duplicates silently
File size and page count
The color of the PDF
The file's last modified time
The caller's email domain
40. How does batch output sharding work in Document AI?
Large batch results are not always one file. Document AI can write a single processed document as several shards, each a Document JSON, under the output prefix grouped by operation.
Each shard has shard_info with a shard_index, a shard_count, and a text_offset. Those values let you sort shards, confirm none are missing, and stitch text and entities back together.
flowchart LR A[batch_process_documents] --> B["Long-running operation"] B --> C["Shards written to GCS output prefix"] C --> D["List and sort by shard_index"] D --> E["Check shard_count is complete"] E --> F["Merge text and entities"] F --> G["Downstream load"]
Do not assume the file name order is the page order. Use the Toolbox to load shards directly from Cloud Storage, and always verify the count before treating a document as complete.
When you merge shards, apply the text offset so anchors still point at the right characters. Also keep the shard list with the operation ID in your logs. If a read fails halfway, you can resume from the same set instead of rerunning the batch.
Take quiz
bucket class and region
shard_index, shard_count, and text_offset
display_name and state
uri, mime_type, and revisions
That file names are alphabetical
That the output bucket is empty
That all shard_count shards are present
That every shard has the same size
41. How do you troubleshoot low extraction accuracy on a Custom Extractor?
Start with evidence, not guesses. Open the evaluation, find the weak labels, and separate misses from wrong values.
| Symptom | Likely cause | Fix |
| Field missing on some layouts | Layout not in training data | Add labeled samples of that layout, or use few-shot or fine-tuning |
| Wrong text picked | Overlapping labels or inconsistent labeling | Merge or rename labels, relabel consistently |
| Garbled values | Poor OCR input | Check image quality scores, fix scanning, deskew |
| Great on test, bad in production | Test set not representative | Rebuild the test set from real traffic |
Check the OCR output first, since extraction cannot beat bad text. Then look at schema ambiguity, label counts per field, and whether test and production documents match. Add post-processing rules, such as format checks, for fields that remain fragile.
Take quiz
Image quality scores and OCR text
The processor's IAM bindings
The output bucket's region
The Pub/Sub topic retention
The test set does not reflect real traffic
Evaluation always lies
Confidence scores are disabled
The processor is in the wrong project
42. How do you handle quota errors and retries with Document AI?
When you exceed a quota, Document AI returns 429 RESOURCE_EXHAUSTED. Treat it, along with 503 UNAVAILABLE and deadline errors, as retryable using exponential backoff with jitter.
from google.api_core import exceptions, retry r = retry.Retry( predicate=retry.if_exception_type( exceptions.ResourceExhausted, exceptions.ServiceUnavailable, exceptions.DeadlineExceeded), initial=1.0, maximum=60.0, multiplier=2.0, timeout=300) result = client.process_document(request=req, retry=r, timeout=120)
Retries alone do not fix sustained overload. Limit concurrency with Cloud Tasks or Pub/Sub flow control, move bulk work to batch processing, and request a quota increase when your steady load is legitimately higher. Do not retry INVALID_ARGUMENT, since the same request will fail again.
Log the request ID and error code on every retry so you can tell a short blip from a quota that needs raising, and cap the attempts so a failing document does not retry forever. Alerts on the rate of 429 responses give you an early signal that traffic has outgrown the current quota before users notice delays.
Take quiz
429 RESOURCE_EXHAUSTED
404 NOT_FOUND
400 INVALID_ARGUMENT
401 UNAUTHENTICATED
INVALID_ARGUMENT
UNAVAILABLE
DEADLINE_EXCEEDED
RESOURCE_EXHAUSTED
Concurrency limits via Cloud Tasks or Pub/Sub flow control
Larger PDF files
More IAM roles
A different file extension
43. How would you design a multi-document-type intake pipeline on Document AI?
The aim is to accept any upload and still run only the extractor that fits. Use the splitter and classifier as routers, and keep a human fallback for anything uncertain.
flowchart TD
A[Upload] --> B["Custom Splitter"]
B --> C["Sub-documents by page range"]
C --> D["Custom Classifier"]
D --> E{Class and confidence}
E -- Invoice --> F["Invoice Parser"]
E -- Bank statement --> G["Bank Statement Parser"]
E -- Contract --> H["Custom Extractor"]
E -- Low confidence --> I["Manual queue"]
F --> J[Validation]
G --> J
H --> J
Store the original file, the split ranges, the class, and the extractor result together under one case ID so any step can be audited. Version the routing table in code, so adding a new document type is one extractor plus one route, not a rewrite.
Test each route with a deliberately misclassified sample. Wrong classification is the hardest failure to notice, because the wrong extractor still returns plausible-looking fields. Keep the routing table small and explicit, with one owner per route, so a new document type does not quietly change how an existing one is handled.
Take quiz
It is sent to every extractor
It is deleted
It goes to a manual queue
It is merged into the previous file
To audit and replay each step later
To skip validation
To disable the splitter
To reduce OCR cost to zero
44. How do you secure Document AI for sensitive documents?
Security is layered, since documents often hold personal and financial data. Treat the extracted JSON as sensitive as the source file.
| Layer | Control |
| Identity | Least-privilege service accounts, apiUser for callers, editor only for builders |
| Network | VPC Service Controls perimeters around Document AI and Cloud Storage |
| Encryption | Customer-managed encryption keys where required |
| Residency | Processor location set to eu or another required geography |
| Data minimization | Delete raw files and JSON on a retention schedule, redact unneeded fields |
| Audit | Cloud Audit Logs, plus your own access logs for review tools |
Review Google's data processing terms for your use. Also remember that review UIs and logs can leak data, so never log full entity values for sensitive fields.
Run periodic access reviews on service accounts and buckets, since pipelines tend to collect extra permissions over time.
Take quiz
Cloud CDN
Cloud NAT
Cloud Scheduler
VPC Service Controls
The API version in the URL
The processor display name
The OCR language hint
Logs and review tools showing full field values
45. How do you fine-tune a generative AI Custom Extractor?
Fine-tuning adapts a foundation model version to your layouts and labeling conventions. It usually follows a zero-shot baseline, so you know what the tuning actually bought you.
- Define the schema and import a representative document set.
- Auto-label with the foundation model, then correct the labels by hand.
- Split into training and test sets, keeping the test set untouched.
- Fine-tune to produce a new version of type Generative AI.
- Evaluate it against the zero-shot baseline, per label.
- Deploy and set as default only if it wins on the labels you care about.
Plan for upkeep. Base foundation versions have deprecation dates, so keep your labeled dataset and be ready to re-tune on a newer base when needed.
Keep a small frozen validation set that is never used while labeling, so later version comparisons stay honest.
Take quiz
To skip evaluation later
To see what the tuning actually improved
Because fine-tuning needs no data
To avoid creating a new version
Base versions retire, so you may need to re-tune
IAM requires it
Datasets are required to call online mode
It makes confidence always 1.0
46. How do you export Document AI results to BigQuery?
Flatten each Document into one row per document, with repeating items such as line items in an ARRAY<STRUCT> column. Keep the raw JSON in Cloud Storage and store its URI in the row.
rows = [{ "doc_id": file_hash, "gcs_uri": json_uri, "processor_version": version_name, "invoice_id": get("invoice_id"), "total_amount": float(total), "currency": cur, "line_items": [{"description": d, "amount": float(a)} for d, a in items], }] bq.load_table_from_json(rows, "proj.ds.invoices").result()
Use load jobs rather than streaming for large volumes, and partition by processing date. The Toolbox also has an entities_to_bigquery helper for simple cases. Record the processor version so you can explain a value later or reprocess one version's output.
Keep a second table for low-confidence or failed documents so analysts can see data quality without opening raw JSON. For dashboards, expose a view that unnests line items and joins the confidence columns, so analysts do not need to know the storage layout. Partition by processing date and cluster by supplier to keep those queries cheap.
Take quiz
As a single comma-joined string only
As separate PDFs
As a Cloud Storage lifecycle rule
As an ARRAY of STRUCT in the document row
To reduce BigQuery storage to zero
To trace and reprocess a value from its source
To avoid partitioning
To skip loading jobs
47. Why might entity bounding boxes not line up with the rendered page?
Usually it is a coordinate mismatch, not a wrong extraction. Document AI gives positions as normalized_vertices, values from 0 to 1 relative to page width and height, and also as pixel vertices.
Common causes:
- Multiplying normalized values by the wrong image size, such as a thumbnail instead of the page dimensions.
- Drawing on a rotated or deskewed page while using the original orientation.
- Ignoring PDF page boxes or user units when rendering with a different library.
- Using only the first page reference for an entity that spans pages.
Fix it by reading page.dimension and any transforms, scaling normalized values by your rendered pixel size, and drawing per page_ref. Test with a rotated sample page, because that case breaks most overlays.
Take quiz
0 to 1 relative to page width and height
Absolute millimeters
0 to 255 per channel
Byte offsets in the text
Use only the first page
Merge the pages into one image
Draw boxes per page reference
Skip the entity
48. How do you process documents that exceed processor page limits?
Each processor has its own page limits, and online mode is stricter than batch. If a file is over the limit, process it in parts and merge the results.
- Prefer batch mode first, since its page limits are higher.
- If still over, split the file into page ranges with a PDF library, or use the page selector in
ProcessOptions. - Process parts in parallel and keep each part's starting page.
- Add the offset to page numbers and text indexes when merging.
- Keep logical documents together, for example a table that crosses a split point.
from pypdf import PdfReader, PdfWriter def parts(path, size): r = PdfReader(path) for start in range(0, len(r.pages), size): w = PdfWriter() for i in range(start, min(start + size, len(r.pages))): w.add_page(r.pages[i]) yield start, w
Overlap parts by a page or two if a heading or table may straddle the boundary, then deduplicate the overlap.
Test the merge logic with a table that crosses a split point, because that is where most bugs show up.
Take quiz
Its font size
Its MIME subtype
Its starting page offset
Its IAM principal
Splitter only
Form Parser only
Online with smaller fonts
Batch, because its page limits are higher
49. How would you combine Document AI with Gemini or another LLM?
Use each for what it does best. Document AI gives reliable text, layout, and typed fields with confidence and locations. An LLM, such as Gemini on Vertex AI, is better at summarizing, reasoning across sections, and answering open questions.
- Fields first: take amounts, dates, and IDs from Document AI entities, not from the LLM.
- Grounded prompts: pass Layout Parser chunks, with headings, as context for questions and summaries.
- Verification: check any quoted value from the LLM against the document text through text anchors.
- Escalation: send disagreements between the two to human review.
This keeps numbers auditable and limits hallucination. It also makes cost easier to control, since the LLM only sees the chunks it needs.
Log both the Document AI value and the LLM output whenever they disagree. That log becomes a ready source of hard examples for later tuning.
Take quiz
The LLM's free-form guess
The file name
Document AI entities with confidence
A random chunk
Raise the batch size
Verify quoted values against the document text
Use shorter file names
Disable OCR
50. Explain how to validate extracted invoice data before posting it to ERP?
Never post straight from the model. Run business checks that catch both extraction errors and genuine invoice problems.
| Check | What it catches | On failure |
| Required fields present | Missed invoice_id or total_amount |
Review |
| Confidence on critical fields | Shaky reads | Review |
Sum of line_item/amount vs net_amount |
Missed or misread line | Review |
Net plus tax vs total_amount |
Wrong total | Review |
| Duplicate key: supplier, invoice ID, amount | Double payment | Reject or flag |
| Supplier match by tax ID or vendor master | Unknown supplier | Review |
| PO match | Unapproved spend | Hold |
flowchart LR
A["Parsed invoice"] --> B["Field and confidence checks"]
B --> C["Totals reconciliation"]
C --> D["Duplicate and vendor checks"]
D --> E{All pass?}
E -- Yes --> F["Post to ERP"]
E -- No --> G["Review queue with reasons"]
Compare money with a small tolerance for rounding, and log which rule fired so reviewers can fix the right field fast.
Store the rule results with the invoice so auditors can see why it was approved or held, and tune the rounding tolerance per currency, since some currencies have no minor units.