ai.extract, Extract structured data from text using AI with a JSON schema
Use ai.extract after parsing or collecting text when you need typed JSON back:
invoice fields, contract clauses, email metadata, line items, or classifications
with supporting fields.
Keep the schema as narrow as possible. Enum fields work well for closed choices,
and descriptions should explain business meaning, not just repeat the field
name. For deterministic calculations after extraction, pass the output into
transform.script instead of asking the model to do math.
Grounding and confidence (on by default)
Every extraction also runs a grounding pass: each extracted field is traced back to the exact place in the input text it came from, and gets a confidence level. The result lands under a reserved_grounding key in the step output,
keyed by field name, so downstream steps can reference it directly:
highmeans the value appears verbatim in the source text,mediummeans it matches approximately (formatting or currency drift) or is derived from a highlighted source passage through a transformation the model attested (for example a date normalized from “January 25, 2016” to “2016-01-25”; the span carriesalignment: "match_derived"), andlowmeans no supporting source passage could be located (possible OCR error or hallucination).- Fields at or below the
reviewOnthreshold carryneedsReview: trueand areason, so a downstream condition or approval step can route them to a human. By default onlylowfields are flagged; setreviewOn: medium_or_lowto also flag approximate and derived matches. source_spanholds the character range of the value in the input text; the run view highlights it when you open a field in the Grounding panel.- Long documents are chunked automatically; no tuning is needed.
groundingModel picks a
different one. When no model is available it falls back to deterministic text
matching and marks the result with _grounding._degraded: true instead of
failing the run. Set grounded: false to turn grounding off for a step, or
grounded: true to make a missing grounding model fail the run instead of
degrading.
Note that grounding confidence measures whether the value is present in the
source text, not whether OCR read the original document correctly. For numeric
cross-checks (for example rate times hours equals gross), add a
transform.script step.
Configuration
Configuration goes inside the step’swith: block.
string
required
Text content or template expression
object
required
JSON Schema defining the structure to extract
string
Custom prompt template for extraction
string
Provider ID (e.g., “openai-gpt4o”)
string
Model override
integer
Max input tokens. Truncates input text and logs a warning when exceeded. Omit for no limit.
boolean
Grounding is ON by default: each schema field gets a source span + confidence (high=verbatim, medium=fuzzy, low=ungrounded) under a reserved
_grounding output key, and fields whose value cannot be located in the source are flagged for human review. Values stay the reliable schema-typed ones. The pass runs through the workspace LLM (any provider) and chunks long documents automatically. Tri-state: unset (default) = on, degrading gracefully to deterministic text alignment (_grounding._degraded: true) if no grounding model is available; true = strict, the step fails when the grounding model cannot be resolved; false = off, no _grounding key at all.string
Provider/model for the grounding pass. Defaults to the workspace default LLM. Any configured provider works; the pass only fails the step when
grounded: true is set explicitly and no model resolves.array<object>
Optional few-shot examples pinning grounding to verbatim source text per field.
"medium_or_low" | "low_only"
Which grounding confidences set needsReview on a field. Default: low_only (only fields whose value could not be located in the source). Use medium_or_low to also flag approximate and derived matches.
Output
Returnsrecord<string, unknown>. Extracted structured data matching the provided schema. Unless grounding is disabled (grounded: false), the output also carries a reserved _grounding map keyed by field name: _grounding.<field> = { confidence: high|medium|low, needsReview, reason?, source_span: { start, end, text, alignment } | null }, plus reserved _degraded: true / _reason markers when the grounding LLM pass could not run.