Fields Shorthand
Build schemas on the fly from the CLI using a concise field definition string.
The --fields flag (short: -f) lets you describe extraction output as a comma-separated string directly on the command line, without writing or maintaining a JSON Schema file.
echo "The Dark Knight (2008), directed by Christopher Nolan. Genre: action." | \
struktur --stdin --fields "title, year:integer, director, genre" \
--model openai/gpt-4o-miniOutput:
{
"title": "The Dark Knight",
"year": 2008,
"director": "Christopher Nolan",
"genre": "action"
}Synopsis
struktur [extract] --fields "<field-definitions>" [other options]--fields is one of three mutually exclusive schema options. Pass exactly one of:
Prop
Type
Field syntax
fields = field ("," field)*
field = name
| name ":" typeWhitespace around commas and colons is ignored.
Scalar types
--fields "title"
--fields "title:string"Default when no type is specified. Produces { "type": "string" }.
--fields "price:number"
--fields "price:float"Any numeric value. Both produce { "type": "number" }. float is an alias for number.
--fields "count:integer"
--fields "count:int"Whole numbers only. integer produces { "type": "integer" }. int produces { "type": "integer", "multipleOf": 1 } — explicitly disallows fractions.
--fields "active:boolean"
--fields "active:bool"Both produce { "type": "boolean" }. bool is an alias for boolean.
Enums
--fields "status:enum{draft|published|archived}"Values are separated by |. At least two values are required.
Arrays
--fields "tags:array" # shorthand for array{string}
--fields "tags:array{string}"
--fields "scores:array{float}"
--fields "ids:array{int}"The item type can be any scalar keyword (including aliases). If omitted, defaults to string.
Examples
Basic fields with types
Extract article metadata
Enum field
Status extraction with predefined values
Mixed types
Products with arrays and enums
Piped input
Processing reviews from stdin
Batch processing
Process a directory of documents
struktur --input article.txt \
--fields "title, author, published_date, word_count:integer" \
--model openai/gpt-4o-miniecho "Order #4421 is currently being packed." | \
struktur --stdin \
--fields "order_id, status:enum{pending|processing|shipped|delivered}" \
--model anthropic/claude-3-5-haiku-20241022struktur --input product.html \
--fields "name, price:float, in_stock:bool, tags:array{string}, category:enum{electronics|clothing|food}" \
--model openai/gpt-4o-minicat reviews.txt | \
struktur --stdin \
--fields "sentiment:enum{positive|neutral|negative}, score:int, summary" \
--model openai/gpt-4o-mini \
--output result.jsonfor f in docs/*.txt; do
struktur --input "$f" \
--fields "title, category:enum{invoice|receipt|contract}, amount:float" \
--model openai/gpt-4o-mini \
--output "out/$(basename "$f" .txt).json"
doneGenerated schema
--fields "title, price:number, tags:array" produces this schema internally:
{
"type": "object",
"properties": {
"title": { "type": "string" },
"price": { "type": "number" },
"tags": { "type": "array", "items": { "type": "string" } }
},
"required": ["title", "price", "tags"],
"additionalProperties": false
}All fields are required. For optional fields, nested objects, or $ref, use --schema instead.
SDK Usage
The fields parameter is also available in the SDK:
import { extract, simple } from "@struktur/sdk";
import { openai } from "@ai-sdk/openai";
const result = await extract({
artifacts,
fields: "title, author, year:integer, genre:enum{fiction|nonfiction|reference}",
strategy: simple({ model: openai("gpt-4o-mini") }),
});
// result.data is typed as Record<string, unknown> when using fields
console.log(result.data.title);For full TypeScript inference on result.data, use schema with JSONSchemaType<T> instead.
Utility exports
The parser and schema builder are exported for use outside of extract():
import {
parseFieldsString,
buildSchemaFromParsedFields,
buildSchemaFromFields,
} from "@struktur/sdk";
// Parse to an intermediate representation
const parsed = parseFieldsString("title, price:number, status:enum{draft|live}");
// [
// { name: "title", kind: "scalar", type: "string" },
// { name: "price", kind: "scalar", type: "number" },
// { name: "status", kind: "enum", values: ["draft", "live"] }
// ]
// Build a schema directly
const schema = buildSchemaFromFields("title, price:number");parseFieldsString(fields: string): ParsedField[]
Parses the fields string into an array of ParsedField discriminated union entries:
type ParsedField =
| { name: string; kind: "scalar"; type: ScalarFieldType }
| { name: string; kind: "enum"; values: string[] }
| { name: string; kind: "array"; items: ScalarFieldType };
type ScalarFieldType = "string" | "number" | "boolean" | "integer" | "int";buildSchemaFromParsedFields(fields: ParsedField[]): AnyJSONSchema
Builds the JSON Schema object from a pre-parsed array. Useful if you want to inspect or modify the parsed fields before building.
buildSchemaFromFields(fields: string): AnyJSONSchema
Convenience one-liner: parses and builds in a single call.
Error messages
Bad field definitions fail immediately with a helpful message:
--fields "count:bigint"
# Error: Unknown type "bigint" for field "count".
# Scalar types: bool, boolean, float, int, integer, number, string.
# Complex types: enum{a|b|c}, array{string}, or array (shorthand for array{string}).
--fields "role:enum{admin}"
# Error: enum for field "role" must have at least two values separated by "|", got: "admin".
--fields "tags:array{}"
# Error: array for field "tags" requires an item type, e.g. array{string}.
--fields "name:enum{a|b"
# Error: Unmatched braces in fields string.When to use --fields vs --schema
| Situation | Use |
|---|---|
| Quick one-liner or experiment | --fields |
| All fields are flat, all required | --fields |
| Need optional properties or nested objects | --schema |
| Schema is reused across many runs | --schema |
Need $ref, allOf, custom formats | --schema |
Need TypeScript inference on result.data | --schema with JSONSchemaType<T> |
See also
- extract — full CLI flag reference