Agent 框架层出不穷,到底哪个值得长期投入?

LangGraph 讲 Checkpoint,OpenAI 讲 ThreadRun,A2A 讲 Task,AG-UI 讲 Event,Deep Agents 又引入 TodoSubagentVirtual Filesystem。名字越来越多,API 越来越像一套套独立世界观。

框架名词在变,但底层问题始终围绕任务、上下文、步骤、事件、状态和产物展开。 如果把这些名词往下拆,会发现它们其实都在回答同一个底层问题:

一个 Agent 任务,如何被启动、携带上下文、持续观测、中断恢复,以足够低的使用成本完成执行,并最终产生产物?

换成协议视角,这个问题可以说得更直接:

一个生产级 Agent Protocol 应该包括什么?为什么这些协议对象会比具体框架 API 更稳定?

我不想每换一个 Agent 框架,就重新学习一套对象体系。我更关心的是,那些跨框架反复出现的稳定边界是什么。

框架会更迭,协议对象会换名字,但生产级 Agent 系统要解决的问题不会消失:

本文的目标不是介绍某一个框架怎么用,而是以 Agent Protocol 为主线,把 Agent Runtime 拆成一组可协议化的对象、操作和状态机。

这里先把边界说清楚:本文所说的 Agent Protocol 不是某一个具体标准,不等于 A2A、AG-UI、LangChain Agent Protocol 或任意单一规范;它指的是 Agent Runtime 对外暴露的一组稳定对象、生命周期操作和状态迁移。具体协议标准和框架 API 是证据,不是本文主线。

这篇文章也承接了我前面几篇 Agent 实践文章。

如何快速创建领域Agent - OneAgent + MCPs 范式 讨论的是如何把 Manus / Claude Code 式 Loop Agent 带进企业业务场景;从Claude Code到 OneAgent:如何做好上下文工程 讨论的是长任务 Agent 如何通过 Plan / Offload / Isolate / Retrieve / Reduce / Cache 管理上下文。本文再往下抽一层:这些实践背后,哪些对象和边界会沉淀为 Agent Runtime 的稳定协议语言?

协议告诉我们外部世界需要什么契约,Runtime 告诉我们内部如何实现这些契约。Harness 则进一步回答另一个现实问题:这些 Runtime 能力是否已经被打包成足够易用的默认体验。理解这层关系后,再看新框架时,就能快速判断:

  • 它只是换了一套 API 名字,还是解决了一个真实的 Runtime 问题?
  • 它强化的是执行模型、状态管理、工具协议,还是流式事件?
  • 它是暴露底层能力,还是把一整套长任务 Agent 能力封装成开箱即用的 harness?
  • 它的设计是长期趋势,还是阶段性流行?

我认为:

  1. Agent Runtime 的核心不是模型调用,而是任务生命周期管理
  2. Thread / Run / Step / Event / Artifact / Checkpoint 会成为跨框架的稳定对象
  3. 执行模型不会统一:Runtime Loop 承载方式和编排协议会长期分层演进
  4. 真正区分玩具 Agent 和生产 Agent 的,是状态持久化、中断恢复、可观测性和可评测性
  5. 值得看的不是某个框架 API,而是协议边界和 Runtime 抽象

读这篇文章前,请先理解 6 个对象

对象人话解释它回答的问题
Thread / Session一段长期上下文这是谁的哪段任务?
Run / Task一次具体执行这次具体跑了什么?
Step执行中的一个可观测步骤哪一步调用了模型、工具或子 Agent?
Event执行过程中的进展变化现在发生了什么?
ArtifactAgent 产出的正式结果结果在哪里,由哪次执行产生?
Checkpoint可以恢复的执行快照失败或中断后从哪里继续?

这 6 个对象,是理解 Agent Runtime Protocol 的入口。

围绕这 6 个对象,生产级 Agent Protocol 至少还要表达 stream / interrupt / resume / cancel / retry 这些生命周期操作。后文所有框架对比、Runtime 分析和 Harness 讨论,都应回扣到这组对象与操作:它们分别解决任务创建、上下文携带、步骤执行、事件观察、中断恢复、产物沉淀和评测审计的问题。

1. 先定义 Agent Protocol 的边界

1.1 三层概念:标准、对象、Runtime 能力

讨论 Agent Protocol 时,最容易把三层东西混在一起:

层级例子解决的问题
具体协议标准A2A、AG-UI、LangChain Agent Protocol、AITP、ACP不同系统如何通信,如何描述任务、消息、事件和产物
通用协议对象Thread、Run、Step、Event、Artifact、Checkpoint外部世界如何稳定理解一次 Agent 任务
Runtime 实现能力状态持久化、中断恢复、可恢复流、权限控制、可观测性Runtime 内部如何兑现这些对象和状态机

本文重点讨论第二层:通用协议对象。具体协议标准和框架实现只作为证据,用来说明这些对象正在跨系统收敛。

1.2 Runtime Protocol:外部世界如何理解一个 Agent

Agent Runtime Protocol 是 Agent Runtime 暴露给外部世界的契约。它回答的不是”模型如何思考”,而是:

  • 如何启动一次任务 :创建 Thread、Task、Run,或发送一条 Message
  • 如何携带上下文 :历史消息、文件、结构化数据、参与者、能力声明
  • 如何观察进展 :状态变更、流式事件、Artifact 增量、Trace
  • 如何中断和恢复 :需要输入、需要授权、取消、重试、继续执行
  • 如何拿到结果 :最终消息、Artifact、结构化输出、错误信息

一句话:Protocol 是 Runtime 的外部边界,Runtime 是 Protocol 的内部实现

因此,讨论 Agent Runtime 时不应该只讨论内部编排,也要讨论它被什么协议对象驱动,以及它向外承诺什么状态机。换句话说:Runtime 是内部能力,Protocol 是外部可依赖的边界

1.3 Runtime:模型调用之外的执行系统

Agent Runtime 是 Agent 的执行环境,负责:接收输入 → 调用 LLM → 执行工具 → 管理状态 → 产出结果。

不同框架对 Runtime 的定义边界不同:LangGraph 包含了从编排到持久化的完整栈;OpenAI Assistants 把整个 Runtime 藏在服务端;AutoGen 更强调多 Agent 对话组织。但它们都必须回答同一组问题。

更精确地说,Agent Runtime 不是”一次模型调用”,而是模型调用之外的那层执行系统。它至少要管理五类事情:

  • 生命周期:一次任务如何开始、运行、暂停、恢复、结束
  • 上下文:哪些消息、文件、状态、外部资源对当前执行可见
  • 调度:下一步调用模型、工具、子 Agent,还是等待人类
  • 控制面:权限、Guardrail、取消、超时、预算、并发限制
  • 数据面:状态快照、事件流、Trace、Artifact、成本数据如何流动

这也是为什么 Responses API 不是完整 Runtime,而 OpenAI Agents SDK 是更高层 Runtime:前者主要给你模型和工具调用能力,后者开始接管循环、工具执行、Handoff、Session、Guardrail、Tracing 等运行时职责。

1.4 最小生命周期:一个 Agent 任务到底经历了什么

不管采用哪种框架,生产级 Agent Runtime 都绕不开同一个生命周期:

这里最关键的概念是 Run。Thread/Session 描述长期上下文,Run 描述一次具体执行。没有 Run 这个边界,就很难定义超时、取消、Trace、成本、权限审批和最终结果。

从协议角度看,这条生命周期可以被映射成一组稳定对象:

Protocol 对象Runtime 含义典型来源
Agent / Assistant可被调用的能力提供者A2A Agent Card、OpenAI Assistant、LangGraph assistant
Thread / Context多轮上下文边界OpenAI Thread、AITP Thread、A2A Context
Task / Run一次执行边界A2A Task、OpenAI Run、LangGraph Run
Message / Part输入输出内容单元A2A Message/Part、AITP Message
Artifact任务产物A2A Artifact、文件、报告、代码 diff
Event进展增量SSE event、status update、artifact update
Checkpoint / State可恢复状态LangGraph Checkpoint、State Snapshot

后文的八个维度,本质上就是解释这些对象如何被 Runtime 实现。

为了避免后文变成框架名词堆叠,全文可以按这条任务生命周期阅读:

生命周期阶段主要协议对象后文对应部分
创建任务Agent / Thread / Run执行模型、Runtime Loop
携带上下文Thread / Message / Workspace状态管理、Workspace / Sandbox
执行步骤Step / Tool Call / Subagent task执行模型、工具协议、多 Agent 协作
观察事件Event / Trace / State Snapshot流式输出、可观测性
中断恢复Checkpoint / Interrupt / Resume状态管理、中断恢复、错误恢复
产生产物Artifact / Workspace file状态管理、流式输出、Harness
评测审计Step / Event / Artifact / Trace可观测性与可评测性

1.5 现有协议已经在向同一组对象收敛

下面这张表不是为了横向堆框架名词,而是作为证据:不同标准和框架正在围绕 Thread、Run、Step、Event、Artifact、Checkpoint 这些对象收敛。

