教程

AI Agent State 是什么?2026 Agent 状态管理、JSON State、Memory、Workflow 与任务执行完整指南

聊天记录不是状态。Agent 能暂停、恢复、交给下一跳,靠的是一份可校验的 JSON:目标、步骤、工具回执、记忆指针与任务信封。

2026 年把 Agent 跑进生产,卡点很少是「模型够不够聪明」,而是停机、重试、人工确认之后,它还记不记得自己做到哪一步。上一篇把 Agent 收成「观察—决策—调工具」循环,见 AI Agent 是什么。本篇补上循环之外的那一层:State。State 不是把整段对话塞进上下文,也不是向量库里的一段记忆。它是运行时当前机位的结构化快照——几乎总是 JSON。下面按 JSON State、Memory、Workflow 与任务执行拆开,并接到站内无状态 MCP、A2A、Structured Output 与 1M 上下文文。

Agent State 是什么:和聊天记录、Session 差在哪

最小定义只需要一句话:Agent State 是让一次 run 可暂停、可恢复、可回放的结构化快照。它至少回答四个问题:目标是什么、现在停在哪一跳、已经确认的工作结果是什么、下一步被谁拦住(工具、人、还是 maxSteps)。模型负责在当前观察上选行动;运行时负责执行并把机位写回这份快照。没有可校验的机位,循环只能靠「再把整段聊天贴回去」——那是聊天,不是状态管理。

聊天记录是给模型看的消息列表:user / assistant / tool。Session(OpenAI Conversations、previous_response_id、旧 Assistants Thread)是给供应商看的会话句柄:下一请求要带上哪些模型侧条目。State 是给你的运行时看的机位:发票对到哪、待确认金额、当前图节点、checkpoint id。三者可以共存,但不要互相冒充。把 messages[] 当成唯一真相,重试时就会重复扣款、重复发邮件;把 Conversation id 当成业务状态,供应商一切换,机位就丢了。Assistants 迁到 Responses 之后,会话原语变了,业务快照更不该绑在平台对象上——见 Assistants → Responses 迁移。

2026 年常见事故几乎都是「层搞混了」:把工具 arguments 写进 State、把 State 整包塞进下一轮 prompt、或把长期记忆当 checkpoint 回放。分层之后,调试才有抓手:模型看错了是观察问题;机位写错了是 reducer / Schema 问题;记错用户偏好是 Memory 问题。对照如下。

概念 谁读 丢了会怎样
聊天记录 / messages模型(本轮上下文)答非所问;一般能从 checkpoint 再投影
Session / Conversation模型供应商多轮推理条目对不上;你的业务机位仍应独立
Agent State / checkpoint你的运行时、编排器无法安全恢复;重试可能双写下游
Memory跨 run 的检索与偏好忘了用户习惯;不应当成当前步骤的真相

JSON State:checkpoint 才是契约

把 State 写成 JSON,不是为了好看,而是为了校验、Diff、回放。LangGraph 一类编排器在每个 super-step 落一份 checkpoint,用 thread_id 串起一条线,再用 checkpoint_id 指向某一拍;生产上用 Postgres / SQLite saver,而不是进程内 MemorySaver。名字会变,形状不应变:一份可 parse 的对象,带 schemaVersion、status 枚举、step、working、memoryRefs。序列化实现可以是 JsonPlus 或扩展 JSON,但你对外暴露、写日志、做联调的那一层,应是普通 JSON object——否则 Schema 校验与浏览器 Diff 都用不上。

下面这份快照只描述机位,不把 messages[] 或下游 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 补丁。全量好 Diff、好回放;补丁省存储、要求补丁本身可校验。无论哪种,先定一份 Draft 2020-12 Schema:status 用枚举(running / awaiting_tool / awaiting_human / succeeded / failed / cancelled),step 是整数,working 的键来自业务,禁止 additionalProperties 把工具垃圾字段漏进来。最终给用户或下游系统的答案是另一份 Structured Output,不要和 checkpoint 共用一个文件——见 AI Structured Output。

Memory:回忆不是机位

Memory 解决「跨时间还该记得什么」,State 解决「这一拍停在哪」。2026 年常见三层:工作记忆(本轮上下文里的消息与最近 tool_result)、短期 / 线程记忆(同一 thread_id 上的 checkpoint 链,LangGraph 把这层叫 short-term memory)、长期记忆(跨 thread 的 Store:用户偏好、事实、程序说明)。把三层揉进一个大 JSON,看起来省事,回放和遗忘策略都会一起坏掉。

再按内容分:情景记忆(这次对账发生过什么)、语义记忆(用户喜欢美元合计)、程序记忆(「先搜发票再汇总」这类可复用步骤)。只有被引用进当前 run 的记忆,才应出现在 State 的 memoryRefs 里。上下文窗口涨到百万 token,也不等于可以取消这层指针——窗口是预算,不是真相。见 1M Token 上下文。

层 典型载体 不该塞什么
工作记忆本轮 messages / tool_result跨会话的用户偏好全文
短期 / checkpointthread_id 上的 State 快照向量库原文、未裁剪日志
长期 Store按 userId / namespace 的条目当前 step、pendingTool、幂等键
模型侧 SessionConversation / previous_response_id你的业务 working 对象

长期条目建议固定信封:id、kind、scope、text 或 data、source、updatedAt。source 写明是用户明示、工具回执还是模型总结——后两种要能作废。检索命中之后,只把 id 写进 State,全文按需注入上下文。示例:

