☰
OpenChronicle 记忆数据流全解:从 S1 解析到 FTS5 索引的 5 级压缩漏斗
2026/10/1 2:22:22 网站建设 项目流程

OpenChronicle 记忆数据流全解:从 S1 解析到 FTS5 索引的 5 级压缩漏斗

【免费下载链接】OpenChronicle项目地址: https://gitcode.com/gh_mirrors/op/OpenChronicle

OpenChronicle 是一个开源、本地优先的 AI Agent 记忆系统:它在 macOS 上持续捕获你的屏幕上下文(AX 可访问性树),通过一条5 级压缩漏斗把原始事件逐级压缩成可读的 Markdown 记忆,并最终建入SQLite FTS5 全文索引,让任意支持工具调用的 AI Agent 都能快速检索"你正在做什么、做过什么决定"。

🗺️ 一眼看懂:5 级压缩漏斗总览

整条数据流只有一条入口,没有多模式分支。每一级都只做一件事,输出有界、prompt 可控:

级别阶段输入 → 输出核心动作
1️⃣S0 分发 + S1 解析AX 事件流 → 结构化 JSON 捕获去抖、去重,提取focused_element/visible_text/url
2️⃣Timeline 归一化原始捕获 → 1 分钟时间块保字面归一化,剔除 UI 噪音
3️⃣会话切割 + S2 归约时间块 → 会话级日记条目按空闲/切换/超时切会话,5 分钟增量刷写
4️⃣Classifier 分类日记条目 → 结构化记忆文件提取持久事实,写入 user-/project-/person- 等文件
5️⃣FTS5 索引 + MCP 检索Markdown + 捕获 → 索引库BM25 全文检索,Agent 随时可查

官方对整体管线的完整描述见 docs/architecture.md,端到端流程图与运行时序列都在里面。

1️⃣ 第一级:S1 解析——把"屏幕事件"变成结构化上下文

macOS 的屏幕信号来自一个 Swift 编写的mac-ax-watcher二进制,它订阅所有应用的可访问性事件(窗口聚焦、输入值变化、标题变化),每个事件吐出一行 JSON。

原始事件像消防水带一样嘈杂,先要过S0 分发器(event_dispatcher.py)的四道时间闸:

旋钮默认值作用
debounce_seconds3.0s连续击键只触发一次捕获
dedup_interval_seconds1.0s同类型事件直接丢弃
min_capture_gap_seconds2.0s两次捕获的硬性最小间隔
same_window_dedup_seconds5.0s同窗口非聚焦事件折叠

之后才是真正的S1 解析(s1_parser.py)。它从庞大的 AX 树里只抽取下游 LLM 真正需要的三个字段:

  • focused_element—— 光标所在元素(你正在输入什么、选中了哪一行)
  • visible_text—— 屏幕上可见内容的 Markdown 渲染(上限约 10 KB)
  • url—— 从可见文本中正则提取的网址

这一步是"压缩"的关键起手:下游所有 LLM 阶段读的都是这三个字段,而不是动辄 200–400 KB 的原始 AX 树。捕获结果以{时间戳}.json写入~/.openchronicle/capture-buffer/,细节见 docs/capture.md。

2️⃣ 第二级:Timeline 时间块——1 分钟一格的"保真存档"

如果直接把原始捕获丢给归约器,prompt 预算瞬间爆掉。于是 Timeline 阶段(timeline/aggregator.py)每 60 秒扫描一次已关闭的整分钟窗口(对齐真实时钟,如[10:00, 10:01)),调用 LLM 把窗口内最多 30 条捕获归一化成一组活动记录:

