Domain 4 of 5 · Chapter 1 of 2

Language model text analysis: extraction, sentiment, and translation

Three engines read the same paragraph

Pick the engine by the shape of the answer you need, not by how hard the text looks.

A support email arrives: "Our Contoso Brew 300 stopped heating on 14 March. Karin Weber has called 555-0176 twice and is losing patience." Three different useful things can come out of that one paragraph. A list of the named things in it, each with the exact character position where it appeared. A record with your own columns filled in: product, fault, severity, promised remedy. Or the same email in German for the regional desk. On Azure those are three engines, not three prompts to one model.

The three engines

Azure AI Language prebuilt tasks. Azure AI Language[1] exposes a set of ready-trained text tasks through one runtime endpoint. Each task has a published label set you cannot extend and a fixed response shape you can code against: entity recognition, entity linking, key phrase extraction, sensitive-information detection, sentiment analysis, and summarization, among others. You send documents and a task kind; you get that task's response object back.

A Foundry chat model with structured outputs. When the categories you need are not in anybody's published list, the extraction moves to a model in Microsoft Foundry and the guarantee moves into the request. Structured outputs[2] let you attach a JSON Schema to a chat completion so the reply comes back in the shape you declared. Your taxonomy, your field names, your enum values.

Azure Translator. Azure Translator[3] does one thing: it takes text in one language and returns it in another. It does not classify, summarize, or extract, and the controls that decide whether its output is usable are request parameters rather than prompt wording.

A naming note before we go further. Current Microsoft Learn product-doc titles render these as "Azure Language in Foundry Tools" and "Azure Translator in Foundry Tools", part of the consolidation into Microsoft Foundry. Azure AI Language and Azure Translator are the same services under their established names, and this page uses those names throughout.

What this page owns

Everything here starts once the text already exists as characters. The sibling page on speech solutions owns anything that arrives as, or leaves as, audio, which includes spoken translation. The document content extraction page owns getting text and layout out of a PDF, a scanned form, or a Word file in the first place. An email body, a chat transcript that is already text, a product review, a contract clause pasted into a field: those are this page.

Figure 1 below traces one input through all three engines and shows what each hands back. Read it left to right and notice that the difference is never how clever the engine is; it is what the response object contains.

So the selection question is mechanical. Does a published label set already describe what you need, and do you want offsets? Take the prebuilt task. Do you need field names and enum values that only exist in your domain? Take a model with a strict schema. Is the job language to language on text? Take Translator.

Your textalready charactersAzure AI Languageprebuilt analyze-text taskFoundry chat modelprompt plus JSON SchemaAzure Translatortranslate or document APIPublished labelsfixed response shape, character offsetsYour declared fieldsJSON that matches the schema you sentThe same text, another languagestrings, or whole files with layout keptOne input, three output shapes. The shape the application needs is what picks the engine.
Figure 1: one input, three engines, three output shapes.

What each prebuilt extraction task returns

Choosing among the prebuilt extraction tasks is choosing what the response object contains. Four tasks compete for the same-sounding requirement "pull the important things out of this text", and they return four different things.

Named entity recognition

Named entity recognition[4], usually written NER, identifies mentions in text and types each one against a preset category and subcategory list: Person, Location, Organization, Quantity, DateTime and others. Every returned mention carries an offset (where it starts), a length, and a confidenceScore. Those three fields are the reason NER is the right task whenever something downstream has to highlight, crop, mask, or index the exact span rather than merely know a name was present.

Entity linking

Entity linking[5] is a separate task, not a NER option. It resolves an ambiguous mention to a single knowledge-base entry and returns that entry's reference URL. The predictable misread is worth killing on sight: NER alone never returns a knowledge-base identifier. If the requirement is deciding whether "Mars" in a document means the planet or the confectionery company, NER will tell you it is an entity and entity linking will tell you which one.

Key phrase extraction

Key phrase extraction[6] surfaces the main talking points of a document as a flat list of phrases. No entity category, no character offset, no relevance ranking. That makes it a good cheap signal for tag clouds, coarse topic routing, and "what is this document about" dashboards, and a poor fit the moment a consumer needs the type of a value or the place it appeared. Populating form fields, driving redaction, and filtering a search facet all need type or position, so they belong to entity recognition or to schema-driven generative extraction.

Custom named entity recognition

When your domain has entity types the preset list does not carry, part numbers in a specific format, internal case identifiers, clause types in a contract, custom NER[7] adds them. The cost is a project lifecycle rather than a parameter: an authoring project holding human-labeled documents, a training run over those labels, and an explicit deployment that exposes a runtime prediction endpoint you then call. Prebuilt entity recognition requires none of that; you call the runtime immediately with the entity recognition task kind. There is no configuration-only or prompt-only shortcut that adds a new type to the prebuilt model.

Figure 2 below puts one sentence through all four tasks so the four response shapes sit side by side. The published category list shown there is a sample of the preset categories rather than the whole list, which is long and differs by input language.

The takeaway is a two-question filter. Does the consumer need to know where the value was, or which real-world thing it is? That rules key phrase extraction out. Is the type you need on the published list? If yes, prebuilt NER; if no, either custom NER with labeled data or a generative extraction with a schema.

One source documentsame text sent to each task kindEntity recognitionpreset categoriesEntity linkingknowledge baseKey phrase extractionmain talking pointsCustom NERyour own typesCategory and subcategoryoffset and lengthconfidence scoreOne knowledge base entryplus its reference URLthe ambiguity resolvedFlat list of phrasesno type, no offsetno rankingYour categoriesafter labeling, trainingand deploymentFour tasks over the same document, four response shapes. Pick the shape the next stage can consume.
Figure 2: the four prebuilt extraction tasks and the response shape each one returns.

Calling the analyze-text runtime

