50 / STRUCTURED OUTPUTS & AGENT CONTRACTS / TOOL-ACTION + QUALITY
50 / CORE / TYPED INPUTS · OUTPUTS · ERRORS · VERSIONING

STRUCTURED OUTPUTS
& AGENT CONTRACTS.

Structured Outputs & Agent Contracts — способ превратить обмен между AI-компонентами из «надеемся, что текст поймут» в формальный протокол: какие данные принимаются, какие возвращаются, какие ошибки возможны, какие поля обязательны и как меняется контракт со временем.

Главный принцип: модель может генерировать значение. Система должна проверять его против контракта до того, как использовать результат как state transition, tool argument, A2A message, release artifact или side effect.
00. ARCHITECTURAL STATUS

КОНТРАКТ — БАЗОВАЯ ГРАНИЦА МЕЖДУ КОМПОНЕНТАМИ

Тема относится к CORE: typed contracts нужны там, где система передаёт результат дальше в code path. Но отдельный «contract agent» не нужен — это схемы, типы, validators, adapters и compatibility rules.
TYPECOREФундаментальная межмодульная дисциплина.
DEFAULTONИспользуется на машинно значимых границах.
ENABLE WHENMACHINE CONSUMESTool call, state, A2A, workflow, API, artifact metadata.
SEPARATE COMPONENTNOSchemas/types/validators внутри существующих модулей.
LIVES INR07 + R08Tool / Action Engine + Quality Engine.
COMPLEXITYLOW → MEDIUMНачать с JSON Schema / typed models.
IMPLEMENT: YES / EARLY
Минимум 80% ценности: versioned JSON Schema или typed models для critical boundaries, strict validation, explicit error envelope, canonical status/result enums, backward-compatible evolution и contract tests. Не нужен отдельный LLM-компонент.
01A. ARCHITECTURE BOUNDARIES & OPERATIONS

EXPLICIT SYSTEM CONTRACT

A. BOUNDARY WITH NEIGHBORS

№12 Tools & Function Calling описывает механизм вызова конкретной операции; №50 описывает формальный input/output/error contract на границе. №43 A2A определяет lifecycle делегирования между агентами; №50 задаёт payload schema сообщений. №45 Verification проверяет correctness результата; schema validation проверяет только форму/constraints. №48 Guardrails решает, допустимо ли действие; contract задаёт, как действие представлено. №49 HITL использует decision/review contracts. №68 Durable Workflow позже использует versioned state/activity contracts.

B. PREREQUISITES / CROSS-REFERENCES

Prerequisites: №10 State Management, №12 Tools & Function Calling, №41 Architecture, №43 A2A, №45 Verification. Forward references: №51 Permissions, №54 Connectors, №57 Queues, №59 Broker, №68 Durable Execution, №69 Distributed Reliability.

C. PLANE PLACEMENT

REQUEST-TIME: YES — model/tool/A2A boundaries. CONTROL PLANE: YES — schema registry/version/deprecation policy. DATA PLANE: YES — serialized payloads/events/results. OFFLINE: YES — contract tests, migration tests, compatibility analysis.

D. FAILURE & OPERATIONS CONTRACT

Success: payload validates against expected version and semantic preconditions are separately checked. Retryable: generation produces invalid structure and bounded targeted repair is allowed. Permanent: unsupported schema version, missing mandatory data, incompatible contract, forbidden enum. Idempotency: contract carries stable operation/message IDs where needed. Persist: schema version + payload + validation result + adapter version. Trace: validation/repair/compatibility events.

E. WHAT THIS TOPIC DOES NOT OWN

№50 не владеет business correctness, policy decisions, transport protocol, tool execution, workflow lifecycle, state database или schema generation vendor APIs. Она владеет THE SHAPE, MEANING, VERSION AND VALIDATION RULES OF MACHINE-CONSUMED EXCHANGES.

01. WHY CONTRACTS MATTER

TEXT IS A POOR INTERNAL API

FREE TEXT

«Отправь письмо Ивану завтра. Всё ок.»

