Jason Pan

Agent Runtime 概念与边界

潘忠显 / 2026-07-01


这是「Agent Runtime 系列」的第一篇,我们从最基础的概念开始。如果你最近在用 OpenClaw 或者 LangGraph 这类 Agent 框架,大概率会反复撞见一个词:Agent Runtime

image-20260701161421167

很多人第一次接触 Agent,都会把两个概念搅在一起:AgentAgent Runtime

因为它们经常出现在同一个 Demo 里,有时甚至写在同一个文件中,于是很容易让人产生一个疑问:Runtime 不就是 Agent 吗?

最小版可以写成一个 Agent,但 Runtime 本身并不是 Agent。本文就是说清楚,两者的实际关系是:Agent 决定“要做什么”,Runtime 负责“让它跑起来”。Agent 是跑在 Runtime 上面的。

一、什么是 Runtime

在谈 Agent Runtime 之前,我们得先对“Runtime”本身有个直觉。这个词在软件领域早就存在,借两个熟悉的例子就能讲明白。

JVM:Java 程序的 Runtime

如果你写过 Java,你一定知道 JVM。可以这样理解:

JVM Runtime
Java Program

JVM 不是你的 Java 程序。它提供的是运行环境:

真正决定业务逻辑的,是你的 Java 程序。同一个 JVM,可以跑电商系统,也可以跑风控系统,还可以跑聊天应用。JVM 并不关心你写的是什么业务,它只负责把程序运行起来,并提供底层能力。

Chrome:网页应用的 Runtime

浏览器也是 Runtime:

Chrome
网页 / JavaScript 应用

Chrome 本身不是淘宝,也不是 Gmail,也不是 Notion。它提供的是:

网页才是真正的应用。同一个 Chrome,今天打开淘宝,明天打开 Gmail,后天打开一个在线代码编辑器,浏览器自己不需要为不同网页改一行代码。

两个例子的共性

把 JVM 和 Chrome 放在一起,Runtime 的本质就浮出来了:Runtime 是一套通用的执行环境。它不关心具体业务,只负责把“跑在它上面的东西”稳定地运行起来,并提供一组底层能力。

记住这个直觉,接下来我们把它套到 AI Agent 上。

二、Agent Runtime 提供了什么

把上面的结构平移到 Agent 系统,大致可以画成这样:

Client / User
┌────────────────────────────────────┐
│           Agent Runtime            │
│                                    │
│ Message History / State            │
│ Tool Registry / Tool Executor      │
│ Permission / Sandbox               │
│ Event Loop                         │
│ Transport / WebSocket              │
│ Memory / Logging / Retry           │
└───────────────┬────────────────────┘
                │ loads / runs
        Agent(Prompt + Policy)
               LLM

分工很清晰:Runtime 提供能力,Agent 使用这些能力完成任务。

Agent 里通常包含的是“策略”这一层:

Runtime 提供的则是“执行”这一层:

所以可以这样记:Agent 更像“大脑里的策略”,Runtime 更像“身体和神经系统”。

正因如此,上图里画的是 Agent 调用 LLM,但刚刚又说 Runtime 负责调用 LLM,这两种说法并不矛盾。前者是从“策略归属”上看:Agent 决定什么时候需要问模型、带着什么 Prompt、工具声明和上下文去问;后者是从“工程执行”上看:真正发起 LLM 请求、维护消息历史、处理返回结果、再把结果交还给 Agent 流程的,通常是 Runtime。

值得一提的是,本系列后面会专门用一篇文章讲 WebSocket、Session、Event Bus,它们本质上都属于 Runtime 提供的 Transport 能力。Agent 本身根本不关心自己是通过 WebSocket 还是 SSE 与客户端通信——那是 Runtime 的职责。这也预告了一个结论:通信模型的演进,本质上是 Runtime 这一层在演进。

三、Demo 既有 Agent 又有 Runtime

理解了分工,再回头看最常见的那个困惑:为什么很多 Agent Demo 看起来就是 Runtime?

因为一个最简单的 Agent 大多长这样:

while True:
    response = llm(messages)

    if response.has_tool_call:
        result = run_tool(response.tool_call)
        messages.append(result)
    else:
        break

这段代码看着简单,但里面其实已经同时塞进了两层东西,只是被写在了一个文件里。

这个 while True 循环,本身就是一个最小 Runtime。 它负责:

而 Agent 的部分,则隐藏在这些数据里:

这个程序更准确的叫法应该是:Single-Agent Runtime,一个只服务于单个默认 Agent 的最小运行时,里面 Agent 和 Runtime 被揉在了一起。

