Skip to content

Structured Output

When another application calls a program, it needs a result it can read reliably. Structured output returns values such as records and lists instead of asking the caller to interpret a printed sentence. For example, a pricing tool can return an amount and a customer tier as separate fields.

Use Respond with to finish successfully with a value, or Fail with to report an error. This page shows the Devlish statements, their JSON representation, and how a caller receives the result. See Your First Tool for a complete tool-building tutorial.

Respond with serializes a value as JSON, writes it to the program’s output, and stops execution.

Respond with record with "completed" as status and 42 as score

Output:

{
"status": "completed",
"score": 42
}

Any value type works: records, lists, strings, numbers, or booleans.

Respond with list of "tax_credit", "depreciation", and "bonus"

When Fail with receives a record, it serializes as JSON and exits with a non-zero code:

Fail with record with "awaiting_input" as status and "Cannot classify document" as message

Output (exit 1):

{
"status": "awaiting_input",
"message": "Cannot classify document"
}

When Fail with receives a plain string, the error message is returned directly:

Fail with "Missing required field: customer_email"

When a Devlish program runs as an MCP tool, the response is wrapped in the MCP result envelope:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"status\":\"completed\",\"score\":42}"
}
]
}
}

The calling LLM receives the JSON string in the tool result and can parse it for further reasoning.

Compose complex responses by building records step by step:

# Gather data
Read JSON from "analysis.json" as raw_data
findings equals filter items of raw_data where severity equals "high"
finding_count equals count of findings
# Build response record
response equals record with "success" as status and finding_count as total_findings and findings as high_severity_items
Respond with response

Use branching to return different shapes based on results:

If validation_passed:
Respond with record with "pass" as result and score as final_score
Otherwise:
Fail with record with "fail" as result and errors as validation_errors

In class-style programs, respond with serves as both the method return value and the tool output:

Finance's Credit Analyzer:
analyze credit using project_id and credit_type:
# ... computation ...
result equals record with project_id as id and calculated_value as value and "ITC" as type
respond with result
# Permissions:
# Read files from "/data/"
Read JSON from "/data/projects.json" as projects
active equals filter projects where status equals "active"
total_value equals reduce active starting at 0 with sum and item to sum plus value of item
Respond with record with count of active as project_count and total_value as portfolio_value