SwiftRelay

← All sprint notes

First Lap: Ship Schema-Checked JSON from Chat Models

First lapsEN

1. Pick one JSON contract before writing the prompt

Start with a small extraction task: turn a customer message into a support ticket. Your application needs a subject, a category, and an urgency flag. Define those fields before choosing a model or polishing instructions. Structured output works best when the destination is a contract, not a suggestion to “return something useful.”

For this first run, require exactly three fields: subject as a string, category as one of billing, access, or other, and urgent as a boolean. Reject extra properties so an unexpected explanation cannot quietly become part of your application data.

2. Express the ticket contract as JSON Schema

Use a schema your application can validate independently. A compact starting point is:

{"type":"object","properties":{"subject":{"type":"string"},"category":{"type":"string","enum":["billing","access","other"]},"urgent":{"type":"boolean"}},"required":["subject","category","urgent"],"additionalProperties":false}

This contract prevents several common mistakes: missing fields, invented categories, and the string “false” where your code expects a boolean. Keep the schema within the subset supported by your selected endpoint. Some structured-output implementations support fewer JSON Schema features than a general-purpose validator.

3. Connect your SDK and verify structured-output support

If you want a shared connection point for model experiments, SwiftRelay provides a pay-as-you-go relay compatible with OpenAI SDKs. Set the SDK base URL to https://api.fastapirelay.com/v1 and load your API key from an environment variable. Keep that key on your server, never in browser code or a committed example file.

Sign up for SwiftRelay to try this workflow with the small gift credit provided to new accounts. Before sending your schema, verify that the selected model and relay route support your intended structured-output parameters. OpenAI-compatible transport does not guarantee identical feature support across every model.

4. Request schema-constrained output, not just JSON

For a Chat Completions endpoint that supports it, configure response_format with type json_schema. Its json_schema object should contain a name such as support_ticket, the schema from step two, and strict set to true where supported. Parameter placement differs between API families, so match the endpoint documentation rather than copying settings across APIs.

Do not treat JSON mode as equivalent. JSON mode targets valid JSON syntax; schema-constrained output additionally targets the declared structure. Neither proves that the extracted facts are correct. If your route only supports JSON mode, retain the same application validator and expect to handle more structural failures.

5. Give the model explicit extraction rules

Keep the instructions separate from the customer message. Tell the model to classify payment problems as billing, sign-in problems as access, and everything else as other. Define urgent narrowly, such as an explicit report that work is blocked. Ask for a short subject based only on the supplied message.

For example, the input “I cannot sign in, and my work is blocked” could produce:

{"subject":"Unable to sign in","category":"access","urgent":true}

Treat customer text as data, not instructions. A message saying “ignore the schema” should remain material to classify, not permission to change your output contract. The schema helps constrain shape; your instruction hierarchy and application controls still matter.

6. Validate the response before using its fields

Check for API errors, refusals, and incomplete generation before parsing the response content. Then parse JSON and run a local JSON Schema validator. Do not extract an apparent object from surrounding prose with a regular expression and assume success.

  • Syntax check: the content parses as JSON.
  • Schema check: required fields, types, enums, and extra-property rules pass.
  • Business check: the values make sense for the original message and your workflow.

Keep authorization separate. A valid urgent flag must not automatically grant privileges or trigger an irreversible action.

7. Add bounded recovery and a regression checklist

On a recoverable validation failure, make a bounded retry with a concise description of the failed constraint. Do not retry indefinitely or silently replace invalid values with guesses. Route persistent failures to a controlled error path or human review.

Before shipping, test empty messages, ambiguous categories, instruction-like customer text, refusals, and interrupted responses. Record the model identifier, schema version, validation outcome, and retry count while redacting sensitive content. Repeat these tests when changing models or schemas. Your finish line is not “the model returned JSON”; it is “the application accepted a validated, meaningful object.”

Keep reading

Back for another lap?Log in