One synchronous call runs one task; the asynchronous job endpoint runs several tasks over the same documents in one submission.

That single sentence decides the shape of most Azure AI Language pipelines. If a corpus needs entity recognition, key phrase extraction, and sensitive-information detection, three synchronous calls send the same documents across the wire three times. Submitting them asynchronously[8] sends the corpus once and attaches a list of tasks to it.

Request body: three tasks over one document collection

{
  "displayName": "Support mail enrichment",
  "analysisInput": {
    "documents": [
      { "id": "1", "language": "de", "text": "Unsere Contoso Brew 300 heizt nicht mehr." }
    ]
  },
  "tasks": [
    { "kind": "EntityRecognition" },
    { "kind": "KeyPhraseExtraction" },
    { "kind": "PiiEntityRecognition" }
  ]
}

The tasks array is what makes this a batch: each element names one kind, and every task runs over every document in analysisInput.documents. The submission returns immediately with an operation location you poll; the task results arrive together when the job completes. Notice language on the document rather than on the request, because the collection can mix languages.

The language field is not optional in practice

Prebuilt Language tasks accept a per-document language code, and when none is supplied the analysis defaults to English[9]. Nothing errors. A German document analyzed as English simply comes back with fewer entities and weaker phrases, which reads in production like a model-quality problem and is actually an unset field. Supported entity categories also differ by input language[10], and categories that are not enabled by default for a given language have to be requested explicitly through the task's category parameter.

Results have a 24-hour life

Asynchronous results are available for retrieval for 24 hours from the time the request was ingested, and after that window they are purged and can no longer be fetched. The job identifier is a handle on a temporary result, not a storage key. Any pipeline that will want those entities next week writes them somewhere itself.

Figure 3 below puts the two call paths side by side, with the polling loop and the 24-hour window drawn only on the asynchronous lane where they apply.

So the mechanics reduce to three habits: batch tasks that share a corpus, always set the language code, and persist results before the day is out.

SynchronousPOST :analyze-textone task kindService runs it nowstateless for PIIResults in the responsenothing to pollAsynchronous jobPOST the jobseveral task kindsOne corpussent once, not per taskPoll job statusuntil it completesResults, then purged24 hours from ingestionBatch the tasks that share a corpus, then persist the results before the 24-hour window closes.
Figure 3: the synchronous single-task call path against the asynchronous multi-task job.

Schema-driven extraction with structured outputs

Setting strict to true is what turns a JSON Schema from a suggestion into a guarantee.

There are two ways to ask a Foundry chat model for JSON, and only one of them binds. JSON mode, response_format of type json_object, promises that the reply parses as valid JSON and nothing more; the model can still rename a field, drop one, or invent one. Structured outputs[2], response_format of type json_schema with strict set to true, force the reply to conform to the schema you supplied. That difference is what makes generative entity, topic, and field extraction machine-consumable without a defensive parsing layer that guesses.

Anatomy of a strict response_format block

"response_format": {
  "type": "json_schema",
  "json_schema": {
    "name": "support_case",
    "strict": true,
    "schema": {
      "type": "object",
      "properties": {
        "product":  { "type": "string" },
        "fault":    { "type": "string" },
        "severity": { "type": "string", "enum": ["low", "medium", "high"] },
        "promised_remedy": { "type": ["string", "null"] }
      },
      "required": ["product", "fault", "severity", "promised_remedy"],
      "additionalProperties": false
    }
  }
}

Three rules of strict mode are visible in that listing. Every property appears in the required array. Every object sets additionalProperties to false. And there is no genuinely optional field: promised_remedy is emulated as optional by giving it a union type that includes null while still being listed in required. Output key ordering follows the order of the schema you send, so the listing above produces product, fault, severity, promised_remedy in that order.

What the schema will not do for you

The supported subset of JSON Schema covers string, number, boolean, integer, object, array, enum, and anyOf, with the caveat that the root object itself cannot be an anyOf. Definitions through $defs and recursive references are supported. A schema may declare at most 100 object properties across five levels of nesting.

What is not honoured is most of the validation vocabulary: minLength, maxLength, pattern, and format on strings, minimum, maximum, and multipleOf on numbers, and minItems, maxItems, and uniqueItems on arrays. The model will return a string where you asked for a string; it will not guarantee that string matches your regular expression. Range checks, format checks, and array bounds run in your own code after parsing. Figure 4 below draws that split so the boundary is hard to forget.

Strict tool arguments cost you parallel calls

Structured outputs apply to tool definitions as well: strict: true on a function forces the generated arguments to match the parameter schema exactly. The catch is that structured outputs are not supported together with parallel function calling, so parallel_tool_calls must be set to false whenever strict tool schemas are in use. Leaving parallel calls enabled and assuming the strict argument contract still holds for every emitted call is the failure worth remembering.

Surfaces where structured outputs do not apply

Microsoft documents structured outputs as unsupported with Azure OpenAI On Your Data (the bring-your-own-data scenarios), with the Assistants and Foundry Agent Service surfaces, and with the gpt-4o-audio-preview and gpt-4o-mini-audio-preview models. The design consequence is concrete: an extraction step that must return a guaranteed schema calls chat completions directly rather than routing through an agent run, even when the rest of the workflow is agentic.

Pulling it together: strict mode gives you names, types, and presence. Everything about the values remains your responsibility, and the guarantee only exists on the surfaces that support it.

Your JSON Schemaevery property required,additionalProperties falsestrict: trueon the json_schema blockGuaranteed by the servicefield names and types, every property presentno extra properties, key order follows the schemaStill your code's jobpattern, format, minLength and maxLengthminimum and maximum, minItems and uniqueItemsStrict mode fixes the shape of the answer. It never checks the values inside it.
Figure 4: what strict structured outputs guarantee, and what they leave to your own validation.

What sentiment analysis can and cannot label

