你在一个角色上玩了 100 小时——这个角色是什么?不是引擎、不是主机、不是手柄,是存档文件。AI agent 正在撞上同一个拐点:agent 是它的 durable 事件历史,不是跑它的进程。
大多数人以为 agent 是模型、是 runtime、是正在执行任务的那个循环。这些东西重要,但它们不是 agent。agent 是它的数据——具体说,是它的 log。构造得当的 log 足以单独恢复 agent。
PlayStation 起火了,角色没死——买台新的、从云端下载存档,角色正好停在挥剑到一半的地方。agent 与 worker 的关系,和角色与主机的关系同构:
log 由两部分组成:一条 append-only 事件历史,加上一份会话定义的引用。两者合起来 = agent 的完整状态。
把 agent 定义成 log 之后,系统的其余部分都变得好推理——对 agent 的每个操作,要么读 log、要么追加 log、要么渲染 log 的一个视图。这和数据库多年前达成的模式一模一样:表、索引、缓存全是底层一条变更 log 的投影。
while session_has_work:
take_temporary_lease(session_id) # 认领临时租约
state = reconstruct_from_log(session_id)
response = model.next(state)
append(response, to=session_log)
if response.requests_tool:
append(tool_call_started, to=session_log)
result = run_tool(response.tool_call)
append(result, to=session_log)
continue
finish_turn(session_id)
关键:每一趟都认领一个临时租约、读 log、推进一步、把结果写回。循环因此幂等且容错。这正好是姊妹篇 Serverless Agents 里 advance(agent_id, event) 的理论原型——worker 退场后,agent 仍持久存在于 log 中。
compaction 用一个摘要替换掉之前所有内容——这难道不破坏"log 是 agent"吗?不会,反而强化它。 compaction 是有损的:它不是用更小的形式复现状态,而是扔掉信息。完整 log 是记录,compaction 只是它的一个投影。
agent 编辑了文件、开了个 GitHub issue、发了封邮件——现在有状态活在 log 之外了。不会破坏。 你从 log 而不是从世界重新推导 agent 状态:邮件已发出,fork 回去也收不回;它编辑过的文件可能已被改过。
这五个性质不是独立的,它们都从同一个假设掉出来:
| 性质 | 从"log 是 agent"掉出来的含义 |
|---|---|
| 可靠性 Reliability | Claude Code 到权限提示框时进程死了 → 恢复后提示框没了、agent 卡住——生产不可接受。log 即 agent 时执行者允许出错:新 worker 重建状态,权限提示框还在原地。进程死了;agent 没死。 |
| 可扩展 Scalability | 从"每 agent 一个进程"反转为"一个进程推进上千 agent",每个每轮从 log 重建。无 sticky session、无状态迁移、无协调开销,扩展只是加 worker。 |
| 分叉 Forking | 分支 log:一条跑 Claude、一条跑 GPT、一条跑本地 Qwen,各在不同沙箱、用不同工具探索不同策略。 |
| 多人 Multiplayer | 分享 ≠ 把 transcript 复制进 Slack(那像截一张数据库的图就管它叫"复制")。分享 = 授予对一个 durable history 的访问——可检视、恢复、扩展。 |
| 迁移 Migration | 身份若困在 provider 专属假设里换 provider 很痛。log 即 agent 时迁移变成 adapter 问题:不同模型想要不同投影,那是工程问题,不是身份问题。 |
与姊妹篇的关系:这五性质从"log 即 agent"这个本体论断言掉出来;Serverless Agents 的四性质(可用性/韧性/可扩展/效率)从"控制/执行平面分离"这个架构断言掉出来。重叠在 scalability,reliability ≈ resilience。本篇是"agent 是什么",那篇是"系统怎么搭"。
文章点名当今主流 harness 把 log 当副作用而非系统:
| 工具 | log 的处理 | 问题 |
|---|---|---|
| Claude Code / Codex | messy JSONL 写到本地磁盘 | SDK 模式下 fire-and-forget——写完前出问题,数据就没了 |
| OpenCode | 状态存本地 SQLite | GitHub issues 报告 corruption 和数据丢失 |
| Durable objects | 持有不同 shards | 历史难以重建 |
把 log 当成一等公民——durable、结构化、可重放、独立于机器——这些性质全部变成结构性的。你不用 bolt on,它们自己掉出来。
最深的锁入是 log 锁入
模型可换、API/工具可被 wrap——但 provider 若持有你 agent 历史的唯一 durable 副本,provider 就拥有你的 agent。因为 agent 不是它的最终输出,而是产生它的那条路径依赖的历史。
这不是反对托管基础设施(对多数团队有用且可能不可避免),而是:你应该知道你的 log 住在哪、谁能检视它、它能否被重放/fork/迁移/导出。一旦 session log 成了原语,log 的所有权就是 agent 的所有权。
这条论证在姊妹篇里向上爬一层:不只是 log(记录层)应可拥有,控制平面(log 居住、harness 运行之处)也应可拥有——这正是 Omnara 开源其控制平面的动机。
从第一性原理推理 agent:agent 是 durable 历史,那个历史就是 log。一旦这么看,很多事就各就各位——可靠性、可扩展、compaction、分叉、迁移、多人、所有权。停止把 log 当系统排出的废气,开始把它当成系统本身。循环变成 log 之上的执行者。这和数据库多年前经历的倒置一模一样:durable 历史是主,其余都是投影。
原文:The Log Is the Agent · Ishaan Sehgal (@ishaansehgal), Omnara (YC S25) · 2026-06-11。姊妹篇 Serverless Agents: No Machine Owns the Loop(2026-07-23)把本论点推到架构层。