Учебник
Что такое 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.
- JSON.parse checkpoint; при ошибке отказать в записи и оставить предыдущий ckpt_id.
- Проверить status / step / working по State Schema (Draft 2020-12); выдать path и keyword.
- Бизнес-ворота: монотонный 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.