Sentiment analysis[11] has exactly three labels, and no amount of configuration adds a fourth meaning.

The task returns confidence scores between 0 and 1 for positive, neutral, and negative, for the document as a whole and for every sentence inside it, then assigns the highest-scoring label at each level. At document level there is also a derived mixed label, which appears when a document contains both positive and negative sentences. Scoring at two levels matters more than it sounds: a long review whose document label lands on neutral can still contain individually negative sentences, and a triage rule that reads only the document label never sees them.

Opinion mining attaches an opinion to its target

Opinion mining is an option on the sentiment task, not a separate service. Switching it on performs aspect-based sentiment analysis: it links each expressed sentiment to the concrete thing it is about, "the room", "the staff", "battery life", and returns target and assessment pairs. Base sentiment analysis returns only a label per sentence with no attribution to a product or service attribute, so a report that has to say what customers disliked rather than how many were unhappy needs opinion mining enabled.

Figure 5 below shows the three levels together: the document label on top, the per-sentence labels under it, and the target and assessment pairs that opinion mining hangs off the sentences carrying opinions. Sentences that express no opinion about a specific target simply have nothing below them.

The tone gap, and how to close it

None of these labels has any vocabulary for tone or emotion: frustration, urgency, politeness, sarcasm, escalation risk. This is the trap worth debunking on the spot. "Negative" cannot distinguish an angry customer from a disappointed one, and it cannot flag an urgent but perfectly polite escalation, because it is one axis with three labels. Enabling opinion mining does not add emotion classes either, since it returns target and assessment pairs on that same three-label scale. Lowering a confidence threshold changes which label wins, not which labels exist.

Detecting tone means defining the taxonomy yourself and then classifying against it. Three approaches, in rough order of how much machinery they need:

Approach What you define When it fits
Chat model with a constrained enum The tone classes, as an enum in a strict schema Per-message or per-ticket labelling at scale
Evaluator or LLM-judge rubric A scoring rubric applied to whole conversations Quality review over transcripts, offline
Content Understanding audio analyzer with custom generative fields The fields to generate from the audio Tone carried by spoken delivery rather than wording

The first row is the one that belongs on this page, and it is the structured-outputs mechanism from the previous section pointed at a classification job rather than an extraction job. The third row applies when the signal is in how something was said, which puts it on the speech solutions page rather than here.

So the boundary to carry into the exam: sentiment for polarity, opinion mining for polarity plus target, and a taxonomy of your own for anything that has a name other than positive, neutral, or negative.

Document levelpositive, neutral, negative, or mixedSentence 1three scores, one labelSentence 2three scores, one labelSentence 3three scores, one labelTarget: the roomassessment: spotlessTarget: the staffassessment: slowOpinion mining adds the bottom row. Sentences with no opinion about a target have nothing under them.
Figure 5: document label, per-sentence labels, and the target and assessment pairs opinion mining adds.

Redacting sensitive information from text

The sensitive-information task hands back the masked copy of the text; you do not assemble it yourself.

That is the part people miss. PII detection[9] evaluates unstructured text for predefined personal information (PII, for personally identifiable information) and health information categories, and returns two things in one response: the entity list, each item carrying category, offset, length, and confidenceScore, and a redactedText string in which every detected span is already masked. Running generic entity recognition and hand-building the masked string throws away the category-aware spans the task already produced.

Called synchronously the feature is stateless. No data is stored in the resource and results come back in the response, which is what lets a pipeline log entity metadata for audit and forward only the redacted copy downstream. Called asynchronously it inherits the 24-hour retrieval window described earlier for jobs.

The redaction policy decides what survives

The redactionPolicies parameter, introduced in the 2025-11-15-preview API version, sets how detected spans are masked. It accepts four policy kinds, and one request can carry a default policy plus per-entity overrides:

Policy kind What redactedText looks like Offsets and length
characterMask (default) The span replaced by a repeated character, ******** Preserved
entityMask A typed placeholder, [PERSON_1] Not preserved
noMask No redactedText field is returned at all Not applicable
syntheticReplacement A realistic but fictitious value, Sam Johnson Not preserved

Only length-preserving character masking keeps downstream character offsets valid. If a later stage indexes into the original document by offset, or diffs the redacted copy against the original, entityMask and syntheticReplacement silently break it because the replacement is a different length from what it replaced. The characterMask policy also takes an optional redactionCharacter field when the default asterisk is inconvenient. Synthetic replacement is currently a preview anonymization capability, so treat it as a test-data generator rather than a production control until it reaches general availability.

Figure 6 below runs one sentence through all four policies so the trade-off is visible in the output rather than in a rule.

Narrowing what gets detected

The task attempts the defined entity categories for the input language, and the optional piiCategories parameter restricts the response to the categories you name. The same parameter is how you request categories that are not enabled by default for your input language. One gotcha: if you specify categories without including default, the API returns only the categories you listed.

The design rule that falls out: choose the policy from what the next stage needs, not from what looks most thoroughly redacted. Offsets to preserve means characterMask; a human-readable transcript means entityMask; metadata only, with the original held elsewhere, means noMask.

Input textPerson and PhoneNumberdetected with offsetscharacterMask (default)span replaced by a repeated character, original length and offsets preservedentityMasktyped placeholder such as [PERSON_1], length changes so offsets no longer line upnoMaskresponse carries the entity list only, with no redactedText field at allsyntheticReplacementrealistic but fictitious substitute values, drawn from a predefined setOnly character masking keeps downstream offsets valid.
Figure 6: one detected sentence under each of the four redaction policy kinds.

Severity scoring for harmful text

Harm screening answers a different question from anything above it on this page, and it uses a different scale to do it.

Sentiment tells you how a passage feels. Sensitive-information detection tells you which spans must be masked. Azure AI Content Safety[12] tells you how severely a passage falls into a harm category, and it does that for four categories: Hate, Sexual, Violence, and SelfHarm.