四、把 Agent 和 Runtime 拆开

对于上面的程序,只要稍微整理一下结构,这两层就能各归各位:

class Agent:
    prompt = ...
    tools = ...
    policy = ...


class Runtime:
    def loop(self):
        ...

    def call_llm(self):
        ...

    def execute_tool(self):
        ...


runtime.run(agent)

这样一下就清楚了:

拆分之后,runtime.run(agent) 这一行还透露出一个关键信号:Runtime 接收 Agent 作为参数。也就是说,Agent 变成了可以被传入、被替换的东西。这正是写一个真正独立的 Runtime的起点。

五、一个独立的 Runtime

成熟的架构会把这两层彻底分开,让 Runtime 不再绑定任何具体的 Agent:

            Runtime
      ┌─────────┴──────────┐
      │                    │
  Coding Agent        Research Agent
      │                    │
      ▼                    ▼
     GPT                Claude

要做到这一点,需要回答两个问题:它支持什么形式的 Agent?跑起来是什么样?

Agent 是什么形式?

独立 Runtime 不在乎自己跑的是 Coding Agent、Research Agent 还是 Customer Service Agent。它只对 Agent 提出一个要求:遵循统一的协议/接口

image-20260701170109790

换句话说,Runtime 眼里的 Agent,是一个标准化的“可插拔单元”:

$$ Agent ≈ Prompt + Policy + Tools Definition $$

只要一个 Agent 能告诉 Runtime “我的 Prompt 是什么、我的行为策略是什么、我声明了哪些工具”,Runtime 就能把它跑起来。至于这个 Agent 具体想干嘛,Runtime 不需要知道,也不应该知道。

它跑起来是什么样?

运行时,Runtime 和 Agent 之间是一种持续的“请求—执行”协作。Agent 提出意图,Runtime 负责安全、稳定地把意图执行出来:

Runtime:Agent,你想干什么?
Agent:  我要调用 read_file。
Runtime:好的,我来检查权限并执行。

Agent:  我还要调用 grep。
Runtime:执行完成,结果给你。

Agent:  根据结果,我要修改文件。
Runtime:先检查写权限,然后执行修改。

这里真正决定任务方向的是 Agent;Runtime 只负责把 Agent 的意图,安全、稳定、可观测地执行出来。

因为 Agent 被标准化成了可插拔单元,同一个 Runtime 今天可以跑 Coding Agent,明天换成 Research Agent,都不需要改 Runtime:

Runtime          Runtime
   ↓     →→→        ↓
Coding Agent     Research Agent

甚至可以编排多个 Agent,组成一条工作流:

Runtime
Planner Agent
Executor Agent
Reviewer Agent

这就是 OpenClaw 这类系统被称为 Runtime 的原因:它们做的事,不特殊服务于某一个 Agent,而是提供这样一个通用的 Agent 运行环境:

LLM + Tool Calling + Memory + Context
+ Permission + Session + Transport / WebSocket
+ Event Loop + Sandbox + Logging

独立 Runtime 的好处

这样做有三个直接收益:

第一,复用基础能力。 不管什么 Agent,都需要上下文、工具调用、权限、日志、状态管理、错误处理。Runtime 把这些通用能力沉淀下来,避免每个 Agent 重复实现一遍。

第二,让 Agent 可插拔。 只要 Agent 遵循 Runtime 的协议,就能被替换。今天用 Coding Agent,明天换 Research Agent,Runtime 不需要大改。

第三,让系统更容易演进。 一开始你可能只有一个 Agent,但后面往往要支持多模型、多 Agent 协作、Planner / Executor / Reviewer 架构、长期记忆、权限审批、沙箱执行、WebSocket 会话、用户中断与恢复、任务追踪与回放。如果 Agent 和 Runtime 一开始就混在一起,后面会很难拆;一开始就分层,系统才长得动。

这也是目前大多数成熟 Agent 框架共同的设计思路。

六、小结

本文围绕 Agent 和 Agent Runtime 的关系,反复强调一个核心判断:Agent 是运行在 Runtime 上的智能策略层,Runtime 是支撑 Agent 执行任务的基础设施层。 或者更简单:Agent 负责想,Runtime 负责跑。

后面讨论现成框架时,也会把 LangGraph、OpenAI Agents SDK、Mastra 这类工具放进这套模型里看。它们在不同层次上帮你实现 Runtime 的状态管理、工具执行、权限控制、可观测性和多 Agent 编排。