02 执行模型:Agent如何跑起来(Part 1)#

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

通用概念#

子概念

  • 执行单元 (Execution Unit):一次不可分割的计算步骤——一个 LLM 调用、一次工具执行、一个决策节点

  • 调度模型 (Scheduling):执行单元的排列方式——顺序、并行、条件分支

  • 控制流 (Control Flow):谁决定下一步做什么——显式的图边、LLM 的推理、代码逻辑

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

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

  1. Runtime Loop 承载方式:谁拥有主循环,控制流被放在哪种运行时容器里

  2. 编排协议模式:主循环内部哪些语义对象被显式化,哪些 Action 副作用会进入 Runtime 状态机

Graph、Code、Managed 属于第一层,回答 loop 的承载容器;ReAct、Plan-and-Execute、Conversation-style coordination 属于第二层,回答 loop 内部的主导语义对象。

Loop承载方式#

  • 图式 Runtime(LangGraph为代表):使用构建图的方式来构建条件和边,节点函数、条件边和工具调用仍然由代码实现,这些代码被放进图运行时里,控制流被结构化为节点、边、状态和 checkpoint。它的价值在于给复杂分支、并行、恢复和观测提供稳定运行时边界,是一种基于 Code 的 DSL。

  • 代码式 Runtime(OpenAI Agents SDK、Claude Agent SDK):控制流由Python代码直接驱动,上手快,工具执行和事件流由SDK托管。

  • 托管式 Runtime(OpenAI Assistants):用户将runtime托管给平台,最省心,但控制权和可观测性最少。

编排协议层#

  • 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。

Agent Harness:Protocol/Runtime能力产品化#

这里还有 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 的产品形态。

Harness体验对象与协议对象对应#

Harness体验对象

回扣到的协议对象

说明

Todo / Plan

Step / Event

把长任务进度变成可观察、可恢复的步骤

Subagent task

Run / Step / Artifact

把委派任务变成可追踪的子执行和结果

Virtual filesystem / Workspace

Artifact / Checkpoint

把中间结果、文件和最终产物沉淀到可恢复状态

Skill

Tool / Artifact / Metadata

把可复用能力包变成 Runtime 可发现的能力

Permission / HITL

Interrupt / Resume / Event

把高风险动作放入中断恢复状态机

生产环境推荐:使用这些成熟框架的时候,手里有源码能够覆写乃至重写很有必要,不然复杂的业务场景很难被都满足。相比强绑定二进制产品形态的路线,生产环境更推荐使用 Deep Agents 这类基于开源Runtime的Harness。

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

跨框架映射#

概念

LangGraph

OpenAI Assistants

Agents SDK

AutoGen

Claude SDK

执行单元

Node(函数/Runnable)

Run Step

Agent turn

Agent message handler

Agent turn

调度模型

Graph(DAG + 循环)

服务端托管循环

Python 控制流

对话协议(轮转/选择)

代码驱动循环

控制流

条件边 / Command

服务端决定(不透明)

Handoff / 代码分支

Selector / RoundRobin

工具结果驱动 LLM

并行执行

Send API(fan-out/fan-in)

不支持

不支持

GroupChat 内并行

不支持

执行容器

Thread + Run

Thread + Run

Runner 上下文

Runtime + Team

Session

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,不要看它是否能调模型,而要看它是否拥有这个循环。

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

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

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

事件驱动Runtime(AutoGen Core模式)#

AutoGen Core 把 Agent 执行看成事件驱动系统。Agent 不再只是"被调用的函数",而是订阅 Topic、接收 Message、发布 Message 的 Actor。

价值

  • 解耦:发送方不需要知道谁会处理消息

  • 并发:多个 Agent 可以订阅同一个 Topic 并行响应

  • 分布式:Runtime 可以演进成跨进程、跨机器的消息总线

  • 弹性:失败的 Agent 可以独立重启,不必拖垮整个工作流

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

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

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

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

四层状态对比#

类型

例子

生命周期

风险

Prompt Context

消息、系统提示词

单次模型调用

泄漏、污染

Runtime State

Checkpoint、Session 变量

跨步骤/跨请求

版本不一致

Workspace State

文件、代码仓库、浏览器页面

跨工具调用

破坏性副作用

External State

数据库、工单、支付系统

Runtime 外部

真实业务影响

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

设计决策分析#

Loop承载方式对比#

Loop 承载方式

容易做到

困难做到

典型场景

图式 Runtime

分支、并行、可视化、断点调试

简单的线性对话(过度建模)

复杂工作流、审批流、研报生成

代码式 Runtime

灵活、学习曲线低、调试直观

持久化、断线恢复、可视化

简单 Agent、脚本任务

托管式 Runtime

零运维、开箱即用

自定义执行逻辑、成本控制

快速原型、客服 Bot

编排契约对比#

编排契约

显式建模对象

典型触发形式

Runtime 需要管理什么

ReAct Tool Loop

Tool Call / Observation / Result

LLM 选择工具

工具执行、结果回写、错误作为数据

Plan-and-Execute

Plan / Todo / Step / Progress

工具调用或调度器触发

计划持久化、进度更新、计划修正、阶段恢复

Conversation-style coordination

Participant / Message / Route / Handoff / Speaker

工具调用或消息路由触发

发言顺序、路由、权限切换、上下文可见性、trace 归属

Manager-Worker

Task / Subtask / Assignment / Result

工具调用或调度器触发

子任务分派、上下文隔离、结果汇总、失败重试

本章结论#

执行模型回答"一个 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 时,其他能力仍然可以复用。