协议/规范核心对象主要关注点对 Runtime 的启发
LangChain Agent ProtocolThread、Run、Store、Command、OpenAPI spec用框架无关 API 服务化生产 AgentRuntime 要暴露可创建、搜索、更新、流式运行和发送命令的标准资源
A2AAgent Card、Task、Message、Part、Artifact、Streaming Event独立 Agent 系统之间互操作Task 状态机和 Artifact 是跨 Agent 协作的核心
AITPThread、Actor、Capability、Transport跨信任边界的 Agent 交互和交易Thread 是最低公共接口,Capability 承载结构化能力
ACPAgent metadata、REST endpoint、Message、SSE跨框架、跨组织 Agent 通信协议要简单到能用 HTTP 直接接入,同时支持异步长任务
AG-UIRun event、Message event、Tool event、State deltaAgent 与前端 UI 的事件协议前端需要的不只是最终答案,而是标准化事件流
OpenAI AssistantsAssistant、Thread、Message、Run、Run Step托管式 Agent 执行Thread/Run/Step 是生产 Runtime 的基础资源模型
LangGraph Server APIThread、Run、Stream Mode、State Update可恢复流和状态观测Runtime 协议需要同时支持 run stream 和 thread stream
Deep AgentsTodo、Subagent task、Virtual filesystem、Backend、Skill复杂任务 Agent HarnessRuntime 之上还需要面向长任务的 planning、delegation、workspace 和 skill 协议对象
OpenTelemetry GenAITrace、Span、Event、Attributes跨框架可观测性语义Protocol 不只面向业务调用,也面向观测系统

这些标准并没有完全收敛,但它们已经共同指向一个事实:Agent Protocol 的中心不再是单次 chat completion,而是 长生命周期、可观测、可评测、可恢复、可协作的任务对象

1.6 本文使用哪些框架作为证据

后文会多次出现框架对比表。它们不是主线,而是证据:用来观察不同实现如何落到同一组协议对象上。

框架全称核心定位版本基准
LangGraphLangGraph + LangGraph Platform图执行引擎 + Agent Server0.3.x
Deep AgentsDeep Agents SDK(built on LangGraph)面向复杂任务的 Agent Harness2026.06
OpenAIAssistants API + Responses API + Agents SDK托管式 Agent Runtime2025.04
AutoGenAutoGen 0.4(Core + AgentChat)多 Agent 对话框架0.4.x
Claude SDKClaude Agent SDK(Anthropic)代码执行 Agent0.1.x

Part 1:创建任务与执行步骤:Agent 如何跑起来

这一部分对应任务生命周期里的“创建任务”和“执行步骤”:一个外部请求如何变成 Run,Run 又如何被拆成 Step、Tool Call、Subagent task 和状态事件。先看 Runtime Loop 被谁承载,再看 loop 内部哪些动作会被提升为协议状态。

2. 执行模型 (Execution Model)

2.1 通用概念

执行模型定义了 Agent 计算如何被编排:什么是执行的基本单元、单元之间如何调度、控制流由谁决定。放到协议视角,它还定义了一个外部请求如何变成内部执行:一条 Message 如何创建 Task/Run,一次 Run 如何拆成多个 Step,每个 Step 如何产生状态、事件和产物。

子概念

  • 执行单元 (Execution Unit):一次不可分割的计算步骤——一个 LLM 调用、一次工具执行、一个决策节点
  • 调度模型 (Scheduling):执行单元的排列方式——顺序、并行、条件分支
  • 控制流 (Control Flow):谁决定下一步做什么——显式的图边、LLM 的推理、代码逻辑

2.2 两层模型:Loop 承载方式与编排协议

讨论 Agent 执行模型时,最容易混淆的是把不同层级的东西放在一起比较。更清晰的做法是拆成两层:

  • Runtime Loop 承载方式:谁拥有主循环,控制流被放在哪种运行时容器里
  • 编排协议模式:主循环内部哪些语义对象被显式化,哪些 Action 副作用会进入 Runtime 状态机

Graph、Code、Managed 属于第一层,回答 loop 的承载容器;ReAct、Plan-and-Execute、Conversation-style coordination 属于第二层,回答 loop 内部的主导语义对象。Conversation 和 Graph / Code / Managed 放在同一层会制造误判,它更适合作为广义 Agent loop 上的一种消息协作契约。

执行模型应拆成两层看:Loop 承载方式决定循环在哪里,编排协议决定循环内部哪些语义被显式建模。

图式 Runtime并不排斥代码。LangGraph 的节点函数、条件边和工具调用仍然由代码实现,这些代码被放进图运行时里,控制流被结构化为节点、边、状态和 checkpoint。它的价值在于给复杂分支、并行、恢复和观测提供稳定运行时边界。

ReAct 可以看成最小 Agent loop:Observation 进入上下文,模型完成 Reasoning,再选择 Action,最后把 Result 写回上下文继续推进。这里的 Action 可以是普通业务工具,也可以是带 Runtime 语义的工具,例如更新计划、发送消息、路由、handoff、请求人类确认。

Plan-and-Execute 的关键是把 Plan / Todo / Step / Progress 提升为显式状态。计划依然可以由 ReAct 的 update_plan()update_todo() 触发,但 Runtime 会把这些副作用纳入进度展示、checkpoint、恢复、审计和评测。

Conversation-style coordination 的关键是把 Participant / Message / Route / Handoff / Speaker 提升为显式状态。transfer_to_agent() 可以表现为一次工具调用,同时触发 active agent、权限边界、上下文可见性和 trace 归属的状态迁移。它的核心语义来自持续参与者之间的消息协议,而非一次性调用对象。

这也解释了为什么 Agent 可以作为工具存在。子 Agent 被一次性调用并返回结果时,更接近 capability invocation;多个 Agent 以持续身份参与同一段消息协议,订阅、响应、修正彼此的消息时,更接近 conversation-style coordination。差异来自运行时角色:一次性能力调用,或持续参与者交互。

这里还有 Runtime 和 Framework 之间的层:Agent Harness。它不是主线之外的新概念,而是 Protocol/Runtime 能力产品化后的应用层。LangChain 官方把 Deep Agents SDK 归为 harness:它基于 LangGraph runtime 封装高层电池包,把 planning、todo、subagents、filesystem、context management、HITL、streaming、memory、permissions 组合成一个开箱即用的复杂任务 Agent。

Harness 的价值是易用性:它把原本需要开发者自己组装的 Runtime 能力,预先打包成一套默认可用的工作方式。Deep Agents 的优势就在这里——你不需要从零设计 todo list、subagent task、virtual filesystem、backend 和 permission model,就能获得一个接近 Claude Code 使用体验的长任务 Agent。

Claude Agent SDK 走的是另一种路线:它直接复用 Claude Code 二进制能力,因此可以获得成熟的代码 Agent 体验、文件操作、权限模型和工具链集成;对应的限制是,它的执行环境、工具边界、可移植性和可观测性会更强地绑定到 Claude Code 的产品形态。

这也解释了我在 从Claude Code到 OneAgent:如何做好上下文工程 里为什么把规划工具、子智能体、虚拟文件系统和长 Prompt 放在同一组能力里讨论:它们不是零散技巧,而是 Harness 把 Runtime 能力产品化后的默认工作方式。到了协议视角,这些能力会进一步被拆成 Todo / Subagent task / Workspace / Skill / Event 等可观察对象。

换成本文的六对象主线,可以这样对应:

Harness 体验对象回扣到的协议对象说明
Todo / PlanStep / Event把长任务进度变成可观察、可恢复的步骤
Subagent taskRun / Step / Artifact把委派任务变成可追踪的子执行和结果
Virtual filesystem / WorkspaceArtifact / Checkpoint把中间结果、文件和最终产物沉淀到可恢复状态
SkillTool / Artifact / Metadata把可复用能力包变成 Runtime 可发现的能力
Permission / HITLInterrupt / Resume / Event把高风险动作放入中断恢复状态机

易用性也会带来约束。封装越强,默认路径越清晰,框架替你做的决策也越多。因此使用这些成熟框架的时候,手里有源码能够覆写乃至重写很有必要,不然复杂的业务场景很难被都满足。相比强绑定二进制产品形态的路线,生产环境我更推荐使用 Deep Agents,原因也在于此。

所以评价一个 Agent 框架,既要看底层 Runtime 能力,也要看这些能力是否容易被正确使用。Runtime 解决能不能做,Harness 解决开发者能不能低成本做好;二进制复用型 SDK 进一步解决成熟体验复用问题,同时也带来更强的平台约束。

Harness 把 Runtime 能力打包成默认可用的长任务 Agent 体验,解决“能不能做”之外的“能不能低成本做好”。

2.3 跨框架映射

