Macro 的文档块:markdown 原生编辑与 Loro CRDT 实时协作是怎么组织的
多人同时改一份文档,问题从来不在”能不能一起编辑”,而在三件事:网断了还能不能写、两个人改同一行会不会互相把内容顶掉、写完的东西能不能原样拿出来。很多协作文档工具在前两件事上做得不错,第三件事上却把内容锁在自家格式里,导出一次结构就散了。
Macro 把文档当成一种 block 来做。按官方文档的说法,Macro 里所有东西都是 block,第一方 block 类型里 md 就是文档,和 email、channel、chat、project、canvas、call 这些并列。所以”文档”在这套体系里不是一个独立应用,而是和任务、频道、邮件共用同一套引用、权限和搜索机制的一类内容。
这篇按官方文档把 docs 块的机制过一遍:编辑器到底支持什么、实时协作的底层结构是什么、标签和属性怎么用、通知规则里有哪些反直觉的地方。文中所有事实都来自 Macro 官方文档的 Documents 与 Blocks 两页,没有安装体验和实测数据。
markdown 原生的意思是编辑器直接吃 markdown 语法
官方文档对文档的定位是 markdown-native 的文本文件,通过 @mentions 和工作区其余部分连起来。这里的”原生”不只是能导出成 markdown,而是输入时的自动格式化就按 markdown 语法走。
文档列出的自动格式化触发符包括:
# → Heading 1
## → Heading 2
### → Heading 3
- → 无序列表
1. → 有序列表
[] → 清单(带可勾选的复选框)
> → 引用块
--- → 分隔线
` → 代码
块节点支持的范围,官方文档写得比较全:段落,Heading 1/2/3,无序列表、有序列表、清单列表(复选框可交互),引用块,代码块(Prism 语法高亮,覆盖 15 种以上语言),表格,分隔线,图片,视频,链接,另外还有用 KaTeX 渲染的行内公式和块级公式。
行内格式沿用常见快捷键,官方文档给的这一组是:
| 操作 | 快捷键 |
|---|---|
| 加粗 | cmd + b |
| 斜体 | cmd + i |
| 下划线 | cmd + u |
| 删除线 | shift + cmd + x |
| 高亮 | shift + cmd + h |
| 行内代码 | cmd + e |
| 查找替换 | cmd + f |
| 复制链接 | shift + cmd + c |
| 新建 markdown 文档 | c 然后 d |
查找替换这一条值得单独说一句:官方文档写明它支持正则,并且区分”替换单个”和”全部替换”。另外还有上标和下标,:shortcode: 形式的 emoji 也支持,块可以拖动重排,tab 与 shift+tab 用来缩进和反缩进。
斜杠菜单(输入 /,或者走命令菜单)能插入的条目是固定的一份清单:普通文本、Heading 1/2/3、引用块、代码块、无序/有序/清单列表、Task(一个带 mention 的行内任务)、图片、视频、链接、公式(/latex 或 /math)、表格(5×3)、分隔线。输入 ; 打开的是片段菜单,用来插入可复用内容。
这里面 Task 是个跨块的口子——它插进来的是行内任务,不是一段假装成任务的文字。文档、任务、频道之间的连接更完整的说明可以看 blocks 数据模型这篇。
最后,导出是”导出成 markdown 文本”。写进去的是 markdown,拿出来的还是 markdown,这条链子是闭合的。
实时协作底下是 Loro CRDT 加 Durable Objects
官方文档在 Documents 页里的说法是:Macro 用 CRDT 加 durable objects 保证多个同事可以同时在同一份文档、任务或消息里打字,并且在没有网络连接的情况下继续工作;即使改的是同一行,也能收敛而不来回抖动。
Blocks 页把结构写得更具体。协作类 block(文档、PDF 标注)通过 Loro CRDT 同步,后端是 Cloudflare Durable Objects:用 Rust 写的 sync-service 为每份文档拉起一个 Durable Object “房间”,客户端通过 WebSocket 连到 /document/:id。文档说这套结构带来的是多人编辑、协作光标(presence cursors)和完整的离线支持。
客户端 --WebSocket--> /document/:id
|
Durable Object 房间(每文档一个)
|
Rust sync-service(Loro CRDT)
值得注意的是”一文档一房间”这个粒度。它意味着并发压力是按文档分散的,而不是集中在一个全局服务上;也意味着跨文档的操作不共享这条实时通道。至于单个房间能承载多少人、同步延迟是多少,官方文档没有给数字,这里就不推测了。
CRDT 这条路线的另一个直接结果是离线可写。文档明确提到”no network connection”下仍可继续工作——这是 CRDT 相对于 OT(操作变换)那类需要中心服务器定序的方案在工程上的常见取舍,Macro 选的是前者。
不能无限嵌套:官方自己拿 Notion 做的对照
Macro 官方文档在这一点上说得很直白:和 Notion 不同,Macro 目前不允许文档套文档再套文档这样的多级嵌套;所有文档都存放在某个位置,要么在根级别(未经筛选),要么在某个文件夹里。这是官方文档自己拿 Notion 作参照给出的说法。
对习惯了用嵌套页面当目录树的人,这个限制需要先想清楚组织方式。官方给的替代路径是文件夹加标签这两套并行的归类办法,文件夹那套可以看文件夹与标签怎么分工这篇。
补一个信息密度上的设计:官方文档说较长的文档会在左侧边缘显示 outline——每个标题对应一个短横,随滚动跟踪当前位置,当前所在小节的短横会高亮;悬停可展开完整标题列表,点击跳转。这个 outline 的出现条件是文档至少有三个标题、并且窗口宽度放得下,在移动端和浏览版本历史时不出现。
标签把一堆文档变成能筛的库
在文档的标题或正文里输入 # 会打开标签菜单,可以选已有标签或新建一个,新建时指定颜色,以及它是个人标签还是与团队共享的标签。标签在正文里渲染成彩色的行内 pill,点一个能看到所有带这个标签的其他内容。
官方文档对这套机制的定位写得很清楚:打标签把一组文档变成一个轻量数据库,可以按标签筛选文件、按标签搜索,用类似 Notion 数据库的方式切分工作区。
和标签并行的是属性。文档右侧(或者按分屏宽度落在 Info 面板里)能看到文档详情——所有者、所在文件夹、创建时间、更新时间——以及属性。属性可以给文档指派负责人、关联到某个任务、设置紧急程度等。属性可以钉住,钉住后它的值会以 pill 的形式渲染在标题下方;还可以打开一个可选的 YAML front-matter 展示,以及实时的字数和字符数统计。属性系统本身的机制见 properties 这篇。
评论、版本历史和 fork
评论是行内的、按线程组织的,锚定在一段选中的文本上。可以回复、可以解决和取消解决、可以存草稿,自己的评论可以编辑或删除。
版本历史官方叫 time-travel:可以按用户和时间分组浏览历史状态,并且能把文档在任意一个历史版本处 fork 成一份新文档。fork 这个动作比单纯回滚更实用一些——想从三周前那版重新分叉一条思路,又不想动现在这份,不用先复制再手工粘。
通知规则里最容易踩的两条
这部分是官方文档里少见的、写得像是被问烦了才补上的说明,也是最该记住的:
| 场景 | 会不会通知对方 |
|---|---|
| 在文档正文里 @ 某人 | 不通知 |
| 在评论里 @ 某人 | 会通知 |
| 文档没有共享给某人 | 该文档产生的通知他收不到 |
原文的表述是:在文档正文里 @ 提及一个人不会通知他;一个人要能收到某份文档的通知,前提是这份文档先被共享给了他;而在评论里 @ 某人,他会收到通知。
还有一条相关的权限规则在 Blocks 页:文档里的嵌入和提及不会自动授予权限,这一点和频道里的提及不同——频道成员会自动获得访问权。所以在文档里嵌入了别的 block,还得单独把那些文件也共享出去。权限层级本身可以看权限模型这篇。
分享侧用的是统一的四级访问权限:owner、editor、commenter、viewer。可以用邮箱地址把文档分享给 Macro 之外的人,也可以在 Share 菜单里启用 Public Link 后给一条 URL;未登录的用户看到的是文档预览,不需要登录或注册账号。另外,通过 Macro 消息分享一份文档时,它的权限会自动更新,好让收到消息的人能打开。
什么时候这套不合适,以及还没解决的
先说边界。不支持文档多级嵌套这一条,对以嵌套页面为主要信息架构的团队是硬约束,迁过去要重做目录组织,靠文件夹加标签补。分屏那套窗口管理,官方文档写明只在桌面端有,移动端没有;outline 在移动端也不显示。
其次是没有公开数字的部分。单个 Durable Object 房间的并发人数上限、同步延迟、离线状态能缓存多久、版本历史保留多长时间,官方文档都没有说明。要评估能不能扛住几十人同时编辑一份长文档,只能自己压测,不能拿文档里”almost instantly”这种描述性说法当指标。
第三是依赖面。实时协作这条链子绑在 Cloudflare Durable Objects 上,自托管场景下这部分怎么落地,Documents 和 Blocks 这两页都没有展开,需要去看仓库里的自托管说明再判断。
最后一点取舍:markdown 原生的好处是内容可以原样搬走,代价是表达能力被 markdown 的语法边界框住——文档里能插的块节点是上面那份固定清单,想要 Notion 那种任意数据库视图、看板、日历,在 docs 块里没有对应物,那些能力在 Macro 里分给了别的 block 类型。要判断这套是不是够用,先看自己的文档里有多少内容是靠嵌套页面和数据库视图撑起来的:如果多,得先改组织方式;如果只是长文本加交叉引用,markdown 加 @mention 这条路会顺一些。
延伸阅读
- 从头读起:Macro 是什么:邮件、任务、文档、CRM 共用一个双向数据库的开源工作区
- 本专题共 40 篇,完整分组目录见专题页
- Macro 的 Canvas 二维板怎么用:板上的 @ 链接是活块,权限和反链要分开看
- Macro 的通话录制与转写:默认共享给全团队,怎么按次退出
本文依据 Macro 官方仓库(github.com/macro-inc/macro,AGPL-3.0 协议)的 apps/docs/ 产品文档、
MCP 工具参考与自托管说明整理,核对日 2026-08-17。
我们没有注册或运行过 Macro,因此不涉及界面外观与操作手感;
官方标注为计划中的能力文中已如实标明,不代表当前可用。
价格与额度以官网 macro.com 最新页面为准;许可证相关问题请咨询专业人士并以官方许可证原文为准。