Two properties of the scoring matter for design decisions. First, the text model rates on the full 0 to 7 severity scale, and the API can return either that full scale or a trimmed one in which each adjacent pair of levels collapses to a single value, giving 0, 2, 4, and 6. Text scoring and multimodal image-with-text scoring both offer the eight-level output. A threshold policy built on the assumption that only four buckets exist cannot express the difference between a level 4 finding and a level 5 one, which is exactly the granularity a tiered review queue needs.

Second, classification is multi-label. One passage can be flagged under more than one category at once, so a routing rule reads the whole set of category severities rather than picking a single winning category the way sentiment picks a single winning label.

What this page does not cover is what you then do with a severity: configuring content filters on a deployment, choosing block thresholds, running blocklists, and the annotation and streaming behaviour of the filter pipeline all belong to the responsible AI pages of this guide. Here the point is narrower. When an exam stem says a workload must rate text on how harmful it is, that is Content Safety and its severity levels, not a sentiment score and not an entity category.

Summarization: verbatim, generated, and per aspect

Summarization[13] forks on one question: may the summary contain words that are not in the source?

Extractive keeps every word; abstractive writes new ones

Extractive summarization produces a summary by selecting salient sentences from the source and returning each one with two extras. A rank score indicates how relevant the sentence is to the main topic, and you can choose whether the sentences come back in the order they appear in the document or in rank order. Positional information gives the start position and length of each extracted sentence. Every word in the result is verbatim and every line maps back to a location in the input, which is what compliance reviewers usually mean when they say the summary must be traceable.

Abstractive summarization generates concise, coherent sentences that are not verbatim extracts. Instead of per-sentence offsets it returns a contextual input range, the range within the input that was used to generate each summary text; a long input can be segmented so several groups of summary texts come back, each with its own range. If the requirement is that no wording may be invented, abstractive is the wrong branch no matter how much better it reads.

Conversations are summarized per aspect

Conversation summarization takes structured, speaker-tagged conversational input rather than a plain text block, and it is requested per aspect. The documented aspects[14] are issue and resolution for contact-centre calls, recap for a single-paragraph summary of the whole conversation, and chapterTitle together with narrative, which segment a long conversation and title and summarize each segment. Text summarization accepts only a plain text block and has no aspect concept at all, so flattening a call transcript into one string and still expecting separated issue and resolution output does not work.

A third genre, native document summarization, is in preview and accepts documents in their original format, currently .txt, .pdf, and .docx, with the same extractive and abstractive approaches.

Figure 7 below lays the genres, approaches, and output shapes out in three columns so the mapping is one glance rather than three paragraphs.

Jobs, and the 24-hour window

Summarization is processed as an asynchronous job. As with the other job-based tasks described earlier, the output is available for retrieval for 24 hours and is then purged, so the pipeline persists what it needs.

The retirement, and what replaces it

Microsoft has published a retirement date for Summarization in Azure AI Language of 31 March 2029, and directs both existing workloads and all new projects to Microsoft Foundry models for natural-language understanding. For a green-field Foundry build, the task-specific summarization API is a migration path for legacy code rather than the recommended default, even though it looks like the purpose-built choice.

That lines up with a second limit. Domain summarization work often carries output requirements the prebuilt task cannot express: mandatory sections, a fixed tone, named clause types that must be called out, citations back to the source. The prebuilt API exposes summary-length and style controls over content it chooses itself; it has no surface for "always surface the indemnity clause". A Foundry model steered by a system prompt plus a strict JSON schema, the mechanism from the structured-outputs section above, delivers that control.

So: extractive when traceability is the requirement, abstractive when readability is, conversation aspects when the input has speakers, and a prompted model when the shape of the summary is itself a requirement.

Plain text blockor a native documentin previewSpeaker-tagged turnsa conversationExtractivepicks source sentencesAbstractivewrites new sentencesConversation, per aspectissue, resolution, recapRanked verbatim sentencesrank score, start position, lengthNewly written summarycontextual input range, no offsetsOne summary per aspectchapterTitle pairs with narrativeTraceability points at extractive, readability at abstractive, and speakers at the conversation genre.
Figure 7: summarization genres, the approaches each one supports, and the output shape each approach returns.

Choosing a Translator surface

What you hand Azure Translator decides which surface you are on: strings go to the text translation endpoint, one file goes to synchronous document translation, and a library of files goes to asynchronous batch.

Strings

The text translation API[15] takes a JSON array of strings and returns a translation array, one result per input string, with one entry per target language. Repeat the to parameter to translate into several languages in the same call. Because it takes and returns strings, it cannot round-trip a .docx or a .pptx: extracting the text from a file and looping it through this endpoint discards exactly the layout and formatting that document translation exists to preserve.

Files

Document translation[16] has two processes, and they differ in more than throughput.

Asynchronous batch handles multiple documents and large files. It requires an Azure Blob Storage account with separate source and target containers, and a way to authorize access to those storage URLs: either shared access signature (SAS) tokens or managed identities. You upload sources, submit the batch job, poll job status and per-document status, then download the translated files from the target container. Batch is also the path that accepts Adobe PDF, where optical character recognition (OCR) extracts and translates the text of a scanned PDF while retaining the original layout.

Synchronous single-file accepts one document per request, needs no storage account, and returns the translated document directly in the response. Its supported formats are .txt, .tsv/.tab, .csv, .html/.htm, .mhtml/.mht, .pptx, .xlsx, .docx, .msg, and .xlf. Both processes preserve the original layout and formatting, and both can apply a custom translation model and a custom glossary.

The inversion worth naming out loud, because it reads backwards to most people: it is the asynchronous batch mode that requires the blob source and target containers, not the synchronous one, and synchronous accepts only a single document per request. Figure 8 below draws the three call paths so the storage requirement sits visibly on one lane only.