概念LangGraphOpenAI AssistantsAgents SDKAutoGenClaude SDK
执行单元Node(函数/Runnable)Run StepAgent turnAgent message handlerAgent turn
调度模型Graph(DAG + 循环)服务端托管循环Python 控制流对话协议(轮转/选择)代码驱动循环
控制流条件边 / Command服务端决定(不透明)Handoff / 代码分支Selector / RoundRobin工具结果驱动 LLM
并行执行Send API(fan-out/fan-in)不支持不支持GroupChat 内并行不支持
执行容器Thread + RunThread + RunRunner 上下文Runtime + TeamSession

2.4 Runtime Loop:Agent 的隐藏主循环

很多 Agent 框架表面 API 差异很大,但内部都存在一个主循环:

while not done:
    messages = load_context()
    model_output = call_llm(messages, tools)
    if model_output.tool_calls:
        tool_results = execute_tools(model_output.tool_calls)
        append_results(tool_results)
        continue
    if model_output.handoff:
        transfer_to_next_agent()
        continue
    if model_output.needs_human:
        interrupt()
        break
    return final_output

Runtime Loop 在内部决定下一步调用模型、执行工具、切换 Agent、等待人类还是返回结果;协议外部则需要把这些分支稳定表达成 Task / Run 状态。

框架差异主要在于这个循环由谁拥有:

拥有者代表特点
开发者拥有循环Responses API、Claude Client SDK灵活,但状态、重试、工具执行都要自己写
SDK 拥有循环OpenAI Agents SDK、Claude Agent SDK上手快,工具执行和事件流由 SDK 托管
图引擎拥有循环LangGraph循环被拆成节点、边、Checkpoint 和 Pregel-style SuperStep
服务端拥有循环OpenAI Assistants最省心,但控制权和可观测性最少

判断一个框架是不是 Runtime,不要看它是否能调模型,而要看它是否拥有这个循环。

Deep Agents 的位置很特殊:它不重新发明 Runtime Loop,而是把 LangGraph 的 durable execution、streaming、checkpointing、人机协作能力包装成一个默认可用的 harness。对协议设计来说,这意味着外部对象仍然是 Thread/Run/Event/Artifact,但内部多了 todo list、virtual filesystem、subagent task、skill、backend 这些更贴近复杂任务的中间对象。

从协议角度看,这个循环就是 Task/Run 状态机的内部实现:

SUBMITTED ──► WORKING ──► INPUT_REQUIRED ──► WORKING ──► COMPLETED
                  │              │
                  │              └── 等待 Message / Resume / Authorization
                  │
                  ├──► FAILED
                  └──► CANCELED

A2A 把这类状态显式放进 Task;OpenAI 把它放进 Run;LangGraph Server 则通过 Thread/Run stream 暴露生命周期事件。对象名不同,但协议都需要向客户端回答同一个问题:这次执行现在处于什么状态,客户端下一步能做什么?

2.5 事件驱动 Runtime

AutoGen Core 展示了另一条路线:把 Agent 执行看成事件驱动系统。Agent 不再只是”被调用的函数”,而是订阅 Topic、接收 Message、发布 Message 的 Actor。

这种模型的价值在于:

  • 解耦 :发送方不需要知道谁会处理消息
  • 并发 :多个 Agent 可以订阅同一个 Topic 并行响应
  • 分布式 :Runtime 可以演进成跨进程、跨机器的消息总线
  • 弹性 :失败的 Agent 可以独立重启,不必拖垮整个工作流

但代价也明显:调试困难、消息顺序复杂、状态一致性变差。适用于大规模(超过 10个 Agent 协作)多 Agent 系统。

2.6 Workspace / Sandbox:执行环境也是状态

新一代 Agent Runtime 开始把”工作区”作为一等概念。OpenAI Agents SDK 的 Sandbox agents、Claude Agent SDK 的文件工具和权限模式,本质上都在回答同一个问题:Agent 执行时能读写哪些外部资源?

Deep Agents 把这一点推得更彻底:它默认提供 virtual filesystem,并支持 StateBackend、FilesystemBackend、StoreBackend、CompositeBackend 等可插拔 backend。也就是说,文件不只是工具调用的副作用,而是 Agent 管理上下文、沉淀中间结果、组织长任务产物的核心状态层。

Workspace 和普通上下文不同:

类型例子生命周期风险
Prompt Context消息、系统提示词单次模型调用泄漏、污染
Runtime StateCheckpoint、Session 变量跨步骤/跨请求版本不一致
Workspace State文件、代码仓库、浏览器页面跨工具调用破坏性副作用
External State数据库、工单、支付系统Runtime 外部真实业务影响

因此,生产 Runtime 不能只管理”对话历史”,还要管理工作区隔离、文件变更审计、权限审批和副作用回滚。

2.7 设计决策分析

执行模型的设计决策要分两层看。第一层是 Runtime Loop 承载方式,它决定控制权、状态、恢复和观测主要由谁负责:

Loop 承载方式容易做到困难做到典型场景
图式 Runtime分支、并行、可视化、断点调试简单的线性对话(过度建模)复杂工作流、审批流、研报生成
代码式 Runtime灵活、学习曲线低、调试直观持久化、断线恢复、可视化简单 Agent、脚本任务
托管式 Runtime零运维、开箱即用自定义执行逻辑、成本控制快速原型、客服 Bot

第二层是 编排协议模式,它决定 loop 内部哪些语义被 Runtime 正式承认:

编排契约显式建模对象典型触发形式Runtime 需要管理什么
ReAct Tool LoopTool Call / Observation / ResultLLM 选择工具工具执行、结果回写、错误作为数据
Plan-and-ExecutePlan / Todo / Step / Progress工具调用或调度器触发计划持久化、进度更新、计划修正、阶段恢复
Conversation-style coordinationParticipant / Message / Route / Handoff / Speaker工具调用或消息路由触发发言顺序、路由、权限切换、上下文可见性、trace 归属
Manager-WorkerTask / Subtask / Assignment / Result工具调用或调度器触发子任务分派、上下文隔离、结果汇总、失败重试

2.8 本章结论

执行模型回答“一个 Run 如何被调度”。后面的状态、工具、流式、中断和观测能力,都是围绕这条 Runtime Loop 展开的。

执行模型不会统一。Loop 承载方式回答主循环放在哪里,编排协议模式回答哪些 Action 副作用会被 Runtime 提升为状态对象。复杂工作流适合图式 Runtime,简单任务适合代码式 Runtime,快速原型适合托管式 Runtime;ReAct、Plan-and-Execute、Conversation-style coordination 可以运行在不同 Runtime 之上,也可以在同一个 Runtime 内叠加。

作为开发者,关键不是押注某一种 loop,而是让状态管理、工具调用、流式输出独立于具体执行模型。这样从代码式 Runtime 切到图式 Runtime,或从 ReAct 切到 Plan-and-Execute 时,其他能力仍然可以复用。— 虽然对于 LangGraph来说都可以做。


Part 2:保存状态、中断恢复与重试:Agent 如何活得久

这一部分对应任务生命周期里的“携带上下文”“中断恢复”和“失败重试”:Run 执行到一半时哪些状态必须保存,暂停后如何继续,失败后如何保留已有进度。状态管理是基础,中断恢复和错误恢复都是它向外延伸出来的生产能力。

3. 状态管理:生产级 Agent 的分水岭

3.1 通用概念

状态管理定义了 Agent 执行过程中的可变数据如何表示、持久化、版本化和恢复。协议视角下,状态管理还要决定哪些状态可以被外部看见:Thread history、Task status、Artifact、State Snapshot、Trace metadata,分别暴露给不同类型的客户端。

子概念

  • 状态表示 (State Schema) :数据的形状——类型化的结构(TypedDict)、消息列表、JSON blob
  • 状态持久化 (Persistence) :数据存到哪——内存、数据库、服务端托管
  • 状态版本化 (Versioning) :能否查看/回滚历史——快照链、消息追加、无版本
  • 状态作用域 (Scope) :数据对谁可见——全局、Agent 级、Channel 级
  • 增量更新 (Update Mechanism) :如何修改状态——Reducer 函数、直接覆盖、追加消息

3.2 持久化光谱

各框架在状态持久化上的立场差异巨大,形成了一个光谱:

状态持久化从“进程内临时状态”到“服务端托管状态”形成一条光谱,生产 Agent 必须明确自己站在哪一段。

3.3 跨框架映射