Неясны recipient ID, timestamp, timezone, status, confidence, side-effect intent.

STRUCTURED CONTRACT

recipient_id, send_at, timezone, body_ref, action_intent, policy_context.

Каждое поле имеет type и constraints.

VALIDATED EXECUTION

Code принимает только корректный payload и отдельно проверяет permissions/policy.

Structured output уменьшает ambiguity и parsing errors. Но valid JSON ≠ valid action: после schema validation всё равно нужны state, policy, permission и business verification.
02. CONTRACT ANATOMY

ЧТО ДОЛЖЕН ОПИСЫВАТЬ ХОРОШИЙ CONTRACT

NAME / IDСтабильное имя интерфейса: task.result, tool.email.send, agent.delegate.
VERSIONВерсия структуры и semantics.
INPUTТипы, обязательные/optional поля, enums, bounds, references.
OUTPUTResult envelope, artifacts, status, evidence refs.
ERRORSTyped error classes и retry semantics.
INVARIANTSУсловия, которые schema alone не выражает.
IDEMPOTENCYoperation_id/message_id/dedupe key where required.
SECURITYSensitive fields, allowed producer/consumer, redaction class.
CONTRACT = MORE THAN JSON

Shape + semantics + lifecycle

JSON Schema отлично описывает форму. Но production contract также фиксирует смысл статусов, допустимые переходы, error taxonomy, compatibility и ownership.

Контракт должен быть понятен как producer, так и consumer. Если consumer вынужден угадывать, что означает поле status: "ok", контракт неполный.

03. EXAMPLE: TASK RESULT

НЕ ПЕРЕДАВАТЬ ВНУТРИ СИСТЕМЫ «ВОТ МОЙ ОТВЕТ»

{
  "contract": "task.result",
  "version": "1.2",
  "task_id": "TASK-123",
  "status": "SUCCESS",
  "result": {
    "artifact_ref": "artifact://...",
    "summary": "...",
    "claims": [
      {
        "claim_id": "c1",
        "text": "...",
        "evidence_refs": ["src://..."]
      }
    ]
  },
  "quality": {
    "verification": "PASS",
    "unresolved_items": []
  },
  "usage": {
    "model_calls": 2,
    "tool_calls": 1
  }
}
WHY THIS HELPS

Consumer can reason deterministically

  • SUCCESS не надо извлекать из текста.
  • Artifact передаётся reference, а не огромным blob.
  • Claims можно проверять по отдельности.
  • Quality verdict отделён от content.
  • Usage можно агрегировать без LLM parsing.
  • Version позволяет безопасно эволюционировать consumer.
04. STRUCTURED OUTPUTS FROM LLM

MODEL OUTPUT — UNTRUSTED UNTIL VALIDATED

SCHEMAExpected contract version selected by host.
MODELGenerate structure / tool args / typed answer.
PARSESyntax / decoding.
VALIDATESchema / type / enum / constraints.
SEMANTIC CHECKCross-field / state / business invariants.
POLICYAllowed action/resource/context?
EXECUTE / STOREOnly validated canonical value enters system.
IMPORTANT
Даже если provider обещает structured output / constrained decoding, host всё равно должен валидировать received payload. Provider feature снижает вероятность invalid structure, но не заменяет contract enforcement в вашей системе.
05. VALIDATION LAYERS

ФОРМА, SEMANTICS И POLICY — РАЗНЫЕ ПРОВЕРКИ

L1 / SYNTAX

Can parse?

JSON/MessagePack/typed encoding корректно декодируется.

L2 / SCHEMA

Correct shape?

Types, required fields, enum, ranges, pattern, additionalProperties.

L3 / SEMANTICS

Internally consistent?

start_at < end_at, resource belongs to tenant, mutually exclusive fields.

L4 / STATE

Valid now?

Object exists, version current, transition allowed, no stale approval.

L5 / POLICY

Allowed?

Permissions, guardrails, data egress, approval requirement.

L6 / OUTCOME

Actually happened?

Execution/readback/result verification after side effect.