Translator against a chat model

A Foundry chat model can also translate, and there are jobs where it is the better tool. It can be steered on register, audience, and terminology inside the prompt ("formal German for a legal notice, keep product names in English"), and it can fuse translation with another task, translating and summarizing a review in one call.

What it does not give you is the rest of Translator's contract: layout-preserving round-trip of an Office file or a scanned PDF, per-document job status over a library, a trained glossary applied the same way every time, or the X-mt-system response header that reports whether a custom system actually served the request. So the split is not quality against quality. Use Translator when the artifact is a file or the terminology has to be provable; use a model when the requirement is stylistic control or translation fused with another job.

Text translation: stringsPOST /translatean array of strings, one or more target languagesTranslated strings in the responsecannot round-trip a .docx or .pptxDocument translation: one filePOST one documentno storage account neededTranslated file returned directlylayout preserved, single document per requestDocument translation: asynchronous batchSource containerSAS or managed identitySubmit batch jobmany or large filesPoll statusjob and per documentTarget containerPDF via OCR, layout keptOnly the batch lane needs Blob Storage containers.
Figure 8: the three Azure Translator call paths and where the storage requirement actually sits.

Translator request parameters that change the output

Translator's quality controls are query-string parameters, not prompt wording. Six of them decide whether a translation is publishable, and each has a default that is worth knowing because the defaults are permissive.

Parameter Values Default What it does
category a Custom Translator category ID general Routes the request to your trained custom system
allowFallback true, false true Whether a missing custom system silently falls back to the general one
textType plain, html plain Whether markup is preserved or translated as prose
profanityAction NoAction, Marked, Deleted NoAction Whether profanity passes through, is marked, or is removed
profanityMarker Asterisk, Tag Asterisk How marked profanity is rendered
from a source language code autodetect Required when the dynamic dictionary is used

Proving a custom system was used

A trained Custom Translator[17] system is invoked by passing its category ID in category. The trap is allowFallback, which defaults to true: the request quietly falls back to the general system whenever no custom system exists for that language pair, and the caller sees a perfectly fluent translation that ignored every trained term. Setting allowFallback=false makes the request return HTTP 400 instead of a non-custom translation. If a chain through a pivot language is needed, every system in the chain has to be custom and share the same category. In a regulated workflow that 400 is the feature, not the bug: it is how you prove every returned string came from the trained terminology. The X-mt-system response header is the second check, reporting Custom when at least one custom system served the request.

Pinning one phrase against training a system

The dynamic dictionary[18] supplies a known rendering for a single span inline:

The word <mstrans:dictionary translation="wordomatic">wordomatic</mstrans:dictionary> is a dictionary entry.

Three constraints ride with it. It is case-sensitive. It requires the from parameter, because source-language autodetection is not allowed alongside it. And Microsoft documents it as safe only for proper nouns such as personal names and product names. Injecting this markup for an entire glossary is the wrong shape of solution: it costs you autodetection and it does not use context the way a trained system does. Systematic terminology and style control belong in Custom Translator, which learns those choices from in-context training data.

Markup and profanity

Setting textType=html tells Translator the payload is well-formed markup, so tags are preserved rather than translated as prose, and any element carrying class="notranslate" is returned in its source language[19]. That combination is how boilerplate, code samples, brand names, and legal identifiers stay untouched on a translated page. Submitting HTML under the default plain text type translates the markup itself and corrupts the document.

Profanity passes through untouched by default. Deleted removes the profane words from the output with no replacement, while Marked replaces them, with asterisks by default or wrapped in <profanity> tags when profanityMarker=Tag. The distinction matters for moderation: Deleted destroys the evidence that anything was there, whereas Marked with Tag leaves a signal a downstream workflow can detect and act on.

Exam-pattern recognition

The stems on this topic are almost always a requirement in disguise. Read for the output the scenario needs, then map it.

"Must know both the entity type and where in the document each value appeared." Prebuilt entity recognition. Key phrase extraction is the distractor and it loses on both counts: no category and no offset. Entity linking loses because the requirement is not disambiguation.

"Decide whether a mention refers to the company or the planet." Entity linking, because it resolves the mention to one knowledge-base entry and returns its reference URL. Named entity recognition tells you the span is an entity and never returns a knowledge-base identifier.

"Add a new domain-specific entity type." Custom NER, and the correct answer includes labeling documents, training, and deploying. Any option implying a configuration switch or prompt-only change to the prebuilt model is wrong.

"Output must always contain the same fields with the same types." A chat model with response_format of type json_schema and strict: true. JSON mode (json_object) is the near-miss distractor: it removes parse errors but still permits renamed, missing, or invented fields.

"The extraction runs inside an agent and must return a guaranteed schema." The trick is that structured outputs are not supported on the Assistants and Foundry Agent Service surfaces, nor with On Your Data, nor with the audio-preview models. The correct design calls chat completions directly.

"Detect frustration, urgency, or escalation risk." Not sentiment analysis, and not opinion mining. The answer defines a tone taxonomy and classifies into it, typically a model constrained to an enum through a strict schema.

"Summary must not invent wording and must map back to the source." Extractive summarization, which returns ranked verbatim sentences with start position and length. Abstractive is the fluent-sounding wrong answer.

"Separate the issue from the resolution in a call transcript." Conversation summarization with the issue and resolution aspects, on speaker-tagged input. Flattening the transcript for text summarization is the distractor.

"Mask personal data but keep character offsets valid downstream." The sensitive-information task with the characterMask policy, which preserves original length and offsets. entityMask is the trap because typed placeholders change the length.

"Rate how harmful a passage is." Azure AI Content Safety severity levels, on the 0 to 7 scale (or the trimmed 0, 2, 4, 6 form), multi-label across Hate, Sexual, Violence, and SelfHarm. A negative sentiment score is not a harm severity.