[Notes] 购物清单: 用户起草清单,最新版本 "milk, eggs, flour, butter" [Chrome] ACME Q3 roadmap (https://docs.example/roadmap): 阅读文档,记录 Owner Alice

它的规则非常克制,核心是verbatim-preserving(保字面):

  • ✅ 用户亲手输入的文字、URL、窗口标题、专名——原样保留,绝不改写
  • ✅ 剔除 UI 框架噪音、折叠重复快照
  • ✅ 防幻觉:不同对话里的人/话题不得互相串供

时间块存入 SQLite 的timeline_blocks表(timeline/store.py),(start_time, end_time)唯一键保证幂等。设计动机完整解释见 docs/timeline.md。

3️⃣ 第三级:会话切割 + S2 归约——"一段专注工作"成为日记条目

人的记忆单位不是"事件",而是一段专注的工作(session)。session/manager.py 用三条规则切分会话:

规则条件(默认)直觉
🔪 硬切空闲超过 5 分钟你去吃饭了,会话在"停下来那一刻"结束
🪄 软切单个无关应用持续聚焦 3 分钟你转去看视频了(快速多应用切换时自动豁免)
⏰ 超时会话超过 2 小时兜底,防止会话失控

会话结束后,S2 归约器(writer/session_reducer.py)把时间范围内的所有时间块交给 LLM,压缩成一条带精确时间范围的日记条目,追加到当天的event-YYYY-MM-DD.md。

亮点在于增量刷写:长会话期间每 5 分钟就 flush 一次([flush]标记的条目),长工作不会被"先写后丢"地漏报——这正是 v1 逐捕获写入踩过的坑。会话状态机、重试队列(5/15/30/60/120 分钟退避)与书签机制(flush_end/classified_end)见 docs/session.md 和 docs/writer.md。

4️⃣ 第四级:Classifier 分类——从"活动日志"提炼"持久记忆"

活动日志回答"今天做了什么",但"用户换了新公司"、"Alice 是设计负责人"这类持久事实需要单独沉淀。

Classifier(writer/classifier.py)每 30 分钟(活跃会话中)加会话结束时各跑一轮,通过一个有上限(12 次迭代)的工具调用循环操作记忆库:

工具用途
read_memory/search_memory追加前先去重
append/create写入新事实
supersede事实变更时"划线取代",永不删除
commit结束本轮(无持久信号时直接空提交)

它默认偏向"什么都不做":纯粹的刷了 2 小时 Cursor 不算可分类事实。最终产出的是~/.openchronicle/memory/下一系列人类可读的 Markdown 文件——user-*.md、project-*.md、tool-*.md、topic-*.md、person-*.md、org-*.md。文件结构、supersede 语义、压缩(compact)保护机制见 docs/memory-format.md,完整记忆规范(也是 MCPget_schema返回的内容)在 prompts/schema.md。

5️⃣ 第五级:FTS5 索引——让记忆"秒级可查"

最后一级是检索。store/fts.py 里建了两套 FTS5 虚拟表,全部使用unicode61 remove_diacritics 2分词器(大小写不敏感、Unicode 友好):

索引表索引对象支撑的 MCP 工具
entries_fts压缩后的记忆条目(Markdown 层)search/list_memories/read_memory
captures_fts原始捕获的 S1 字段(visible_text、url…)search_captures/current_context

两层设计的妙处:压缩层答"我知道什么",原始捕获层答"屏幕上当时到底写了什么"。MCP 服务端明确教会 Agent 这个下钻路径——先查压缩层,查不到再搜原始层。

几个工程细节值得留意:

  • SQLite WAL 模式:MCP 读与写入方并存不互锁(paths.py 管理~/.openchronicle/index.db路径)
  • 触发器同步:captures表的插入/删除/更新由触发器自动同步进captures_fts,索引不漂移
  • 随时可重建:openchronicle rebuild-index从 Markdown 全量重建entries_fts,rebuild-captures-index同理——索引永远只是派生副本
  • Agent 入口:守护进程内置只读 MCP 服务(http://127.0.0.1:8742/mcp),Claude Code、Claude Desktop、Codex 等一次配置即可接入,详见 docs/mcp.md

💡 磁盘上你能看到什么

跑起来之后,一切状态都摊在~/.openchronicle/下,随手可查:

~/.openchronicle/ ├── capture-buffer/ # 第一级:S1 增强 JSON 捕获 ├── index.db # SQLite:timeline_blocks / sessions / FTS5 ├── memory/ # 第四、五级:Markdown 记忆 + 索引 │ ├── index.md # 自动生成的总览 │ ├── event-2026-04-22.md │ └── user-/project-/person-… .md └── logs/ # 每个阶段一份日志,方便排查

常用巡检命令:openchronicle status(守护进程状态)、openchronicle timeline list(看时间块)、openchronicle writer run(补跑未完成的会话)、openchronicle rebuild-index(重建 FTS5 索引)。

📌 小结:为什么是"漏斗"而不是"一把梭"

OpenChronicle 的数据流把"压缩"和"分类"刻意拆开:

  1. 每级 prompt 有界——S1 只给结构化字段,Timeline 只给 1 分钟窗口,S2 只给时间块,Classifier 看到的已是会话级摘要;
  2. 保真与压缩分层——用户亲手输入的文字在每一级都被"verbatim"保护,压缩的是 UI 噪音而非事实;
  3. 永不删除——记忆变更走 supersede 划线取代,FTS5 索引可随时从 Markdown 重建,整条链可审计、可手工修复。

想动手体验?安装只需 macOS 13+ 与 Xcode Command Line Tools,克隆仓库后执行bash install.sh再运行openchronicle start即可。更多配置与模型选择见 docs/config.md,遇到问题可查 docs/troubleshooting.md。

【免费下载链接】OpenChronicle项目地址: https://gitcode.com/gh_mirrors/op/OpenChronicle

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询