Учебник

Что такое AI Agent State? Руководство 2026: управление состоянием, JSON State, Memory, Workflow и выполнение задач

История чата — не состояние. Агент может паузить, продолжать и передавать ход, только если есть проверяемый JSON-снимок: цель, шаг, квитанции инструментов, указатели памяти и конверт задачи.

В 2026 агент в проде редко ломается из‑за того, что модель «недостаточно умна». Он ломается после сбоя, повтора или человеческого подтверждения — когда рантайм больше не знает, на каком hop он был. Предыдущий разбор свёл агента к циклу наблюдение–решение–вызов; см. Что такое AI Agent. Эта статья добавляет слой вне цикла: State. State — не весь транскрипт в контексте и не кусок из векторного хранилища. Это структурированный снимок текущей позиции рантайма — почти всегда JSON. Ниже — JSON State, Memory, Workflow и выполнение задач, плюс ссылки на Stateless MCP, A2A, Structured Output и статью про 1M контекст.

Что такое Agent State: чат и сессии

Достаточно одного предложения: Agent State — структурированный снимок, из‑за которого run можно поставить на паузу, продолжить и воспроизвести. Он отвечает на четыре вопроса: какова цель, на каком hop мы стоим, какие результаты уже зафиксированы, кто блокирует следующий шаг (инструмент, человек или maxSteps). Модель выбирает действие по текущему наблюдению; рантайм исполняет и записывает позицию обратно. Без проверяемой позиции цикл умеет только снова вставить весь чат — это чат, не управление состоянием.

История чата — список сообщений, который видит модель: user / assistant / tool. Сессия (OpenAI Conversations, previous_response_id, старый Assistants Thread) — ручка, которую видит поставщик: какие модельные элементы должен унести следующий запрос. State — позиция, которую видит ваш рантайм: до куда дошла сверка, сумма на подтверждении, текущий узел графа, checkpoint id. Они могут сосуществовать, но не притворяться друг другом. Считать messages[] единственной правдой — и повторы дважды спишут деньги или дважды пошлют письмо. Считать Conversation id бизнес-состоянием — и смена поставщика уронит позицию. После перехода Assistants → Responses примитив сессии изменился — ещё меньше привязывайте бизнес-снимки к объектам платформы. См. миграция Assistants → Responses.

Большинство инцидентов 2026 — смешанные слои: arguments инструмента записаны в State, весь blob State засунут в следующий промпт, долгая память проигрывается как checkpoint. Разделив слои, отладка получает ручку: модель неверно прочитала наблюдение; reducer / Schema записали плохую позицию; Memory достала не то предпочтение. Карта:

Понятие Кто читает Если потеряно
Чат / messagesМодель (контекст этого хода)Неверные ответы; обычно можно заново спроецировать из checkpoint
Session / ConversationПоставщик моделиРасходятся reasoning-элементы; бизнес-позиция должна стоять отдельно
Agent State / checkpointВаш рантайм и оркестраторНебезопасное продолжение; повтор может дважды записать вниз по потоку
MemoryПоиск и предпочтения между runЗабытые привычки; никогда не истина текущего шага

JSON State: контракт — это checkpoint

State пишут JSON, чтобы проверять, делать Diff и воспроизводить. Оркестраторы семейства LangGraph кладут checkpoint на каждый super-step, связывают их thread_id и указывают на кадр через checkpoint_id. В проде — Postgres / SQLite saver, не MemorySaver в процессе. Имена меняются; форма — нет: разбираемый объект с schemaVersion, перечислением status, step, working, memoryRefs. Сериализатор может быть JsonPlus или расширенным JSON, но слой, который вы логируете, отдаёте наружу и отлаживаете, должен быть обычным JSON object — иначе Schema и браузерный Diff бесполезны.

Снимок ниже — только позиция. Ни messages[], ни сырого downstream HTTP. Бизнес-поля живут в working; вызов инструмента хранит name и callId; память — указатели. Полный транскрипт проецируйте из checkpoint в контекст модели — не считайте контекст State наоборот.

{
  "schemaVersion": "1.0",
  "runId": "run_7c2a",
  "threadId": "thr_invoice_42",
  "goal": "Reconcile January 2026 paid invoices",
  "status": "awaiting_tool",
  "step": 3,
  "maxSteps": 12,
  "node": "call_tools",
  "plan": ["searchInvoices", "sumTotals", "askConfirm"],
  "working": {
    "invoiceCount": 2,
    "currency": "USD"
  },
  "pendingTool": {
    "name": "searchInvoices",
    "callId": "call_8f3a"
  },
  "memoryRefs": ["mem_user_prefs", "mem_last_reconcile"],
  "checkpointId": "ckpt_3"
}