"Translate a library of PDFs and keep the layout." Asynchronous batch document translation over Blob Storage source and target containers. Looping text through the /translate endpoint is the distractor, and so is the synchronous single-file path, which takes one document per request and does not accept PDFs.

"Prove every translated string used the trained glossary." allowFallback=false, which returns HTTP 400 rather than a general-system translation. Leaving the default true is exactly the silent failure the stem is testing.

"A green-field Foundry solution needs summaries." Watch for the retirement: Summarization in Azure AI Language retires on 31 March 2029 and Microsoft directs new projects to Foundry models. "Use the purpose-built summarization API" is the plausible-sounding wrong answer.

"Results are read from the job a few days later." Wrong by construction. Asynchronous Language job output is retrievable for 24 hours from ingestion and then purged; the correct answer persists the results.

Choosing between the three engines that read text

RequirementAzure AI Language prebuilt taskFoundry model with structured outputsAzure Translator
Label setPublished categories you cannot extend, except through custom NERAny enum you declare in the schemaNot a labeling service
Output shapeFixed response object per task kindThe JSON Schema you supply, when strict is trueTranslated strings, or translated files with layout preserved
Character offsetsReturned for entities, PII spans, and extractive summary sentencesOnly if you declare them, and you must validate them yourselfNot applicable
Training or labelingNone for prebuilt tasks; labeled project, training run, and deployment for custom NERNone; steering is the system prompt plus the schemaOptional Custom Translator model trained on in-context data
How it is calledanalyze-text synchronously for one task, or an async job for several tasks at onceChat completions with response_format of type json_schematranslate for strings, document translation for files
Where it runs outNo vocabulary outside the published taxonomy, and no tone or emotion classesNo offsets, no ranking, and validation keywords such as pattern and minimum are ignoredCannot classify, summarize, or extract; it only changes the language

Decision tree

What must the text produce? pick by the output shape you need extract values label the passage mask personal data condense it change its language Which extraction task? what the response must carry Sentiment or harm? two different scales PII detection masked copy + entity list Which summary shape? verbatim, generated, or per aspect File or strings? layout matters or not Named entity recognition preset type + exact offset Entity linking which real-world thing Key phrase extraction talking points, no type Foundry model + strict schema your own fields and enums Sentiment + opinion mining polarity, optionally per aspect Azure AI Content Safety harm severity, 0 to 7 Extractive summarization verbatim, ranked, with offsets Abstractive summarization newly written wording Conversation summarization speaker-tagged, per aspect Document translation files, layout preserved Azure Translator: strings the text translate endpoint Same text, many output shapes: match the box to the response object the next stage needs, not to how clever the engine is.

Sharp facts the exam loves — give these one last read before exam day.

Cheat sheet

Sharp facts the exam loves — scan these before test day.

Structured outputs with json_schema and strict:true guarantee schema adherence; JSON mode only guarantees valid JSON

Setting response_format to {"type": "json_schema", "json_schema": {..., "strict": true}} forces a Foundry model to emit output that conforms to the JSON Schema you supply, which is what makes generative entity, topic, and field extraction machine-consumable. The older JSON mode (response_format of type json_object) guarantees only that the reply parses as valid JSON; it cannot guarantee the reply carries the fields, names, or types your extraction pipeline expects.

Trap Choosing JSON mode (json_object) for a schema-driven extraction job: it eliminates parse errors but still lets the model rename, omit, or invent fields.

7 questions test this
A strict structured-outputs schema must mark every property required and set additionalProperties to false

In strict mode every property must appear in the object's required array and every object must set additionalProperties: false. There is no genuinely optional field: you emulate one by giving the property a union type that includes null (for example "type": ["string", "null"]) while still listing it in required. Output key ordering follows the order of the schema you send.

Trap Leaving a property out of required to make it optional — the schema is rejected rather than treated as an optional field.

7 questions test this
Structured outputs support only a subset of JSON Schema and drop most validation keywords

The supported subset covers string, number, boolean, integer, object, array, enum, and anyOf (the root object cannot be anyOf), plus $defs and recursive references. Validation keywords are not honored: minLength, maxLength, pattern, and format on strings, minimum, maximum, and multipleOf on numbers, and minItems, maxItems, and uniqueItems on arrays. A schema may declare at most 100 object properties across five levels of nesting.

Trap Expecting the schema to enforce value ranges, regex patterns, or array bounds; those checks must run in your own code after parsing.

10 questions test this
strict:true on a function tool constrains generated arguments but forbids parallel tool calls

Structured outputs also apply to tool definitions: setting strict: true on a function forces the generated arguments to match the parameter schema exactly. Structured outputs are not supported together with parallel function calling, so parallel_tool_calls must be set to false whenever strict tool schemas are in use.

Trap Leaving parallel tool calls enabled and assuming the strict argument schema still holds for every emitted call.

4 questions test this
Structured outputs are unsupported on the bring-your-own-data, Assistants/Agent Service, and audio-preview surfaces

Microsoft documents structured outputs as not supported with Azure OpenAI On Your Data (bring-your-own-data) scenarios, with the Assistants and Foundry Agent Service surfaces, and with the gpt-4o-audio-preview and gpt-4o-mini-audio-preview models. An extraction step that must return a guaranteed schema therefore calls chat completions directly rather than routing through an agent run.

Trap Designing an agent tool that relies on strict schema adherence from the agent run itself instead of from a direct model call.

NER types a mention against a fixed category list; entity linking disambiguates it against a knowledge base

Prebuilt named entity recognition returns spans typed against a preset category and subcategory list (person, location, organization, quantity, and so on) with an offset, length, and confidence score. Entity linking is a separate task that resolves an ambiguous mention to a single knowledge-base entry and returns its reference URL; named entity recognition alone never returns a knowledge-base identifier.