{
  "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 与 Agent:谁画边、谁写 State

传统工作流(n8n、Temporal、自建状态机)的下一跳由人预先连好,State 是工作流变量:订单 id、已重试次数、补偿是否发出。Agent 的下一跳由模型根据当前这份 JSON 观察决定,State 还要记下 plan、node、pendingTool。2026 年生产上两者很少纯种出现:更常见的是「图 + 若干 Agent 节点」——边是工作流,节点内部是工具循环。一份 JSON State 同时服务两套读者:编排器读 status / node,模型只看到你投影出去的观察子集。

MCP 不管这件事。2026-07-28 一带的远程 MCP 把协议收成无状态 JSON-RPC:每次请求自带元数据,Server 不替你记住业务机位。那是传输层的正确选择,不是「Agent 不能有状态」。应用状态仍在你的 checkpoint。细节见 Stateless MCP 解析。工具 arguments 的 Schema 与 State Schema 必须分文件:前者描述这一跳入参,后者描述机位——见 MCP 与 JSON Schema。

多 Agent 横向委托走 A2A:对端是不透明的 Agent,任务有自己的生命周期(submitted / working / completed / failed)和 artifacts。那是另一份状态机,不要和本地 checkpoint 共用一个对象。编排器用 parentRunId 把它们钉在一起。对照 A2A vs MCP。换模型网关(例如本地 /v1)只改推理供应,不改 State 形状——契约稳定,降级才有意义。

任务执行:run、step、幂等与重试

执行层把 State 从「照片」变成「可恢复的机器」。每次用户目标开一个 runId;循环里每个工具 hop 一个 step;写下游(扣款、发信、建工单)必须带 idempotencyKey。崩溃后从最近 checkpoint 恢复时,已成功的 step 不得重放副作用。pending writes(部分节点成功、部分失败)应记在快照里,而不是靠运维猜。

人工确认是一等状态,不是特殊分支:status=awaiting_human,working 里放待确认对象,恢复时只允许有限的合法迁移(批准 → 继续,拒绝 → 失败或改 plan)。不要用「再问模型一遍」代替状态迁移——模型看不到你没写进观察的那次点击。maxSteps、用户取消、Schema 失败同样是停止条件,应写进 status,而不是只打日志。

平台会话与你的执行记录选一个历史主人。OpenAI Responses 可用 Conversation 或 previous_response_id 续上推理条目;那是模型侧的磁带,不是发票对账机位。推荐:你拥有 checkpoint 与任务信封,平台只拥有它必须拥有的 reasoning 条目(某些供应商在带 tool_calls 时要求原样回放 reasoning_content)。任务信封示例如下。

{
  "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": []
}

委托给子 Agent 时,把远端 taskId 写进本地 working 或 steps,而不是把对方 artifacts 摊进同一份 checkpoint。中间产物是新的 JSON 家族,最终 Structured Output 与 MCP arguments 都不要和它共用文件。现在就给每条工具日志打上 correlationId / runId,以后对账才对得上——DevDay 一类平台观测也按同一键对齐,见 OpenAI DevDay 2026 预测。

落地校验与 JSONVue 实操

每个 checkpoint 落地前固定三步:parse → Schema → 业务规则。模型再聪明,也不替代这三步。State 坏了比 arguments 坏了更危险:后者是一跳,前者是整条 run 的真相。

  1. checkpoint JSON.parse;失败则拒绝写入,保留上一拍 ckpt_id。
  2. 对照 State Schema(Draft 2020-12)校验 status / step / working;输出 path 与 keyword。
  3. 业务门:step 单调、幂等键稳定、memoryRefs 都存在、非法 status 迁移直接失败。

联调时把三份 JSON 并排:ckpt_n、ckpt_n+1、以及你投影给模型的观察。形状跳变几乎总在 reducer。浏览器里:JSON 格式化看清快照树;JSON Schema 校验卡住 State 与 Memory 信封;JSON Diff对比相邻 checkpoint。固定 fixture:valid、缺 step、非法 status,CI 与手工共用。

延伸阅读:AI Agent 是什么、Structured Output、Stateless MCP、A2A vs MCP、1M Token 上下文。

常见问题 FAQ

State 和 Memory 是一回事吗?

不是。State 是当前 run 的机位(能否安全恢复);Memory 是跨时间的回忆(偏好、事实、旧情节)。checkpoint 链可以充当短期记忆,但长期 Store 不应写成 step / pendingTool。回放用 State,检索用 Memory。

上下文窗口到 1M 了,还需要 checkpoint 吗?

需要。窗口解决的是「这一轮能塞多少观察」,不解决「崩溃后从哪一跳继续」和「重试会不会双写」。把整段历史当 State,账单和故障面会一起变差。1M 是预算工具,checkpoint 是执行工具。

用了 OpenAI Conversation,还要自己存 JSON State 吗?

要。Conversation / previous_response_id 续的是模型侧条目,不是你的业务机位。供应商配额、区域切换或换网关之后,平台会话可能对不上。业务 working、幂等键和人工确认状态应落在你控制的 JSON 上。

Stateless MCP 是不是就不能做有状态 Agent?

能。协议无状态只表示每次 tools/call 自带参数,Server 不保存你的对账进度。应用状态放在你的 checkpoint;MCP 仍是工具发现与传输。把 inputSchema 和 State Schema 分成两份文件。

总结与下一步

2026 年的 Agent State 可以概括成:运行时用一份可校验的 JSON 快照记住机位,Memory 只提供被引用的回忆,Workflow 画边或把边交给模型,任务执行用 run / step / 幂等键把快照变成可恢复的机器。聊天记录和平台 Session 都不是这份快照的替代品。

下一步:写出你系统里的 State Schema 与一份 valid checkpoint;用 JSONVue 做相邻快照 Diff,再补上缺字段 / 非法 status 夹具。循环定义读 Agent 文,最终答复形状读 Structured Output,协议层读 MCP / A2A。