The GEML Manifesto: Doc-as-a-Base
文档即真相之源 (Doc-as-a-Base)
一份关于人机共写时代文档协议的设计宣言
English | 中文
一、由来
当年,Roy Fielding 提出 REST,并没有发明新的网络硬件,而是为网络上散落的资源统一赋予了名字(URI)和一组标准的动词(GET / POST / PUT / DELETE),从而奠定了现代 Web 协作的基石。
今天,在人类与 AI Agent 共同工作的场景中,文档同样散落着无数段落、规则、参数与结论。由于缺乏统一的名字与操作规范,人类与 Agent 只能进行粗暴的全文重写与复制粘贴。
Doc-as-a-Base 的由来正是对 REST 思想的延展:文档需要的不再只是一个格式,而是一组动词。
为文档内的每一个逻辑块赋予唯一的名字(#id),并赋予标准的操作动词(get / set / add / delete)。
二、含义
在传统认知中,文档只是人类阅读的静态排版文本,或系统运行后的离线输出物。
而在 AI Agent 深度介入系统构建与知识协作的今天,GEML 提出:文档应当成为系统运行与协作的真相之源(Doc-as-a-Base)。
- 文档即操作对象:文档不是用于全文打印的无序流,而是由离散、强类型、可寻址的区块(Typed Blocks)构成的可读写结构化文本。
- 文档即有状态的:文档本身就是具备严格数据结构的上下文载体,历史上下文、会话信息或状态数据,不应依赖外部脆弱的临时状态本地存储与零散提示词帮忙记录。
- 文档即最终共识:无论人类还是 AI Agent,所有读取皆以文档为单一基准,所有产出皆以原子级 Patch 直接回写于文档。
Doc-as-a-Base 不是把文档包装成一个庞杂的系统,而是确立文档在人机协作中的位置:单一事实来源(Single Source of Truth)。
Base,即 base of truth:
Doc-as-a-Base:一份仍是纯文本、但自带动词的文档——
每块有名字,可以单独取;引用构建期核验,坏写入挡在落盘之前;
内嵌是投射,不是复制;回滚只退一块,不推倒整篇。
它是所有交付物的基座(base):既是可精细操作的中间产物,又是快照的投射来源,也是最终产物的桥梁。
三、核心理由:为何必须 Doc-as-a-Base?
1. 终结上下文状态的“碎片化与漂移”
- 现状:当前 Agent 系统中,上下文被拆散在向量数据库、运行时内存、聊天历史与零散的 Markdown 片段中。多轮交互后,状态不同步、副本满天飞,导致严重的幻觉与数据失真。
- 理由:当文档成为唯一真相基准(Single Source of Truth),所有 Agent 操作均直接对齐文档节点。源头唯一,才能从机制上消除副本冗余与版本脱节。
2. 终结全量重写带来的“Token 膨胀与解析失真”
- 现状:传统非结构化文档缺乏精确的边界定义,Agent 哪怕仅修改一处参数,也必须读入并重新生成全篇内容,导致系统饱受 Token 膨胀之苦。
- 理由:作为 Base 的文档必须具备块级确定性。Agent 仅需查询目标 Block ID 并提交局部 Patch,以极低 Token 开销完成精确更新,释放宝贵的上下文窗口。
3. 实现人机心智的“同构交互”
- 现状:JSON 等格式对机器友好但阻断了人类的直观阅读与编辑;Markdown 方便排版但缺乏机器操作的严谨边界。
- 理由:Doc-as-a-Base 统一了两者的语义层。人类看到的是直观清晰的纯文本,Agent 读写的是强类型、可校验的块节点。两者在同一个 Base 上无损协作。
四、核心取舍与四大定律
先立一条前提,它不占四条之一:人看不懂的格式,不属于这里讨论的任何东西——纯文本可读性是地基,其余一切都盖在它上面。
在新范式里,我们主张:
- 局部精确修改 > 整篇读写
- 显式声明与校验 > 隐式猜测
- 单一源头动态引用 > 复制粘贴
- 极简语法规则 > 复杂类型系统
四条缺一不可:不能寻址就无法安全写入,不能投射就只能复制,不能校验就拦不住坏写入,不能回滚就无法恢复。
旧范式的事物并非没有价值——其中一些,我们至今每天在用——但为了与机器读者共写,我们更看重左边。
这四组取舍,不是用来给现有格式打分的。每种格式都为一个具体问题而生,而且大多把那个问题解决得很好。它们只是从来没被要求解决「机器反复改写」这一个问题——Markdown 诞生的 2004 年,还没有人需要一份能被程序原子化改写的文档。
主张要能验,才不是口号。四条主张对应四条定律,每条配一个可判定的判据;面向第二个读者的格式,四条必须同时满足:
- 寻址律 (Addressing):每个结构块必须有稳定的、机器可识别的主键,脱离上下文即可被单独读取与替换。 文档由离散的 Typed Blocks 构成,Agent 与人类均可通过
#id进行原子级定位与原地局部读写。get(id)只返回那一块,set(id)只替换那一块——其余部分不但不改,根本不加载。没被加载的东西不可能被改坏——要隔离,不要自律。 - 投射律 (Projection):引用必须是视图端的动态取值,而非静态复制。 副本自诞生就在漂移;投射让「同步副本」这项劳动消失。内嵌是求值,不是复制,也不是指路(那是链接的事)。源头单一定义,彻底终结副本碎片化。
- 校验律 (Validation):块间引用必须在构建期受核验,坏写入挡在落盘之前。 写入即防御。写入路径上多出一道门,不等人工 review 介入拦截。
- 回退律 (Rollback):出错时必须能只回滚出错的那一块。 借助伴生
.gemlhistory,异常变更支持针对单个 Block 的原子级版本回退,不波及全篇。Agent 长期记忆天然就是短期记忆的历史。相比 Git 以文件与提交为单位来说,操作太重,结构上给不出块级粒度。不是 Git 不好,是它不在这一层。
寻址、投射、校验、可逆——四样能力,在各自的领域都有成熟方案:数据库有主键,XML 有 XInclude,Schema 能校验,Git 管历史。不寻常的不是其中任何一样,是把四样同时装进一种人类可读的纯文本。(逐格式的对照,见 能力矩阵。)
四条之外还有一件事,它不是第五条定律,而是前四条兑现后自然到手的东西:上下文是稀缺资源。取一块和取整篇,在纸面上只是效率差别;在 Agent 的多轮循环里,它决定了模型的注意力落在哪、这一轮还剩多少预算。按块寻址省下的不是流量,是模型用来想事情的余地。
五、设计信条
为了让 Doc-as-a-Base 成为可落地的基础设施,GEML 确立以下技术信条:
类型化区块架构 (Typed Block as Primitive)
文档由结构化的 Typed Block 构成,每个 Block 具备全局唯一可寻址 ID,赋予 Agent 精确读写能力。原地局部修补 (In-Place Mutation)
严禁为局部修改执行全篇重写。所有对 Base 的变更必须支持按 Block ID 进行原地 Patch 与幂等更新。语法克制 (Syntax Austerity)
不为排版与包裹花一个多余的 Token;语法只承载结构,省下的上下文留给内容。前置校验拦截 (Validation-First Ingestion)
写入即校验。破坏性格式或非法引用在进入 Base 前被即时阻断,确保真相源的纯净度。区块级版本追溯 (
.gemlhistory)
Base 的演进历史必须可追溯、可归因。借助伴生历史文件,任意单一区块均可独立回滚,保障人机协同的安全性。
六、边界
GEML 主动声明自己的边界——这正是这份规范的信用所在:
- 它不是数据库:查询是 O(N) 的字符流遍历,没有索引;并发写至多依赖整文件锁;没有跨文件事务。GEML 借用的是数据库的操作语义(寻址、读写、校验、回退),而非它的运行时属性。
- 它不取代向量库与 Agent 运行时记忆:向量数据库负责语义相似度检索,短期记忆负责维持对话上下文;GEML 的职责是且仅是——作为可持久化、可审计、可精确读写的文档真相底座。
- 它不承诺语法零开销:
=== type {#id ...}语法本身必然占用 Token。GEML 追求的是通过“局部精准 Patch”消灭“全文反复重写”所带来的几何级 Token 浪费,而非虚无的零开销。 - 校验拦不住内容写得烂:它拦的是结构破坏和断引用。Agent 把一段话写得很蠢,它一个字都不会说。
七、结论
Doc-as-a-Base 不是要创造一个沉重的系统,而是用极简的约定,给混沌的文档带来秩序。
让每段文字拥有名字,让每次修改拥有边界,让文档真正成为人类与 AI Agent 之间可靠、确定的真相之源。
这份宣言不设签名页。以 GEML 格式写出一个文件,就是签名。