Trap Reaching for named entity recognition when the requirement is to decide whether 'Mars' means the planet or the company — that disambiguation is entity linking.

9 questions test this
Key phrase extraction returns untyped, unpositioned talking points

Key phrase extraction surfaces the main talking points of a document as a flat list of phrases with no entity category, no character offset, and no relevance ranking. Whenever the downstream consumer needs typed, positioned values — populating form fields, driving redaction, or filtering a search facet — prebuilt entity recognition or a schema-driven generative extraction is required instead.

Trap Selecting key phrase extraction for a pipeline that must know both the entity type and where in the document each value appeared.

7 questions test this
Custom NER needs a labeled authoring project, a training run, and a deployment before it can be called

Custom named entity recognition adds domain-specific entity types beyond the preset list, but only through an authoring project with human-labeled documents, a training run, and an explicit deployment that exposes a runtime prediction endpoint. Prebuilt entity recognition requires none of that — you call the analyze-text runtime immediately with the entity recognition task kind.

Trap Assuming a new domain entity type can be added by configuration or prompt alone, with no labeled data and no deployment step.

5 questions test this
The analyze-text runtime can batch several Language tasks over one document collection

A synchronous analyze-text call runs a single task over the submitted documents, while the asynchronous job endpoint accepts several tasks — for example entity recognition, key phrase extraction, and PII detection — over the same document collection in one submission. Batching this way avoids re-sending the corpus once per feature.

Trap Issuing one synchronous call per feature over the same documents and paying the ingestion cost repeatedly.

Omitting the language code makes Language analysis default to English and silently lose recall

Prebuilt Language tasks accept a per-document language code, and when none is supplied the analysis defaults to English. Supported entity categories also differ by input language, so a non-English document analyzed without its language code returns degraded results with no error, and categories not enabled by default for that language must be requested explicitly.

Trap Treating missing recall on multilingual text as a model-quality issue rather than an unset language code.

Extractive summarization returns ranked verbatim sentences with offsets; abstractive generates new wording

Extractive summarization selects the highest-ranked original sentences from the source and returns each with a rank score plus its start position and length, so every word in the summary is verbatim and traceable to a location in the input. Abstractive summarization writes new, coherent sentences that appear nowhere in the source and returns a contextual input range rather than sentence offsets.

Trap Choosing abstractive summarization when the requirement is that no wording may be invented and each summary line must map back to a source offset.

6 questions test this
Conversation summarization is requested per aspect and needs turn-structured input

Conversation summarization accepts structured, speaker-tagged conversational input and is requested per aspect: issue and resolution for contact-center calls, recap for a single-paragraph summary, and chapterTitle together with narrative to segment a long conversation and summarize each segment. Text summarization accepts only a plain text block and has no aspect concept at all.

Trap Flattening a call transcript into plain text for text summarization and still expecting separated issue and resolution output.

5 questions test this
Summarization retires from Azure Language and Microsoft directs new projects to Foundry models

Microsoft has published a retirement date for Summarization in Azure Language (31 March 2029) and directs both existing workloads and all new projects to Microsoft Foundry models for natural-language understanding. For a green-field Foundry build the task-specific summarization API is a migration path for legacy code, not the recommended default.

Trap Standardizing a brand-new Foundry solution on the prebuilt Language summarization task because it is the 'purpose-built' service.

3 questions test this
Domain summarization that must hit fixed sections or highlight clauses needs a prompted model, not the prebuilt task

Compliance and other domain summarization work carries output requirements the prebuilt task cannot express: mandatory sections, a fixed tone, named clause types to call out, and citations back to the source. A Foundry model steered by a system prompt plus a strict JSON schema delivers that control, while the prebuilt summarization API exposes only summary-length style controls over content it chooses itself.

Trap Assuming a task-optimized summarizer can be configured to always surface a specific clause type; it has no such steering surface.

6 questions test this
Asynchronous Language job output is retrievable for 24 hours and then purged

Summarization is processed as an asynchronous job whose output is available for retrieval for 24 hours from ingestion, after which the results are purged and cannot be fetched again. A production pipeline must persist the returned summaries itself rather than treating the job identifier as durable storage.

Trap Storing only the job identifier and planning to re-read the result days later.

Sentiment analysis scores positive, neutral, and negative at both document and sentence level

The sentiment task returns confidence scores between 0 and 1 for positive, neutral, and negative for the document as a whole and for each sentence inside it, then assigns the label with the highest score at each level. Because scoring is per sentence as well as per document, a long review whose document label is neutral can still contain individually negative sentences that a document-only reading would miss.

Trap Routing escalations on the document label alone and losing the negative sentences buried inside long feedback.

9 questions test this

Opinion mining is an option on the sentiment task, not a separate service, and it performs aspect-based sentiment analysis: it links each expressed sentiment to the concrete target it is about — 'the room', 'the staff', 'battery life' — and returns target and assessment pairs. Base sentiment analysis returns only an overall label per sentence with no attribution to a product or service attribute.

Trap Expecting per-attribute sentiment from the sentiment task without enabling opinion mining.

9 questions test this
Content Safety text scoring runs on the full 0-7 severity scale and can be trimmed to 0/2/4/6

The Content Safety text model rates Hate, Sexual, Violence, and SelfHarm on the full 0-7 severity scale and can return either that full scale or a trimmed one in which each adjacent pair of levels collapses to a single value (0, 2, 4, 6). Text and multimodal image-with-text scoring offer the eight-level output; classification is multi-label, so one passage can be flagged under more than one category at once.

Trap Building text thresholds on the assumption only four buckets exist, which cannot express the distinction between a level 4 and a level 5 finding.

4 questions test this
The PII task returns both the detected entity list and a ready-made redacted copy of the text

