Building an Extraction App: Resource, Deployments, and the Analyze Loop
Building an Extraction App: Resource, Deployments, and the Analyze Loop
The pieces you have to stand up
Reading about analyzers gives you the vocabulary; building something forces you to notice what else must exist. An extraction application needs four things in place before a single field comes back.
A Foundry resource, because Content Understanding is a Foundry Tool reached through it. Model deployments, because the generative work runs on models you own rather than on capacity the service hides from you. An analyzer, prebuilt or custom, stored under an identifier. And a client that can drive an asynchronous operation to completion.
Miss any one and the failure is confusing rather than obvious — a call that authenticates and then fails on a missing deployment reads like a bug until you know the architecture.
Bring your own models
Content Understanding uses your model deployments for every operation that needs a generative model. That is a deliberate design: it lets you concentrate provisioned capacity into fewer deployments and pick a model that suits your price and latency targets, and it means token consumption appears on your deployment alongside everything else.
There are two ways to tell the service which deployments to use. You can set defaults once at the resource level, mapping model names and aliases to deployment names, after which analyze requests need say nothing about models. Or you can pass the deployment mapping in each analyze request, which overrides any resource defaults and lets different requests use different deployments.
Prebuilt analyzers use aliases rather than concrete model names — a general completion alias, a lighter one used by the retrieval analyzers, and an embedding alias — and you map those aliases to your deployments. This indirection is what lets the service move prebuilt analyzers to newer models without editing every definition.
A useful diagnostic: you can query an analyzer and read back the set of models it supports, which saves guessing whether a model you want to use is compatible with the analyzer you chose.
The analyze loop
Analysis is asynchronous, and the pattern is the same one many Azure services use.
You post to the analyzer's analyze operation, naming the analyzer in the path and supplying input — typically a URL pointing at the file, or the bytes themselves for direct upload. The service accepts the request and returns a header pointing at a result location. You then poll that location until the status stops being not-started or running. On success, you get the result object: content objects carrying markdown, and the fields your schema asked for.
Polling every second or two is the documented rhythm. The language SDKs wrap this in a poller object so that application code reads as a single call, but the underlying interaction is unchanged, and understanding it is what lets you reason about timeouts, retries and long videos.
Two operational details ride along. The response carries a usage block reporting pages, audio and video hours, contextualisation tokens, and input and output tokens per model, which is how you correlate a spike in the bill with a specific workload. And when the safety layer on your model deployment blocks content, the response carries filter results instead of fields — a blocked completion returns an error, while annotated content passes through with severity metadata attached for you to act on.
Choose your API version deliberately
There are two versions in play, and choosing between them is an architectural decision rather than a preference. The generally available version is the one to build production on. The preview version carries the newer capabilities — agentic mode, in-page segmentation, signature and document metadata additions, improved training behaviour — without a service-level agreement.
The sane pattern is to pin the generally available version for the shipping path and to evaluate preview features on a separate analyzer, rather than to move a whole application onto preview for one capability.
Limits that shape the design
Two categories of limit matter early.
Throughput limits are per resource: a large ceiling on how many analyzers you may define, a per-minute ceiling on pages and images and on hours of audio and video, and a per-minute ceiling on operations. Batch workloads meet these before individual users do, so a queue in front of the service is normal.
Input limits differ between the synchronous and asynchronous paths, and the gap is wide. The asynchronous path takes files in the hundreds of megabytes and documents up to a few hundred pages; the synchronous path is capped at a few megabytes and a handful of pages, and it silently processes only the first few pages of a longer document unless you specify a page range. A prototype that worked on a five-page sample and mysteriously ignores half of a fifty-page file is usually this limit, not a schema problem.
Two portals, one service
Beyond code there are two web surfaces, and they are not the same thing. The Foundry portal is where Content Understanding sits among the rest of the platform, oriented towards building agentic workflows that use it as a tool. Content Understanding Studio is a complementary experience aimed at analyzer quality work — labelling data to improve custom analyzers and building classification-based ones.
For an exam scenario, the distinction usually reduces to intent: assembling an application that consumes extraction, or improving the analyzer that produces it.