Schema validation — важная, но только одна ступень. Нельзя делать schema_pass → execute для чувствительных операций.
06. ERROR CONTRACT

ОШИБКА ТОЖЕ ЯВЛЯЕТСЯ РЕЗУЛЬТАТОМ

{
  "contract": "operation.error",
  "version": "1.0",
  "error_id": "ERR-...",
  "code": "RESOURCE_NOT_FOUND",
  "class": "PERMANENT",
  "retryable": false,
  "message_safe": "Target resource does not exist.",
  "details": {
    "resource_type": "document"
  },
  "source": "tool.files",
  "trace_id": "TRACE-..."
}
DO NOT

Не использовать exception text как protocol

Consumer не должен парсить строку «Something went wrong: 404 maybe...», чтобы понять retry.

Typed error contract позволяет router/orchestrator deterministically решить:

  • retry?
  • fallback?
  • clarify?
  • replan?
  • human?
  • terminate?
07. ERROR TAXONOMY

НЕ ВСЕ FAILURES НУЖНО RETRY

Error classПримерОбычное действие
TRANSIENTProvider timeout, temporary network issue.Bounded retry / fallback.
RATE_LIMITEDQuota/rate constraint.Backoff / queue / alternate provider if policy allows.
INVALID_INPUTSchema/semantic validation failed.Targeted repair or caller fix.
NOT_FOUNDResource absent.Retrieve alternate / clarify / terminal depending task.
CONFLICTOptimistic version mismatch.Reload state / re-evaluate / avoid blind retry.
PERMISSION_DENIEDScope missing.Do not retry unchanged; human/admin path if appropriate.
POLICY_DENIEDAction prohibited.Terminate/narrow; never retry to bypass.
UNSUPPORTED_VERSIONConsumer cannot read contract v3.Adapter/upgrade/compatible producer.
08. AGENT CONTRACTS

AGENT-TO-AGENT MESSAGE ДОЛЖНО БЫТЬ API, А НЕ ЧАТОМ

{
  "contract": "agent.task",
  "version": "2.1",
  "task_id": "SUB-42",
  "parent_task_id": "ROOT-1",
  "goal": "...",
  "inputs": {
    "artifact_refs": ["..."],
    "evidence_refs": ["..."]
  },
  "constraints": [
    "read_only",
    "no_external_publish"
  ],
  "budget": {
    "deadline_ms": 30000,
    "max_model_calls": 4
  },
  "output_contract": "research.answer.v2",
  "callback": {
    "mode": "ASYNC"
  }
}
AGENT BOUNDARY

Separate context, explicit responsibility

Subagent получает task contract, а не весь parent conversation.

Контракт фиксирует goal, permitted inputs, constraints, budget, output schema и completion semantics.

A2A lifecycle остаётся темой №43; здесь важна shape/compatibility сообщения.

09. VERSIONING

КОНТРАКТЫ ДОЛЖНЫ ЭВОЛЮЦИОНИРОВАТЬ БЕЗ «BIG BANG»

CHANGE
EXAMPLE
COMPATIBILITY
RISK
ACTION
Add optional field
metadata?: {...}
Usually backward compatible
LOW
Deploy producer/consumer independently if unknown fields tolerated.
Add required field
tenant_id required
Old producers break
MEDIUM/HIGH
New version or staged default/migration.
Rename/remove field
user → principal
Breaking
HIGH
Version bump + adapter/deprecation window.
Change semantics
status=READY means something else
Silent break
VERY HIGH
Never reuse old field meaning; version semantics explicitly.
Самая опасная поломка — не invalid schema, а syntactically compatible payload с изменившимся смыслом.
10. VERSION STRATEGY

ПРОСТОЙ ПОДХОД ДОСТАТОЧЕН

V1

Contract ID + version

Каждый machine boundary carries contract name/version или знает его из endpoint/topic.

ADAPTERS

Translate at boundaries

v1 → canonical internal model → v2. Не распространять compatibility hacks по business logic.

DEPRECATION

Measure usage

Сначала telemetry consumers/producers, затем warning, migration, removal.

