Agent Runtime 概念与边界
潘忠显 / 2026-07-01
这是「Agent Runtime 系列」的第一篇,我们从最基础的概念开始。如果你最近在用 OpenClaw 或者 LangGraph 这类 Agent 框架,大概率会反复撞见一个词:Agent Runtime。
很多人第一次接触 Agent,都会把两个概念搅在一起:Agent 和 Agent 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 程序。它提供的是运行环境:
- 内存管理
- GC
- 类加载
- 线程调度
- JNI
- 异常处理
真正决定业务逻辑的,是你的 Java 程序。同一个 JVM,可以跑电商系统,也可以跑风控系统,还可以跑聊天应用。JVM 并不关心你写的是什么业务,它只负责把程序运行起来,并提供底层能力。
Chrome:网页应用的 Runtime
浏览器也是 Runtime:
Chrome
↑
网页 / JavaScript 应用
Chrome 本身不是淘宝,也不是 Gmail,也不是 Notion。它提供的是:
- JavaScript 执行环境
- DOM
- 网络请求
- 存储
- 权限管理
- 渲染能力
- 事件循环
网页才是真正的应用。同一个 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 里通常包含的是“策略”这一层:
- 系统 Prompt
- 角色设定
- 行为策略
- 可用工具声明
- 任务规划方式
- 失败处理偏好
- 模型选择偏好
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。 它负责:
- 调用 LLM
- 判断模型是否要调用工具
- 执行工具
- 把工具结果放回上下文
- 继续下一轮推理
而 Agent 的部分,则隐藏在这些数据里:
prompttoolsmessages- 模型行为约束
这个程序更准确的叫法应该是: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)
这样一下就清楚了:
- Agent 定义自己是谁、能做什么、应该怎么做。
- Runtime 负责把这个 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 提出一个要求:遵循统一的协议/接口。
换句话说,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 编排。
