Complete technical specification for Instruction Template Specification v1.0
The Instruction Template Specification (ITS) defines a JSON-based format for creating templates that compile into AI instructions rather than static content. This enables content creators to build reusable templates with placeholders that generate dynamic, AI-powered content.
https://alexanderparker.github.io/instruction-template-specification/schema/v1.0/its-base-schema-v1.json
| Property | Type | Description |
|---|---|---|
version |
string | Template format version (semantic versioning) |
content |
array | Array of content elements (text, placeholders, conditionals) |
| Property | Type | Description |
|---|---|---|
extends |
array | Schema references for instruction type definitions (URLs or relative paths) |
metadata |
object | Template metadata (name, author, tags, etc.) |
customInstructionTypes |
object | Template-specific instruction type definitions |
compilerConfig |
object | Configuration for template compilation |
variables |
object | Template-level variables for reuse |
Static text content that appears as-is in the compiled template.
{
"type": "text",
"text": "Your static content here",
"id": "optional-identifier"
}
Placeholder that becomes an AI instruction in the compiled template.
{
"type": "placeholder",
"id": "unique-identifier",
"instructionType": "list",
"config": {
"description": "Content description for the AI",
"displayName": "Human-readable name",
"dataSource": "forecast", // optional: variable(s) rendered as reference data
// Additional type-specific configuration
}
}
Four config keys are reserved by the specification: description (required, the content request
passed to the AI), displayName (optional human-readable label), dataSource (a
variable name or array of variable names rendered as reference data) and dataLimit (a positive
integer capping how much of each data source is included). All other config keys are defined by the
placeholder's instruction type.
A placeholder's dataSource config names a variable (or an array of variable names) holding data the
generated content should be grounded in, such as a table of records. Rather than spelling values out one element
at a time, compilers render each referenced variable once in a REFERENCE DATA section above the
template - arrays of objects as tables, plain objects as field tables - and add a processing instruction telling
the model to use the section as context only and never include it in the output. Sources referenced by several
placeholders appear once; sources referenced only inside excluded conditional branches are omitted; a
dataSource naming an undefined variable is a compilation error.
{
"type": "placeholder",
"instructionType": "paragraph",
"config": {
"description": "Summarise the weekly trends in the forecast reference data",
"dataSource": "forecast",
"dataLimit": 50
}
}
The optional dataLimit config caps how much of each referenced source is included: the first N items
of an array, or the first N fields of an object, with the truncation stated in the rendered section (for example
"Showing the first 50 of 3200 items."). When several placeholders reference the same source with different
limits, compilers render one section using the most generous request - a reference without a limit beats any
limit, otherwise the maximum applies. This guards prompt size when variables carry large datasets fetched from
databases or APIs.
Filtering and shaping data is deliberately out of scope for templates: when templates run inside an integration
or workflow tool, apply filters, sorting and projections in the steps that fetch the data, before it is injected
as variables. dataLimit is a size guard, not a query language.
A variable reference that resolves to an object, such as ${school} or
${product.details}, also produces reference data: the compiler substitutes the pointer text
"the school reference data" at the reference site and renders the object once in the
REFERENCE DATA section, under a heading matching the reference path. Objects referenced both this
way and through dataSource render a single section. References resolving to scalars or arrays
substitute their value as before; only object values are promoted.
Compilers enforce resource limits while processing templates - template size, content element count, nesting depth, total variable count (nested values included), items per variable array, and text length - to protect the operator from oversized or hostile inputs. Conforming compilers must make these limits configurable by the operator (through a configuration object, environment variables or command-line flags) so workloads carrying large reference datasets can raise them deliberately. Limits belong to the operator's configuration, never to the template document itself: a template cannot raise the limits of the compiler processing it. The reference compilers default to 10000 total variables, 1000 items per array and 10000 characters of text, with every limit adjustable; see each compiler's documentation for its configuration surface.
Content that appears based on conditions. Conditions can include variables, literals, and expressions.
{
"type": "conditional",
"condition": "audienceLevel == 'technical'",
"content": [
// Content if condition is true
],
"else": [
// Content if condition is false (optional)
]
}
Variables are defined in the top-level variables object and can store strings, numbers, booleans, objects, or arrays.
{
"variables": {
"tone": "professional",
"productType": "gaming headset",
"featureCount": 5,
"includeSpecs": true,
"brandInfo": {
"name": "TechCorp",
"tagline": "Innovation First"
}
}
}
Use ${variableName} syntax to reference variables throughout your template:
{
"type": "text",
"text": "Welcome to ${brandInfo.name} - ${brandInfo.tagline}"
}
{
"type": "placeholder",
"instructionType": "list",
"config": {
"description": "List ${featureCount} key features of a ${productType}",
"format": "bullet_points",
"itemCount": "${featureCount}"
}
}
Array references accept negative indices, which select from the end of the array: ${items[-1]}
is the last item and ${items[-2]} the second last. Arrays and strings also expose a
.length pseudo-property: ${items.length} substitutes the number of items and
${title.length} the number of characters, and both may be used in conditional expressions.
{
"type": "text",
"text": "The forecast covers ${forecast.length} days, ending on ${forecast[-1].day}."
}
References to array variables accept a chain of collection functions after the path, applied left to right during substitution. A property argument extracts that property from each object item; without one the items themselves are used. Aggregations require numeric values, and whole-number results render without a decimal part. Functions are part of the reference syntax for substitution only; conditional expressions do not accept function calls.
${forecast.concat(day)} // "Monday, Tuesday, Wednesday" - joins with ", "
${forecast.sum(high)} // 82
${forecast.avg(high)} // averages; min(prop) and max(prop) likewise
${scores.sum()} // aggregate arrays of numbers directly
${forecast.top(3)} // first three items; chains with other functions
${forecast.top(2).concat(day)} // "Monday, Tuesday"
Supported functions: concat(property?), sum(property?), avg(property?),
min(property?), max(property?) and top(n), alongside the existing
.length pseudo-property. Applying a function to a non-array, referencing a property missing from
any item, or aggregating non-numeric values is a compilation error.
| Type | Example | Access Method |
|---|---|---|
| String | "professional" |
${variableName} |
| Number | 42 |
${variableName} |
| Boolean | true |
${variableName} |
| Object | {"name": "value"} |
${object.property} |
| Array | ["item1", "item2"] |
${array[0]}, ${array[-1]}, ${array.length} |
Conditional elements use JavaScript-like expression syntax to control content inclusion:
==, !=>, <, >=, <=, including chained comparisons such as 1 < number <= 10&& (AND), || (OR), ! (NOT), with the word forms and, or and not accepted as equivalentsin and not in (for arrays and strings), with array literals such as status in ['active', 'trial']// Simple equality
"condition": "tone == 'professional'"
// Numeric comparison
"condition": "featureCount > 3"
// Boolean check
"condition": "includeSpecs == true"
// Compound conditions
"condition": "tone == 'professional' && featureCount > 3"
// Membership test
"condition": "productType in ['headset', 'speakers', 'microphone']"
// Object property access
"condition": "sections.intro == true"
// Negation
"condition": "!includeSpecs"
Reference: Standard Types Schema
Generates titles and headlines with customizable style and length.
{
"instructionType": "title",
"config": {
"description": "Create a catchy product headline",
"style": "headline", // headline, descriptive, catchy, formal, creative
"length": "short" // short, medium, long
}
}
Generates formatted lists with customizable styling and item counts.
{
"instructionType": "list",
"config": {
"description": "list 5 different citrus fruits",
"format": "bullet_points", // bullet_points, numbered, dashes, plain
"itemCount": 5 // optional
}
}
Generates paragraphs with specified tone and length.
{
"instructionType": "paragraph",
"config": {
"description": "Write about sustainable technology",
"tone": "professional", // formal, casual, enthusiastic, professional, friendly
"length": "medium" // short, medium, long
}
}
Generates tables with configurable formatting and dimensions.
{
"instructionType": "table",
"config": {
"description": "Compare technology features",
"format": "markdown", // markdown, plain_text, csv
"columns": 3, // optional
"rows": 4 // optional
}
}
Generates code snippets with syntax highlighting.
{
"instructionType": "code_block",
"config": {
"description": "Create a Python function that sorts a list",
"language": "python" // javascript, python, java, html, css, sql, bash, generic
}
}
Generates conversations between multiple participants.
{
"instructionType": "dialogue",
"config": {
"description": "Conversation about project planning",
"participantCount": 2, // 2-6
"style": "casual" // casual, formal, dramatic, humorous
}
}
Generates relevant quotes with optional attribution.
{
"instructionType": "quote",
"config": {
"description": "Quote about innovation and creativity",
"includeAttribution": true // include attribution if true
}
}
Generates summaries of varying lengths and detail.
{
"instructionType": "summary",
"config": {
"description": "Summarize the key benefits of renewable energy",
"length": "standard" // brief, standard, detailed
}
}
Generates descriptive text for images with different styles.
{
"instructionType": "image_description",
"config": {
"description": "Describe a futuristic city skyline",
"style": "photorealistic" // photorealistic, artistic, technical
}
}
The specification publishes the following instruction type libraries. Templates import them through the extends mechanism and may combine several libraries in one template; type names are prefixed by domain so they never collide.
Templates can import instruction type definitions from external schemas using the extends property. This enables sharing and reusing instruction types across templates.
{
"$schema": "https://alexanderparker.github.io/.../its-base-schema-v1.json",
"version": "1.0.0",
"extends": [
"https://alexanderparker.github.io/.../its-standard-types-v1.json",
"./my-local-types.json",
"https://example.com/custom-types.json"
],
"content": [...]
}
When multiple schemas define the same instruction type, the entire definition from the later schema replaces the earlier one. No partial merging occurs.
Instruction types are resolved in this order (highest to lowest precedence):
customInstructionTypes defined in the templateextends arrayextends array{
"extends": [
"schema-a.json", // Lowest precedence
"schema-b.json", // Overrides schema-a
"schema-c.json" // Overrides schema-b and schema-a
],
"customInstructionTypes": {
"mytype": {...} // Highest precedence, overrides all
}
}
Extended schemas must be compatible with the template's base specification version. The version is determined by the $schema reference in the template.
Extended schemas must follow this structure and be validated against the Type Extension Schema:
{
"$schema": "https://alexanderparker.github.io/.../its-type-extension-schema-v1.json",
"title": "My Custom Types",
"description": "Description of these types",
"version": "1.0.0",
"instructionTypes": {
"typeName": {
"template": "<>",
"description": "What this instruction type does",
"configSchema": {
"type": "object",
"properties": {
// Configuration property definitions
}
}
}
}
}
You can define custom instruction types for specific use cases within your template:
{
"customInstructionTypes": {
"my_custom_type": {
"template": "<>",
"description": "Description of what this type does",
"configSchema": {
"type": "object",
"properties": {
"customParam": {
"type": "string",
"enum": ["option1", "option2"],
"default": "option1"
}
}
}
}
}
}
Custom instruction types defined in the template have the highest precedence and will override any types with the same name from extended schemas.
Templates compile into AI prompts following this process:
${variable} references with values
The compiled prompt contains up to four sections. A REFERENCE DATA section appears between
INSTRUCTIONS and TEMPLATE whenever any placeholder names a dataSource
or any variable reference resolves to an object; templates using neither omit that section entirely.
Multiple compiler implementations are available that implement this specification:
The ITS Compiler Python provides the complete reference implementation of the compilation process.
The ITS Compiler JavaScript provides a TypeScript implementation with jsep-based expression evaluation.
See the Compiler Implementation Guide for detailed requirements when building your own compiler.
To prevent parsing conflicts when user descriptions contain quotes, brackets, or other special characters, ITS uses a robust escaping system:
User content wrapper: ([{<USER_CONTENT>}])
Why this pattern:
Handles edge cases like:
"description": "Create code like {\"key\": \"value\"} with \"quotes\" and <<brackets>>"
Safely compiles to:
([{<Create code like {"key": "value"} with "quotes" and <<brackets>>>}])
Input Template:
{
"content": [
{"type": "text", "text": "Here are some fruits:\n"},
{
"type": "placeholder",
"instructionType": "list",
"config": {
"description": "list 5 citrus fruits",
"format": "bullet_points"
}
}
]
}
Compiled Output:
INTRODUCTION
You are an AI assistant that fills in content templates. Follow the instructions exactly and replace each placeholder with appropriate content based on the user prompts provided. Respond only with the transformed content.
INSTRUCTIONS
1. Replace each placeholder marked with << >> with generated content
2. The user's content request is wrapped in ([{< >}]) to distinguish it from instructions
3. Follow the format requirements specified after each user prompt
4. Maintain the existing structure and formatting of the template
5. Only replace the placeholders - do not modify any other text
6. Generate content that matches the tone and style requested
7. Respond only with the transformed content - do not include any explanations or additional text
TEMPLATE
Here are some fruits:
<<Replace this placeholder with a list using this user prompt: ([{<list 5 citrus fruits>}]). Format requirements: Use bullet_points formatting with each item on a new line.>>
This template uses no reference data, so the REFERENCE DATA section is omitted here. When any
placeholder names a dataSource, or any variable reference resolves to an object, that section
is inserted between INSTRUCTIONS and TEMPLATE, giving up to four sections in
total.