PRACTICAL RULE
Не нужен сложный schema registry на первом этапе. Для монорепозитория достаточно versioned schema files + generated/typed models + CI compatibility tests. Registry нужен, когда producers/consumers масштабируются независимо.
11. OPTIONALITY & DEFAULTS

OPTIONAL ПОЛЕ — НЕ «МОЖЕТ БЫТЬ ЧТО УГОДНО»

PatternПроблемаЛучше
Everything optionalConsumer вынужден угадывать состояния.Required core + explicit nullable/optional semantics.
null means many thingsUnknown? not applicable? failed? redacted?Status/reason enum + field.
Magic defaultProducer omitted field, consumer silently assumed dangerous value.Host-controlled default with documented semantics.
Open string enumTypos become states.Closed enum for control fields; extensible metadata separately.
12. REFERENCES VS BLOBS

НЕ ТАЩИТЬ ВСЁ ЧЕРЕЗ КАЖДЫЙ MESSAGE

ANTI-PATTERN

Huge embedded payload

Agent message содержит полный PDF, trace, 20 images и весь conversation state. Это усложняет retries, logging, privacy и versioning.

BETTER

Stable references

Передавать artifact_ref, evidence_ref, state_ref + hashes/versions/metadata. Сам blob хранится в соответствующем store.

№60 позже детализирует Artifact Store.

13. CONTRACT-DRIVEN TOOL CALL

TOOL ARGUMENTS — ЭТО COMMAND CONTRACT

{
  "contract": "tool.publish_post.command",
  "version": "1.0",
  "operation_id": "OP-...",
  "resource": {
    "channel_id": "vk:brand_A"
  },
  "payload_ref": "artifact://post/17",
  "mode": "PUBLISH",
  "expected_state": {
    "draft_version": 12
  }
}
AFTER SCHEMA

Still check the world

  • Does channel exist?
  • Does it belong to tenant?
  • Does caller have permission?
  • Does policy allow PUBLISH?
  • Is draft_version still 12?
  • Was operation_id already executed?

Contract делает command однозначным; он не заменяет runtime validation.

14. OUTPUT REPAIR

INVALID STRUCTURE НЕ ВСЕГДА ТРЕБУЕТ ПОЛНОЙ РЕГЕНЕРАЦИИ

INVALID OUTPUTParser/schema gives exact errors.
CLASSIFYSyntax? missing field? enum? semantic?
TARGETED REPAIRGive only validation errors + schema context.
REVALIDATESame host validator.
BOUNDMax repair attempts → fallback/fail.
Для deterministic output лучше сначала использовать provider-native constrained output / code formatter / parser. LLM repair — fallback, а не основной parser.
15. CONTRACT TESTS

КОНТРАКТ — ЭТО ТЕСТИРУЕМАЯ СПЕЦИФИКАЦИЯ

VALID

Golden payloads

Representative correct messages pass.

INVALID

Negative cases

Missing required, wrong enum, wrong type, extra prohibited field.

COMPAT

Old vs new

Can vN consumer read vN-1? Do adapters preserve meaning?

ROUNDTRIP

Serialize / parse

Canonical model survives serialization without semantic drift.

CI GATE
Если schema/typed model меняется, CI должен показать, какие producers/consumers потенциально ломаются. Breaking change без explicit version/migration не проходит release gate.
16. CONTRACT OWNERSHIP

КТО ИМЕЕТ ПРАВО МЕНЯТЬ INTERFACE

RoleResponsibility
Contract ownerDefines semantics, versioning and deprecation policy.
ProducerMust emit valid supported version.
ConsumerMust reject unsupported/invalid input predictably.
Adapter ownerMaintains compatibility translations.
Quality/CIRuns validation, compatibility and regression tests.
В маленькой системе все роли могут принадлежать одному репозиторию/команде. Важно не количество команд, а ясность ответственности.
17. SECURITY & PRIVACY

SCHEMA МОЖЕТ ПРЕДОТВРАТИТЬ ЛИШНИЕ ДАННЫЕ

CLOSED SHAPE

No arbitrary extras

