skip to content

Why send schema-validated payloads between agents instead of free-text messages?

level: middleimportance: must knowfreq 62%

answer

  1. free text is an unwritten contract
  2. required fields, types, enums
  3. fails loudly and locally instead
  4. costs no model call to check
  5. valid shape, still-wrong value

basics

~20 s

A schema turns an implicit agreement into a checkable one. Required fields, types and enums let the receiving agent reject a malformed message at the boundary with a precise error, instead of a model quietly inventing the missing value and shipping a wrong result downstream.

solid answer

~50 s

Free text between agents is an undocumented contract: the sender can drop a field, rename it, or hedge it, and nothing fails — the receiver just reasons over slightly different input and produces a slightly worse answer. A schema (typically JSON Schema) makes the contract explicit: `QuoteRequest` requires `sku`, `quantity` and `currency`, `currency` is an enum, `quantity` is a positive integer. When a message arrives without `currency`, validation fails at the boundary and the receiver returns a machine-readable error naming the missing field, so the producing agent can repair and resend. Crucially, the check is cheap and deterministic — it costs no model call and cannot itself hallucinate. What a schema does *not* buy is semantic correctness: a payload with `currency: "USD"` when the supplier quotes euros is perfectly valid and completely wrong, so you still need business validation and, for anything consequential, verification against a source of truth.

code

json · 13 lines
json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "QuoteRequest",
  "type": "object",
  "required": ["sku", "quantity", "currency"],
  "properties": {
    "sku": { "type": "string", "pattern": "^SKU-[0-9]{4}$" },
    "quantity": { "type": "integer", "minimum": 1 },
    "currency": { "type": "string", "enum": ["USD", "EUR", "GBP"] },
    "needed_by": { "type": "string", "format": "date" }
  },
  "additionalProperties": false
}

go deeper

for a junior

Know that agents can exchange JSON validated against a schema, and that a missing required field should be rejected rather than guessed at by the next model.

for a middle

Explain what the schema enforces — required fields, types, enums — and why the check is valuable precisely because it is deterministic and costs no model call.

for a senior

Show the layering: shape at the boundary, cross-field business rules next, verification against a source of truth for consequential values. Be explicit that a valid payload can still be entirely wrong.

for a principal

Own schema evolution and placement: who publishes the contract, how it versions across independently released agents, and when a typed envelope around free text beats forcing everything into fields.

## The problem with free text at a seam When agent A sends agent B a paragraph, there is still a contract between them — it is just written nowhere and enforced by nothing. A stops emitting the delivery date; B keeps running. A renames "unit price" to "price per unit"; B keeps running. A hedges ("roughly 1,200, possibly in euros"); B keeps running. In every case the system does not fail loudly, it degrades quietly, and the defect surfaces several steps later as a wrong answer whose cause is expensive to trace. This is the central argument for structured payloads between agents: **turn a silent degradation into a loud, local failure.** ## What a schema actually gives you A schema — in practice JSON Schema, because it is what tool and agent ecosystems already speak — declares: - **Which fields must be present** (`required`), so an omission is an error rather than a default. - **Types**, so `quantity: "a dozen"` is rejected before anyone reasons about it. - **Enums and ranges**, so `currency` must be one of a known set and `quantity` must be a positive integer. - **Shape of nested objects and arrays**, so a list of line items cannot arrive as a single blob of prose. Two properties matter more than the list itself. First, validation is **deterministic and free**: it is a library call, not a model call, so it costs no tokens, adds a millisecond, and cannot itself be wrong in the way a judging model can. Second, the error is **specific**: "required property `currency` is missing at `/items/0`" is something the producing agent can act on, unlike "that didn't look right". ## A concrete rejection A procurement intake agent builds a `QuoteRequest` from an unstructured purchase request and sends it to a negotiation agent. The buyer's email said "120 units of SKU-4471, need it in two weeks" and never mentioned a currency. The intake agent, generating JSON from free text, simply omits the field. With a schema, the negotiation agent's boundary rejects the payload immediately and returns an error naming `currency`. The intake agent can then do the right thing: ask the user, look up the buyer's default, or fail the request explicitly. Without a schema, the likely outcome is that the model on the other side assumes dollars, negotiates a contract in the wrong currency, and nobody notices until reconciliation. Note what the boundary should *not* do: it should not guess. Silently defaulting `currency` to USD and logging a warning is how a validation layer becomes a source of bugs — it converts an error the system could have surfaced into data the system now believes. ## Where validation belongs Validate on the **receiving** side, always — that is your trust boundary, and the sender's promises are not enforcement. Validating on the sending side too is a cheap extra: it catches the model's own malformed generation before it crosses the wire, where the fix is local and the context that produced it is still available. Many stacks also constrain the model at generation time (structured-output or strict schema modes), which reduces malformed payloads but does not remove the need for the receiver's check — the message may have crossed a network, a queue, or an organizational boundary since. Treat an incoming agent message as **untrusted input** regardless of schema conformance. Schema validity says nothing about authorization, and a well-formed payload from an agent you did not expect to hear from is still an attack surface. ## What a schema cannot check This is the half of the answer that separates a middle from a senior response: - **Semantically wrong but structurally valid.** `unit_price: 12.40` when the real quote was 1240.00 passes every check. - **Hallucinated values.** A model asked to fill a schema will fill it — a required field is pressure to invent, not permission to omit. Optional fields plus an explicit `unknown` signal often produce more honest payloads than making everything required. - **Cross-field consistency**, unless you encode it: `delivery_date` before `order_date` needs a business rule, not a type. - **Stale or unauthorized data.** Freshness and permission live outside the schema. So the layered answer is: schema validation at the boundary for shape, business rules for consistency, and verification against a source of truth for anything consequential. ## The cost Schemas are not free. They must be versioned and evolved on both sides, and inside one codebase where both agents deploy together, a shared typed object is usually enough — a formal schema earns its keep when the two ends are released independently or owned by different teams. Overly rigid schemas also constrain what agents can express; a common compromise is a small typed envelope (identity, task id, structured fields) around a free-text section for genuinely open content.

  • Doesn't marking every field required just push the model to invent values?
    Often, yes. A required field is pressure to fill it, and a model under that pressure will guess rather than omit. The usual mitigation is to require only what genuinely cannot be defaulted, allow an explicit null or an `unknown` enum member for the rest, and treat a returned `unknown` as a signal to ask a human or another source rather than as a failure.
  • Where should validation run when the two agents are in different organizations?
    On the receiver, unconditionally — the sender's validation is a courtesy, not a guarantee, and anything crossing an organizational boundary is untrusted input. Validate shape at the edge, then authorize the calling agent separately: a schema-valid request from an agent with no right to quote on your behalf is still a request you must refuse.
  • What breaks first when you version a shared payload schema badly?
    Adding a required field breaks every sender that has not shipped yet, and removing one breaks receivers that still read it. The safe evolution path is the usual contract discipline: add optional fields, never repurpose an existing field's meaning, and retire a field only after both ends have stopped using it. Ship the schema and its consumers as a versioned artifact so drift is visible.

saying these in an interview costs you the question

  • Says the model will figure out a missing field
  • Defaults the missing value silently and logs a warning
  • Claims schema validity proves the values are correct
  • Validates only on the sending side
  • Treats a schema-valid message as automatically authorized

context