Оба стиля работают: полный снимок каждый раз или JSON Patch / reducer. Полный удобно сравнивать и воспроизводить; патч экономит место и сам должен быть проверяемым. В любом случае зафиксируйте Schema Draft 2020-12: status как enum (running / awaiting_tool / awaiting_human / succeeded / failed / cancelled), step — целое, ключи working из бизнеса, additionalProperties false, чтобы мусор инструментов не протекал. Ответ пользователю или downstream — отдельный файл Structured Output, не общий с checkpoint. См. AI Structured Output.

Memory: воспоминание — не позиция машины

Memory отвечает на «что ещё нужно знать сквозь время». State — на «где остановился этот кадр». Три слоя обычны в 2026: рабочая память (сообщения этого хода и недавние tool_result), краткая / потоковая (цепочка checkpoint на одном thread_id — short-term memory в LangGraph), долгая (Store между потоками: предпочтения, факты, процедуры). Свалить всё в один огромный JSON кажется дёшево; воспроизведение и политики забывания ломаются вместе.

По содержанию: эпизодическая (что случилось в этой сверке), семантическая (пользователь хочет итоги в USD), процедурная (повторяемые шаги вроде «сначала счета, потом сумма»). В State.memoryRefs только те воспоминания, на которые ссылается текущий run. Окно в миллион токенов не отменяет эти указатели — окно это бюджет, не истина. См. контекст 1M токенов.

Слой Типичный носитель Сюда не класть
Рабочая памятьmessages / tool_result этого ходаПолный текст предпочтений между сессиями
Краткая / checkpointСнимки State на thread_idСырой текст векторного хранилища, неподрезанные логи
Долгий StoreЗаписи по userId / namespaceТекущий step, pendingTool, ключи идемпотентности
Сессия поставщикаConversation / previous_response_idВаш бизнес-объект working

Долгим записям нужен стабильный конверт: id, kind, scope, text или data, source, updatedAt. source говорит, заявил ли это пользователь, вернул инструмент или суммировала модель — последние два должны отзываться. После попадания в поиск пишите в State только id и подмешивайте тело в контекст по необходимости. Пример:

{
  "id": "mem_user_prefs",
  "kind": "semantic",
  "scope": "user",
  "userId": "u_1042",
  "text": "Prefers USD totals and weekday email summaries",
  "source": "explicit_setting",
  "updatedAt": "2026-09-01T09:00:00Z"
}

Workflow и агент: кто рисует рёбра, кто пишет State

В классическом workflow (n8n, Temporal, свой автомат) люди заранее соединяют следующий hop. State — переменные workflow: id заказа, число повторов, ушла ли компенсация. У агента модель выбирает hop по текущему JSON-наблюдению, поэтому State ещё хранит plan, node, pendingTool. Прод 2026 редко чистокровный: граф с агентными узлами — рёбра это workflow, внутри узла цикл инструментов. Один JSON State служит двум читателям: оркестратор читает status / node; модель видит только спроецированное подмножество наблюдения.

MCP этим слоем не владеет. Удалённый MCP около 2026-07-28 — stateless JSON-RPC без сессии: каждый запрос несёт свои метаданные; сервер не помнит вашу бизнес-позицию. Это правильный выбор транспорта, а не «агент не может иметь состояние». Состояние приложения по-прежнему в вашем checkpoint. Подробности: Stateless MCP. Schema аргументов инструмента и Schema State — разные файлы: вход одного hop против позиции машины. См. MCP и JSON Schema.

Поперечное делегирование идёт через A2A: визави — непрозрачный агент; у задачи свой жизненный цикл (submitted / working / completed / failed) и artifacts. Это другой автомат — не сливайте его с локальным checkpoint. Оркестратор скрепляет их parentRunId. Сравнение: A2A vs MCP. Шлюз моделей (например локальный /v1) меняет только поставку инференса, не форму State. Стабильный контракт делает fallback осмысленным.

Выполнение: run, step, идемпотентность, повторы

Слой исполнения превращает снимок в восстанавливаемую машину. Каждая цель пользователя открывает runId; каждый hop инструмента — step; каждая запись вниз (списание, письмо, тикет) несёт idempotencyKey. После сбоя продолжайте с последнего checkpoint и не повторяйте побочные эффекты уже успешных step. Pending writes (часть узлов ок, часть нет) живут в снимке — не в догадке дежурного.