Для чувствительных commands использовать строгие schemas и запрещать unexpected fields.

CLASSIFICATION

Sensitive fields

Помечать secret/PII/internal refs, чтобы logger/redactor/connector knew handling policy.

MINIMIZATION

Only required data

Контракт не должен включать «весь user object», если operation нужен только user_id.

№51 Permissions & Secrets продолжит эту тему на уровне identity/scopes/credential handling. №50 фиксирует data shape, но не выдаёт permission.
18. OBSERVABILITY

КОНТРАКТНЫЕ FAILURES ДОЛЖНЫ БЫТЬ ВИДНЫ

VALIDATION

Pass / fail

contract_id, version, validator, failure path.

REPAIR

Attempts

repair count, success rate, error classes.

COMPAT

Versions

producer_version / consumer_version / adapter path.

LATENCY

Boundary cost

Validation/serialization overhead where material.

19. FAILURE MODES

КАК CONTRACTS ЛОМАЮТСЯ

PARSE NATURAL LANGUAGE
Internal modules regex-парсят prose.
TYPED CONTRACT
VALID JSON = VALID ACTION
После schema pass сразу side effect.
SEMANTIC + POLICY CHECK
EVERYTHING OPTIONAL
Contract не определяет обязательную state.
REQUIRED CORE
MAGIC STRINGS
status/retry/error encoded arbitrary strings.
ENUM + ERROR TAXONOMY
SILENT SEMANTIC CHANGE
Field name same, meaning changed.
VERSION SEMANTICS
BREAKING FIELD REMOVE
Old consumer crashes after deploy.
ADAPTER / DEPRECATION
HUGE BLOBS
Every message copies artifacts/context.
REFERENCES + HASH
MODEL OWNS SCHEMA VERSION
LLM chooses arbitrary version or contract.
HOST SELECTS CONTRACT
EXCEPTION TEXT PROTOCOL
Consumer parses free-text errors.
TYPED ERROR ENVELOPE
20. METRICS

ЧТО ИЗМЕРЯТЬ

VFR

Validation Failure Rate

% machine outputs failing schema/semantic validation.

RR

Repair Rate

Сколько invalid outputs требуют repair; сколько repair успешны.

BC

Breaking Changes

Contract regressions caught before production.

UV

Unsupported Version

Runtime failures caused by version mismatch.

P95

Validation Latency

Overhead critical boundaries.

DR

Deprecated Usage

Traffic still using old contract versions.

SE

Semantic Errors

Schema-valid but semantically invalid payloads.

ESC

Escape Rate

Invalid/unsupported payloads reaching downstream side effect.

21. MVP IMPLEMENTATION

JSON SCHEMA / PYDANTIC / ZOD УЖЕ ДОСТАТОЧНО

contracts/
├── task/
│   ├── task_request_v1.json
│   └── task_result_v1.json
├── tools/
│   ├── publish_command_v1.json
│   └── publish_result_v1.json
├── agents/
│   ├── delegate_v1.json
│   └── response_v1.json
├── errors/
│   └── operation_error_v1.json
├── adapters/
├── generated/
└── tests/
    ├── valid/
    ├── invalid/
    ├── compatibility/
    └── regression/
80% VALUE MVP

No contract platform required

  • Versioned schema files in repository.
  • Typed runtime models.
  • Strict validation at boundaries.
  • Closed enums for control states.
  • Typed error envelope.
  • Stable IDs/idempotency keys where needed.
  • Adapters isolated in one layer.
  • CI compatibility tests.
  • Validation telemetry.

Отдельный schema registry/IDL platform появляется позже, когда many independently deployed producers/consumers justify it.

22. PRACTICAL DECISION

СТОИТ ЛИ ДЕЛАТЬ ОТДЕЛЬНЫЙ КОМПОНЕНТ?

