ReMe/docs4/old/structure.md
Sen Huang a2d76cc034
Some checks are pending
Pre-commit / run (ubuntu-latest) (push) Waiting to run
Tests ReMe / Unit Tests - py3.11 (push) Waiting to run
Tests ReMe / Unit Tests - py3.12 (push) Waiting to run
Tests ReMe / Unit Tests - py3.13 (push) Waiting to run
refactor(auto_dream): improve recall workflow and documentation (#272)
* feat(file_store): add concurrency protection to LocalFileStore.dump()

* feat(file_catalog): replace file_store with file_catalog in DreamStep

* feat: add ChannelSink for Claude Code channel notifications

* feat(auto-memory): add transcript_path support and enhance metadata
2026-06-04 19:56:50 +08:00

49 KiB
Raw Blame History

reme4 系统架构 — 设计文档

文档定位

本文档定义 reme4 的架构设计:概念边界、数据流契约、职责划分。

  • 不涉及代码路径 / 实现进度 / API 具体形态
  • 执行栈与架构角色(分层、模块切分、职责划分)在第 6-7 节;源码映射与落地状态见 docs4/reme4_report.md 与源码
  • 不规定怎么做,只规定是什么、谁负责、输入输出

阅读顺序:第 1 节给出完整的架构总览(数据视角 + 运行时视角 + 核心机制 + 不变量 + 导航);第 2-5 节逐层展开三层存储 / 6 类 L4 动作语义 / 反向回流 / 触发节奏;第 6 节描述底层执行栈(L0→L5);第 7 节把 6 类 Action 落到 L4 实现模块;第 8 节讲跨切面 schema 契约;第 9 节列出明确不属于本架构的反例。


1. 架构总览

本章给出 reme4 完整的设计骨架,后续 §2-§9 逐项展开细节。

1.1 解决什么问题

reme4 是 agent 的长期记忆系统。它把 agent 的工作过程沉淀为可检索、可演化的知识结构。

设计要解耦两件事:

关注点 由谁负责
agent 写什么 / 读什么 agent 的工作流自决
vault 自身如何健康演化 reme 自治,agent 不感知

实现方式:三层存储拓扑为"两路并行写入(原始资料 / 任务过程) → 双源合流到沉淀知识层",reme 提供这三层的容器、动作语义、反向检索与自治维护。

1.2 数据视角:并行起点 + 双源合流 + 反向回流

数据有两个并行起点 —— External source(webhook/upload/pull)与 Agent(外部主体,自身任务驱动)。两条独立通道各自落地到并行的材料层:External 经 ingest 沉到 resource/,Agent 经 sync 写到 daily/。两层材料合流digest/,由 reme 通过 digest 动作完成"消化"。digest/ 自身由 maintain 做 in-place 重组。Agent 通过 retrieve 从 resource + daily + digest 三层并行回流。notify 是 reme 跨过 vault 直接提醒 Agent 的虚边(控制信号,不写任何文件)。每段路径都对应一个 L4 动作语义(完整动作详见 §5.2 / §7):

路径 L4 动作 说明
External source → resource ingest 外部信源落到 vault
External source ╌╌► Agent notify reme 推送通知(虚边,只走 L2 推送队列,不写文件)
Agent → daily sync Agent 写 daily(响应 notify 或自身任务驱动)
resource + daily → digest digest reme 内部 LLM 抽取沉淀(双源合流)
digest → digest maintain reme 内部 LLM 折叠重组(in-place, fold-only)
resource + daily + digest → Agent retrieve 三层并行回流(state / semantic / topological 三种正交问法)
                                notify(虚边,控制信号)
External source ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌►  AGENT
(webhook/upload/pull)                                     (外部主体/自身任务)
        │                                                    │    ▲
        │ ingest                                             │    │ retrieve
        │                  ┌────── sync ────────────────────-┘    │ (state /
        ▼                  ▼                                      │  semantic /
   ┌──────────┐       ┌──────────┐                                │  topological)
   │resource/ │       │  daily/  │                                │
   │ 原始资料  │       │任务工作区  │───────── retrieve ─────────────┤
   │ 不可变    │       │ 半可变    │                                │
   └───┬──┬───┘       └────┬─────┘                                │
       │  │                │                                      │
       │  │ digest  digest │                                      │
       │  └────────┐  ┌────┘                                      │
       │           ▼  ▼                                           │
       │       ┌────────────────────┐                             │
       │       │      digest/       │ ◄──╮                        │
       │       │     沉淀知识        │    │ maintain               │
       │       │  可重组(语义索引)    │ ───╯ (in-place, fold-only)  │
       │       └──────────┬─────────┘                             │
       │                  │ retrieve                              │
       │                  └─────────────────────────────────────-─┤
       │                                                          │
       │ retrieve                                                 │
       └──────────────────────────────────────────────────────────┘

模型要点:

  • 两个起点平行,不存在主从 —— External 与 Agent 各自独立驱动;Agent 既可响应 notify 也可由自身任务直接 sync
  • 两层材料平行,不存在传递 —— resource 与 daily 是两条独立的写入通道,不互相穿越:Agent 不写 resource,ingester 不写 daily。
  • digest 是双源合流的产物 —— digest 动作的输入是 resource + daily 的组合(不是仅 daily);相应地,digest 节点的 provenance 可同时指向 resource 与 daily。
  • digest 自循环 —— maintain 在 digest 内部做密度折叠,不与上游材料层交互。
  • notify 是虚边 —— reme 用它提醒 Agent "有新 resource 值得看",但不落任何文件;Agent 的响应通过 sync 落 daily(并可选地用 wikilink 引 resource)。

retrieve 三种问法正交:

问法 工具 主要看哪层
state(谁在 / 是什么状态) list / frontmatter 各层平等
semantic(我想到一个意思) search digest > daily > resource(默认权重)
topological(从一个点向外摸) traverse 沿 wikilink 跨层平等

1.3 运行时视角:六层执行栈 + 双进程

reme4 的功能不是堆在一层,而是从文件系统底层往上栈式堆叠。顶层 Service 与 Runtime 是同一套 vault 上的两个进程角色,共享 L0-L4 全栈(详见 §5.3 / §6)。

   ┌─────────────────────┐      ┌─────────────────────┐
   │  L5  Service         │      │  L5  Runtime         │
   │  (HTTP / MCP)        │      │  (scheduler 自治)    │
   └──────────┬───────────┘      └──────────┬──────────┘
              │                              │
              └─────────────┬────────────────┘
                            ▼
   ┌──────────────────────────────────────────────────┐
   │  L4   6 类 Action(动作语义)                     │
   │  ingest  notify  sync  retrieve  digest  maintain│
   └──────────────────────┬───────────────────────────┘
                          ▼
   ┌──────────────────────────────────────────────────┐
   │  L3   原子工具                                   │
   │  ┌─────────────────────┐  ┌──────────────────┐   │
   │  │ 基础工具             │  │ 高级工具          │   │
   │  │ create/append/edit/  │  │ search           │   │
   │  │ read/write/move/     │  │ traverse         │   │
   │  │ delete/list/stat     │  │ frontmatter      │   │
   │  └──────────┬──────────┘  └────────┬─────────┘   │
   └─────────────│──────────────────────│─────────────┘
                 │ 直读 / 直写            │ 走索引读
                 │ (eventual,有滞后)    │
                 │                       ▼
                 │       ┌────────────────────────────┐
                 │       │  L2   文件状态              │
                 │       │  · file_store(chunk+vec)   │
                 │       │  · file_graph(node+link)   │
                 │       │  · 自治状态(scheduler 用): │
                 │       │    - resource: 入流批次/    │
                 │       │      未消化(orphan)        │
                 │       │    - daily: 任务索引        │
                 │       │      (进行中/stale/完成)   │
                 │       │    - digest: 密度水位/      │
                 │       │      断链(broken wikilink) │
                 │       │  · 推送队列(notify):       │
                 │       │    pending/notified/        │
                 │       │    acknowledged             │
                 │       └─────────────▲──────────────┘
                 │                     │ 派生 / 更新
                 │       ┌─────────────┴──────────────┐
                 │       │  L1   file_watcher          │
                 │       │  fs event → state delta     │
                 │       │  (唯一 fs→state 桥)         │
                 │       └─────────────▲──────────────┘
                 │                     │ 监听
                 ▼                     │
   ┌──────────────────────────────────────────────────┐
   │  L0   vault 文件系统                             │
   │  resource/    daily/    digest/                  │
   └──────────────────────────────────────────────────┘

Service 与 Runtime 是同一份 vault 上的两个进程角色:

进程 触发源 时延敏感 典型动作
Service 外部 push / 外部 pull / agent 同步请求 / MCP 推送通道 ingest / sync / retrieve / notify-out(MCP)
Runtime scheduler 周期 + L2 自治状态阈值 否(eventual) notify 决策 / digest / maintain

1.4 核心机制总览

机制 一句话 详见
三层存储 resource(冷) / daily(温) / digest(冷,组织化) §2
6 类 L4 动作 ingest / notify / sync / retrieve / digest / maintain §1.2 / §3
notify+sync 链 reme 主动从 L2 资源自治状态选候选,经 MCP 推给 agent;agent sync 落 daily §3.3-3.4 / §7.1
反向 retrieval state / semantic / topological 三种正交问法 §4
触发四源 外部 push / 外部 pull / agent on-demand / reme 后台 §5.1-§5.2
Service + Runtime 双进程角色,共享 L0-L4,职责按时延分 §5.3
执行栈(L0-L5) filesystem → file_watcher → 文件状态 → 原子工具 → Action → Service/Runtime §6
原子工具:基础 vs 高级 基础直 fs;高级走 L2 索引(eventual) §6.4 / §5.5
Action 模块映射 6 类 Action 由 5 个模块实现(retrieve 直走原子工具) §7
Schema 跨切面 name+description 是核心强约束,其余 opinionated default 可重载 §8

1.5 核心不变量速览

写入拓扑(架构脊梁,来自 §2.3):两路并行写入(External→resource、Agent→daily)→ 双源合流到 digest;resource 与 daily 之间互不写入;任何一层都不能反向改写它的上游。

不变量 内容 来源
I-1 agent 不直接写 digest(digest 写权只属 dreamer / maintainer) §2.4
I-2 daily folder 单作者(同 folder 不并发改) §2.4
I-3 resource 内容不可变,只允许 metadata appendable §2.4
I-4 三层共用同一套 wikilink 索引,跨层引用全靠 wikilink §2.4
R-1 retrieve 三种问法分立,不合并为单一 read verb §4.3
M-1 Maintainer 只做一件事:密度折叠(把碎片叶子折叠到新的中间节点下) §7.3
F-1 L1 file_watcher 是 L0→L2 的唯一派生桥 §6.5
F-2 L3 基础工具直接读写 L0;高级工具只走 L2 §6.5
F-5 L5 Service / Runtime 共享 L0-L4,不直接通信 §6.5
F-6 L0↔L2 存在 eventual 窗口,agent 上下文承担近期信息 §5.5 / §6.5

1.6 文档导航

想了解…
三层各自的定位、不变量 §2
6 类 L4 动作语义(notify / sync / digest / maintain 的输入产出不变量) §3
Retrieval 的三种问法与跨层语义 §4
谁来触发、什么节奏、为什么分两个进程 §5
系统从文件系统到 Service 的分层(底层基础) §6
L4 五个模块的对称结构与 Maintainer 折叠设计 §7
Schema 协议与重载机制 §8
哪些设计不属于本架构(反例与边界) §9
术语回查 附录

2. 三层存储

2.1 一句话定位

一句话
resource/ 外部原始资料的不可变快照。reme 是容器,不是作者。
daily/ agent 的任务工作区。folder 是单位,以"日 + 任务"为索引。
digest/ 跨任务沉淀的有组织知识。以语义(概念/实体/方法)为索引,与时间无关。

2.2 五维度对照

维度 resource/ daily/ digest/
组织主轴 时间(<date>/<name>) 时间 + 任务(<date>/<slug>/) 语义(<slug>/<subslug>/...,任意嵌套)
写权归属 入流通道唯一(webhook / upload / pull) agent(写入任务过程) dreamer / maintainer(无 agent 直写)
可变性 不可变,只追加新文件 folder 内可反复更新 单节点可演化,可被合并/拆分/移动
不变量 写入即冻结,原文永不变 folder 名 = summary note 名(可移动单元);同 slug 同日只一份 slug 全局唯一;每 folder 有 canonical entry;wikilink 全路径
谁在用 agent(查原文)、dreamer(双源输入之一) agent(自己的工作记录)、dreamer(双源输入之一) agent(召回主目标)、maintainer(自维护对象)

2.3 写入纪律:并行写入 + 双源合流

   External source                       Agent
         │                                 │
         │ ingest                          │ sync
         ▼                                 ▼
    ┌──────────┐                      ┌──────────┐
    │resource/ │                      │  daily/  │
    │ 不可变   │                      │ 半可变   │
    │(ingester)│                      │ (agent)  │
    └─────┬────┘                      └─────┬────┘
          │                                 │
          │ digest                  digest  │
          └──────────────┐    ┌─────────────┘
                         ▼    ▼
                    ┌──────────────┐  ◄──╮
                    │   digest/    │     │ maintain
                    │  可重组      │ ────╯ (in-place,
                    │ (dreamer +  │       fold-only)
                    │  maintainer) │
                    └──────────────┘

写权按这个两层并行 → 单层合流的拓扑分配:resource 写权专属 ingester(外部入流通道),daily 写权专属 agent(sync 落入,可响应 notify 或自身任务驱动),digest 写权专属 dreamer + maintainer。resource 与 daily 之间互不写入(agent 不动 resource,ingester 不动 daily);任何一层都不能反向改写它的上游。这是整个架构的脊梁。

2.4 不变量(永远成立)

# 不变量 否则后果
I-1 agent 不直接写 digest digest 的"有组织"性失守,沉淀质量退化
I-2 daily folder 单作者(同 folder 不并发改) 任务边界模糊,sync/digest 竞态
I-3 resource content immutable,只允许 metadata appendable 原文可能消失/被覆写,citation 不可信
I-4 三层共用同一套 wikilink 索引,跨层引用全靠 wikilink 引入第二套引用机制 → 索引重建复杂 / 跨层关系不可达

3. L4 动作语义详解

§1.2 给出了 6 个 L4 动作在数据视角下的整体形态。本节按动作逐个展开输入 / 产出 / 不变量 / 反例。ingest(外部→resource,机械)和 retrieve(三层并行回流,只读)分别在 §5/§7.4 与 §4 详述,本节聚焦四个写动作:notify / sync / digest / maintain

3.1 统一原则

四个写动作都遵守:

原则 内容
Monotonic content 上游内容不可变,下游只能新建节点或加链接,不能改写上游
Provenance 必须可达 任何下游节点必须能通过 wikilink 反查到上游来源
Wikilink 是新结构的唯一载体 跨层关系靠 wikilink,不靠内容拷贝

它们都不是"数据搬家",而是"在下游新生成有引用关系的节点"。

3.2 四个写动作的本质对照

动作 上游 → 下游 性质 上游变化 下游变化
notify resource → Agent Attention(推送注意力) 不变 不写 vault;仅入 L2 推送队列
sync Agent → daily Reference(引用落地) 不变 daily 中新增工作记录 + 对 resource 的 wikilink
digest resource + daily → digest Crystallize(双源合流结晶) 不变 digest 新增节点,wikilink 反指上游来源(daily 与/或 resource)
maintain digest → digest Reorganize(重组) 结构变,内容守恒 fold-only:引入子中间节点搬叶子,改变拓扑

notifysync 共同实现"resource 中的候选被 Agent 看见并织入 daily"这条Reference 链;它们是两个独立的 L4 动作,主体不同(notify 由 Reme 自治触发,sync 由 Agent 触发)。

3.3 notify:reme → Agent 推送候选

维度 内容
主体 Reme Runtime(notifier 模块)
输入 L2 资源自治状态:orphan(无 inbound wikilink)/ 入流批次 / 未消化老于 N
产出 L2 推送队列条目;通过 Service MCP server-initiated notification 推到 Agent;不写任何 vault 文件
不变量 resource 原文 0 修改;完全单向,不维护任何反向元数据;notify 决策在 Runtime,Service 只作 MCP transport
Acknowledge 机制 L1 watcher 检测到 daily→resource 新 wikilink → L2 推送状态 notifiedacknowledged,避免重复推送
反例 (a) Service 自决推什么 notify(✗-17);(b) notify 写入 vault(✗-16);(c) Agent 主动调 notify(✗-18)

3.4 sync:Agent → daily 落地

维度 内容
主体 Agent(synchronizer 模块在 Service 内编排)
输入 Agent 当前事件流(响应 notify 的候选,自身任务直接驱动)
产出 daily folder 内的工作叙事;可选地用全路径 wikilink 引 resource(agent 自决,reme 不强制)
不变量 resource 原文 0 修改;daily 单作者(I-2);folder 名 = summary note 名(可移动单元)
Provenance daily → resource 可达(通过 daily body 中的 wikilink)
反例 "agent 把 resource 内容拷进 daily" —— 不允许,daily 只持有引用 + 自己的工作记录

3.5 digest:resource + daily → digest 双源合流结晶

维度 内容
主体 Reme Runtime(dreamer 模块,LLM-driven)
输入 一组待蒸馏的 daily folder + 相关 resource(双源合流;通常以 daily 任务为线索,顺着 wikilink / 同主题搜索拉入相关 resource 原文)
产出 digest 中 0~N 个新节点 或 已有节点的更新;新节点必须用 wikilink 反指至少一个上游来源
不变量 resource / daily 正文 0 修改;digest 新节点必须 wikilink 反指上游(provenance);digest 节点遵守第 2.4 节列的不变量
Provenance digest → daily / resource 双源链条可达(资料源是 resource 时直接反指,任务过程是 daily 时反指 daily 进而可达 resource)
反例 dreamer 改写 resource;dreamer 改写 daily 正文

3.6 maintain:digest → digest 折叠

维度 内容
主体 Reme Runtime(maintainer 模块,LLM-driven,fold-only)
输入 digest/ 当前整体状态
产出 同一 digest/ 树的密度折叠(fold):某中间节点下叶子过多时,引入子中间节点把相关叶子归簇 + 写"高密度摘要"
不变量 只向下生长(从不反向);叶子内容 0 修改,只被搬位置;新中间节点 = 一个高密度摘要文件;任何节点移动原子重写所有入边(retarget);slug 全局唯一在折叠后仍成立
Provenance digest → daily 的反指链接在折叠后仍有效(retarget 保证)
反例 merge / move / promote / demote 等改写既有拓扑的操作;改写既有叶子内容

折叠操作的承诺与决策点见 §7.3。

3.7 链接重定向例外

maintain 的 retarget 会改写其它节点中指向被移动节点的 wikilink。从字面看,这违反了"上游内容不可变"。

实际上这是 wikilink 系统的机械性副作用,不算下游写上游:

字面 实质
daily 里的 [[digest/old.md]] 被改成 [[digest/new.md]] 作者意图("我引用了 X 这个 digest 节点")没变,只是 X 的物理位置变了

只要 retarget 保持 wikilink 的目标语义不变,就允许它作为机械维护副作用穿越层界。这是这条规则的唯一例外。


4. Retrieval 反向回流

Retrieval 是把 §3 几条正向写动作反着读:agent 站在结果端,沿 wikilink 反查源头。

4.1 三种问法

按 agent 意图分,有三类完全不同的读需求,正交,各自独立:

问法 例子 本质
状态问 (State) "我有哪些 in-progress 的任务?""哪些 resource 还没被引用?" 在某层做 list + frontmatter 过滤
语义问 (Semantic) "关于 auth 重构我知道什么?" 跨层全文/向量检索
拓扑问 (Topological) "auth 概念周围都连了什么?" 从某节点沿 wikilink 走

4.2 三层 × 三问法 矩阵

问法 resource/ daily/ digest/
状态问 "未处理 resource 清单" "active / pending-digest 清单" "孤儿节点 / canonical 缺失 清单"(给 maintain 用)
语义问 兜底(原文,信噪比低) 次优(最新,但未沉淀) 首选(沉淀过,信噪比高)
拓扑问 通常是叶子(被指向) daily → resource / digest digest 内部连接最密

4.3 设计原则

# 原则 含义
R-1 三种问法分立,不合并为单一 "read" verb 不同问法的索引、过滤、排序逻辑完全不同
R-2 语义问的默认权重 digest > daily > resource,可被显式覆盖 默认体现"沉淀质量",但 agent 可指定单层或调权
R-3 拓扑问与层无关 traverse 沿 wikilink 走,天然跨三层(I-4)
R-4 Provenance expansion 默认 lazy,eager 是上层便利封装 原子 retrieval 不自动展开;agent 需要时再 traverse
R-5 Cold start 不是新的 retrieval mode 只是状态问 + 语义问的组合,reme 不为它单设 verb

4.4 在主干图里的位置

Retrieval 不引入新存储,不引入新层。它是 agent 与三层存储之间的读视图,通过三种正交问法暴露,共享同一套 wikilink 索引(I-4)。


5. 节奏与触发

锁定"谁推动每个动作发生"。这一步定 reme 是纯被动 service 还是带后台 runtime。

5.1 触发源四分类

触发源 性质 例子
External push 外部事件主动推 webhook / 用户 upload
External pull reme 主动去外部拉 scheduled fetcher(RSS / 邮件 / API 轮询)
Agent on-demand agent 在请求里显式调用 "sync 我的对话" / "搜 X"
Reme background reme 自己的 watcher / scheduler file_watcher / cron-like

5.2 六个动作的触发归属

动作 主触发 备用触发 备注
ingest External push / pull 外部→resource,机械
notify Reme background(cron + L2 资源自治状态阈值) Runtime 决策,Service MCP 推送
sync Agent on-demand agent→daily;notify 的响应也走这里
digest Reme background Agent 显式(后门) resource + daily 双源合流到 digest
maintain Reme background(cron + threshold) Agent / 人工 显式(后门) digest 内部折叠
retrieve Agent on-demand 三层只读

关键定性:notify / digest / maintain 三个 reme 自治动作的主控制权在 reme,不在 agent。Agent 只负责"响应 notify + 写 daily(响应或自身任务驱动)+ 主动读";不需要记得"该看哪些 resource""该蒸了""该整理了"。

5.3 Service + Runtime 双进程结构

把 5.2 的归属直接推出 reme 的基本架构。两进程共享 L0-L4 全栈,只在 L5(进程入口)分叉:

┌──────────────────────────────────────────────────────────┐
│                      Reme System                         │
│                                                          │
│  ┌────────────────────┐      ┌────────────────────────┐ │
│  │  L5 Service        │      │  L5 Runtime            │ │
│  │  (HTTP / MCP)      │      │  (scheduler 自治)       │ │
│  │  服务 agent 请求:   │      │  服务 vault 健康:        │ │
│  │  · ingest          │      │  · notify(决策)        │ │
│  │  · sync            │      │  · digest              │ │
│  │  · retrieve        │      │  · maintain            │ │
│  │  · notify(MCP 推送)│      │                        │ │
│  └─────────┬──────────┘      └───────────┬────────────┘ │
│            │                              │              │
│            └──────────────┬───────────────┘              │
│                           ▼                              │
│   ┌──────────────────────────────────────────────────┐   │
│   │  L4 Action / L3 原子工具                          │   │
│   │  Action 编排 → 基础工具 + 高级工具                  │   │
│   └──────────────────────┬───────────────────────────┘   │
│                          ▼                               │
│   ┌──────────────────────────────────────────────────┐   │
│   │  L2 文件状态(file_store + file_graph + 自治)       │   │
│   └──────────────────────▲───────────────────────────┘   │
│                          │ 派生                          │
│   ┌──────────────────────┴───────────────────────────┐   │
│   │  L1 file_watcher(fs → state 的唯一桥)             │   │
│   └──────────────────────▲───────────────────────────┘   │
│                          │ 监听                           │
│   ┌──────────────────────┴───────────────────────────┐   │
│   │  L0 vault filesystem                             │   │
│   │  resource/    daily/    digest/                  │   │
│   └──────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────┘

两进程职责正交、共享 L0-L4 基础设施(详见 §6):

维度 L5 Service L5 Runtime
触发方式 请求-响应 + MCP server-initiated 推送 周期 + L2 自治状态阈值
服务对象 agent vault 自身
暴露给 agent 否(agent 不感知)
主要动作 ingest / sync / retrieve / notify 推送通道(MCP) notify 决策 / digest / maintain
与对端的耦合 通过 L2 推送队列读 notifier 产出 通过 L2 推送队列写,不直接调 Service

5.4 节奏(latency tolerance)

动作 节奏 latency 容忍
retrieve request-driven sub-second
ingest event-driven seconds
sync agent on-demand seconds
notify reactive(L2 资源状态变化后) seconds ~ minutes
digest reactive(状态变化后) minutes ~ hours(eventual consistency)
maintain periodic days(无紧迫)

实时性需求差三个数量级。这是 digest / maintain 必须放后台异步的根本原因 —— 不能阻塞 agent 的 retrieve / sync 请求。

5.5 排序约束与一致性模型

部分动作对不能并发,background runtime 内部要保证排序:

约束 原因
sync(同一 daily)→ digest(同一 daily) digest 不能看到 sync 半成品
digest(同一 scope)→ maintain(同一 scope) maintain 重组的拓扑不应被 digest 中途插入

ingest / retrieve 跟所有动作都可并发(纯入流 + 纯读)。

一致性模型 = Eventual consistency on digest/maintain。Agent 不能依赖"我刚写完 daily 就能查到对应 digest"。digest / maintain 都是后台异步,有可见的延迟窗口。

watcher 滞后契约(L0 ↔ L2):基础工具直接写 L0 文件系统,L2 文件状态由 L1 file_watcher 派生,二者之间存在 eventual 窗口 —— 写完一份 daily 后,search / traverse 这类走 L2 索引的高级工具不一定立刻能看到。这是设计意图,不是 bug:agent 本身有上下文窗口,近期信息靠 agent 自带的对话上下文承接,不依赖 reme 索引立即可见。需要"写后立刻可读"的场景请用基础工具(read 直接读 fs)。


6. 执行栈:六层结构

L3 原子工具、L4 Action、L5 进程都不直接操作文件系统。它们坐在 L0-L2 的底层基础上 —— 这套基础是 reme 的"动力源",决定了为什么上层能解耦成 Service + Runtime 两进程,且两者既正交又共享状态。

6.1 概念分层(L0 → L5)

┌──────────────────────────────────────────────────────────┐
│  L5  Service  ‖  Runtime                                 │
│        进程入口:Service 服务 agent;Runtime 自治维护     │
├──────────────────────────────────────────────────────────┤
│  L4  Action(6 类动作语义)                              │
│        ingest / notify / sync / retrieve / digest / maintain │
├──────────────────────────────────────────────────────────┤
│  L3  原子工具                                            │
│        基础工具(直接 fs) + 高级工具(走 L2 索引)      │
├──────────────────────────────────────────────────────────┤
│  L2  文件状态                                            │
│        file_store + file_graph + 自治状态(scheduler 用) │
├──────────────────────────────────────────────────────────┤
│  L1  file_watcher                                        │
│        fs event → state delta(唯一 fs→state 桥)         │
├──────────────────────────────────────────────────────────┤
│  L0  vault filesystem                                    │
│        resource/ + daily/ + digest/                      │
└──────────────────────────────────────────────────────────┘

数据流(主要关系):
  · L3 基础工具    ──写──►  L0
  · L3 基础工具    ──读──►  L0(无需经 L2)
  · L0 变化        ──►  L1 监听到  ──派生──►  L2 state delta
  · L3 高级工具    ──读──►  L2(走索引)
  · L4 Action      ──编排──►  L3 工具组合
  · L5 进程        ──触发──►  L4 Action
角色 关键约束
L0 vault 文件系统 唯一真相源;任何 L2 状态都可由 reindex 从 L0 重建
L1 file_watcher 唯一与 fs 事件直接耦合的组件;fs→state 的唯一派生桥
L2 文件状态(file_store + file_graph + 自治状态) 高级工具的读视图;由 L1 单向更新,L3+ 只读不写
L3 原子工具(基础 / 高级) 基础直读写 L0;高级只走 L2
L4 Action(6 类语义动作) N:M 编排 L3 工具;不直接碰 L0 / L2
L5 Service / Runtime 进程 共享 L0-L4 全栈,不直接通信,只通过 L0 / L2 状态间接耦合

6.2 L1 file_watcher:fs → state 的唯一桥

file_watcher 是 reme 唯一与 OS filesystem 事件直接耦合的组件。它把 fs 变化翻译为 L2 文件状态的 delta,承担双重职责:

filesystem events (create / modify / move / delete)
       │
       ▼
   file_watcher ─┬─► 索引同步:写完文件,L2 file_store/file_graph 自动更新
                 │     (L3 基础工具不需要显式调用"入索引")
                 │
                 └─► 自治状态派生:维护 scheduler 用的可推导状态
                       · resource: 入流批次 / 未消化(orphan) /
                                  推送状态(pending/notified/acknowledged)
                       · daily:   任务索引(进行中 / stale / 完成)
                       · digest:  密度水位 / 断链(broken wikilink)

关键设计:可派生的状态由 watcher 在外部索引中维护,不写回 frontmatter。L3 工具只管写内容文件,状态由 watcher 独立派生。这是 ✗-14 反例(L3 写 status 字段)成立的基础。

Acknowledge 派生例:notify 的"推送状态"由 watcher 维护 —— 当 watcher 检测到一条新 wikilink 从 daily 指向某 resource,即把该 resource 的推送状态从 notified 改为 acknowledged。notifier / Service 都不需要显式 ack。

6.3 L2 文件状态

组件 职责 由谁更新
file_store chunk 分块 + 向量持久化,提供 search / read API L1 watcher 派生
file_graph wikilink 有向图,提供 upsert / traverse(双向)API L1 watcher 派生
自治状态 scheduler 自治决策的输入(入流批次 / 任务索引 / 密度水位 / 断链) L1 watcher 派生
推送队列 notify 的待推送 / 已推送 / 已确认条目 notifier 写 pending;Service 推送后置 notified;L1 watcher 检测到 ack 后置 acknowledged

L2 只关心"vault 当前是什么样",无业务语义 —— 不知道 daily / digest / 动作语义的存在。L3+ 只读 L2,不写(例外:notifier 写推送队列,这是 Runtime 与 Service 之间唯一的间接耦合通道,见 F-5)。

现状提示:当前实现中 file_store / file_graph 之外的"自治状态"和"推送队列"尚不完整,这是 L1 watcher 与 notifier 待补齐的能力。完整化后 scheduler 才能从"周期扫描"切换为"事件驱动",notify 才能从隐式变为显式。

6.4 L3 原子工具:基础 vs 高级

两组工具的切分依据只有一条:是否必须经过 L2 索引

组别 工具 数据通路 一致性
基础工具 create / append / edit / read / write / move / delete / list / stat 直接对接 L0 写后立即可读(同一工具)
高级工具 search / traverse / frontmatter 必须走 L2 索引 受 watcher 滞后影响(eventual)

写路径全部走基础工具(L4 Action 编排基础工具完成写入)。高级工具是只读的索引查询入口。

eventual 窗口:基础工具写 L0 后,L2 索引由 L1 watcher 异步追平。在窗口内,高级工具看到的是滞后的视图。详见 §5.5"watcher 滞后契约"。

6.5 设计含义

# 不变量 推论
F-1 L1 file_watcher 是 L0 → L2 的唯一派生桥 状态一致性是 L1 的事;L3 工具不要"自己更新索引"
F-2 L3 基础工具直接读写 L0;L3 高级工具只走 L2 写路径无需"先 reindex";读路径接受 eventual
F-3 L0 是唯一真相源 任何 L2 状态都可由 reindex 从 L0 重建,L2 是缓存而非数据库
F-4 L4 Action 与 L3 工具是 N:M 编排关系 Action 不直接碰 L0 / L2
F-5 L5 Service 与 Runtime 共享 L0-L4 全栈,不直接通信 只通过 L0 / L2 状态间接耦合;一边崩了不影响另一边的读
F-6 L0 与 L2 之间存在 eventual 窗口 agent 上下文承担近期信息,不依赖 L2 立即可见(详见 §5.5)

7. L4 Action 模块映射

第 5 节列了 6 类 Action 及其触发源,本节把这些 Action 落到 L4 实现模块(架构角色,不指代源码路径);触发机制(on-demand 路径与 background 路径)见 §5.3。

7.1 五个 L4 模块

模块 实现动作 触发 LLM-driven 单一职责
ingester ingest External push / pull × 原样落 resource + 抽 frontmatter + 入索引
notifier notify Reme background(cron + L2 资源自治状态阈值) × 从 L2 资源自治状态选候选 → 写 L2 推送队列;Service MCP 拿走
synchronizer sync Agent on-demand 把当下事件织入 daily 工作叙事
dreamer digest Reme background resource + daily 双源合流成 digest 长期条目
maintainer maintain Reme background digest topic tree 的密度折叠(fold-only)

retrieve 不构成独立 L4 模块,理由见 §7.4。

三个 reme 自治模块:notifier(机械)、dreamer(LLM)、maintainer(LLM)。三者都由 scheduler 触发,都消费 L2 自治状态,但只有 notifier 是机械的 —— 候选选择不需要 LLM,LLM 决策在 agent 侧的 sync。

7.2 对称结构

                     跨表征层翻译                  结构性纪律
                     (LLM-driven)                 (机械)

  Inbound:                                        ingester
  Attention:                                      notifier
  Working:           synchronizer
  Sink:              dreamer
  Organization:      maintainer (fold-only)

五类不同方向的"翻译":

模块 翻译方向
ingester 外部异构格式 → vault 统一文件
notifier L2 资源自治状态 → agent 注意力(notify 推送)
synchronizer agent 事件流 → 工作过程叙事(写 hot)
dreamer 工作过程 + 原始资料 → 长期知识(双源合流,写 cold)
maintainer 散乱叶子 → 有层次的 topic tree(组织 cold)

ingester 和 notifier 是机械(确定性阈值/流水线);其它三个是 LLM 决策模块,各自跨越一层语义鸿沟。

7.3 Maintainer:Topic Tree 密度折叠

digest/ 整体视为一颗 topic tree:文件夹 = 中间节点,文件 = 叶子。Maintainer 唯一职责:随写入持续,某中间节点下叶子过密时,折叠为新的子中间节点 + 高密度摘要。

触发前:某中间节点叶子过多 / 太碎
  digest/infra/
  ├── logging.md
  ├── tracing.md
  ├── metrics.md
  ├── alerting.md
  ├── dashboards.md
  └── slo.md

折叠后:LLM 判断聚类,引入子中间节点 + 摘要
  digest/infra/
  ├── observability/              ← 新中间节点
  │   ├── _index.md               ← 新生成的高密度摘要
  │   ├── logging.md              ← 内容不变,只搬位置
  │   ├── tracing.md
  │   ├── metrics.md
  │   ├── alerting.md
  │   ├── dashboards.md
  │   └── slo.md
  └── ...(未被折叠的叶子原位)

设计承诺(在 maintain 通用不变量之上进一步收紧):

# 承诺 含义
M-1 Fold-only,无 merge / move / promote / demote / introduce 树只向下生长,从不反向
M-2 叶子内容 0 修改,只被搬位置 maintain 内容守恒一致
M-3 新中间节点带一个高密度摘要文件,读摘要就能决定要不要深入 折叠后可读性不降反升
M-4 每次只处理一个候选节点 最小化变更面
M-5 不能聚类时,不动(默认保守) 宁可不折,不要错折

LLM 唯一的决策点:

  1. 这些叶子能不能聚类(if not → 不动)
  2. 新中间节点叫什么、摘要怎么写

其它都机械:阈值判断(L1 file_watcher 派生 L2 自治状态提供信号)、移动文件(crud)、wikilink 重定向(graph/retarget)。

7.4 为什么没有 retriever 模块

L4 模块的存在条件 = "有跨原子编排 / 需要 LLM 决策"。Retrieve 不满足:

  • 三种问法(state / semantic / topological)各自被 L3 原子工具直接覆盖(list+filter / search / traverse)
  • 没有跨原子状态、没有 LLM 决策点
  • Agent 直接调用 L3 原子即可

8. 跨切面:Schema

Schema(资料的 frontmatter / wikilink / 章节约定)是横跨三层、各写动作的共同契约。reme4 的核心立场:

立场 说明
reme 核心只保留 name / description 两个字段 其它都是 opinionated convention,服务消费层可以替换
Schema 是"协议"不是"代码" 用 markdown 文字描述,LLM agent 自我约束;不内嵌 schema validator
三层共用同一套 wikilink 协议 全路径引用,无 short-link / no-ext 解析

8.1 协议文档(opinionated default)

内容 谁规定
目录结构(三层 + folder 单位) 第 2 节本文档
动作语义契约(notify / sync / digest / maintain 的输入产出不变量) 第 3 节本文档
Frontmatter 推荐字段(4 轴等) reme4/steps/jobs/protocol.md (opinionated)
章节约定(Objective/Plan/Progress/...) sync / digest 各自的 prompt(opinionated)

8.2 重载入口

服务消费层(plugin / 自定义 caller)无需 fork reme,可通过以下方式替换 schema:

入口 适用场景
替换 protocol 文档 改 frontmatter / wikilink / 章节约定
替换 prompt 模板 改 sync / digest 的决策流程
替换 toolkit 改 ReAct agent 可见的工具集

9. 反例:不属于本架构的设计

明确画出不允许的设计,免得后续讨论或扩展时滑回去:

# 反例 违反的不变量
✗-1 Agent 通过任意 verb 直接写 digest I-1(digest 写权只属 dreamer / maintainer)
✗-2 多 agent 并发改同一个 daily folder I-2(daily 单作者)
✗-3 任何动作改写 resource 的原文 I-3(resource immutable)
✗-4 跨层引用引入第二套机制(hash-id / external ref / SQL) I-4(wikilink 是唯一跨层载体)
✗-5 dreamer 改写 daily 正文 digest 不变量(§3.5)
✗-6 maintain 改写 daily / resource 的语义内容 maintain 不变量(§3.6)
✗-7 notify 维护 resource 上的 referenced_by 反指 notify 完全单向(§3.3)
✗-8 把 state / semantic / topological 合并成单一 read verb R-1
✗-9 Retrieve 自动 eager-expand provenance R-4
✗-10 digest / maintain 同步阻塞 agent 请求 5.4 节奏分级
✗-11 digest / maintain 强一致(agent 写完 daily 立即可查 digest) 5.5 eventual consistency
✗-12 maintainer 做 merge / move / promote / demote 等"通用重组" M-1(fold-only)
✗-13 maintainer 改写既有叶子的内容(不只是搬位置) M-2(叶子内容 0 修改)
✗-14 L4 模块在 frontmatter 里写 status / pending 等可派生状态字段 状态由 L1 file_watcher 派生到 L2 自治状态,L4 不重复
✗-15 为 retrieve 单设 L4 模块或聚合 verb §7.4(L3 原子已足够)
✗-16 notify 写入 vault(在 resource 上加 notified frontmatter 或新建 daily 占位) notify 只写 L2 推送队列,不落任何文件;ack 由 L1 watcher 检测 wikilink 派生
✗-17 Service 自决推什么 notify 候选 notify 决策在 Runtime(notifier);Service 只是 MCP transport,从 L2 推送队列读取(F-5)
✗-18 agent 主动调用 notify 想"标记这个 resource 我要看" notify 是 reme→agent 单向,反向是 agent 用 sync 写 wikilink(自然 ack)

附录:术语索引

术语 定义
resource/ 不可变原始资料层
daily/ agent 任务工作区层
digest/ 沉淀知识层
State 问 在某层做 list + 过滤的状态查询
Semantic 问 跨层全文/向量检索
Topological 问 沿 wikilink 走的拓扑查询
Provenance 下游节点反查到上游来源的能力
Retarget 节点移动时对所有入向 wikilink 的原子重写
L5 Service 服务 agent 请求的进程(HTTP / MCP);执行栈最上层;也是 notify 的 MCP transport
L5 Runtime 自治维护 vault 的进程;scheduler 在其中按 L2 自治状态阈值触发 background Action
L4 Action 6 类动作语义:ingest / notify / sync / retrieve / digest / maintain
L4 模块 实现 Action 的架构角色;五个:ingester / notifier / synchronizer / dreamer / maintainer(retrieve 不构成独立模块)
ingester L4 模块,机械:外部源原样落 resource + 抽 frontmatter + 入索引
notifier L4 模块,机械:从 L2 资源自治状态选 notify 候选 → 写 L2 推送队列;Service MCP 拿走推给 agent
synchronizer L4 模块,LLM-driven:agent 事件织入 daily 工作叙事;响应 notify 的也走这里
dreamer L4 模块,LLM-driven:resource + daily 双源合流为 digest 长期条目
maintainer L4 模块,LLM-driven,fold-only:digest topic tree 的密度折叠
scheduler L5 Runtime 内部触发器:按 cron + L2 自治状态阈值拉起 background L4 模块(notifier / dreamer / maintainer)
Topic tree digest/ 的心智模型:文件夹 = 中间节点,文件 = 叶子
Fold(密度折叠) maintainer 唯一操作:把过密叶子归簇到新子中间节点 + 写高密度摘要
L3 原子工具 基础(create/append/edit/read/write/move/delete/list/stat,直 fs)+ 高级(search/traverse/frontmatter,走 L2)两组
L2 文件状态 file_store + file_graph + 自治状态(resource 入流批次/orphan、daily 任务索引、digest 密度水位/断链)+ 推送队列;由 L1 派生(推送队列由 notifier 写)
L2 推送队列 notify 的 L2 状态条目;notifier 写 pending,Service MCP 推送后置 notified,L1 watcher 检测到 daily→resource wikilink 后置 acknowledged
L1 file_watcher fs event → L2 state delta 的唯一派生桥;承担索引同步 + 自治状态派生 + notify ack 派生
L0 vault filesystem 物理目录:resource/ + daily/ + digest/;唯一真相源
Eventual consistency digest / maintain 异步处理,有可见延迟窗口;L0↔L2 之间 watcher 滞后窗口同理
Opinionated default reme 提供的参考实现,服务层可替换