C3 AI Documentation Home

Configure Tag and Entity Extraction for Document AI

Document AI can do more than make documents searchable. While it processes a document, it can extract descriptive tags (a document type or category, for example) and typed entities (such as organizations or contract terms). You configure extraction through the ingestionSettings field of a processing request, defining a schema instead of writing extraction code—the model fills it in.

Configuring extraction takes two decisions: which level to run, and what to pull out. Choose document-level, passage-level, or both, then define a tagsToExtract map, an entitiesToExtract map, or both—the worked example below shows a complete request using both. The results land as metadata and typed records in your application. A typo in either schema produces no error, so check the last section before you trust a run that came back clean.

Choose the extraction level

Extraction runs at two levels, configured independently. A request can use either level or both.

Settings blockRunsUse for
documentExtractorOne time per document, against the whole document.Facts that describe the document itself: type, language, issuing party, effective date.
passageExtractorOne time per chunk, against that chunk's text.Facts scattered through the body: section labels, referenced organizations, individual measurements.

The passage_level strategy supports both blocks. The document_level strategy supports documentExtractor only; it reads a limited set of pages and produces no chunks.

Document-level extraction costs one model pass per document. Passage-level extraction costs one pass per chunk, so its cost grows with document length. Start with document-level tags and add passage-level extraction only when you need per-passage facts. A level with no configured targets costs nothing: without targets in documentExtractor or passageExtractor, that level makes no extraction call at all.

Define tags

The tagsToExtract schema is a map of tag names to a type declaration. Every tag must declare a type; a tag entry without one fails the run. Add an optional enum to constrain the value to a fixed set:

JSON
{
  "tagsToExtract": {
    "document_type": { "type": "string" },
    "language": { "type": "string" },
    "review_status": { "type": "string", "enum": ["draft", "approved", "superseded"] }
  }
}

The model extracts a value for every tag name. Use enum whenever the valid values are known in advance. A constrained tag is far more reliable than a free-text one, and it keeps downstream filtering predictable.

Define entities

The entitiesToExtract schema is a map of entity type names to field definitions. Each field declares a type, whether it's required, and a description. The accepted types are str, int, float, and bool, and common aliases such as string, integer, double, and boolean also work:

JSON
{
  "entitiesToExtract": {
    "<YourEntityType>": {
      "id": { "type": "str", "required": true, "description": "Unique short identifier for this record" },
      "name": { "type": "str", "required": true, "description": "The name of the referenced organization" },
      "amount": { "type": "float", "required": false, "description": "The monetary amount, in the document's currency" }
    }
  }
}

The description is your main quality lever: the model reads it as an instruction. Write each description the way you would brief a person. Name the units or format you expect, and state what to do when the fact is absent. Mark a field required only when a record without that field has no value; the model skips a candidate record it can't complete.

Entity type names must be real types in your target application, and field names must match that type's fields—both are used directly as write targets. A name or field that doesn't exist doesn't fail the submission: the run completes, the passages persist, and only the entity writes fail. Document AI converts extracted values to the declared type before writing them, so declare the same type your target field uses. A mismatch also surfaces as a failed write. Include an id field and at least one data field in every entity schema.

Worked example

The following request ingests a set of contracts, classifies each document, and pulls the referenced parties out of every passage:

JSON
{
  "source": { "folder": "azure://<container>/<contracts-path>/" },
  "strategyName": "passage_level",
  "retrieverId": "default-pg",
  "sourceApp": "<target-app-id>",
  "ingestionSettings": {
    "documentExtractor": {
      "tagsToExtract": {
        "document_type": { "type": "string", "enum": ["contract", "amendment", "statement_of_work"] },
        "language": { "type": "string" }
      }
    },
    "passageExtractor": {
      "entitiesToExtract": {
        "<YourPartyType>": {
          "id": { "type": "str", "required": true, "description": "Unique short slug for this party" },
          "name": { "type": "str", "required": true, "description": "The legal name of the contracting party" }
        }
      }
    }
  }
}

Every tag name, entity type, and field in these examples is a placeholder. Replace them with a schema that fits your documents and your application's data model. A request that keeps a placeholder such as <YourEntityType> still completes; only the entity writes fail, which often goes unnoticed.

Where extracted data lands

When a run persists, the extracted data is written into your target application alongside the passages:

  • Document-level tags: Stored as metadata on the document's Genai.SourceFile record.
  • Passage-level tags: Stored as metadata on each Genai.Vector.SourcePassage record, where retrieval features can filter on them. They're also added as tags on the document's Genai.SourceFile record, so file-level filters see them too.
  • Entities: Written as records of the named entity type in your application.

Validation and runtime behavior

A request behaves differently depending on what's wrong with it, or whether anything is configured at all:

  • Settings key names aren't validated: an unrecognized key is logged and ignored, so a misspelled key, such as documentExtracter, produces a run that completes with no extraction and no error. Copy key names from this topic's examples instead of retyping them, since a typo gives no warning.
  • Setting values are validated during processing: a malformed value, such as a tag entry without a type, fails the run.
  • Extraction is best-effort: a document or passage the model can't extract from is left without results, and the run still completes. Check the run's errors list when you expected tags or entities and got none.
  • Omit a documentExtractor or passageExtractor block to skip extraction at that level. Omit ingestionSettings entirely, and Document AI processes the documents for search only.

See also

Was this page helpful?