Search IOCombats

Search challenges, guides, questions and articles

Structured output vs JSON mode vs function calling: what is the difference?

Intermediate9 min interview
Skills tested:
Explaining the guarantee each approach gives: valid JSON vs schema-shaped JSON vs typed tool argumentsKnowing who consumes the output: your UI for structured output, your code for tool callsKnowing the strict schema rules: additionalProperties false, required fields, nullable instead of optionalHandling the cases where even strict output can fail: refusals and token limitsMapping the concepts to the AI SDK output option and tool definitions

Advertisement

🧩 Scenario

Your team wants an AI feature that turns a pasted job description into a form: title, location, salary range and skills. One engineer suggests "just ask for JSON", another suggests a tool call. The interviewer asks you to explain the three options and pick one.

Concept Walkthrough

Three different promises

Think of it like TypeScript levels of safety.

  • JSON mode is like JSON.parse succeeding. You know the text is valid JSON. You do not know if title exists or if salary is a number. It is the any of the three.
  • Structured output is like a typed API response. You send a JSON Schema, and the provider constrains generation so the reply follows that schema. Anthropic describes its version as compiling the schema into a grammar, which is why the first request with a new schema has extra latency (both OpenAI and Anthropic document this).
  • Function calling (tool calling) uses a schema too, but for the arguments of a function. The model does not answer the user. It returns "please call searchJobs with these arguments", your server runs it, and the result goes back to the model.

Who reads the output?

This is the simplest way to choose. If your UI or database reads the result directly (a form, a card, a list), use structured output. If your code needs to do something before the model can answer (look up data, call an API, write to a database), use a tool. OpenAI's guide frames it the same way: tools connect the model to your functions and data, a response format shapes the reply to the user.

Strict schemas have rules

For strict mode, OpenAI's examples set additionalProperties: false, list every property in required and express "optional" as a union with null. So you write salary: z.number().nullable(), not .optional(). Anthropic's SDK helpers remove constraints such as minimum and maxLength from the schema they send and check them after the response instead.

Strict is not the same as guaranteed

Two cases still break the shape. A refusal: Anthropic notes the refusal message takes precedence over schema constraints, and you still get a 200. A token limit: if output stops at max_tokens, the JSON may be incomplete. That is why you still validate.


Key Code Explained

import { generateText, Output, NoObjectGeneratedError } from 'ai';
import { z } from 'zod';
import { chatModel } from '@/lib/models';

const jobSchema = z.object({
  title: z.string(),
  location: z.string().describe('City, or "Remote"'),
  // nullable, not optional: strict schemas want every key present
  salaryLakhsPerYear: z
    .object({ min: z.number(), max: z.number() })
    .nullable(),
  skills: z.array(z.string()),
});

export async function extractJob(description: string) {
  try {
    // Structured output: the final answer itself follows the schema
    const { output } = await generateText({
      model: chatModel,
      output: Output.object({ schema: jobSchema }),
      prompt: `Extract the job details:\n\n${description}`,
    });
    return output; // typed as z.infer<typeof jobSchema>
  } catch (error) {
    if (NoObjectGeneratedError.isInstance(error)) {
      // Parse or validation failed. error.text has the raw reply
      console.error('Bad object', error.cause);
      return null;
    }
    throw error;
  }
}

Compare this with a tool. With a tool you would define searchJobs with an inputSchema, and the model would return arguments for your code to run. Using a tool only to get JSON back works, but it is a workaround from before structured output existed.


Tradeoffs

ApproachGuaranteeBest forWatch out for
JSON modeValid JSON syntax onlyOlder models without schema supportMissing or extra fields
Structured outputJSON that follows your schemaForms, cards, extraction, UI dataSchema feature limits, first-call delay
Function callingTyped arguments for your functionActions and data lookups in your codeExtra round trip, security of the tool

What Interviewers Actually Check

  • Whether you can say exactly what JSON mode does not guarantee
  • Whether you pick based on who consumes the output
  • Whether you know strict schemas use nullable fields instead of optional ones
  • Whether you still validate after strict output, and can explain why
  • Whether you know your server, not the model, executes a tool

Follow-Up Questions

  1. Why does the first request with a new schema take longer?
  2. How would you handle a field that has a regex rule the provider does not support?
  3. What happens to your schema guarantee when the response hits the output token limit?
  4. Can you stream structured output to the UI? What does the client receive mid-stream?
  5. When would you combine a tool call and a structured final answer in one request?

Common Candidate Mistakes

  • Calling JSON mode and structured output the same thing
  • Using .optional() everywhere and then hitting strict schema errors
  • Skipping validation because "strict mode guarantees it"
  • Explaining function calling as "the model runs my function"
  • Ignoring refusals, so the UI tries to render a refusal as a job card

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you explain the guarantee of JSON mode, structured output and function calling in one line each?
  • Can you choose between structured output and a tool for a given feature?
  • Can you write a strict-friendly Zod schema?
  • Can you name two cases where strict output still fails?
  • Can you write generateText with Output.object and handle NoObjectGeneratedError?

Summary

JSON mode gives you parseable JSON and nothing more. Structured output constrains the reply to your JSON Schema, which makes it the right default when your UI or database consumes the result. Function calling uses schemas for tool arguments, so the model can ask your code to do something before it answers. Strict schemas want every key present, so use nullable fields for missing data. Even with strict mode, refusals and token limits can break the shape, so validate the result in your code and handle the failure path.

Frequently Asked Questions

If structured output enforces the schema, do I still need Zod on my side?

Yes. Rules like minimum, maximum or string length may be dropped from the schema the provider enforces, a refusal or a token limit can cut the output short, and older models may not support strict schemas at all. Validating the final object in your code is cheap insurance.

Is JSON mode still useful?

OpenAI describes Structured Outputs as the evolution of JSON mode and recommends it where supported. JSON mode is mostly a fallback for models that do not support schemas.

Can a single request use structured output and tools together?

Yes. Anthropic, for example, documents JSON outputs and strict tool use as features you can use separately or together. The tools control how the model calls your code, the output format controls its final answer.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Namaste Dev
Sponsored

Cohort-style courses to go from tutorials to job-ready.

Explore Courses

Advertisement