Generating and editing structured output (JSON) with LLM's

May 5, 2025

LLM’s are great at creating text output even containing code or other structured data. But it can also output JSON directly according to a JSON schema, which makes it much more reliable.

Below is a small example of how to do that with the OpenAI Completions API (I still use this because other LLM’s like Anthropic and Mistral support this as well).

const response = await fetch(`https://api.openai.com/v1/chat/completions`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer [ADD API KEY HERE]`,
    },
    body: JSON.stringify({
      model: "gpt-4.1",
      messages: [
        { role: "system", content: "you're an expert at creating json data according to a schema" },
        { role: "user", content: "create a random data object" },
      ],
      temperature: 0.2, 
      response_format: {
          type: "json_schema",
          json_schema: {
            name: "Form_schema",
            schema: {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "$id": "https://example.com/schema.json",
              "title": "UI Schema",
              "description": "Schema for describing complex UIs, including websites, forms, decision trees, and CRUD operations.",
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"              
                },                
              },
              "required": ["name"]
            },
          },
      }
    })
});
const data = await response.json();
console.log(data.choices[0].message.content);

While the above example is a simple one, using a json schema is a very powerful method because you can transform human natural language to a technical format that can be used in your code. For example, if you create a JSON schema for forms, you can use the LLM to create a form based on a description of the form in natural language. This way non or less technical people can create forms and other structured data without needing to know how to code. This doesn’t make developers obsolete, but it does make it easier for non-technical people to create structured data and smoothen the proces.

One step further is to use the LLM to edit existing JSON data. JSON data can be edited with the JSON Patch standard RFC 6902. This is a standard for editing JSON data in a structured way. The LLM can be used to create a JSON Patch based on a description of the changes that need to be made to the JSON data. This way you can use the LLM to edit existing JSON data in a structured way.

const response = await fetch(`https://api.openai.com/v1/chat/completions`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer [ADD API KEY HERE]`,
    },
    body: JSON.stringify({
      model: "gpt-4.1",
      messages: [
        { role: "system", content: `You are an expert at generating JSON patches to update form definitions. Your task is to analyze the current form definition and the requested changes, then generate a JSON patch document that will update the form according to the requirements.

The JSON patch document should follow RFC 6902 specification and contain one or more operations to modify the form definition. Each operation should be a valid JSON patch operation with:
- "op": The operation to perform (add, remove, replace, move, copy)
- "path": The JSON pointer to the location to modify
- "value": The new value (for add and replace operations)

Example JSON patch:
[
  {
    "op": "replace",
    "path": "/app/pages/0/components/0/props/content",
    "value": "New content text"
  },
  {
    "op": "add",
    "path": "/app/pages/0/components/0/props/helperText",
    "value": "Additional help text"
  }
]

Your response must be a valid JSON array of patch operations. Do not include any explanations or markdown formatting.` },
        { role: "user", content:`Current form definition:
{
  name: "Hello data!",
}

Requested changes:
Change the name to "Hello world!"

Generate a JSON patch document to update the form according to the requested changes.`},
      ],
      temperature: 0.2, 
    })
});
const data = await response.json();
console.log(data.choices[0].message.content);

The above doesn’t use a json-schema for the json patch document, that could improve it further. I didn’t include the processing of the JSON patch document in the example either, you can use a library like fast-json-patch to apply the JSON patch document to the JSON data. But the idea is clear I think.

This is a very powerful method to use LLM’s and allow for a much more surgical approach to improving the software devlelopment process. I know that an LLM is already very good at creating code, but I think you need to split the process in smaller steps to get the best results. If you just let it generate code, you let it do too much in one go. By splitting the process in smaller steps, you also keep the human in the loop and have controll. The code that needs to be used to render the generated JSON can off course also be generated by an LLM. See PromptToForm.AI for an example of this, which is also created by me using LLM’s.

Basically any repeatable code can be expressed as a json schema, and then you can use an LLM to generate the JSON data and modify it further yourself. If needed you can add some escape hatches to the JSON schema to allow for more complex cases that need custom code as well.

If you have any questions or feedback, feel free to reach out to me here: maikel@devhelpr.com