Человеческое подтверждение — статус первого класса, не особая ветка: status=awaiting_human, объект на подтверждении в working, при продолжении только законные переходы (одобрить → дальше, отклонить → провал или новый plan). Не «спрашивайте модель ещё раз» вместо перехода — модель не видит клик, который вы не записали в наблюдение. maxSteps, отмена пользователем и провал Schema тоже условия остановки: пишите их в status, не только в лог.

Выберите одного хозяина истории между сессией поставщика и вашей записью исполнения. Responses может продолжать reasoning через Conversation или previous_response_id; эта лента на стороне модели, не позиция сверки счетов. Рекомендация: вам принадлежат checkpoint и конверт задачи; платформе — только те reasoning-элементы, которые она требует воспроизвести как есть (некоторые поставщики требуют reasoning_content дословно, если есть tool_calls). Конверт:

{
  "taskId": "task_a2a_91",
  "parentRunId": "run_7c2a",
  "kind": "delegate",
  "status": "working",
  "idempotencyKey": "inv-jan-2026-reconcile",
  "steps": [
    { "id": "s1", "name": "searchInvoices", "ok": true },
    { "id": "s2", "name": "sumTotals", "ok": null }
  ],
  "artifacts": []
}

Делегируя дочернему агенту, кладите удалённый taskId в локальный working или steps — не расплющивайте их artifacts в тот же checkpoint. Промежуточные продукты — новое семейство JSON; держите их отдельно от финального Structured Output и MCP arguments. Сейчас же ставьте correlationId / runId на каждый лог инструмента. Наблюдаемость в духе DevDay должна стыковаться по тому же ключу. См. прогнозы OpenAI DevDay 2026.

Проверка на земле и JSONVue

До записи checkpoint три шага: parse → Schema → бизнес-правила. Умная модель их не заменяет. Плохой State опаснее плохих arguments: arguments — один hop; State — истина всего run.

  1. JSON.parse checkpoint; при ошибке отказать в записи и оставить предыдущий ckpt_id.
  2. Проверить status / step / working по State Schema (Draft 2020-12); выдать path и keyword.
  3. Бизнес-ворота: монотонный step, стабильный ключ идемпотентности, каждый memoryRef существует, незаконные переходы status закрываются отказом.

Поставьте рядом три JSON: ckpt_n, ckpt_n+1 и наблюдение, которое вы спроецировали модели. Скачок формы почти всегда в reducer. В браузере: форматтер JSON чтобы увидеть дерево снимка; Проверка JSON Schema чтобы зафиксировать конверты State и Memory; JSON Diff для соседних checkpoint. Делите фикстуры valid / нет step / незаконный status между CI и ручной отладкой.

Дальше: Что такое AI Agent, Structured Output, Stateless MCP, A2A vs MCP, контекст 1M токенов.

FAQ

State и Memory — одно и то же?

Нет. State — позиция текущего run (можно ли безопасно продолжить?). Memory — воспоминание сквозь время (предпочтения, факты, старые эпизоды). Цепочка checkpoint может быть краткой памятью; долгий Store не должен держать step / pendingTool. Воспроизведение использует State; поиск — Memory.

Окно контекста уже 1M — checkpoint всё ещё нужен?

Да. Окно решает, сколько наблюдения влезет в этот ход. Оно не решает, с какого hop продолжать после сбоя и не запишет ли повтор дважды. Считать всю историю State ухудшает и счёт, и поверхность отказа. 1M — инструмент бюджета; checkpoint — инструмент исполнения.

Мы используем OpenAI Conversation — всё равно хранить JSON State?

Да. Conversation / previous_response_id продолжает модельные элементы, не вашу бизнес-позицию. После квоты, региона или смены шлюза сессия поставщика может не совпасть. working, ключи идемпотентности и статус человеческого подтверждения должны жить в JSON, которым управляете вы.

Значит ли Stateless MCP, что нельзя сделать агента с состоянием?

Нет. Бессостояние протокола значит лишь, что каждый tools/call несёт свои аргументы; сервер не хранит прогресс сверки. Состояние приложения — в вашем checkpoint; MCP остаётся обнаружением и транспортом. Держите inputSchema и State Schema в двух файлах.

Итог и следующие шаги

Agent State 2026 в одной строке: рантайм помнит позицию в проверяемом JSON-снимке, Memory даёт только процитированное воспоминание, workflow рисует рёбра или отдаёт их модели, а исполнение делает снимок восстанавливаемой машиной через run / step / ключи идемпотентности. История чата и сессии поставщика этот снимок не заменяют.

Дальше: напишите State Schema и один valid checkpoint; сделайте Diff соседних снимков в JSONVue; добавьте фикстуры без поля и с незаконным status. Определение цикла — в статье про агента; форма финального ответа — в Structured Output; протоколы — в MCP / A2A.