如一 Agent 架构解读(一):数字分身的执行模型------Run、Turn 与四个时间尺度
「如一」是我们做的一个面向 C 端的云端数字分身:它在云端 7×24 运行,有自己的浏览器、文件系统和记忆,能替你持续完成任务。这个系列逐层解读如一的真实架构------不是 Demo 级玩具,而是一个多租户生产系统。开篇先讲最核心的执行模型:一个 Agent 到底"活"在什么结构上。
为什么大多数 Agent 只是 Demo
先看几个 Agent 项目的经典死法:
- 进程崩一次,会话上下文全丢,用户只能从头再来;
- 模型追问"你确认吗?",然后整个线程挂在那里等用户回复,一等就是三天;
- 模型被限流,重试逻辑无限循环,账单爆炸;
- 上下文越来越长,直到某一天 prompt 超出窗口,整个会话永久报废。
这些都不是模型能力问题------换个更强的模型,一个都解决不了。它们是架构问题:把 Agent 当成了一次函数调用,而它实际上是一个持续运行系统。
如一从第一天就是奔着"长期在线的数字分身"去设计的,所以这些问题必须在架构层回答。这篇讲清楚我们的答案:四个时间尺度,和一条决策与执行的分工线。
先给定义:如一眼中的 Agent
Agent 不是"带工具的聊天模型",也不是一条从 Prompt 到 Answer 的请求链。如一的定义是:
一个持续运行的智能系统:消息驱动,以持久事实维持连续性;模型负责开放决策,平台保证确定执行;它最终要对外部世界产生可验证的结果。
拆开来是五个要素,缺一不可:
- 消息驱动:外部世界以统一消息进入。Agent 不直接依赖具体渠道------WebSocket、IM 协议、摄像头驱动,都是接入层的事。
- 事实连续:会话历史、工具结果、交付状态进入权威存储。进程内对象不是长期记忆。
- 开放决策:目标理解、路线选择、内容判断交给模型。
- 确定执行:状态迁移、权限、事务、幂等、并发、恢复由程序保证。
- 真实结果:输出不只是文本,还可以是文件、应用、卡片,以及对外部系统的真实操作。
三个平面:Input / Runtime / Output

三个平面各有一条容易被忽视的设计原则。
Input Plane 的核心是"信箱",它不是 UI 比喻,是并发模型。 外部消息可以随时到达;同一会话的主执行必须串行消费;进程故障后未完成的输入必须能被重新认领。Runtime 不应该知道手机号、Cookie、WebSocket 或某个 IM 的报文结构------它只处理通道中立的命令和消息。
Output Plane 的核心是"交付不等于回答"。 如一的输出至少有三类:Message(解释、确认、进度、最终文本)、Artifact(文件、报告、图片、音视频、可交互应用)、Command(对文件、浏览器、外部系统的真实操作)。三者都可以是中间结果或最终交付。是否展示、何时展示、用什么媒介展示,取决于用户目标,而不是"某个工具刚刚返回了文件"。
Runtime Plane 是决策与执行内核,也是本文剩下部分要拆的东西。
把三个平面展开,如一的完整架构长这样(实线是命令、执行与交付的主路径,虚线是发现、读取、持久化等事实关系):

这张图的密度很高,值得放大看的部分后面都会逐一讲到。本文聚焦 Runtime Plane 内部,也就是 Run 和 Turn 那一块。
四个时间尺度:Session / Run / Turn / Model Attempt
Agent 系统最容易混淆的概念就是这四个,它们不是同一层东西:
| 尺度 | 定义 | 结束条件 | 连续性靠什么 |
|---|---|---|---|
| Session | 用户与 Agent 的长期会话空间 | 产品生命周期决定 | transcript、会话投影 |
| Run | 一次被消息触发、连续推进到终态的执行 | completed / failed / aborted | 持久事实 + runId |
| Turn | Run 内一次"观察---决策---行动---提交"的节拍 | 继续下一 Turn 或终结 Run | 本轮提交的 assistant/tool 事实 |
| Model Attempt | Turn 内真正发起的一次模型调用 | 合法返回、失败或取消 | 逐次调用事实记录 |
这个区分带来几个直接结论:
- 一个 Session 包含多个 Run。用户回答 Agent 的提问,是启动一个新 Run,不是恢复一条阻塞的线程。
- 一个 Run 通常包含多个 Turn------模型调用工具后需要看到结果再继续判断。
- 一个 Turn 包含一到多个 Model Attempt。恢复重试、协议重建、超长续写,只增加 Attempt,不增加 Turn。
- Model Attempt 是推理事实和计费事实,不是 Agent 任务的生命周期。
第一条值得展开一句。分身需要用户补充信息或授权时,系统里不存在"挂起等待"这个状态:提交问题,发出事件,然后正常结束当前 Run;用户的回复作为新消息启动新 Run,从持久历史里重新规划。没有 SUSPENDED,没有挂起线程,没有等待句柄。分身可以 7×24 在线,靠的不是一个永不退出的 while(true),而是持久事实 + 新消息的再次驱动。
第三条则是线上事故换来的。早期实现里,模型被限流重试一次,前端的"第 N 步"就 +1,用户眼睁睁看着分身"走了 20 步"其实一件事还没做完;运行统计里 turn 数和模型调用数混在一起,排障时根本对不上。重构之后:Turn 只统计认知---行动节拍,Attempt 只统计真正进入模型的调用,恢复绝不虚增 Turn。每个已开启的 Turn 必须且只能闭合一次------安全护栏按 Turn 计数,瞬态故障就不许消耗它。
Run 内部的结构展开是这样:

注意这张图刻意把模型放在 Turn 的"决策"位置,而不是系统中心。系统的中心是从消息到事实、再从事实到行动的闭环,模型只是这个闭环里最擅长开放判断的那个零件。
一条分工线:决策自由与执行确定
Agent 系统设计的关键,不是尽可能多地把控制交给模型,而是把不同性质的决策放到正确的一侧。
模型负责开放决策:理解用户真正想完成什么;判断事实是否充分;选择能力、顺序和探索路径;根据工具观察调整路线;判断内容、审美和交付媒介;决定继续行动、向用户询问还是结束。
平台负责确定机制:消息幂等与同会话串行;参数与协议校验;权限、隔离、资源和 deadline;事务、幂等与副作用边界;超时、取消、重试预算和崩溃恢复。
一句话概括:
模型拥有路线选择权,平台拥有事实裁决权和执行约束权。
很多 Agent 项目的问题正是这条线画错了:让模型用 prompt 约束去"保证"幂等、用自然语言去"维护"事务、用系统提示词去"防止"路径越权。这些都是机械可验证的机制,交给一个概率模型去守护,出事只是时间问题。反过来,把路线选择写死成固定工作流的,也不叫 Agent,叫 RPA。
结尾
回到开头的定义,把它串成这个执行模型的样子:
如一是一个以消息为刺激、以 Run 为执行边界、以 Turn 为认知节拍、以持久事实维持连续性、以模型作开放决策、以平台完成确定执行,并最终通过 Message、Artifact 和 Command 改变用户世界的智能运行系统。
这条分工线和这四个尺度,落到每一处具体机制里还有各自的功课:上下文怎么构造、压缩怎么折、工具协议怎么定、记忆怎么活。这是后面每一篇的事。
这篇是全系列的地基,欢迎按顺序读,也欢迎评论区交流你踩过的坑。
智创者社区:apmen.cn