EverRoom Context Docs:Agent可编辑的版本化文档与可审阅操作设计解析
【免费下载链接】EverRoomEverRoom - A workspace that remembers your projects, decisions, and sources.项目地址: https://gitcode.com/gh_mirrors/ev/EverRoom
EverRoom 是一个会"记住"你的项目、决策与信息源(Sources)的 AI 工作区,其中的 Context Docs 让 Agent 可以安全地编辑版本化文档:每一次改动都被记录为可回滚的版本快照,而 Agent 的每一次写操作都要经过"创建 → 审阅 → 应用"的可审阅流程。本文用零代码的方式,带你看懂这套 Agent 文档操作的版本控制与审阅机制是如何设计的,适合刚接触 AI 文档协作的新手。
什么是 EverRoom:一个会记住的工作区
EverRoom 的核心理念是A workspace that remembers your projects, decisions, and sources—— 它不只是编辑器,而是把"上下文"(Context)当作一等公民:项目文档、Agent 的会话、外部信息源都围绕一个个"房间"(Room)组织。
在这个体系里,文档不是静态文件,而是可以被 Agent 持续编辑的活对象。这就引出了两个关键问题:
- Agent 改错了怎么办?—— 靠版本化:每次提交(Commit)都会推进一个版本号,历史可查、可对比、可恢复。
- 怎么防止 Agent 乱改?—— 靠可审阅的操作流程:Agent 的修改先进入"待审阅"状态,由你确认后才会真正落到文档上。
这两点构成了 Context Docs 设计的两大支柱。
版本化文档:每次提交都是一个可回滚的版本
EverRoom 的文档提交由网关中的 commit-service.ts 负责。它的设计思路可以概括为三条规则:
- 🆕新文档必须从版本 1 开始(草稿则为版本 0),保证版本号单调递增、永不跳号;
- 🔒乐观锁防冲突:提交时可以携带
expectedVersion(期望版本),如果文档在你编辑期间被别人(或 Agent)改过,版本对不上就直接拒绝,避免"覆盖别人的修改"; - 📦原子提交:一次提交会同时更新文档内容、版本号,并把这份内容写入历史快照,保证"内容 + 版本"永远一致。
历史快照的存储与对比在 yjs-history-service.ts 中实现。它基于 CRDT(Yjs)记录编辑历史,并具备两个很实用的工程细节:
- 每 100 个版本自动打一个检查点(checkpoint),恢复任意历史版本时无需重放全部历史,速度稳定;
- 块级 Diff:对比两个版本时,会把变化拆成"新增 / 删除 / 修改 / 未变"的块(
DocumentDiffBlock),并给出块内文字级别的差异,让你一眼看清"Agent 到底改了哪几段"。
对比结果的数据结构定义在契约包 index.ts 中,同时支持"恢复到指定版本"(RestoreDocumentVersionInput)——也就是说,回滚不是"另存为",而是真正的版本回退。
可审阅操作:Agent 改文档前的 4 种交互模式
Agent 要修改文档,不能直接"裸写"。EverRoom 把 Agent 的文档写入建模为一个DocumentOperation(文档操作),每种操作声明自己的交互模式(interaction mode),共 4 种:
| 交互模式 | 行为 | 适用场景 |
|---|---|---|
streaming_commit | 边生成边提交,内容流式写入 | 实时草稿续写 |
atomic_review | 一次性生成完整修改,整体送审 | 整段重写、结构调整 |
incremental_review | 修改拆成多条 item,逐条接受/拒绝 | 多点小修小补 |
preview_replace | 先给你看替换预览,确认后才落盘 | 划词改写 |
在逐条审阅模式下(incremental_review),每个修改项(item)都是一个独立的"小补丁":操作类型是插入、替换、删除之一,附带改动前后的内容(before / after)和 Markdown 摘要,你可以逐条接受或拒绝,而不是被迫"全盘接受或全盘拒绝"。相关类型定义见 index.ts。
状态机:12 个状态保证操作全程可控
整个操作的生命周期由一个显式状态机驱动,源码在 state-machine.ts。它的 12 个状态可以分成两组:
进行中(5 个):created→running→awaiting_input(等用户补充输入)→awaiting_review(等用户审阅)→applying(正在应用修改)
终态(6 个):completed✅ /rejected/conflicted(版本冲突)/failed/cancelled/expired(超时自动过期)
状态机只允许按白名单跳转,任何非法跳转(比如从completed再回到running)都会直接抛错。这带来三个实际好处:
- 可追溯:Agent 每次操作都带着会话 ID(sessionId)、运行 ID(runId)落库,"这段话到底是谁在什么时候改的"永远有答案;
- 防并发:同一文档的多个操作通过队列串行执行,配合版本号乐观锁,多 Agent 同时改文档也不会互相踩踏;
- 防越权:每个能力(Capability)都声明了所需权限(
document:read/document:write等),路由层在启动操作前统一鉴权,见 routes.ts。
关键模块路径速查 📁
想深入源码的话,按下面的地图找:
- 文档核心(提交、内容引擎、历史):apps/gateway/src/modules/documents/core/
- 操作服务与状态机:apps/gateway/src/modules/documents/operations/
- 能力注册(Agent 权限声明):apps/gateway/src/modules/documents/capabilities/
- 契约类型(DocumentOperation、状态、交互模式):packages/agent-contract/src/index.ts
- 数据库表结构(operations、items、versions):apps/gateway/drizzle/
- 配套开发规范文档:docs/agent-document-development-sop.md
小结:版本化 + 可审阅 = 放心的 AI 写作
EverRoom Context Docs 的设计可以一句话总结:Agent 有"笔",但你的手永远握着"橡皮"和"审批章"。
- 版本化让任何一次 Agent 修改都可对比、可回滚;
- 可审阅操作让 Agent 的修改必须经过状态机流转,重要改动等你点"通过"才生效;
- 状态机与权限模型把"乱改、覆盖、越权"这三类风险从机制上堵死。
对新手来说,理解了这三层,你就能看懂绝大多数 AI 文档协作产品的底层逻辑——EverRoom 只是把它做了一套非常完整的工程示范。
【免费下载链接】EverRoomEverRoom - A workspace that remembers your projects, decisions, and sources.项目地址: https://gitcode.com/gh_mirrors/ev/EverRoom
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考