Part I — Software proposals
When generated language becomes input
A model response crosses a consequential boundary when software, rather than a person, consumes it. Ordinary prose can suggest, “Create an issue titled Login failure.” A machine-readable response can represent the same intent as an operation name plus arguments. That representation enables automated checks, but it does not give the model authority to execute anything. In the demonstrated function-calling loop, the model expresses an intended operation and arguments; application code performs the operation and returns its result to the model. Software contracts supply the broader idea: an interface states obligations, but code at the boundary must establish them at runtime.
Four states worth naming
- Proposed record — Candidate data, such as an extracted invoice or classification. It has not yet been accepted as correct application data.
- Proposed action — A request naming an operation and its arguments. It describes what the model wants the application to consider doing.
- Accepted operation — A proposal that has passed the application’s structural, semantic, state, and authorization checks.
- Observed effect — Evidence from the relevant external boundary that execution produced, failed to produce, or may have produced the intended state change.
These states prevent a fluent response from laundering uncertainty. A sentence saying “The message was sent” is merely generated text. A tool result saying “accepted” proves only what that component’s contract defines. If the user cares whether a message rendered in a client, a provider receipt or edge observation must establish that later fact. The evidence chain is proposal, policy decision, execution attempt, and external confirmation—not one undifferentiated success flag.
From model response to observed effect
A typed representation enables checks, but proposal, acceptance, execution, and observation remain separate states.
Read the diagram as text
- Model response. Generated content that is not trusted merely because it is fluent.
- Prose. A person interprets meaning and decides whether to act.
- Typed proposal. Candidate record or action request; it has not executed.
- Validate. Establish completion, parsing, schema, and domain claims.
- Authorize. Decide whether this actor may perform this operation on this resource.
- Execute. Dispatch a recognized implementation across the effect boundary.
- Observed effect. Evidence from authoritative state or the user-visible boundary.
- Model response → Prose: text for interpretation.
- Model response → Typed proposal: structured representation.
- Typed proposal → Validate: candidate data.
- Validate → Authorize: accepted arguments.
- Authorize → Execute: policy allows.
- Execute → Observed effect: external observation.
What a schema promises
A schema is a machine-readable description of permitted data structure. JSON Schema can constrain object properties, required fields, primitive types, arrays, enumerated values, numeric bounds, and whether undeclared properties are allowed. The details matter. Listing a property does not make it required. additionalProperties is allowed by default unless constrained. A missing property differs from a present property whose value is null. A root $schema declaration identifies the dialect whose keyword meanings apply, although a generation engine may still implement only a subset of that dialect.
Constraint and claim
| Schema element | What it establishes | What it does not establish |
|---|---|---|
type: "integer" | The value has the validator’s integer representation. | The number is factually correct or sensible for the domain. |
required: ["project_id"] | The named field must be present. | The referenced project exists or is accessible. |
enum: ["low", "high"] | Only a listed value is accepted. | The chosen value matches the source or user intent. |
additionalProperties: false | Unknown object fields are rejected. | Known fields are sufficient for the operation. |
description or default | Documentation or a hint is attached to the schema. | The description is enforced or a missing value is inserted. |
items plus length rules | Array members and permitted length are constrained. | The members are complete, unique in the domain, or correctly ordered. |
Suppose a valid record is {"project_id":"P-17","priority":"high"}. The schema can prove that both fields are present and have permitted representations. It cannot prove that P-17 exists, that the caller may modify it, or that “high” reflects the request. Structured-output APIs themselves warn that schema-conforming values can still contain mistakes, and applications must separately handle refusals and incomplete responses. Structure is a precondition for dependable consumption, not a certificate of truth or permission.
Part II — Continuing foundations
Grammars, interfaces, and constrained generation
Modern structured output combines several older engineering lines. Formal-language work made valid symbol sequences explicit. Interface contracts separated operation descriptions from implementations. Schema languages described admissible data. Later neural systems incorporated grammatical structure into generation, and model APIs exposed function-shaped records that applications could dispatch. These lines coexist because they answer different questions: what strings belong to a language, what values an interface accepts, what operation is being requested, and who actually performs it.
Foundations of structured generation and tool calling
1963Revised ALGOL 60 reportSpecified valid program structure with recursive metalinguistic formulas.
Contributors: Peter Naur and the ALGOL committee
What changed: Made a programming language’s permitted symbol sequences explicit independently of executing the programs they described.
February 1984Cedar RPCGenerated client and server stubs from typed procedure interfaces.
Contributors: Andrew Birrell and Bruce Nelson
What changed: Reduced bespoke communication code while preserving the reality that remote components can fail independently.
December 5, 2009Early JSON Schema Internet-DraftProposed JSON-based contracts for validation, documentation, properties, arrays, bounds, and enumerated values.
Contributors: Kris Zyp
What changed: Established an early standards proposal for describing admissible JSON data separately from each instance.
2017Yin and Neubig syntax-directed generationGenerated abstract syntax trees through grammar-production actions.
Contributors: Pengcheng Yin and Graham Neubig
What changed: Encoded syntax in the available generation actions instead of requiring the model to learn the entire grammar from examples.
November 2021PICARDRejected inadmissible SQL continuations through incremental parsing during decoding.
Contributors: Torsten Scholak, Nathan Schucher, and Dzmitry Bahdanau
What changed: Showed how inference-time parsing could constrain ordinary generated text and incorporate database-schema checks.
February 2023ToolformerTrained a model to decide whether, when, and how to call a bounded set of APIs.
Contributors: Timo Schick and colleagues
What changed: Combined model-selected API calls with returned results across calculator, search, translation, calendar, and question-answering tools.
June 13, 2023OpenAI function callingExposed JSON Schema function descriptions and model-selected argument objects.
Contributors: OpenAI
What changed: Applied function-shaped output to both proposed external operations and structured data extraction.
July 2023Efficient guided generationIndexed recognizer states to acceptable vocabulary tokens for regex-guided generation.
Contributors: Brandon Willard and Rémi Louf
What changed: Moved repeated token-validity work outside sampling and reduced per-step lookup work in the analyzed construction.
Selected turning points
| Date | Development | Contribution |
|---|---|---|
| 1963 | Revised ALGOL 60 report | Used recursive metalinguistic formulas to specify which symbol sequences form programs. |
| February 1984 | Birrell and Nelson’s Cedar RPC system | Generated client and server stubs from interfaces naming procedures and argument/result types, while acknowledging independent network failures. |
| December 5, 2009 | Early JSON Schema Internet-Draft | Proposed JSON-based contracts for validation, documentation, properties, arrays, bounds, and enumerated values. |
| 2017 | Yin and Neubig’s syntax-directed code generation | Generated abstract syntax trees through grammar-production actions instead of learning all syntax only from examples. |
| November 2021 | PICARD | Rejected inadmissible SQL continuations through incremental parsing during decoding. |
| February 2023 | Toolformer | Trained a model to decide whether, when, and how to call a bounded set of APIs and incorporate their results. |
| June 13, 2023 | OpenAI function calling announcement | Let developers provide JSON Schema function descriptions and receive model-selected argument objects for extraction or external operations. |
| July 2023 | Efficient guided generation | Indexed recognizer states to acceptable vocabulary tokens for regex-guided generation. |
The chronology is not a claim that one publication caused the next or that newer mechanisms replaced earlier ones. Constrained generation still needs a parser or recognizer. A schema-shaped function request still needs application dispatch. RPC-style interfaces still face remote failure. None of these mechanisms decides whether the requested action is semantically appropriate or authorized.
Part III — Structured values
Parsing is a sequence of claims
“It looks like JSON” compresses several independent questions. First, did the provider finish the response rather than stop at a length limit or refusal? Second, did transport decoding yield the intended bytes or text? Third, did the parser consume exactly one complete JSON document under the application’s chosen policy? Fourth, does the resulting value satisfy the schema? Only then can domain validation ask whether the value is usable. Validate external values develops this general boundary; model output adds the risk that a plausible-looking value was probabilistically generated.
Acceptance gates for generated data
Completion, parsing, schema conformance, and application validity fail for different reasons and justify different responses.
Read the diagram as text
- Provider response. Content plus refusal, completion, or truncation status.
- Completion check. Reject refusal, token exhaustion, or unfinished output.
- Whole-document parse. Consume exactly one JSON document under explicit duplicate, suffix, and number policies.
- Schema validation. Check the declared structural contract.
- Application validation. Check invariants, references, state, and other domain rules.
- Accepted record. Candidate data admitted to the next application boundary.
- Rejected result. Preserve the failed claim and safe corrective information.
- Provider response → Completion check: status and content.
- Completion check → Whole-document parse: complete.
- Completion check → Rejected result: refused or incomplete.
- Whole-document parse → Schema validation: one parsed value.
- Whole-document parse → Rejected result: syntax or policy failure.
- Schema validation → Application validation: structure accepted.
- Schema validation → Rejected result: schema rejected.
- Application validation → Accepted record: domain accepted.
- Application validation → Rejected result: domain rejected.
Small failures at different layers
| Emission or condition | First failed claim | Why policy matters |
|---|---|---|
Response ends after {"id":"P- | Completion | A partial parser may retain earlier fields, but that does not make the original response complete. |
{"n":1} trailing text | Whole-document parsing | Some parsers can decode the first value and report where it ended; callers must reject an unconsumed suffix when the contract requires one document. |
{"role":"viewer","role":"admin"} | Unambiguous object interpretation | JSON implementations may reject duplicate names, retain one value, or expose both. |
{"count":"7"} | Schema or strict runtime validation | A permissive validator may coerce a numeric string; that transformation must be an explicit interface policy. |
{"project_id":"P-404"} | Domain validation | The shape can be valid while the referenced entity does not exist. |
Repair and coercion are transformations, not neutral cleanup. Guessing a missing quotation mark, discarding a suffix, selecting the last duplicate member, or converting strings to numbers can change meaning. A safe system preserves the raw emission for diagnosis, records the transformation policy, and rejects ambiguity when downstream consequences exceed what the repair can justify. TypeScript annotations alone do not help at this boundary because ordinary annotations are erased from emitted JavaScript; incoming data still needs runtime checks.
How constrained decoding blocks malformed continuations
Autoregressive generation chooses one token after another. Constrained decoding adds a recognizer for the permitted output language. Given the generated prefix, the recognizer determines which vocabulary tokens can still lead to a valid completion. Invalid candidates are masked before selection; the chosen token then advances the recognizer state. OpenAI has described compiling supported JSON Schema into a context-free grammar and caching an artifact used to determine valid continuations. Outlines describes the same central idea as testing candidate tokens and masking those that would violate the requested structure.
The recognizer cannot simply count braces. JSON strings can contain escaped quotation marks and brace characters that do not close an object. A tokenizer token can also span grammar boundaries or split a UTF-8 character, so implementations may need to match its bytes through several parser transitions. XGrammar describes a byte-level pushdown automaton with live stack state, cached context-independent masks, and additional checks for context-dependent tokens. The representation details belong in Tokenization; the consequence here is that token validity depends on both the prefix and the tokenizer.
Prefix state changes the allowed next piece
ExampleCandidate validity depends on both the candidate text or byte piece and the recognizer state created by the prefix.
The current state is after the opening brace. Every stable candidate is classified: the id field piece is allowed and selected; the colon, closing brace, and escaped quote are masked.
Read the diagram as text
- Toy object schema. Requires one string field named id.
- Candidate piece: "id". Illustrative text or byte piece, not a claim about one tokenizer vocabulary entry.
- Candidate piece: :. Illustrative separator piece.
- Candidate piece: }. Illustrative object-closing piece.
- Candidate piece: \". Illustrative bytes for an escaped quotation mark inside a JSON string.
- Current state: after {. The required property name must begin here.
- Next state: after field name. Reached by selecting the allowed id field piece.
- Current state: after field name. The recognizer now expects the name/value separator.
- Next state: before string value. Reached by selecting the allowed colon piece.
- Current state: inside string value. Escape-aware string rules now determine candidate validity.
- Next state: still inside string. An escaped quotation mark adds content without ending the string.
- Toy object schema → Current state: after {: constrains.
- Current state: after { → Candidate piece: "id": allowed and selected.
- Current state: after { → Candidate piece: :: masked.
- Current state: after { → Candidate piece: }: masked: required field missing.
- Current state: after { → Candidate piece: \": masked.
- Candidate piece: "id" → Next state: after field name: advance.
- Current state: after field name → Candidate piece: "id": masked.
- Current state: after field name → Candidate piece: :: allowed and selected.
- Current state: after field name → Candidate piece: }: masked.
- Current state: after field name → Candidate piece: \": masked.
- Candidate piece: : → Next state: before string value: advance.
- Current state: inside string value → Candidate piece: "id": masked: unescaped quote.
- Current state: inside string value → Candidate piece: :: allowed string content.
- Current state: inside string value → Candidate piece: }: allowed string content.
- Current state: inside string value → Candidate piece: \": allowed and selected.
- Candidate piece: \" → Next state: still inside string: advance without closing.
- Object opened. The current state is after the opening brace. Every stable candidate is classified: the id field piece is allowed and selected; the colon, closing brace, and escaped quote are masked. Active: Toy object schema, Candidate piece: "id", Candidate piece: :, Candidate piece: }, Candidate piece: \", Current state: after {, Next state: after field name. New: Toy object schema, Candidate piece: "id", Candidate piece: :, Candidate piece: }, Candidate piece: \", Current state: after {, Next state: after field name.
- Property named. The current state now expects a separator. The colon is allowed and selected; all other displayed candidates are masked. Selecting the colon advances to the value position. Active: Toy object schema, Candidate piece: "id", Candidate piece: :, Candidate piece: }, Candidate piece: \", Current state: after field name, Next state: before string value. New: Current state: after field name, Next state: before string value.
- Inside the string. The current state is inside a JSON string. Colon and closing-brace pieces are permitted as string content, an unescaped quoted id piece is masked, and the escaped quote is allowed and selected. Its escape keeps the recognizer inside the string. Active: Toy object schema, Candidate piece: "id", Candidate piece: :, Candidate piece: }, Candidate piece: \", Current state: inside string value, Next state: still inside string. New: Current state: inside string value, Next state: still inside string.
Masking guarantees only membership in the language implemented by the recognizer. It does not guarantee that a generated identifier exists, an extracted amount matches a document, or a requested operation is permitted. It can also alter content probabilities. Ordinary grammar-constrained decoding renormalizes among currently admissible tokens; that distribution is not generally identical to the model’s distribution conditioned on eventually producing a complete valid string, because exact conditioning would also account for each candidate’s probability of future grammatical completion.
Coverage, latency, and incomplete output
A schema can be valid JSON Schema yet unusable by a particular structured-output engine. Providers commonly support subsets; large or deeply nested schemas may be rejected, and converters can silently skip unsupported features. A production contract must therefore pin the provider, model or runtime, schema dialect, converter, and supported feature set. Inspect warnings and test the language actually enforced rather than assuming that a valid application schema was translated exactly.
Four independent operational questions
| Question | Evidence needed | Common mistake |
|---|---|---|
| Will the API accept the schema? | A versioned feature-coverage test against the actual endpoint. | Treating general JSON Schema validity as provider support. |
| Does the engine enforce the intended language? | Positive and negative conformance cases, including unsupported keywords and nesting. | Inferring exact language equivalence from a few compliant samples. |
| Will execution meet latency and capacity needs? | Compilation, cache, per-token, batching, and memory measurements on the target stack. | Repeating an implementation-specific “zero overhead” claim universally. |
| Is a streamed prefix safe to consume? | Explicit partial-state semantics and a final completion signal. | Treating a parsed partial object as a final authorized record. |
| Does task quality remain acceptable? | Representative semantic evaluation separate from format compliance. | Assuming fewer malformed outputs means better answers. |
Published results illustrate why these dimensions stay separate. JSONSchemaBench evaluates schema acceptance, feature coverage, compliance, efficiency, and task quality independently; finite compliant samples cannot prove that an engine implements exactly the schema’s accepted language. A 2025 study across its selected models and tasks found that format constraints and semantic task quality could move differently, with effects varying by model and task. Treat such findings as reasons to measure your own workload, not as a universal penalty or benefit.
Structure is not domain correctness
Once a record passes structural validation, semantic validation asks whether its values are acceptable in the application’s domain and current state. Checks can include cross-field invariants, membership in a controlled set, referential integrity, units, temporal order, and preconditions. A receipt model can require numeric line items, yet still need to verify that quantity times unit price reconciles with totals. A scheduling request can contain valid timestamps while placing the end before the start. A project identifier can match its pattern while naming no current project.
Checker and supported claim
| Checker | Can establish | Cannot establish alone |
|---|---|---|
| Schema validator | Fields, representations, and declared local constraints. | Existence, freshness, permission, or intent. |
| Deterministic domain validator | Specified relationships such as start < end or totals reconciling under defined rounding rules. | Facts for which it has no authoritative data or rules. |
| Authoritative lookup | Current existence, version, membership, or provider state. | That the user intended this entity or operation. |
| Authorization policy | Whether this actor may perform this operation on this resource now. | Whether the proposed values accurately express the user’s goal. |
| Intent or factual assessment | Evidence that a proposal corresponds to the request or source. | A universal proof when the property itself lacks a complete specification. |
Put known constraints into field descriptions before generation when that helps the model choose correctly, but retain validators afterward. In a Pydantic demonstration, a hidden date constraint caused an initial validation failure; returning the error enabled a corrected retry, while the speaker recommended stating the century requirement in the field description up front. The two controls are complementary: descriptions guide generation, and validators enforce specified acceptance rules.
No validator is stronger than its oracle. A deterministic rule is excellent for an invariant that code can fully state. It cannot generally decide whether an unrestricted answer is “safe,” whether an ambiguous request meant one customer rather than another, or whether a source supports a claim. Checks and their limits explains how to state what each oracle observes and what remains open.
Part IV — Operation requests
Tool definitions shape available choices
A tool definition is a model-visible description of an application operation. It normally includes a stable name, purpose, input schema, and—where supported—a result contract. The description should explain when to use the tool, when not to use it, prerequisites, specialized terms, resource relationships, and important effects. Parameter names and descriptions should state units and meaning; enums should expose the actual finite choices. The executable implementation and authorization policy remain separate.
Overlapping tools
| Weak definition | Better distinction | Remaining question |
|---|---|---|
search: Search for information. | search_web: Use for public, current webpages; do not use for private account data. | Will the model obey the distinction on representative requests? |
query: Run a query. | query_orders: Read the current tenant’s order index using the documented filter grammar; load syntax guidance first. | Can arguments still misuse the query language? |
| One tool per backend endpoint. | One task-oriented lookup returning the contextual fields required by the workflow. | Does the broader tool expose excessive data or hide useful control? |
Tool granularity is an interface decision, not a mechanical reflection of backend APIs. Too many overlapping declarations can make selection harder; overly broad tools can expose unnecessary authority or return bloated results. Start with distinct task-level purposes, then use evaluations to justify routing, grouping, or progressive disclosure. Descriptions improve the model’s decision context, but they are instructions—not enforcement and not permission.
Choose a call—or do not call
Immediate tool selection is a disposition decision. The system may answer directly, ask for missing information, state that its tools cannot satisfy the request, or propose an eligible operation. Selection is separate from argument formation: choosing create_issue correctly does not mean the supplied repository, title, and labels are correct. It is also narrower than sequential planning; Choose a useful next action covers prerequisites and consequences across a longer trajectory.
Valid dispositions
| Condition | Disposition | Reason |
|---|---|---|
| The answer is available without an external operation. | Answer directly. | A tool call would add cost and failure modes without adding needed evidence or effects. |
| A required argument is missing and cannot be safely inferred. | Clarify. | Guessing would create an under-specified action request. |
| Available tools cannot perform the requested capability. | Decline or explain the boundary. | A related tool is not an adequate substitute. |
| One permitted external lookup or effect is necessary and arguments are available. | Propose the named call. | The request can now be validated and authorized. |
| Several independent lookups are needed and the interface supports multiple calls. | Propose separately identified calls. | Independence must be established by the application, not inferred from co-occurrence. |
Some APIs expose automatic, required, prohibited, or allowlisted tool modes. These modes alter the model’s available output space; they do not prove that a call is useful or permitted. Requiring a call can be appropriate inside a tightly bounded extraction interface, but it removes direct-answer and no-call options. Evaluate the exact mode together with missing-argument and unavailable-capability cases.
A call is an envelope, not an effect
A tool call needs an identity that survives dispatch and result return. This matters when one response requests several operations, including repeated calls to the same tool with different arguments. In the demonstrated parallel-call loop, each returned result retains the corresponding tool-call ID, allowing the model to distinguish the observations without relying on function name or completion order.
Minimal correlation loop
Illustrative pseudocode
Python-like pseudocodeSeveral calls in one model turn are not necessarily independent. The weather demonstration grouped two retrievals into one step, then waited for both results before requesting dependent arithmetic in the next step. Application code must preserve that dependency order; state-changing calls may need still stricter serialization or transactional controls.
Part V — Controlled effects
Authorization belongs at the protected operation
Authentication establishes an actor’s identity. Authorization decides whether that actor may perform a particular operation on a particular resource under current policy. A schema-valid request supplies only some decision inputs. Policy may also consider the authenticated subject, delegated task scope, resource ownership, environment, current state, and consequence. Attribute-based access control formalizes this as evaluation of subject, object, operation, and sometimes environmental attributes against policy.
Enforce authorization where the protected operation occurs, on every request. An IDOR—Insecure Direct Object Reference—illustrates why a valid token is insufficient: an application can authenticate the caller yet expose another user’s record when lookup-by-ID omits object-level authorization. In the reported agent attack, a visible user ID enabled traversal into personal records because the downstream tool checked admission but not ownership. Enforce current authority develops complete mediation and fail-safe defaults.
Permission is independent of valid arguments
A schema-valid proposal reaches the protected service only after policy evaluates actor, operation, resource, delegated scope, and current conditions.
Read the diagram as text
- Schema-valid call. The arguments have acceptable structure but no implied permission.
- Authenticated actor. The principal and relevant delegated identity are established.
- Policy decision. Evaluates actor, exact operation, resource, delegated scope, state, environment, and approval binding.
- Denied. No protected operation executes; a stable denial is returned.
- Protected service. The enforcement point admits only policy-approved operations.
- Service observation. Result or authoritative state produced by the protected boundary.
- Schema-valid call → Policy decision: operation and resource.
- Authenticated actor → Policy decision: actor and delegation.
- Policy decision → Denied: policy denies.
- Policy decision → Protected service: policy allows.
- Protected service → Service observation: execute and observe.
Human approval is also scoped data, not a vague remembered “yes.” Bind approval to the actor, session, operation, exact consequential arguments, resource scope, and lifetime. If arguments change, approval expires, or the request is regenerated under another identity, run authorization again and obtain any required new approval. OWASP’s transaction-authorization guidance similarly binds acknowledgement to significant operation details and warns against approving one transaction while executing altered details.
Credentials are capabilities, not proof of user intent. Delegated architectures can preserve both user and runtime identity—for example, by exchanging a subject token and authenticated runtime identity for narrowly requested access—but the authorization service must still decide whether to issue that authority. Whole-task accumulation and intervention policy belong in Constrain accumulated effects; broader attack paths belong in AI Security.
Execute through a controlled dispatcher
After acceptance, a controlled dispatcher resolves the operation through an allowlisted registry. It does not evaluate model-generated code, trust an arbitrary URL, or dynamically import a name chosen by the model. At the execution boundary it revalidates arguments, current resource state, authorization, deadlines, and resource limits. The handler then invokes application code or a hosted capability according to the integration’s actual execution contract. Tool-definition ownership and execution ownership are separate: some provider-defined tools still execute in the client, while server-hosted tools execute on provider infrastructure.
Result meanings
| Result | Meaning | Next obligation |
|---|---|---|
| Completed data | The operation returned a final structured observation. | Validate it and check any authoritative postcondition the task requires. |
| Domain failure | The operation ran but the requested domain outcome was rejected or unavailable. | Return a stable error code and safe corrective details. |
| Infrastructure failure | The execution path failed before a final domain result was established. | Apply retry policy only after considering effect knowledge and idempotency. |
| Pending operation handle | Work was accepted but is incomplete. | Track the handle; do not report final success. |
| Cancellation acknowledged | A cancellation request was received. | Inspect eventual operation state because cancellation can be best effort. |
A tool result is an observation from one boundary, not proof that the whole user task is complete. A provider can accept a mutation while dropping requested attributes; an internal message service can accept a request while the user-visible client renders nothing. Define the relevant postcondition, query authoritative state where possible, and preserve the provider receipt or operation handle. Establish the achieved outcome treats completion as a task-level question.
Execution loops also need termination. Bound tool waits with deadlines, represent timeout and cancellation explicitly, and set a maximum iteration or attempt count. A missing tool result must not leave subsequent work queued forever. Recovery commands should remain reachable outside the blocked queue, and receipts should record the terminal state that later steps can trust.
Part VI — Failure and recovery
Failures need distinct meanings
A dependable interface preserves why an attempt did not produce a completed effect. Malformed generation, schema rejection, semantic invalidity, authorization denial, dependency unavailability, domain failure, timeout, cancellation, and executor defects make different claims. They differ especially in whether an external effect is known to have occurred and who may safely decide the next step.
Failure and response
| Failure | Known effect? | Safe response |
|---|---|---|
| Malformed or incomplete generation | No action should have been dispatched. | Reject; optionally regenerate within a bounded budget. |
| Schema or semantic rejection | No action should have been dispatched. | Return precise field or invariant feedback; let the model revise only permitted arguments. |
| Authorization denial | No authorized effect. | Terminate or request a genuinely new authorization decision; do not retry around policy. |
| Dependency unavailable before dispatch | Usually no effect, if the boundary can prove execution never began. | Retry with bounded backoff when the operation is safe and policy allows. |
| Tool-declared domain failure | Defined by the tool result. | Preserve the domain code; revise only if the request can validly change. |
| Timeout after dispatch | Possibly unknown. | Reconcile or repeat with the same enforced operation identity; never assume failure. |
| Cancellation requested | Possibly unknown or partial. | Inspect terminal state; cancellation acknowledgement is not rollback. |
| Executor defect | Depends on where the defect occurred. | Stop, preserve evidence, and investigate before blind replay. |
Error envelopes should expose stable machine fields—such as type, code, affected argument locations, retry guidance, and an occurrence identifier—while keeping stack traces, secrets, internal capabilities, and sensitive policy details out of model-visible text. RFC 9457 is one reference for machine-readable HTTP problems and explicitly separates human-readable detail from fields clients should use for decisions. It does not define universal retryability or effect status, so those remain application-specific.
Validation feedback can support bounded correction. Pydantic demonstrations return an explanatory validator error to the model, which then proposes a corrected result. Instructor documents choosing retryable exceptions, stopping by attempts or elapsed time, and exposing attempt history after exhaustion. This is appropriate for correctable representation or value errors; it does not authorize a previously denied action or make a side effect safe to repeat.
Recover when the effect is unknown
A timeout after dispatch creates three possible realities: confirmed success, confirmed failure without an effect, or an unknown outcome. The client’s missing response cannot distinguish them. Retrying with a fresh identity can create a second effect if the first request committed. Preserve one logical operation identity and record the attempt as pending or unknown until provider evidence resolves it.
Idempotency means repeating the same logical operation adds no further externally visible effect. It requires enforcement at the receiving boundary, not merely a key written to local logs. Stripe’s documented contract illustrates bounded semantics: the caller reuses one key with identical parameters; executed responses, including some failures, are stored; mismatched parameters are rejected; validation failures or concurrent-execution conflicts may not create a stored result; and old keys can be pruned. Those details are provider-specific, so clients must implement the actual service contract rather than a generic “idempotent” checkbox.
Recovery after a lost mutation response
Safe recovery preserves logical operation identity and seeks receiving-boundary enforcement or authoritative evidence before another effect.
Read the diagram as text
- Logical operation op-17. One immutable intent and parameter set.
- Remote mutation. The service may commit before the client receives a response.
- Outcome unknown. The response was lost; success and no-effect failure remain possible.
- Retry with new identity. The service cannot associate the attempt with op-17.
- Repeat original key. Use the provider’s idempotency contract with identical parameters.
- Query authoritative state. Search by operation metadata, provider handle, or resulting object.
- Possible duplicate effect. A second mutation can occur if the first committed.
- Deduplicated result. The provider returns the stored result for the same logical operation.
- Outcome confirmed. Authoritative state establishes success or no effect.
- Unresolved escalation. No safe automated conclusion or retry is available.
- Logical operation op-17 → Remote mutation: submit with stable identity.
- Remote mutation → Outcome unknown: response lost.
- Outcome unknown → Retry with new identity: unsafe fresh identity.
- Retry with new identity → Possible duplicate effect: first may have committed.
- Outcome unknown → Repeat original key: provider enforces key.
- Repeat original key → Deduplicated result: stored result exists.
- Repeat original key → Unresolved escalation: contract cannot resolve.
- Outcome unknown → Query authoritative state: authoritative reconciliation.
- Query authoritative state → Outcome confirmed: state identifies outcome.
- Query authoritative state → Unresolved escalation: evidence remains incomplete.
When provider deduplication or reliable result replay is unavailable, query authoritative state using a local operation identifier or provider job handle. Keep the local operation pending while evidence is incomplete. If a known effect must be countered, compensation performs a new business operation; it is not time travel or database rollback, and it can fail. Workflow replay likewise does not create exactly-once effects: a task may complete an external mutation and crash before its result is persisted, causing a resumed attempt to execute again.
This recovery logic specializes Represent uncertain external outcomes. Strategy-level repair after the effect is known belongs in Repair the strategy from known effects. The immediate boundary rule is simpler: do not transform missing evidence into a fabricated success or confirmed failure.
Part VII — Boundary evidence
Test each claim separately
A complete system needs complementary tests because each boundary supports a different claim. Valid JSON does not establish schema conformance; schema conformance does not establish correct disposition or arguments; correct arguments do not establish authorization; successful dispatch does not establish the external postcondition. Specify the case and its outcome explains how to preserve initial state, permitted actions, stopping conditions, and assessment criteria.
Claim-to-check map
| Claim | Check | Remaining gap |
|---|---|---|
| The engine enforces the schema. | Positive, negative, recursive, unsupported-keyword, and completion cases against the pinned runtime. | Semantic correctness and provider behavior outside tested cases. |
| The parser and validators behave correctly. | Replay recorded malformed, duplicate-field, truncated, coercible, and domain-invalid responses. | Whether the live model emits them at deployment rates. |
| The system chooses appropriately. | Evaluate answer, clarify, abstain, unavailable capability, right tool, and argument correctness separately. | Authorization and external outcome. |
| The dispatcher is correct. | Use controlled model substitutes to emit exact calls; verify allowlist, correlation, ordering, timeout, and error mapping. | Real-model selection quality. |
| Authorization is enforced. | Attempt forbidden actor-operation-resource combinations, changed arguments, expired approvals, and revoked scope. | Completeness of the organization’s policy. |
| Retries avoid duplicate effects. | Inject lost responses, crashes after external commit, concurrent attempts, expired keys, and reconciliation failures. | Provider behavior beyond the tested contract. |
| The intended effect occurred. | Inspect authoritative external state or a user-visible boundary. | Whether the whole workflow was useful. |
Tool evaluations should preserve intermediate expectations. Golden cases can specify whether a call is needed, the intended operation, required arguments, expected tool observation, and acceptable final response. BFCL V3 separately checks resulting backend state and required execution-path calls because a correct end state can omit necessary information gathering, while a correct path can still leave the wrong state. Several trajectories may be valid, so assert required properties rather than one arbitrary call order unless order is itself contractual.
Report stage-specific denominators: parse failures, schema rejections, semantic rejections, incorrect selections, incorrect arguments, authorization violations, executor failures, unknown outcomes, duplicate effects, verified postconditions, and completed tasks. A single “validity rate” hides where risk remains. Representative task sampling and oracle design belong in Choose checks that match the requirement.
Part VIII — Interoperability
Where MCP meets the local action boundary
Tool calling and the Model Context Protocol solve orthogonal problems. Tool calling is the model–application interface for proposing an invocation and returning observations. MCP standardizes capability exchange among a host, its clients, and servers. Servers can expose tools, resources, and prompts; a host can aggregate them and decide what to present to a model. In the 2026-07-28 architecture, each client communicates with one server and requests carry version and capability metadata.
MCP tool definitions contain a name, description, input schema, and optional output schema. Discovery and invocation standardization reduce bespoke integration work, but they do not decide whether a tool is appropriate, whether its description is trustworthy, or whether the current actor may execute it. Names are scoped to a server, catalogs can change with authorization, execution failures differ from protocol errors, and annotations are untrusted unless their server is trusted.
The host therefore retains the local control boundary: select which server capabilities enter the model’s context; disambiguate names; validate arguments and returned data; obtain confirmation where required; enforce authorization; impose timeouts; log use; dispatch according to policy; and translate results back into the model conversation. The server separately enforces access control and validates its inputs. Connecting a server advertises capability—it does not grant authority.
Keep protocol revision boundaries explicit. Older talks and implementations may describe connection-scoped initialization, historical transports, or earlier OAuth behavior. The current protocol chapter should own those version-specific details. The invariant for this chapter is stable: interoperability can supply descriptions and messages, while the application remains responsible for turning a model proposal into a permitted, controlled, and observed effect.
Open questions
How can constrained decoders implement a provider’s advertised schema subset exactly while preserving acceptable latency across tokenizers, recursive structures, batching modes, and streaming? Progress would include versioned conformance suites that separate schema acceptance, recognized-language equivalence, completion behavior, and semantic task quality.
How should systems measure whether tool names, descriptions, parameter semantics, prerequisites, and catalog size improve selection without consuming excessive context or encouraging unnecessary calls? Progress would require controlled, task-representative studies that separate no-call decisions, tool identity, and argument accuracy.
What portable failure envelope can distinguish malformed proposals, policy denials, domain failures, pending work, cancellation, and unknown effects without leaking sensitive diagnostics or pretending that retry semantics are universal? Progress would look like precise, machine-readable effect knowledge and recovery guidance that tool implementations can map to their real contracts.
How can authorization remain bound to exact user intent as arguments, resource state, delegated scope, and long-running execution change? Progress would combine transaction-specific approval, per-request service enforcement, revocation, and auditable identity without treating model reasoning or credentials as authority.
How should a system verify semantic correctness when deterministic validators cover only known invariants and model judges share the generator’s blind spots? Progress would require authoritative domain evidence, calibrated deferral policies, and evaluation designs that keep oracle limitations visible instead of collapsing them into one confidence field.



































































































































































































