02 V2 的核心分离:持久化录入 vs 模型执行


文档摘要

02 V2 的核心分离:持久化录入 vs 模型执行 本节摘要:V1 把所有事塞在一个循环里,简单但难 durable、难并发。V2 做了一次刻意的架构演进,核心动作就一个——把「用户提示如何进入系统」(录入)与「模型如何执行这一回合」(执行)彻底分开。听起来只是拆分,但它换来的是质变:录入变成 durable(不会丢)、可恢复、可并发、可重放。本节讲清这次分离:什么是 durable 录入(收件箱模型)、为什么分开换来这些好处、以及「事件溯源」这个关键词到底意味着什么。读懂本节,你就读懂了 V2 的灵魂——也是 OpenCode 内核正在长成的样子。 一、先看清 V1 的耦合在哪 要理解 V2,先精确指出 V1 的问题在哪。

02 V2 的核心分离:持久化录入 vs 模型执行

本节摘要:V1 把所有事塞在一个循环里,简单但难 durable、难并发。V2 做了一次刻意的架构演进,核心动作就一个——把「用户提示如何进入系统」(录入)与「模型如何执行这一回合」(执行)彻底分开。听起来只是拆分,但它换来的是质变:录入变成 durable(不会丢)、可恢复、可并发、可重放。本节讲清这次分离:什么是 durable 录入(收件箱模型)、为什么分开换来这些好处、以及「事件溯源」这个关键词到底意味着什么。读懂本节,你就读懂了 V2 的灵魂——也是 OpenCode 内核正在长成的样子。

一、先看清 V1 的耦合在哪

要理解 V2,先精确指出 V1 的问题在哪。在 V1 里,「用户输入消息」和「跑这一回合」是同一件事——你输入消息,循环立刻开始跑,输入和执行绑在一起:

V1:输入即执行 用户输入 ──► [循环立刻开始:组装→调模型→工具→续跑]

这种绑定带来三个麻烦:

  1. 不 durable:如果跑到一半进程崩了,用户输入可能还没落盘,就丢了。
  2. 难并发:同一会话来两条输入怎么办?V1 的同步循环处理起来很别扭。
  3. 难恢复/重放:你想「从某个点重新跑一遍」很难,因为输入没被独立记录。

二、V2 的核心动作:把录入和执行分开

V2 的解法是引入一个持久化的收件箱(inbox)。用户输入不再立刻触发执行,而是先被「录入」到这个收件箱(一条持久化记录),执行引擎再从收件箱取出来跑:

V2:录入与执行分离 用户输入 ──► [录入:durable 收件箱,一条持久化记录] │ ▼ [执行引擎:从收件箱取,跑回合]

这两步现在是独立的——录入只负责「把输入安全地记下来」,执行只负责「拿输入跑模型」。它们之间通过收件箱解耦。

💡 关键认知:在 V2 里,「用户输入了一条消息」和「这条消息被执行了」是两件独立的事,各有各的记录。这正是「事件溯源(event sourcing)」的味道——系统的状态由一系列事件推导出来,而不是被就地修改。

三、durable 录入换来什么

把录入独立出来、做成 durable,换来四样实在的东西:

1. 不丢输入

录入第一步就是落盘(写一条持久化记录)。即使执行引擎还没开始跑就崩了,输入也已经在盘上了,重启后能继续。这对长任务、不稳定环境是刚需。

2. 可恢复

因为录入和执行都基于持久化记录,「从某个状态恢复」就是「把记录重放到那个点」。V1 里进程崩了状态可能丢失,V2 里状态永远能从事件重建。

3. 可并发

录入和执行解耦后,并发变得自然:多条输入可以先进收件箱排队,执行引擎按规则协调(下一节的协调器)。同一会话的并发、不同会话的并发,都能被妥善处理。

4. 可重放

想「如果当时换个模型会怎样」?V2 里你可以拿同一份录入记录,换条执行路径重跑——因为录入是「发生了什么」的客观记录,执行只是「怎么响应它」的一种可能。

四、事件溯源的影子

V2 的设计带有明显的「事件溯源」特征。简单说,事件溯源的核心是:

系统不存「当前状态」,而是存「发生过的事件序列」;当前状态由事件序列推导出来。

对照 V2:

事件溯源概念 V2 对应
事件(event) 用户提示被录入、回合开始、工具被调用、工具返回、回合结束......
事件存储 durable 收件箱 + 会话事件流
状态推导 会话当前状态由事件序列重建

这不是说 V2 是教科书式的事件溯源,而是它借用了这套思想来解决「durable + 可恢复 + 可重放」的问题。第 8 章的 Context Epoch 也依赖这种思路——纪元的边界由事件决定。

五、一个常被问的问题:性能不会变差吗

「录入先落盘,再执行,多一步,不会慢吗?」——这是一个合理的疑问。答案是:多了一次落盘,但换来的是 durability,这笔账划算

  • 落盘是顺序写,非常快(毫秒级)。
  • 换来的是「绝不丢输入」「可恢复」「可重放」,这些在长任务和生产环境里价值远超那点延迟。
  • 而且执行引擎可以从收件箱批量取、流水线跑,反而能提升吞吐。

⚠️ 别误读:V2 不是「所有事都变慢了」,而是「录入多了一步落盘,执行可以更自由地调度」。整体上,V2 在 durability 和并发上的收益远大于那一部落盘开销。

六、为什么这是「演进」而非「推翻」

最后强调一点:V2 不是把 V1 推倒重来,而是把 V1 的循环拆开、把录入独立成 durable。V1 里那些「组装系统提示、调模型、处理工具、续跑」的逻辑,在 V2 里依然存在,只是它们现在跑在一个更健壮的骨架上(执行引擎),而录入不再和它们绑死。

这种「保留核心逻辑、升级骨架」的演进方式,是大型项目重构的常态——也是为什么 V1 和 V2 能并存一段时间(迁移期)的原因。

本节要点回顾

  1. V1 的问题:输入与执行绑定,导致不 durable、难并发、难恢复。
  2. V2 核心动作:把「录入」(用户输入进 durable 收件箱)和「执行」(引擎从收件箱取、跑回合)彻底分开。
  3. durable 录入换四样:不丢输入、可恢复、可并发、可重放。
  4. 事件溯源的影子:系统不存当前状态,而存事件序列,状态由事件推导。
  5. 性能账划算:录入多一次落盘,换来 durability 与并发收益,执行还能批量调度。
  6. 演进非推翻:V2 保留 V1 的核心逻辑,只升级骨架——这是为什么二者能并存迁移。

录入和执行分开后,一个新问题来了:多条输入并发进来、执行引擎要不要排队?谁来协调?这正是下一节的「回合协调器」。


发布者: 作者: 灏天文库 转发
评论区 (0)
U