概念LangGraphOpenAI AssistantsAgents SDKAutoGenClaude SDK
状态表示TypedDict + Channel 级 ReducerThread(消息列表 + 元数据)RunContext(Python 对象)ChatCompletionContext + 共享状态对话历史(隐式)
持久化Checkpointer(PG/Redis/SQLite)服务端托管(不透明)无(手动 save_state/load_state无内置无内置
版本控制Checkpoint 链(parent_id,类 Git)Thread 消息历史(追加制)
状态作用域Channel 级(每个字段独立 Reducer)Thread 级Agent 级Agent/Team 级Session 级
增量更新Annotated[list, add_messages] 等 Reducer追加消息直接修改追加消息直接修改

3.4 状态分层:不要把所有东西都叫 Memory

Agent 领域最容易混淆的词是 Memory。更清晰的做法是把状态拆成五层:

层级典型名称内容主要问题
ConversationMessages / Thread用户、模型、工具消息上下文窗口、裁剪、摘要
Run StateState / Context当前执行的结构化变量类型、Reducer、并发更新
CheckpointSnapshot / Savepoint某一步之后的完整可恢复状态存储、版本、回滚
ArtifactFile / Report / Code diffAgent 产出的外部结果生命周期、权限、可追溯
Semantic MemoryLong-term Memory跨会话沉淀的用户偏好或知识检索、污染、遗忘

很多框架说自己支持 Memory,实际只支持其中一层。生产设计必须先问清楚:要保存的是对话、运行状态、可恢复快照、文件产物,还是长期记忆?

这和前文讨论的上下文工程是同一个问题的两个视角。从Claude Code到 OneAgent:如何做好上下文工程 里我从模型可用性的角度拆成 Plan、Offload、Isolate、Retrieve、Reduce、Cache;这里则从 Runtime Protocol 的角度拆成 Conversation、Run State、Checkpoint、Artifact、Semantic Memory。前者回答“怎样让模型在长任务中不迷失”,后者回答“哪些状态必须被 Runtime 稳定保存、恢复和暴露”。

3.5 Session、Thread、Run 的关系

  • Session/Thread :长期上下文边界,回答”这是谁的哪段任务”
  • Run :一次执行边界,回答”这次具体跑了什么”
  • Step :最小可观测执行单元,回答”哪一步调用了模型或工具”
  • Checkpoint :恢复边界,回答”失败后从哪里继续”
  • Artifact :产物边界,回答”结果在哪里、由哪次执行产生”

OpenAI Assistants 把 Thread 和 Run 显式暴露出来;LangGraph 把 Thread 作为 configurable.thread_id,把 Run 隐含在一次 invoke/stream 中;Agents SDK 更强调 Runner 和 Session。名字不同,但边界是相同的。

如果所有 Runtime 都能基于统一 Agent Protocol 表达 Thread -> Run -> Step -> Artifact 这条链路,那么控制台、前端、评测系统、审计系统就不需要理解每个框架的内部状态结构。

3.6 并发会话与并发 Run:Thread 不是锁,Run 才是执行边界

并发会话处理的关键,是不要把 Thread / Session 和 Run 混成一个概念。Thread / Session 是长期上下文边界,Run 是一次执行边界;同一个用户可以有多个 Thread,同一个 Thread 也可能在短时间内收到多个 Run 请求。

生产 Runtime 必须明确一个问题:同一个 Thread 上是否允许多个 Run 同时执行? 不同选择会导向不同的状态一致性策略:

策略行为优势代价典型场景
串行队列同一 Thread 的 Run 按顺序排队执行语义最稳定,消息顺序清晰延迟增加,长任务会阻塞后续输入多轮对话、客服、需要强上下文连续性的任务
拒绝新 RunThread 已有运行中 Run 时直接返回 conflict / busy实现简单,避免状态冲突用户体验生硬,需要前端解释和重试后台任务、审批流、一次只允许一个执行的场景
取消并覆盖新 Run 到来时取消旧 Run,用最新输入重新执行交互体验直接,适合“以最后一次为准”旧 Run 的部分进度和副作用需要可追溯或可回滚搜索、草稿生成、用户频繁改需求的交互
分叉新 Run从同一个 Checkpoint 分叉出多个 Run 并行执行适合 A/B 测试、方案比较、探索式任务需要清晰标记分支、Artifact 归属和最终采纳关系Prompt 对比、策略实验、研究任务
乐观并发Run 开始时记录 state version,提交时检查是否冲突并发度高,适合低冲突写入冲突检测和合并逻辑复杂多 Agent 并行写不同 state channel

这些策略没有绝对优劣,关键是把语义放进协议和 Runtime 状态机里。客户端需要知道新 Run 是被排队、拒绝、取消旧任务、创建分支,还是等待冲突解决;观测系统也要能把每个事件、Artifact 和错误归属到具体 Run。

并发写状态时,Runtime 至少要处理五类冲突:

  • 消息顺序冲突 :两个 Run 同时向同一个 Thread 追加消息,最终历史如何排序
  • 状态版本冲突 :两个 Run 基于同一份 State Snapshot 修改同一个字段,谁覆盖谁
  • Artifact 归属冲突 :多个 Run 生成同名文件或报告,哪个是正式产物
  • Workspace 副作用冲突 :多个 Run 同时改同一份代码、浏览器页面或外部系统资源
  • 事件流归属冲突 :前端同时订阅多个 Run 时,如何用 run_id、step_id、event_id 恢复和去重

因此,Thread 不应该被简单当成一把全局锁。更稳的设计是:Thread 承载上下文,Run 承载执行,Checkpoint 承载版本,Event 承载进展,Artifact 承载产物;并发控制策略则明确写进 Run 创建语义和状态迁移规则。

3.7 状态迁移与 Schema 演进

持久化一旦进入生产,就会遇到 Schema 演进问题:今天保存的 Checkpoint,三个月后代码升级还能不能恢复?或者说历史执行记录还能不能打开继续了?

生产 Runtime 需要考虑:

  • 状态版本号 :每个快照记录 schema version
  • 迁移函数 :加载旧快照时转换到新结构
  • 兼容窗口 :保留多久的旧状态可恢复
  • 失败策略 :迁移失败时是终止、降级,还是创建新 Run

这也是服务端托管状态和自建 Checkpoint 的核心差异:托管方案隐藏迁移复杂度,但也隐藏了控制权;自建方案控制力强,但必须承担 schema 演进成本。

3.8 设计决策分析

LangGraph 的 Checkpoint 模型是目前最完整的状态管理方案:

  • 每个节点执行后自动快照(不需要手动调用 save)
  • 快照具备链式结构,支持”时间旅行”(即任意节点回滚、重放)
  • Content-addressed blob 存储,类似 git 的存储方式,大状态只存一次
  • 允许运行时修改 Agent 的上下文信息,这个相当牛意味着可以运行时让 Agent 自进化

代价是:学习曲线陡峭,Reducer 函数的语义需要理解,Checkpoint 存储占空间。

OpenAI Assistants 的 Thread 模型走了另一个极端:

  • 你不需要(也无法)管理状态——服务端全包
  • 状态只能通过追加消息来修改,不能直接改内部状态
  • 没有回滚——你只能创建新 Thread

代价是:零控制权。调试困难,无法做”如果当时走了另一条路”的分析。

AutoGen / Claude SDK / Agents SDK 基本没有内置持久化,把这个问题留给开发者。对于短生命周期的 Agent 这没问题,但一旦需要跨请求保持状态(如人机协作工作流、事后评测、版本管理等),就必须自己搭建。

3.9 本章结论

状态管理回答“Run 执行到一半时,哪些东西必须被保存,以及多个 Run 同时发生时如何保持一致”。它承接上一章的 Runtime Loop,也直接支撑后面的中断恢复、错误回滚、并发会话和执行回放。

状态持久化是区分“玩具”和“生产”的分水岭。没有持久化的 Agent 无法在进程崩溃后恢复,无法支持真正的 Human-in-the-Loop,无法调试“为什么 Agent 走了这条路”,也无法从同一个状态分叉执行不同策略。并发 Run 进一步要求 Runtime 明确队列、拒绝、取消覆盖、分叉和乐观并发等策略。

真正难的不是保存,而是恢复。恢复要求状态 schema、工具副作用、外部资源、权限上下文都能重新对齐;只把 messages 存进数据库,并不等于具备生产级状态管理。


4. 中断与恢复:Human-in-the-Loop 的真正基础设施

4.1 通用概念

中断与恢复定义了 Agent 执行如何暂停(通常等待人类输入)以及如何从暂停点继续。这是 Human-in-the-Loop 的基础设施。

子概念

  • 中断触发 (Interrupt Trigger):什么条件下暂停——到达特定节点、需要工具审批、主动请求人类输入
  • 中断状态 (Interrupt State):暂停时保存了什么——完整状态快照、对话历史、什么都没保存
  • 中断载荷 (Interrupt Payload):暴露给人类的信息——“Agent 想调用这个工具,你同意吗?”
  • 恢复机制 (Resume Mechanism):人类如何提供输入并让 Agent 继续——提交数据、选择选项、直接回复

4.2 跨框架映射

概念LangGraphOpenAI AssistantsAgents SDKAutoGenClaude SDK
中断触发interrupt() / interrupt_before / interrupt_afterrequires_action(仅工具审批)Guardrail 拦截HandoffTerminationclient.interrupt()
中断状态Checkpoint(完整快照 + pending_writes)服务端 Thread(不透明)无持久化对话历史(手动 save)无持久化
中断载荷任意 JSON(interrupt(payload)tool_calls 列表Guardrail 错误信息HandoffMessage
恢复机制Command(resume=value)submit_tool_outputs()代码手动恢复重新 run_stream(task=input)query()
多点中断支持(多节点设置 interrupt_before不支持不支持不支持不支持

4.3 中断/恢复通用流程

不管框架如何实现,中断/恢复的通用流程是一样的:

Agent 执行 ──► 到达中断点 ──► 保存执行状态 ──► 向前端暴露中断载荷
                                                     │
                                                     ▼
                                               人类查看/决策
                                                     │
                                                     ▼
Agent 恢复 ◄── 从快照加载状态 ◄── 接收人类输入 ◄── 前端提交

关键约束:真正的中断/恢复需要状态持久化。如果框架没有持久化能力(Claude SDK、Agents SDK),就只能做同步的”ask and wait”——进程不能退出,用户必须立即回复。

LangGraph 的方案是最完整的:

# 节点内主动中断,传递任意载荷
def review_node(state):
    decision = interrupt({
        "question": "要发布这篇文章吗?",
        "draft": state["draft"],
        "options": ["发布", "修改", "丢弃"]
    })
    # decision 是人类通过 Command(resume=...) 传入的值
    if decision == "发布":
        return {"status": "published"}
# 人类回复
graph.invoke(Command(resume="发布"), config)

4.4 设计决策分析

方案优势劣势
LangGraph:通用 interrupt + Command任意节点、任意载荷、完整状态保存需要 Checkpointer,学习成本高
OpenAI:requires_action简单,服务端托管状态只能审批工具调用,不能主动问用户问题
AutoGen:HandoffTermination用 Handoff 统一了人机和 Agent 间交互状态需手动保存,恢复不是从断点继续
Claude SDK:interrupt()极简——发信号停止没有恢复,只能重新开始

4.5 本章结论

中断/恢复回答“任务暂停后能否从原位置继续”。它不是独立能力,而是状态管理的直接延伸:只有 Runtime 能保存精确状态,才可能几小时后从同一个断点继续。

中断/恢复是各框架实现差距最大的维度。LangGraph 的方案领先,是因为它把 Checkpoint 和 Interrupt 深度整合;其他框架要么只支持工具审批,要么只能做同步等待或重新开始。

因此 Human-in-the-Loop 的基础设施不是一个 ask-user API,而是“状态快照 + 中断载荷 + 恢复指令 + 权限上下文”的组合能力。


5. 错误恢复:Agent 应该先把错误当数据看

5.1 通用概念

错误恢复定义了 Agent 执行过程中发生故障时,Runtime 如何检测、表示和处理错误。

子概念

  • 错误检测 (Detection) :在哪一层发现错误——工具执行、LLM 调用、状态更新
  • 错误表示 (Representation) :错误以什么形式存在——Exception、错误数据、状态标记
  • 恢复策略 (Recovery Strategy) :如何处理错误——重试、回滚、跳过、交给 LLM
  • 部分进度保留 (Partial Progress) :失败时已完成的步骤是否保留

5.2 跨框架映射

概念LangGraphOpenAI AssistantsAgents SDKAutoGen
错误表示Exception → pending_writesRun status = failedPython ExceptionException in message
重试RetryPolicy(per-node 配置)自动(不透明)手动手动
回滚Checkpoint 回滚N/A(服务端托管)N/AN/A
部分进度Checkpoint 保留Thread 消息保留丢失对话保留
错误传播可配置(error-as-data 或 raise)事件通知抛给调用者消息传给 GroupChat

5.3 两种错误哲学

Error-as-Exception (传统)                Error-as-Data (Agent 原生)

工具调用 ──► 失败 ──► 抛异常             工具调用 ──► 失败 ──► 返回错误信息
                      │                                       │
                      ▼                                       ▼
              框架/开发者 try/catch                      LLM 看到错误信息
              决定重试/放弃                              LLM 自主决定下一步
                                                       (重试/换工具/告知用户)

Agent Runtime 更适合把可理解的工具错误作为数据返回给模型,而不是默认打断执行。 即 Error-as-Data,因为LLM 有足够的推理能力来处理工具错误。这个假设在旗舰级别的模型上是成立的——它们能理解”API 返回 429 限频”并决定等待后重试。

5.4 LangGraph 的 Checkpoint 回滚

LangGraph 是唯一支持 Checkpoint 回滚的框架:

  • 节点 A 执行成功 → 自动保存 Checkpoint A
  • 节点 B 执行失败 → 异常被记录到 pending_writes
  • 重新 invoke 时 → 从 Checkpoint A 恢复,只重试节点 B
  • 已完成的节点 A 不会重新执行

这对长时间运行的工作流至关重要。一个 10 步的 Agent 在第 8 步失败了,你不需要重跑前 7 步。

5.5 本章结论

错误恢复回答“失败是否会抹掉已有进度”。它同样依赖状态管理:没有 Checkpoint,失败只能重跑;有 Checkpoint,Runtime 才能保留已完成步骤并只重试失败部分。

Agent Runtime 应默认采用 Error-as-Data。Agent 的核心价值是自主决策,工具错误也应该优先作为可理解的数据交给模型处理;只有模型无法处理的系统级故障,才应该作为 Exception 向上抛。

Checkpoint 回滚是生产环境的明确缺口。长任务执行到后半段失败时,是否能从最近稳定状态恢复,直接决定这个 Runtime 能否承载真实业务流程。


Part 3:连接工具与观察事件:Agent 如何连接外部世界

这一部分对应任务生命周期里的“执行外部动作”和“观察事件”:Runtime 如何调用外部能力,并把执行进展暴露给外部系统。工具协议处理输入侧能力接入,流式事件处理输出侧进展同步。

6. 工具协议:最可能先标准化的一层

6.1 通用概念

工具协议定义了 Agent 如何发现、调用和处理外部能力。

子概念

  • 工具定义 (Tool Definition):描述工具的名称、参数、返回值——通常用 JSON Schema
  • 工具调用 (Tool Invocation):调用的请求/响应格式和传输方式
  • 工具结果 (Tool Result):返回给 Agent 的数据格式
  • 工具发现 (Tool Discovery):Agent 如何知道有哪些工具可用
  • 错误处理 (Error Handling):工具调用失败时的行为

6.2 跨框架映射

概念LangGraphOpenAIAutoGenClaude SDK
定义格式@tool + JSON SchemaFunction Calling JSON SchemaFunctionTool + JSON SchemaTool(JSON Schema)
调用约定ToolNode 自动执行requires_action → 客户端执行Agent 内部直接调用Agent 内部直接调用
结果格式ToolMessageFunction output(字符串)FunctionExecutionResultToolResult
发现机制构建时 bind_tools()创建 Assistant/Response 时指定创建 Agent 时注册创建时 allowed_tools
错误处理可配置:handle_tool_errors=True错误作为 output 返回 LLM异常转为错误消息错误在结果中

6.3 工具协议独立分层

工具协议的关键问题在于工具能力能否从执行模型里解耦出来。

紧耦合的做法是:

  • 用 LangGraph 时,工具必须适配 LangChain Tool
  • 用 OpenAI 时,工具必须适配 Function Calling 格式
  • 用 Claude SDK 时,工具必须适配它自己的工具定义
  • 切换框架时,工具层跟着重写

更合理的做法是:

  • 工具定义统一使用结构化 schema
  • 工具调用统一表达为请求和响应
  • 工具结果统一转成 Agent 可理解的消息
  • 执行框架只负责编排,不直接拥有工具实现

6.4 MCP:工具层标准化的典型形态

从 Runtime Protocol 的视角看,MCP (Model Context Protocol)把工具发现、工具定义、工具调用、资源读取、Prompt 模板等能力抽象成一组客户端和服务端之间的协议对象。Host / Client / Server 的分层,让 Agent Runtime 可以通过统一连接方式接入外部能力,而不必为每个工具单独写框架绑定。

MCP 对象对应工具协议能力Runtime 意义
Tool工具定义、参数 schema、调用结果让外部能力以统一 schema 暴露给 Agent
Resource可读取的上下文资源把文件、文档、数据库记录等变成可发现上下文
Prompt可复用提示模板把任务模板和工具使用方式沉淀为可调用能力
Client / Server传输与能力发现边界解耦 Runtime 和具体工具实现

MCP 标准化的是“Agent 能调用什么、如何发现和调用”;Runtime Protocol 还要继续表达 Thread / Run / Step / Event / Artifact / Checkpoint / Interrupt 这些任务生命周期对象。MCP 可以成为 Runtime 的工具层和上下文接入层,但完整 Runtime 仍然需要自己管理执行循环、状态持久化、流式事件、中断恢复和观测语义。

MCP 的长期价值在于把工具生态从框架内部抽出来。一个 MCP Server 可以同时服务 Claude、IDE、桌面应用、后台 Agent 或自建 Runtime;Runtime 只需要实现 MCP Client/Host 侧适配,就能复用同一组工具、资源和 Prompt。这正是工具协议最可能先标准化的原因:工具层边界清晰,输入输出结构化,和底层 loop 承载方式解耦。

这也是 如何快速创建领域Agent - OneAgent + MCPs 范式 的核心判断:企业里不会存在全知全能的 God Agent,但可以用一个强基础 Agent 连接 MCP0与各种提供上下文的 MCP,把领域知识、存量服务和工具发现变成可组合的工具生态。本文把这个判断放进 Runtime Protocol 里看,就是“工具发现、工具定义、工具调用、资源读取”会先于完整 Agent Runtime 形成标准化边界。

6.5 Error-as-Data vs Error-as-Exception

工具调用失败时,有两种根本不同的处理策略:

策略行为代表
Error-as-Data错误信息作为工具结果返回给 LLM,由 LLM 决定如何处理OpenAI(错误在 output 中)、LangGraph (handle_tool_errors=True)
Error-as-Exception错误作为异常抛出,执行中断,由框架/开发者处理传统编程模式

Error-as-Data 是更好的默认策略。原因:

  • LLM 能看到错误信息,可以自主决定重试、换工具、或告知用户
  • 不需要开发者为每种错误写 try/catch
  • 更接近人类使用工具的方式——工具出错了,你会看看错误信息然后决定下一步

这类设计的核心是:错误仍然是一个合法的工具结果,不是直接打断 Runtime 的异常。

6.6 Runtime 控制面:权限、Guardrail、预算

工具一旦能产生真实副作用,Runtime 就必须有控制面。控制面负责约束 Agent 能做什么、何时必须停下来、谁可以批准继续。

生产 Runtime 至少需要这些控制点:

控制点作用典型触发时机
Permission限制工具、文件、网络、外部系统访问工具调用前
Guardrail检查输入/输出是否违反安全或业务规则模型调用前后
Human Review让人类审批高风险动作写文件、发请求、提交订单前
Budget限制 token、成本、步骤数、执行时间Run 开始和每个 Step 后
Cancellation允许用户或系统终止执行长任务、误操作、超时

OpenAI Agents SDK 把 Guardrails、Human-in-the-loop、Tracing 做成 Runtime 能力;Claude Agent SDK 暴露 permissions 和 hooks;LangGraph 通过 interrupt/checkpoint 组合实现审批和恢复。它们指向同一个趋势:Agent Runtime 不只是执行器,还是一个安全边界。

6.7 本章结论

工具协议回答“Runtime 如何连接外部能力”。它与执行模型解耦:同一个 Tool API 应该能被图式、代码式、托管式 Runtime 复用,而不是绑定在某个框架的 wrapper 里。

工具层是最可能先标准化的部分。JSON Schema 已经成为事实标准,MCP 进一步把工具发现、资源读取和 Prompt 模板从框架内部抽出来,让外部能力能被不同 Runtime 复用。

一旦工具能产生真实副作用,控制面就必须进入 Runtime。权限、Guardrail、人类审批、预算和取消不是外围功能,而是 Agent Runtime 面向真实系统时的安全边界。


7. 流式输出:不是 token 打字机,而是任务事件流

7.1 通用概念

流式输出定义了 Agent 执行的增量结果如何传递给消费者。协议视角下,流式输出不是”边生成边打印 token”,而是 Runtime 把一次 Task/Run 的状态变化、消息增量、工具进展、Artifact 增量和自定义事件统一编码成事件流。

子概念

  • 传输协议 (Transport) :SSE、WebSocket、异步生成器、轮询
  • 粒度控制 (Granularity) :Token 级、节点/步骤级、消息级
  • 可恢复性 (Resumability) :断连后能否从断点继续接收
  • 多通道 (Multi-channel) :能否同时传递不同类型的事件

生产级流式输出不是 token 打字机,而是状态、消息、工具、产物、错误和 Trace 组成的任务事件流。

7.2 跨框架映射

概念LangGraph PlatformOpenAI AssistantsAgents SDKAutoGenClaude SDK
传输SSESSE / 轮询Python AsyncGenPython AsyncGenPython AsyncGen
粒度9 种 StreamMode 可组合固定事件类型StreamEvent消息级事件级
可恢复支持(Last-Event-ID + Redis Stream)不支持不支持不支持不支持
自定义事件get_stream_writer()不支持不支持不支持不支持
子图/子 Agentstream_subgraphs=TrueN/A不支持Topic 订阅N/A

7.3 Server vs Library:流式能力的分水岭

流式输出的复杂程度与 Runtime 的部署形态直接相关:

形态传输可恢复典型
Library(进程内)Python AsyncGenerator不需要(进程内不会断连)Agents SDK、Claude SDK、AutoGen
Server(跨网络)SSE / WebSocket必须考虑(网络会断)LangGraph Platform、OpenAI Assistants

LangGraph Platform 的可恢复流是目前唯一完整的实现:

  • Producer:将事件持久化到 Redis Stream(XADD
  • Consumer:先 Catch-up 回放历史事件(XREAD),再 Live Tail 实时事件
  • 客户端通过 Last-Event-ID 标识断点位置
  • 服务端配置 stream_resumable: true + on_disconnect: "continue"

可恢复 SSE 的关键是先基于 Last-Event-ID 回放历史事件,再切换到实时 Live Tail。

7.4 本章结论

流式输出回答“外部系统如何实时看见 Run 的进展”。它把状态、消息、工具调用、Artifact 增量和错误统一成事件流,是 Runtime 面向前端、控制台和审计系统的主要出口。

流式能力与部署形态高度相关。进程内 Agent 可以用 AsyncGenerator;一旦跨网络部署,SSE + 可恢复流就成为刚需,因为客户端断线、服务端继续执行、之后补收事件是生产系统的常态。

因此不要把 streaming 理解成 token 打字机。生产级流式输出应该是任务事件流,并能通过 Last-Event-ID、事件持久化和多通道事件支持恢复、追踪和审计。


Part 4:协作、审计与评测:Agent 如何被理解

这一部分对应任务生命周期里的“跨 Agent 分工”和“评测审计”:多个 Agent 如何围绕同一任务协同,外部系统又如何理解一次执行的质量。多 Agent 关注分工边界,可观测性和可评测性关注反馈闭环。

8. 多 Agent 协作:最碎片化,也最不该过早押注

8.1 通用概念

多 Agent 协作定义了多个 Agent 如何共同完成一个任务。协议视角下,多 Agent 的本质不是”多个 prompt 互相聊天”,而是多个 Runtime 或多个 Agent 能否基于共同对象交换任务、消息、能力和产物。

子概念

  • 通信模式 (Communication) :Agent 间如何传递信息——直接发送、发布/订阅、共享状态
  • 委派模型 (Delegation) :任务如何分配——Handoff 接力、层级分工、投票决策
  • 状态共享 (State Sharing) :Agent 间能否看到彼此的状态——共享 / 隔离
  • 拓扑结构 (Topology) :Agent 的组织形式——线性、星型、网状、层级

8.2 四种多 Agent 编排模式

下面四种是协作模式,不是框架能力边界。LangGraph 作为图式 Runtime,可以通过节点、边、状态和 Send 等机制承载子图嵌套、Handoff 接力、群聊选择和发布-订阅等控制流;OpenAI Agents SDK、AutoGen Core 等框架只是把其中某些模式做成了更原生的使用表面。

多 Agent 协作没有统一模型。子图、Handoff、群聊选择和发布订阅是四类编排语义;具体框架的差异在于哪种语义被做成一等 API,哪种需要用更底层的图、消息或工具机制表达。

8.3 跨框架映射

概念LangGraphAgents SDKAutoGenClaude SDK
通信模式Sub-graph / Send API / Deep Agents taskHandoff(transfer_to_agentGroupChat + pub/subN/A
委派模型嵌套图 / 条件路由 / Subagent taskHandoff toolSelector / RoundRobin / SwarmN/A
状态共享Channel 级(可配置映射)共享上下文共享对话N/A
拓扑任意(图可表达任何拓扑)线性 Handoff 链星型(Selector)/ 顺序N/A
并行执行Send API(map-reduce)不支持支持不支持
分布式LangGraph Platform 管理不支持GrpcWorkerAgentRuntime不支持

8.4 设计决策分析

模式优势劣势适用场景
子图嵌套类型安全、状态隔离可控、可复用需要提前定义图结构固定工作流中的子任务分工
Subagent task任务委派自然、上下文隔离、可复用专长需要设计子 Agent 能力边界研究、代码、复杂任务分解
Handoff 接力简单直观,LLM 决定何时交棒无并行,线性执行客服转接、分工明确的流水线
群聊选择最灵活,适合开放式协作难以调试,选择器可能震荡头脑风暴、多角色讨论
发布-订阅解耦、可扩展、支持分布式复杂度高,调试困难大规模 Agent 集群

8.5 本章结论

多 Agent 协作回答“多个 Agent 或 Runtime 如何围绕同一个任务分工”。它建立在执行模型、工具协议和状态隔离之上,但目前也是最不该过早押注的维度。

多 Agent 是最碎片化的方向。更准确地说,图式 Runtime 能用图结构承载多种协作模式,对话框架会把群聊选择做成原生表面,代码式 SDK 会把 Handoff 做成原生表面;这些模式服务于不同执行假设,不会很快统一。

对大多数业务来说,先把单 Agent 的 Thread、Run、State、Tool、Event 和 Artifact 边界做好,再引入必要的 Handoff 或 Subagent task,比一开始设计复杂群聊拓扑更稳。


9. 可观测性与可评测性:看见问题与评价质量

9.1 通用概念

可观测性定义了 Agent 执行过程如何被追踪、记录和调试;可评测性定义了如何基于这些观测数据对 Agent 质量进行评价、归因和持续优化。

二者的关系

  • 可观测性偏运行时:Trace、Event、State Snapshot 帮助开发者在运行时定位问题、理解因果、回放状态。
  • 可评测性偏事后:基于可观测数据形成质量指标、Badcase 分析、对比实验、反馈闭环,进而驱动 Prompt、工具、编排策略的自优化。

没有可观测性,评测就缺乏数据基础;没有可评测性,可观测数据只能用于调试,无法形成质量改进闭环。生产级 Agent Runtime 需要同时提供两者:既能看见“它怎么跑的”,也能评价“它跑得好不好”。

子概念

  • Tracing :分布式追踪——每个步骤的输入/输出、耗时、因果关系
  • Logging :事件日志——Agent 运行过程中的关键事件记录
  • Metrics :量化指标——延迟、Token 消耗、成本、成功率
  • Debugging :调试能力——步进执行、状态回放、条件断点

9.2 跨框架映射

概念LangGraphOpenAIAutoGenClaude SDK
TracingLangSmith(付费产品)内置 Traces(不透明)无内置无内置
事件日志stream_mode="events"/"debug"Run Steps APIConsole + stdlib loggingEvent stream
Token 统计Callback 回调Usage 对象Usage trackingResponse 中的 usage
执行回放Checkpoint historyThread 消息历史不支持不支持
成本追踪LangSmithOpenAI Dashboard手动手动

9.3 Trace 的最小语义模型

OpenAI Agents SDK 的 Tracing 设计给了一个很好的参照:Trace 表示一次端到端工作流,Span 表示其中一个有开始和结束时间的操作。一个 Agent Runtime 的 Trace 至少应该表达:

Span 类型对应 Runtime 动作关键字段
Run Span一次完整执行run_id、session_id、status、cost
Agent Span某个 Agent 被激活agent_id、instructions_version、tools
Generation Span一次 LLM 调用model、prompt_tokens、completion_tokens
Tool Span一次工具调用tool_name、arguments、result、is_error
Handoff SpanAgent 间交接source_agent、target_agent、reason
Guardrail Span安全/业务规则检查rule_name、pass/fail、action
Interrupt Span人类介入点payload、resume_value、latency

这比普通日志强很多,因为它保留了父子关系和因果链。你不只是知道”调用了工具”,而是知道它属于哪次 Run、由哪个 Agent 触发、消耗多少、失败后是否重试、最终是否影响输出。

9.4 三类观测数据

Agent Runtime 的可观测性不能只看 Trace,还要同时看事件和状态:

类型解决的问题示例
Trace为什么这次执行走到这里LLM 调用、工具调用、Handoff、Guardrail
Event Stream现在正在发生什么token、progress、custom event、interrupt
State Snapshot当时系统处于什么状态checkpoint、messages、pending writes

Trace 更适合事后分析,Event Stream 更适合前端实时展示,State Snapshot 更适合恢复和调试。生产 Runtime 应该三者打通:事件能定位到 Span,Span 能定位到 Checkpoint,Checkpoint 能恢复出当时状态。

Trace 解释因果,Event Stream 展示实时进展,State Snapshot 支持恢复和调试;三者打通后才能支撑评测闭环。

9.5 设计决策分析

可观测性是所有框架中最薄弱的维度。具体问题:

  1. 没有标准的 Trace 格式:LangSmith 有自己的 Trace 格式,OpenAI 有自己的 RunStep 格式,两者不互通。Agent 执行的 Trace 需要一个类似 OpenTelemetry 的开放标准。

  2. Tracing 和框架绑定太深:LangSmith 只能追踪 LangChain/LangGraph 的执行。如果你的工作流混用了多个框架,没有统一视图。

  3. 调试能力严重不足:只有 LangGraph 的 Checkpoint History 能做真正的”时间旅行调试”(回到任意一步查看当时的状态)。其他框架只能看日志。

9.6 可评测性:从可观测到质量闭环

可评测性是可观测性的下游。一个具备可评测性的 Runtime 应该能回答:

  • 质量指标 :准确率、召回率、Pass Rate、Token 成本、延迟、用户满意度
  • 归因分析 :某次失败是 Prompt 问题、工具问题、状态管理问题,还是编排策略问题
  • 对比实验 :同一任务在不同策略下的表现差异(A/B 测试、Prompt 变体、工具链变体)
  • 反馈闭环 :评测结果如何驱动 Prompt 更新、工具优化、编排策略调整
  • Badcase 管理 :失败案例的结构化记录、分类、复现和追踪

当前框架的可评测能力普遍较弱。多数框架只提供 Trace 和 Event,但不提供:

  • 标准化的质量指标定义
  • 自动化的 Badcase 归因
  • 对比实验的协议支持
  • 评测结果到配置的自动反馈

这导致可观测数据主要停留在“调试用”,难以形成“质量改进闭环”。无论是自己建还是框架提供能力,都需要下面的:

  • 评测协议 :定义质量指标、评测数据集、对比实验的标准接口
  • 归因工具 :从 Trace 自动推断失败根因
  • 反馈机制 :评测结果能自动驱动 Prompt/工具/策略的调整
  • Badcase 库 :结构化失败案例,支持复现和追踪

9.7 本章结论

可观测性与可评测性回答“如何看见并评价一次 Run”。它收束前面的 Step、Event、State Snapshot、Artifact 和 Error,把 Runtime 执行过程变成可调试、可审计、可优化的数据。

Agent 需要同时具备可观测性和可评测性。可观测性需要 OpenTelemetry-like 的 Span、Trace、Event、State Snapshot、Artifact Link 和 Cost Attribution;可评测性需要 Metric Schema、Evaluation Dataset、Badcase Schema、Experiment Protocol 和 Feedback Loop。

生产级 Runtime 必须把两者打通:可观测数据应该能直接用于评测,评测结果应该能驱动 Prompt、工具和编排策略更新,形成“看见问题 → 评价质量 → 归因分析 → 优化策略”的闭环。


10. Agent Protocol 对象如何落到 Runtime 能力

如果用协议主线串起来,前面的生命周期和八个维度可以归结为一张映射表:

Protocol 对象/操作外部契约Runtime 需要实现的能力对应章节
Agent Card / Metadata告诉别人我是谁、会什么、怎么调用Agent 注册、能力描述、权限声明、版本管理2、6、8
Thread / Context承载多轮上下文和参与者会话管理、历史保存、上下文裁剪、参与者隔离3
Message / Part表达用户、Agent、工具的通信内容多模态输入、结构化数据、文件引用、消息追加3、6
Task / Run表达一次可管理的执行调度、状态机、取消、超时、预算、重试2、4、5
Step / Run Step表达执行内部的可观测步骤LLM 调用、工具调用、Handoff、Guardrail 记录2、9
Event Stream表达进展增量SSE、Last-Event-ID、事件持久化、多通道流7
Interrupt / Input Required表达需要人类或外部系统继续Checkpoint、resume、审批、授权、表单输入4
Artifact表达任务产物文件管理、产物版本、增量产出、可追溯链接3、7、9
Todo / Plan表达长任务的显式计划任务分解、进度跟踪、计划更新、上下文压缩2、8
Workspace / Backend表达 Agent 可读写的工作区virtual filesystem、shell、store、权限、隔离2、3、6
Skill表达可复用能力包动态加载、权限控制、子 Agent 复用、脚本/参考资料6、8
Trace / Span表达执行因果链观测埋点、成本归因、状态关联、审计9
Error表达失败和下一步可能动作Error-as-Data、异常边界、回滚、重试策略5

这张表说明:Agent Protocol 不是 Runtime 之外的”接口文档”,而是 Runtime 架构的反向约束。一个 Runtime 如果无法稳定表达这些对象,就很难被前端、控制台、评测系统、审计系统和其他 Agent 复用。

10.1 一个好的 Agent Runtime Protocol 应该满足什么

综合 A2A、AITP、ACP、LangGraph Server API、OpenAI Assistants 和 AG-UI 的设计,可以抽象出 9 条协议设计原则:

  1. 任务对象一等化:不能只有 request/response,必须有可查询、可取消、可恢复的 Task/Run
  2. 上下文对象一等化:Thread/Context 不能只是 messages 数组,还要承载参与者、能力和元数据
  3. 步骤对象一等化:Run 内部的 LLM 调用、工具调用、Handoff、Guardrail、Subagent task 都应该能被表达为 Step/Run Step
  4. 事件流标准化:token、状态、工具、Artifact、错误都应该是同一条事件流上的不同事件
  5. 产物对象一等化:长任务的结果不应只塞进最终文本,而要成为可引用的 Artifact
  6. 中断是状态,不是异常INPUT_REQUIREDAUTH_REQUIRED 这类状态应该进入协议状态机
  7. 发现与能力声明分离:Agent metadata 负责发现,Capability 负责表达可选增强能力
  8. 协议绑定可替换:同一语义对象可以绑定到 REST、SSE、JSON-RPC、gRPC 或消息队列
  9. 观测语义内建:Trace/Span/Event ID 应该从协议层贯穿到 Runtime 内部

10.2 Protocol 与 Runtime 的边界

Protocol 不应该规定模型怎么思考,也不应该规定内部必须用 Graph、Actor 还是 Code Loop。它应该规定:

  • 哪些资源可以被创建、查询、更新、取消
  • 每个资源有哪些稳定状态
  • 客户端如何订阅变化
  • 人类或其他 Agent 如何补充输入
  • 产物和错误如何被表达
  • 观测系统如何关联一次执行

Runtime 则负责:

  • 如何选择模型和工具
  • 如何调度步骤
  • 如何保存和迁移状态
  • 如何隔离工作区
  • 如何处理副作用
  • 如何把内部细节映射回协议对象

最好的协议是低约束的,最好的 Runtime 是高内聚的:协议只定义外部可依赖的语义边界,Runtime 在边界内保持实现自由。


11. 跨维度分析:设计决策的持久性判断

以下是我个人的一些判断。

11.1 哪些设计决策会持久?

设计决策持久性理由
Graph 是唯一最优 Runtime 形态流行代码式 Runtime、图式 Runtime、托管式 Runtime 会按场景并存;混合模式正在出现
Handoff 是多 Agent 标准流行太简单,无法处理并行和复杂拓扑
Conversation 是独立底层执行模型流行它更像运行在不同 Runtime 之上的编排协议,不应和 Graph / Code / Managed 平级
Checkpoint 链式版本控制可能持久概念有价值(类 Git),但实现可能简化
状态持久化是核心能力持久没有持久化的 Agent 无法用于生产
Error-as-Data 优于 Error-as-Exception持久Agent 需要自主推理错误,不是抛异常然后崩溃
SSE 是流式标准持久HTTP 原生、浏览器原生、自带重连机制
Server-managed Runtime 是生产必需持久但形态未定——可以是 Platform 也可以是自建

11.2 行业收敛趋势

正在收敛的

  • Agent 任务对象(Task / Run)
  • Agent 上下文对象(Thread / Context)
  • Agent 步骤对象(Step / Run Step / Tool Call)
  • Agent 事件流(SSE + 标准事件类型)
  • Agent 产物对象(Artifact / File / Structured Output)
  • 工具定义格式(JSON Schema)
  • 工具调用协议
  • 流式传输协议(SSE)
  • 错误处理哲学(Error-as-Data)

没有收敛的

  • Runtime Loop 承载方式(图式 Runtime / 代码式 Runtime / 托管式 Runtime 并存)
  • 编排协议模式(ReAct / Plan-and-Execute / Conversation-style coordination / Manager-Worker 并存)
  • 状态管理(Checkpoint / Thread / 手动管理并存)
  • 多 Agent 协作(各框架完全不兼容)
  • 可观测性标准(各自为战)

2 年内,Agent Protocol 会先在 Thread / Task / Run / Step / Message / Artifact / Event / Checkpoint 这些外部对象上收敛,工具层会继续标准化,流式层会统一到 SSE + 可恢复流,但 Runtime Loop 承载方式、编排协议和多 Agent 协作不会统一——因为它们解决的问题空间太大,不存在一个”最优解”。相对来说,Graph 可以认为是编排协议的一个超集。

11.3 作为开发者,重点关注什么?

方向建议理由
Agent Protocol 对象模型重点投入Thread、Run、Step、Artifact、Event、Checkpoint 会成为跨框架通用语言
工具协议抽象重点投入工具定义、调用、结果处理的设计模式跨框架可迁移
状态管理抽象重点投入无论哪个框架,状态持久化的设计模式是通用的
Harness 易用性判断重点投入开箱即用程度决定团队能否低成本把 Runtime 能力真正用起来
Error-as-Data 模式理解并应用改变你写 Agent 的方式,不依赖框架
特定框架的执行模型谨慎投入深入 1-2 个即可,重点理解 why,不是记 API
多 Agent 模式观望太碎片化,等标准出现再深入不迟
可观测性关注 OpenTelemetry 方向Agent Tracing 标准化是迟早的事

11.4 如果我从零设计 Agent Runtime Protocol

从零设计 Agent Runtime Protocol 时,外部协议对象应该保持稳定,内部 Runtime 能力则围绕调度、状态、流式、中断、工具、控制面和观测面高内聚实现。

对图中每个维度,我觉得如果按下面选择从头来最好:

维度我的选择理由
协议对象Agent / Thread / Run / Step / Message / Event / Artifact / Checkpoint这些是外部系统真正依赖的稳定边界
执行模型混合:图式 Runtime 做复杂工作流,代码式 Runtime 做简单任务,编排协议按场景选择LangGraph 的 @entrypoint/@task 方向正确——图式能力为底,代码式表面为简
状态管理Checkpoint-based,自动 per-step 快照这是中断恢复、错误回滚、调试回放的前提
工具协议统一 Tool API + Adapter不再写框架特定的 Tool wrapper
流式输出SSE + 可恢复流(Redis Stream)生产环境断线恢复是刚需
中断/恢复通用 interrupt(payload) + resume(value)参考 LangGraph 但简化 Command 的复杂度
错误恢复Error-as-Data 默认,系统错误才 raise让 LLM 自主处理工具错误
多 AgentSub-graph 做紧耦合,消息协议做松耦合避免把所有 Agent 都塞进同一种编排模型
可观测性OpenTelemetry Span 作为一等原语每个节点执行自动生成 Span,不依赖特定平台
控制面权限、Guardrail、预算、取消内建Agent 能产生真实副作用时,控制面就是安全边界
工作区Workspace/Sandbox 一等化文件、浏览器、代码仓库都属于 Runtime 状态

11.5 “用哪个框架”不重要,重点是“我需要什么 Runtime 能力”

Agent 框架还会继续变化。今天是 LangGraph、OpenAI Agents SDK、AutoGen、Claude Agent SDK,明天可能会出现新的图式 Runtime、新的编排协议、新的多 Agent 协作框架和新的托管式 Runtime。每个框架都会带来新的对象名、新的 API 形状和新的最佳实践。

但生产级 Agent 系统真正绕不开的问题一直稳定:一次执行如何创建、取消、重试和结束;哪些历史、文件、状态和权限对当前执行可见;失败、中断、升级后系统还能不能恢复;前端、评测和审计系统如何知道 Agent 正在做什么;最终产物如何被保存、引用、追溯和复用;Agent 什么时候可以真的改文件、发请求或下订单。

如果只盯着框架 API,很容易被短期流行牵着走;如果先建立 Runtime Protocol 的概念模型,就能反过来审视框架:它是否稳定表达 Thread / Run / Step / Event / Artifact / Checkpoint,是否具备真正的状态持久化和可恢复事件流,是否把工具层从框架绑定中抽出来,是否能支撑调试、审计、成本归因和质量评估。

对我来说,理解 Runtime Protocol 的价值,是把知识从“框架熟练度”提升到“系统设计判断力”。框架值得学,但不要只学框架;框架终究只是对现实问题的抽象。


附录 A:术语对照表

通用概念英文LangGraphOpenAI AssistantsAgents SDKAutoGenClaude SDK
执行上下文Execution ContextThread + RunThread + RunRunnerRuntime + TeamSession
执行单元Execution UnitNodeRun StepAgent turnMessage handlerAgent turn
状态快照State SnapshotCheckpointThread stateN/Asave_state()N/A
状态持久化器State PersisterCheckpointer服务端托管N/A手动N/A
工具定义Tool Definition@tool / BaseToolFunction@function_toolFunctionToolTool
工具调用结果Tool ResultToolMessageFunction outputTool outputFunctionExecutionResultToolResult
中断点Interrupt Pointinterrupt()requires_actionGuardrailHandoffTerminationinterrupt()
恢复指令Resume CommandCommand(resume=)submit_tool_outputs手动代码run_stream(task=)query()
流式事件Stream EventStreamPartSSE EventStreamEventMessageEvent
子 AgentSub-AgentSubgraphN/AHandoffNested TeamTask tool
执行追踪Execution TraceLangSmith TraceRun StepsSDK TracesConsole logN/A
错误结果Error Resulterror-as-data / raiselast_errorException错误消息Hook 通知

附录 B:各框架参考链接

LangGraph

Deep Agents

OpenAI

AutoGen

Claude Agent SDK

相关标准与协议