ВопросОтвет
Стоит ли реализовывать?Да, с самого начала для machine-consumed boundaries.
Separate Component?NO. Contracts — cross-cutting discipline внутри Tool/Action + Quality и других consumers.
Минимум 80% ценности?Versioned schemas, strict validator, typed errors, control enums, compatibility tests.
Когда overkill?Если строить enterprise schema registry, codegen platform и distributed IDL governance для одного monolith prototype.
Trigger?Всякий раз, когда output потребляет код/другой agent/tool/workflow, а не только человек.
Как измерить uplift?Parsing/validation failures, downstream contract escapes, regression rate, repair rate, integration defects.
Можно ли rule/tool/code вместо LLM-agent?Полностью. Это прежде всего schema/types/validators/adapters/tests.
23. DESIGN RULES

ПРАВИЛА ДЛЯ РЕАЛЬНОЙ СИСТЕМЫ

RULE 01

Host owns contract

Модель не выбирает schema/version на critical path.

RULE 02

Validate every boundary

Producer correctness не заменяет consumer validation.

RULE 03

Shape ≠ truth

Schema pass не заменяет semantic/verification/policy.

RULE 04

Typed errors

Retry/fallback decisions не должны зависеть от parsing exception text.

RULE 05

Version meaning

Не менять semantics существующего поля silently.

RULE 06

Adapters at edges

Compatibility conversion централизована, а не размазана по business code.

RULE 07

References over blobs

Большие artifacts/state передавать refs + versions/hashes.

RULE 08

Closed control enums

State/action/error class — finite known vocabulary.

RULE 09

Test compatibility

Breaking interface changes должны ловиться до deployment.

24. FINAL MAP

FROM LANGUAGE TO PROTOCOL

LLM / TOOL / AGENT / WORKFLOW
        ↓
HOST SELECTS CONTRACT + VERSION
        ↓
PRODUCER EMITS STRUCTURED VALUE
        ↓
PARSE
        ↓
SCHEMA VALIDATION
        ↓
SEMANTIC / STATE VALIDATION
        ↓
POLICY / PERMISSION CHECK
        ↓
CANONICAL INTERNAL MODEL
        ↓
TOOL / STATE / EVENT / AGENT / ARTIFACT
        ↓
TYPED RESULT OR TYPED ERROR
        ↓
TRACE:
contract_id + version + validation + adapter + outcome

CONTRACT EVOLUTION:
v1 → compatible add → v1.x
breaking semantics → v2
legacy producer → adapter → canonical model

CORE PRINCIPLE:

PROMPTS EXPRESS INTENT.
CONTRACTS DEFINE ACCEPTABLE MACHINE INTERFACES.

VALID JSON IS NOT ENOUGH.
VALID SCHEMA IS NOT ENOUGH.
A PRODUCTION CONTRACT ALSO NEEDS
SEMANTICS, VERSIONING, ERRORS AND OWNERSHIP.

ECC RETROFIT / PRACTICAL HARNESS INTEGRATION

A. Related ECC ideas. Context-as-cache, scoped memory, lifecycle hooks, selective capabilities, feature flags, deterministic enforcement, provider-neutral adapters and eval-gated learning are applied only where relevant to №50 Structured Outputs & Agent Contracts.

B–E. Existing boundary and placement. The existing conceptual boundary, class CORE, default ON and owner Tool / Action Engine + Quality Engine remain authoritative. Runtime/control/data/offline placement is unchanged; durable state stays outside model context.

F–H. Hooks and contracts. Use bounded PRE_MODEL/POST_MODEL, PRE_TOOL/POST_TOOL, CHECKPOINT and TASK_COMPLETED events as applicable. Illustrative fields and canonical contracts are defined in NEW_CONTRACTS_SPEC.md; no universal schema is implied.

I–J. Security and evaluation. Host-side schema, permission, secret, budget, idempotency and audit checks take precedence over LLM output. Optional mechanisms require a feature flag and WITH/WITHOUT ablation; measure quality, acceptance, correction, latency, cost, escalations and severe errors.

K–L. Task profiles and cross-references. A TaskProfile selects the relevant skill, tool/context slice, memory scope and enforcement profile independently from FAST/STANDARD/DEEP. See cross-reference map, hook spec and ablation plan. Provider adapters remain outside the core.