PII detection evaluates unstructured text for predefined personal and health information categories and returns two things in one response: the entity list with category, offset, length, and confidence, plus a redactedText string in which each detected span is already masked. Called synchronously the feature is stateless — no input is stored in the resource — so a pipeline can log entity metadata and forward only the redacted copy downstream.

Trap Running generic entity recognition and hand-assembling the masked string, which discards the category-aware spans PII detection already produced.

5 questions test this
PII redaction policy kinds differ in whether offsets and length survive masking

Redaction behavior is chosen with a redaction policy kind: characterMask (the default) replaces the span with a repeated character and preserves the original length and offsets, entityMask substitutes a typed placeholder such as [PERSON_1], noMask returns the response without a redactedText field at all, and syntheticReplacement swaps in realistic but fictitious values. Only length-preserving masking keeps downstream character offsets valid.

Trap Selecting entityMask in a pipeline whose later stages index by character offset into the original document.

Prebuilt sentiment analysis emits only positive, neutral, and negative, so tone categories such as frustration or escalation risk require a generative classification you define

The Language sentiment analysis feature assigns the labels positive, neutral, and negative with confidence scores at both document and sentence level, plus a derived mixed label at document level when a document contains both positive and negative sentences, and opinion mining only adds the target an opinion is attached to; none of these labels has any vocabulary for tone or emotion classes such as frustration, urgency, politeness, sarcasm, or escalation risk. Detecting those means defining the taxonomy yourself - a chat model prompted to classify into a constrained enum with a structured output schema, an evaluator or LLM-judge rubric applied to conversations, or a Content Understanding audio analyzer with custom generative fields when the tone is carried by spoken delivery rather than wording.

Trap Equating a strongly negative sentiment score with a specific tone: 'negative' cannot distinguish an angry customer from a disappointed one, or flag an urgent-but-polite escalation, because it is one axis with three labels. Enabling opinion mining does not add emotion labels either — it is aspect-based sentiment returning target and assessment pairs on the same three-label scale — and neither does lowering a confidence threshold.

4 questions test this
A Custom Translator system is selected by category ID, and allowFallback decides whether a miss is silent

A trained Custom Translator system is invoked by passing its category ID in the category query parameter of the translate call. allowFallback defaults to true, letting the request quietly fall back to the general system when no custom system exists for that language pair; setting allowFallback=false makes the request return HTTP 400 instead of a non-custom translation, which is how you prove every returned string used the trained terminology.

Trap Leaving allowFallback at its default in a regulated workflow and assuming every translation applied the custom glossary.

7 questions test this
The dynamic dictionary pins one phrase inline; broad terminology control requires Custom Translator

The dynamic dictionary supplies a known rendering for a single span inline as <mstrans:dictionary translation="...">phrase. It is case-sensitive, requires the from parameter because autodetection is not allowed with it, and is documented as safe only for proper nouns such as person and product names. Systematic terminology and style control belongs in Custom Translator, which learns those choices from in-context training data.

Trap Injecting dynamic-dictionary markup for an entire glossary instead of training a custom system, and losing source-language autodetection in the process.

11 questions test this
Translator passes profanity through by default; Marked versus Deleted decides whether the signal survives

By default (profanityAction=NoAction) Translator carries profanity from source to target. Deleted removes the profane words from the output with no replacement, while Marked replaces them — with asterisks by default, or wrapped in tags when profanityMarker=Tag, which leaves the workflow able to detect and post-process the occurrence.

Trap Choosing Deleted in a moderation workflow that still needs to know profanity was present in the source.

textType=html preserves markup, and class=notranslate excludes an element from translation

Setting textType=html tells Translator the payload is well-formed markup so tags are preserved instead of being translated as prose, and any element carrying class="notranslate" is returned in its source language. That combination is how boilerplate, code samples, brand names, and legal identifiers are excluded from a translated page.

Trap Submitting HTML with the default plain text type, which translates the markup itself and corrupts the document.

Translating a library of files uses Translator's asynchronous batch document translation over Blob Storage, not a loop over the text endpoint

Azure Translator document translation has two processes: asynchronous batch, which handles multiple and large documents through an Azure Blob Storage account with separate source and target containers authorized by SAS token or managed identity, while you poll job and per-document status; and synchronous single-file, which accepts one document, needs no storage account, and returns the translated file directly in the response. Both preserve the original layout and formatting and can apply a custom translation model and a glossary, but only the batch path accepts PDFs, where OCR extracts and translates the text of a scanned PDF while retaining the original layout - the synchronous path is limited to .txt, .tsv, .csv, .html, .mhtml, .docx, .pptx, .xlsx, .msg, and .xlf. The text translation API is a different surface entirely - it takes and returns strings, so it cannot round-trip a .docx or .pptx.

Trap Extracting text from each file and looping it through the text /translate endpoint, which discards exactly the layout and formatting document translation exists to preserve. The other inversion is picking the synchronous path for a whole library: synchronous accepts only a single document per request, and it is the asynchronous batch mode - not the synchronous one - that requires the blob source and target containers.

4 questions test this

References

  1. What is Azure AI Language
  2. How to use structured outputs with Azure OpenAI in Microsoft Foundry
  3. What is Azure AI Translator text translation
  4. Named entity recognition (NER) overview
  5. Entity linking overview
  6. Key phrase extraction overview
  7. Custom named entity recognition (custom NER) overview
  8. Use Azure AI Language features asynchronously
  9. Detect and redact PII from text
  10. PII detection entity categories
  11. Sentiment analysis and opinion mining overview
  12. Azure AI Content Safety harm categories and severity levels
  13. What is summarization?
  14. How to use summarization
  15. Translator v3 Translate method reference
  16. What is Azure Translator document translation?
  17. Text translation customization (Custom Translator)
  18. Use the Translator dynamic dictionary
  19. Prevent content translation with Translator