* feat(config): add jsonl support and update LLM integration tests - Added jsonl extension to supported extensions in chunked backend - Refactored LLM integration tests to use async functions instead of nested runs - Created helper functions _run_basic_chat, _run_with_tool, _run_structured_output, _run_structured_output_enum - Implemented _run_all function to execute all test scenarios sequentially - Updated main execution block to use asyncio.run with consolidated test runner - Maintained all original test functionality while improving code structure * feat(config): add dialog directory configuration and reorganize vault structure - Add new dialog_dir field for dialog memory storage - Reorder directory initialization sequence in application setup - Simplify vault_dir description in configuration schema - Update thread_pool_max_workers description to be more concise - Move resource_dir definition earlier in the configuration schema - Remove redundant text from digest_dir description * docs(reme): update design documentation with layered memory architecture - Replace quick test section with comprehensive layered memory structure - Add detailed explanation of three-tier memory organization (resource, daily, digest) - Document Obsidian-compatible Markdown format with YAML front matter - Describe four types of wikilink syntax and semantic linking features - Explain AST-aware semantic chunking for document parsing - Detail self-evolving system with auto-resource, auto-memory, and auto-dream - Document directory structure and lifecycle characteristics - Add comprehensive table showing content nature, triggers, and examples - Include semantic link extraction and knowledge graph formation processes - Describe automated indexing and relationship building workflows * docs(reme): update design documentation with simplified structure and clearer explanations - Simplified directory structure overview with cleaner formatting - Updated memory layering explanation with more concise descriptions - Improved table layouts for better readability - Clarified auto-resource, auto-memory, and auto-dream processes - Streamlined indexing and search mechanism descriptions - Enhanced component system documentation with clearer backend options - Refined job list with more precise functional descriptions - Modernized layout diagrams and process flows - Consolidated repetitive content while maintaining comprehensive coverage * docs(reme): add application scenario documentation for financial industry use case - Document comprehensive example of ReMe usage in新能源 industry research - Detail the week-long process of automatic knowledge graph construction - Explain the auto-memory and auto-dream pipeline with concrete examples - Describe the extract and integrate phases for creating wiki nodes - Illustrate cross-file linking through relates_to and derived_from predicates - Show progressive graph growth from daily sessions to complete ecosystem - Demonstrate hybrid retrieval with vector and keyword search capabilities - Provide detailed directory structure and file organization patterns - Explain the three-phase workflow: ingestion, processing, and retrieval - Document the financial analyst persona and their information management needs * style(config): fix spacing in thread_pool_max_workers field definition - Corrected spacing around description parameter in Field definition - Simplified multi-line assertion to single line in LLM integration test
13 KiB
auto-memory 设计(实时事件拆分 / 写入 daily)
本文档记录 reme4 中 auto-memory 的设计讨论 —— 把 agent 连续的对话 / 任务流切成离散的 daily 事件原子,inline 落到
daily/层。配套阅读:
structure.md§2.1-2.2(daily 层定位)/ §3.4(sync 动作语义)/ §7.1(synchronizer 模块)auto_dream_design.md:auto-memory 产物如何被 dream 消化(dream 读 daily 作为入流之一)auto_consolidate_design.md:digest 的组织端 / CAS 写入协议;auto-memory 不直接复用,但事件级"拆"与节点级 split 在概念上同构(都把过载粒度切小)auto_cognition_design.md:auto-cognition 三阶段顶层思想(写入 / 巩固 / 检索);daily 节点是 cognition 图视图的一部分(承载derived_from::反指),但不参与 Stage 2 巩固改造服务全景:reme 服务两条主线 —— auto-memory(本文档,入流端 / daily 写入)与 auto-cognition(顶层思想:写入 = auto-dream,巩固 = auto-consolidate,检索 = auto-recall)。auto-memory 把 agent 实时事件流切成 daily 事件原子;它的产物是 dream(cognition Stage 1)消化的两路输入之一(另一路是 resource)。
核心立场:auto-memory 是
structure.md§3.4sync动作的实现侧 —— 强调 inline 实时与事件边界检测。是不是改名 sync → auto-memory 留给上层文档对齐,本文档聚焦机制。
0. 问题陈述
agent 的对话与任务过程是连续事件流(用户回合、工具调用、上下文切换、中断恢复),但记忆系统需要离散的、可独立检索的事件单元。auto-memory 解决这个切分问题。
| 输入 | 输出 |
|---|---|
agent 当前事件流(对话回合 / 工具调用 / 任务切换信号);可选 notify 候选作为 cue |
daily/<date>/<event-slug>/<note>.md 事件原子;daily/<date>.md 主索引 |
设计目标:
- 事件边界尽量与 agent 语义意图一致 —— 同一个意图(同一个任务 / 同一段思路)→ 同一个事件;意图切换 → 新事件
- inline 实时写入 —— 不滞后,不批处理;agent 一边工作,记忆一边落地
- 保持 daily 写权契约 —— I-2 单作者(同 folder 不并发改);folder 名 = summary note 名(I-3 可移动单元)
显式排除(不属于 auto-memory 职责):
- ❌ 蒸馏 / 沉淀:那是 auto-dream(
auto_dream_design.md)的事 - ❌ 实体识别 / wikilink 自动补全:cognition 三阶段不在写入后做"事后补 wikilink"(详
auto_cognition_design.md§1.1);所有 wikilink 由 dream 在写入瞬间产出 - ❌ 改写 resource / digest:auto-memory 只写 daily(I-1 / I-3)
1. 已对齐决策
1.1 物理布局:与 structure.md §2.2 对齐
| 项 | 决策 |
|---|---|
| 主轴 | 时间 + 任务:daily/<date>/<event-slug>/ |
| event-slug | LLM 抽取的事件短名(snake_case / dash-case;不强制 schema),同 <date> 下唯一 |
| folder 内 | 一个事件可有 N 个 note(progress.md / decision.md / references.md 等),由消费层 schema 决定;最少含一个 summary note,与 folder 同名 |
| 主索引 | daily/<date>.md:当天事件列表(机械写入,wikilink 指向各 event folder) |
| 跨日索引 | 不强制;dream 消费时按 <date> 范围拉取即可 |
为什么不是单文件 event(report §5.1 一种简化方向):
- 单文件 event =
daily/<date>/<event-slug>.md比 folder 模型简单,但失去"一个事件可包含多个视角 note"的灵活度 - 现行
structure.md已定 folder 单位模型;auto-memory 沿用,不破坏既有 I-2 / I-3 - 若后续 dogfooding 验证单事件普遍只有一份 note,可演进为 folder 内只放一份 summary,机械上等价于单文件方案 —— 演进路径平滑,不需要现在选
1.2 事件边界:语义意图切换驱动
事件边界由 LLM 在 inline 写入时判:当前回合的意图是否仍属上一个 event。
| 维度 | 决策 |
|---|---|
| 决策时机 | 每个 agent 回合写入前 inline 判 |
| 决策依据 | 上一个 active event 的 summary + 当前回合内容;LLM 输出 {continue: bool, new_event_slug?: str, summary_patch?: str} |
| continue=true | append 当前回合到 active event(append-only 或 LLM 重写 summary,详 §1.3) |
| continue=false | 关闭 active event(写最终 summary)+ 开新 event folder(slug 由 LLM 给) |
| 同时 active 多事件 | 不允许(I-2 单作者)—— 一时刻只一个 active event;真要并行任务,agent 自己 sync 切换 |
已排除:
- 时间窗口切分(N 分钟无活动则切)—— 对话节奏因任务而异,时间窗口噪声大
- 关键词切分(出现"切换 / 现在做 X"等触发词)—— 假阳性高,且不所有切换都明显说出
- 后置 batch 切分 —— inline 写入要求 event 必须当下可决定归属,不能等
1.3 事件内写入模型
active event 内,每个回合的内容写到 event folder 下,有两种模式可选(消费层 schema 决定):
| 模式 | 形态 | 适用 |
|---|---|---|
| append-only | 一份 <event-slug>.md,新回合 append 到末尾(章节 / 时间戳 / 等) |
实现最简;事件短(< 几十回合)时可读性 OK |
| 多 note 重写 | summary note(folder 同名)+ 各视角 note(progress.md / decision.md);LLM 把新内容融到对应 note,summary note 重写为当下概览 |
事件长 / 多视角时可读性高;LLM 成本高 |
默认 opinionated default:append-only(最简启动)。消费层可改 prompt + schema 走多 note。
与 E-1 守恒的关系:daily 不强制 E-1 守恒(它是工作记录,允许 LLM 删旧加新);只在 multi-note 重写模式下,可选启用类似守恒(保留所有 wikilink),具体由消费层决定。
1.4 主索引 daily/<date>.md
当天事件 list 视图,机械维护(无需 LLM):
| 触发 | 操作 |
|---|---|
| 新建 event folder | 主索引 append 一行 `[[daily///.md |
| 事件关闭(被切下一个 event) | 主索引该行 append 最终 summary 摘要(可选,LLM 写最终 summary 时附带写入) |
| 索引文件不存在 | 写入第一个 event 时创建 |
主索引仅承担当天浏览锚点:文件系统 ls daily/<date>/ 也能看见,但有主索引人/agent 可直接 read daily/2026/05/28.md 拿到 list 视图 + summary 一览。
不维护跨日索引(daily/2026/05.md 或 daily.md):dream 消费时按时间范围拉取即可;list daily/<date>/ 已经覆盖浏览需求。
1.5 与 notify 的协作
notify 是 reme → agent 的虚边推送(structure.md §3.3),把"有新 resource 值得看"传递给 agent。auto-memory 在以下两点与 notify 协作:
| 维度 | 协作方式 |
|---|---|
| 新事件 cue | agent 收到 notify 后,如果决定响应(开始处理这个候选),通常会触发新 event —— auto-memory 把 notify payload 作为 hint(候选 resource 路径)写入新 event 的 summary,顺手用 wikilink 引上 |
| acknowledge 派生 | event note 里出现指向 [[resource/...]] 的 wikilink → L1 watcher 将该 resource 推送状态置 acknowledged(structure.md §3.3 / §6.2);auto-memory 自身不调任何 ack API |
关键约束:auto-memory 不强制 agent 用 wikilink 引 notify 候选 —— agent 可能略过、也可能不通过 wikilink 而是直接读 resource。ack 是 daily → resource wikilink 的副产品,不是 auto-memory 显式负责的事。
2. 待对齐边界点
2.1 LLM 决策频率与成本
inline 边界检测的最朴素形态是每回合调一次 LLM。在长对话 + 高频回合下成本可观。可选优化:
- continue 假设默认:大多数回合是 continue(同一意图内),LLM 可能只在"看似切换"启发(token 跨度大 / 工具种类突变 / 用户显式说"接下来")时跑;否则默认 continue 不调 LLM
- 批回合:每 N 回合批一次,延迟切分(代价:active event 边界滞后,首版可接受)
首版默认每回合调一次(最简,正确率高),M1+ 视成本优化。
2.2 中断恢复 / 跨进程 active event
agent 进程重启 / Service 重启后,如何识别"还有 active event"?
候选方案:
- L2 自治状态:L1 watcher 派生
daily/<date>/<event-slug>/中最新 mtime 的 event 为 active(默认 N 分钟内有写入) - 状态文件:
.daily-active维护 active event slug,Service 启动时读 - 每次重建:agent 进程重启视为新 event,旧的关闭(切到 §1.2 continue=false 路径)—— 最简但会增加事件数
倾向 §1.2 自然路径(进程重启 = LLM 下次判 continue=false 概率高)+ 不维护状态文件,详细 worker recovery 留给 Service 实现。
2.3 多 agent 同 vault 的 active event 隔离
I-2 daily 单作者契约在多 agent 场景下需细化。候选:
- per-agent date subfolder:
daily/<date>/<agent-id>/<event-slug>/ - 单 agent 模式 + agent ID 进 event-slug:
<date>/<agent-id>_<event-slug>/
第二种破坏 slug 短名习惯;第一种引入额外层级。倾向后者作为消费层契约,reme 核心不固化。
2.4 事件粒度的 prompt 引导
边界检测的 prompt 决定切分粒度。粗 = event 大 / dream 看每个 event 时容易 overflow;细 = event 数爆炸 / 主索引拥挤。
opinionated default prompt 倾向:
- 一个意图 = 一个事件(用户提了 X 问题 / agent 开了 Y 任务 → 直到这个意图收尾)
- 跨意图的"附带工作"(查资料 / 算个数)归入当前意图,不开新 event
- 真新意图("好,现在我们做下一件事")才切
详细 prompt 落 reme4/steps/jobs/protocol.md 或 synchronizer 的 prompt 模板。
2.5 与 resource ingest 的时序
如果 ingest 与 auto-memory 同时活跃(External push 推 resource 进来 + agent 在 sync),且 agent 想响应这个新 resource:
- ingest 写完 resource → L1 watcher 派生 L2 → notifier 决策推送(
structure.md§5.3)→ Service MCP 推给 agent - agent 在当前回合或下一回合响应 → auto-memory 判 continue=false 开新 event,wikilink 引上 resource
整条链 sub-second 到 seconds(notify 节奏);auto-memory 不直接知道 ingest,只在 agent 决定响应时被动接收 notify payload。
2.6 跨日任务延续
event 物理路径含日期(daily/<date>/<event-slug>/),同一意图跨日的任务无法用同一 event folder 承载。候选模型:
| 模式 | 形态 | 适用 |
|---|---|---|
| 每日新 event,wikilink 反指前日 | new day 起新 folder;summary note frontmatter 加 inherits: [[daily/<prev-date>/<prev-slug>/<prev-slug>.md]];新 event body 不复制旧内容,仅引用 |
event-slug 短,日切口干净;查 backlinks 拼出整条任务链 |
| 同 event 重复写不同日 | 不允许(I-2 single author + event folder date 在路径上,跨日写违反路径不可变) | × |
| 任务 ID 跨 daily 抽象 | 引入 task-id 维度,daily event 只是某 task 的某一日切片;额外维护 task index |
复杂度高,M0 不引入 |
倾向:第一种(inherits frontmatter wikilink)—— 与 §1.4 主索引一致(机械维护),实现侧 LLM 在 §1.2 boundary 判定时若发现意图与最近 N 天某个 active 任务一致,直接写入 inherits 即可。详细 boundary prompt 落 §2.4。
INHERIT 行为细节(扫描窗口、predecessor 是否关闭、Plan/Objective 是否拷贝)归消费层 schema 决定;reme 核心只承认 inherits: frontmatter wikilink 作为跨日链路载体。
3. 与其它层的协作
| 上下游 | 关系 |
|---|---|
| ← notify | 接收 notify payload 作为新 event cue;不强制响应,不强制 wikilink 引 |
| ← resource | 只读(通过 wikilink 引);不写 |
| → daily | 唯一写者(I-2);写 event folder + 主索引 |
| → auto-dream | dream 读 daily 作为入流(auto_dream_design.md §4.2 dream scope);auto-memory 写完即对 dream 可见(走 L2 索引,有 eventual 窗口) |
| → auto-cognition (三阶段) | daily 节点是 cognition 图视图的一部分;dream(Stage 1)读 daily 作为入流;consolidate(Stage 2)只对 digest 节点跑 dups / community / decay,不改 daily;recall(Stage 3)三层并行召回时 daily 也参与命中 |
关键边界:auto-memory 是 daily 写入端的唯一入口;cognition 三阶段没有任何子阶段会事后改写 daily(无写回路径)。daily 一旦由 auto-memory 写完,就只被读不被改(I-2 / I-3 仍守);后续 dream / consolidate / recall 都是只读消费。
4. 下一步
- synchronizer step 实现:event 边界检测 prompt + active event 状态管理 + inline 写入(append-only 默认)
- 主索引维护:
daily/<date>.md机械维护(新 event 时 append、关闭时附 summary)—— 走 crud/daily 基础工具 - notify ack 派生验证:L1 watcher 派生 acknowledged 状态(
structure.md§6.2),与 auto-memory 的 wikilink 写入端到端跑通 - 多 agent 隔离 schema(M1+):若实际有并发 agent,确定 daily 子目录 / slug 命名约定
- 粗 / 细粒度 prompt 调参:dogfooding 后看实际 event 数 / dream 消化效率,调 boundary prompt
实现进入 reme4/steps/jobs/ 与 reme4/file_graph/ 时,本文档与 auto_dream_design.md / auto_cognition_design.md 共同作为契约依据。