mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-09-22 00:32:49 +00:00
up
This commit is contained in:
parent
cec7131a5c
commit
d71e01d79f
5 changed files with 0 additions and 1265 deletions
|
|
@ -1,256 +0,0 @@
|
|||
# ReMe V4 能力报告 · 文档大纲
|
||||
|
||||
> 面向受众:Leader / 决策者
|
||||
> 叙事视角:「未来 ReMe 长什么样」 —— 以产品愿景与最终用户体验为主线,
|
||||
> 不区分已实现 / 未实现,将在建能力作为完整版图的一部分自然描述。
|
||||
|
||||
---
|
||||
|
||||
## 一、引言:为什么要做 V4
|
||||
|
||||
### 1.1 个人知识/记忆为什么是 Agent 时代的关键基建
|
||||
- Agent 不只是「工具调用」,更是「带着上下文长期陪伴用户」的角色。
|
||||
- 行业里大模型能力快速趋同,但**用户专属上下文**(个人知识库、工作记忆、长期偏好)才是差异化的护城河。
|
||||
- 当前业界(Memo / Mem0 / Letta 等)方案普遍存在三个问题:黑盒不可读、不可移植、缺乏自进化。
|
||||
|
||||
### 1.2 ReMe V4 的一句话定位
|
||||
> **ReMe 是一个以本地 Markdown 为载体、可被 Agent 读写、可自进化、可被任意 Harness 框架接入的个人知识与记忆引擎。**
|
||||
|
||||
### 1.3 V3 → V4 的关键升级
|
||||
- 从「只是把对话存下来」 → 「会主动整理、会自己长出新结构」
|
||||
- 从「单一向量检索」 → 「向量 + 关键词 + 图谱 多模检索」
|
||||
- 从「ReMe 内置 Agent」 → 「ReMe 作为能力被 qwenpaw / Claude Code / 其它 Harness 接入」
|
||||
- 从「sqlite/chroma 等三方依赖」 → 「自研轻量内核,跨平台稳定」
|
||||
|
||||
---
|
||||
|
||||
## 二、产品全景图
|
||||
|
||||
### 2.1 一张图看 ReMe V4
|
||||
|
||||
> 这一节用一张概念图收束全篇,建议绘制:
|
||||
>
|
||||
> ```
|
||||
> ┌─────────────────────────────────────────────────────────┐
|
||||
> │ 外部 Agent / Harness │
|
||||
> │ qwenpaw · Claude Code · Cursor · 其它 │
|
||||
> └──────────┬──────────────┬───────────────┬───────────────┘
|
||||
> │ SDK │ MCP Tool │ CLI / skill.md
|
||||
> ┌──────────▼──────────────▼───────────────▼───────────────┐
|
||||
> │ ReMe Service Layer │
|
||||
> │ HTTP / MCP / CLI · 服务发现 · 进程托管 │
|
||||
> ├──────────────────────────────────────────────────────────┤
|
||||
> │ ReMe Job/Step 编排 │
|
||||
> │ search · auto_memory · auto_dream · auto_link … │
|
||||
> ├──────────────────────────────────────────────────────────┤
|
||||
> │ Markdown 知识内核(本地文件即数据库) │
|
||||
> │ FileParser · FileStore · FileGraph · FileWatcher │
|
||||
> │ BM25 倒排 · 向量索引 · Wiki Link 图谱 │
|
||||
> ├──────────────────────────────────────────────────────────┤
|
||||
> │ 文件目录约定 │
|
||||
> │ resource/ · daily/ · knowledge/ · proactive/ │
|
||||
> └──────────────────────────────────────────────────────────┘
|
||||
> ```
|
||||
|
||||
### 2.2 三个最直观的故事场景
|
||||
- **金融分析师**:每天盘后聊行情,ReMe 自动把对话拆成事件笔记,按产业链聚成知识库;下次问「钴的下游应用」时,能从历史对话中渐进式展开相关上下文。
|
||||
- **个人工作助理**:日常 Slack/邮件/会议讨论沉淀为 daily 笔记,ReMe 在空闲时自动整理为按主题归档的 knowledge 库。
|
||||
- **AI Agent 框架接入**:开发者在 qwenpaw / Claude Code 中只要安装 ReMe,Agent 就立刻拥有「长期记忆 + 个人知识检索」的能力,无需改 Agent 代码。
|
||||
|
||||
---
|
||||
|
||||
## 三、记忆模型:ReMe 把什么存下来
|
||||
|
||||
### 3.1 四类记忆分层
|
||||
| 类型 | 存什么 | 典型场景 |
|
||||
| --- | --- | --- |
|
||||
| **Resource(原始资料)** | 原始对话日志、上传的文件、网页 HTML | 溯源 / 审计 / 二次加工 |
|
||||
| **Daily(日记记忆)** | 每天的事件性记忆,主 Agent 实时写入 | 「我今天和谁聊了什么」「今天工作内容」 |
|
||||
| **Knowledge(知识记忆)** | 主题化、结构化的长期知识 | 「光伏产业链」「我的工作框架」 |
|
||||
| **Proactive(主动推送)** | Agent 给用户的分析、推荐、心路历程 | 主动提醒、复盘建议 |
|
||||
|
||||
> **重点表达**:ReMe 不是把对话一股脑塞进数据库,而是让记忆**像人脑一样有层次** —— 短期日记、长期知识、原始素材、主动洞察各司其职。
|
||||
|
||||
### 3.2 目录约定(用户可读、可备份、可迁移)
|
||||
- `resource/` — 原始素材
|
||||
- `daily/YYYYMMDD.md` — 当天主索引(兼容主 Agent 的 write/edit 工具)
|
||||
- `daily/YYYYMMDD/{event}.md` — 当天拆分出的事件笔记
|
||||
- `knowledge/{topic}/{xxx}.md` — 主题化整理后的知识
|
||||
- `proactive/YYYYMMDD.md` — Agent 主动产出的建议与分析
|
||||
|
||||
> **重点表达**:所有记忆都是普通 Markdown 文件,用户随时可以用 Obsidian 打开、用 Git 备份、跨设备同步、迁移到任何机器。**没有黑盒数据库,没有锁定。**
|
||||
|
||||
### 3.3 三种记忆的覆盖
|
||||
- **个性化记忆** — 用户的偏好、习惯、个人事件
|
||||
- **程序化记忆** — Agent 完成任务的过程性经验(工作流模板、失败教训)
|
||||
- **知识类记忆** — 客观知识、领域参考资料
|
||||
|
||||
---
|
||||
|
||||
## 四、记忆的自进化(核心差异化)
|
||||
|
||||
> 这是 V4 最重要的一节,决定了 ReMe 能不能真正长期陪伴用户。
|
||||
|
||||
### 4.1 Auto-Memory:实时拆事件
|
||||
- 主对话进行时,ReMe 把上下文按「事件」自动拆分,写入 `daily/YYYYMMDD/{event}.md`。
|
||||
- 同时在 `daily/YYYYMMDD.md` 维护主索引,让所有事件可被反向追溯。
|
||||
- 体验:用户不需要手动整理,ReMe 替他做日记的「分章节」。
|
||||
|
||||
### 4.2 Auto-Dream:空闲整理
|
||||
- Agent 空闲时(夜晚 / 用户离开),ReMe 主动把 daily 笔记按主题、实体重新整理到 `knowledge/{topic}/`。
|
||||
- 类比人在睡眠中做的「记忆巩固」。
|
||||
- 体验:用户第二天打开知识库,会发现昨天散落的对话已经按「客户/项目/学习」自动归档。
|
||||
|
||||
### 4.3 Auto-Link:自动建图
|
||||
- 后台任务自动从正文里识别实体、候选链接,把隐式关系写回 wikilink。
|
||||
- 例如:在「光伏产业链」笔记里提到「隆基」,ReMe 自动补 `[[隆基]]` 链接到对应主题笔记。
|
||||
- 体验:随着使用时间增长,知识库自动「越长越密」,浏览时可以从任意一处跳转到相关全部上下文。
|
||||
|
||||
### 4.4 三者协同:从对话到知识图谱的自然演化
|
||||
> 用一张时间轴图说明:原始对话 → daily 事件 → knowledge 主题 → graph 链接,
|
||||
> 整个过程**不需要用户操心**。
|
||||
|
||||
---
|
||||
|
||||
## 五、检索体验:多模检索 + 渐进式展开
|
||||
|
||||
### 5.1 三路融合的混合检索
|
||||
- **向量检索**:语义层面的相似度
|
||||
- **关键词检索(BM25)**:精确匹配,对中文友好
|
||||
- **图谱检索**:通过 wikilink 邻居展开
|
||||
- 三路结果通过 RRF 排序融合,避免单一检索的盲区。
|
||||
|
||||
### 5.2 渐进式展开
|
||||
- 第一跳:直接命中的笔记
|
||||
- 第二跳:链接邻居(outlinks/inlinks)
|
||||
- 第 N 跳:Agent 按需要主动「再看一层」
|
||||
- 体验:检索像「翻知识网络」,而不是「拉一坨切片塞进上下文」。
|
||||
- 价值:上下文窗口永远只装最相关的部分,token 利用率高。
|
||||
|
||||
### 5.3 关键词索引的工程价值
|
||||
- 中文关键词检索(jieba 分词 + 自研 BM25 增量倒排)
|
||||
- 旧版 sqlite/chroma 在 Linux/Win 老系统会 core dump → V4 用纯 Python + 文件落盘,**跨平台零依赖**。
|
||||
|
||||
---
|
||||
|
||||
## 六、Markdown 内核:把文件当数据库
|
||||
|
||||
### 6.1 Obsidian 兼容的 Markdown 格式
|
||||
- YAML front matter(标题/标签/描述)
|
||||
- 4 种 wikilink 写法:`[[X]]` / `[[X#anchor]]` / `[[X|alias]]` / `![[X]]`
|
||||
- Dataview 风格的语义关系:`predicate:: [[X]]`
|
||||
- 标准 `[text](xxx.md)` 链接也会被识别为图边(计划中)
|
||||
|
||||
### 6.2 比 RAG 更聪明的切片
|
||||
- 解析 Markdown AST,按章节嵌套切分
|
||||
- 每个 chunk 自带**完整的标题骨架**(TOC),保留层级上下文
|
||||
- 检索回来的片段,Agent 一眼就能看出「这段在哪个章节、什么主题下」
|
||||
|
||||
### 6.3 Graph 索引:双向链接
|
||||
- 正向:A → B(A 引用了 B)
|
||||
- 反向:B ← {A, C, D}(谁引用了 B)
|
||||
- 三种 backend:本地 dict / NetworkX / Neo4j,按规模与可视化需求切换
|
||||
|
||||
---
|
||||
|
||||
## 七、工程架构:可扩展、可替换、可演进
|
||||
|
||||
### 7.1 Component 框架
|
||||
- 所有能力封装为 Component(embedding / file_store / file_graph / parser / watcher / tokenizer / index / LLM 适配 / service / client)
|
||||
- 支持 backend 热切换:`local` ↔ `nx` ↔ `neo4j` 一行配置改完
|
||||
- 生命周期托管:start / close / restart 全自动
|
||||
- 拓扑依赖解析:组件间相互调用,按依赖图自动启动
|
||||
|
||||
### 7.2 Job / Step 编排(借鉴 GitHub Actions)
|
||||
- **Step**:最小执行单元,调用 components 完成一件事
|
||||
- **Job**:steps 的有序组合,可复用、可流式
|
||||
- **对外**:每个 Job 可同时暴露为 HTTP API / MCP Tool / CLI 命令
|
||||
|
||||
### 7.3 配置即应用
|
||||
- 一份 `default.yaml` 描述完整应用:service / components / jobs
|
||||
- 替换 backend、增删 Job、调整依赖,全部通过配置完成
|
||||
- 部署上线无需改代码
|
||||
|
||||
---
|
||||
|
||||
## 八、生态接入:ReMe 如何被使用
|
||||
|
||||
### 8.1 三种集成路径
|
||||
| 路径 | 适用对象 | 体验 |
|
||||
| --- | --- | --- |
|
||||
| **SDK 集成** | qwenpaw / AgentScope 等深度合作框架 | 直接调用 `AgentscopeTools`,无感拥有 auto-memory/auto-dream/auto-search |
|
||||
| **MCP Tool** | 任何支持 MCP 的客户端(Claude Code / Cursor / Cherry Studio) | 配 skill.md,开箱即用 |
|
||||
| **CLI + skill.md** | 通用方案,兜底所有 Harness | 一条命令调用,shell 友好 |
|
||||
|
||||
### 8.2 服务托管
|
||||
- Agent 可以「按需拉起」后台 ReMe 服务,无需用户提前启动
|
||||
- 服务发现机制:`find_reme` 一键探活,避免端口冲突
|
||||
|
||||
### 8.3 ReMe 的边界
|
||||
> ReMe **专注于知识加工,不做知识获取**。
|
||||
> 数据采集、网页抓取、邮件接入、Slack 同步等,由上游 Agent 完成;
|
||||
> ReMe 负责把这些资料**消化、整理、链接、检索**。
|
||||
|
||||
---
|
||||
|
||||
## 九、应用场景
|
||||
|
||||
### 9.1 金融场景:产业链知识库
|
||||
- 输入:研报、调研纪要、新闻、对话讨论
|
||||
- 产出:按「产业链 → 公司 → 产品」组织的知识图谱
|
||||
- 体验:分析师问「锂电下游有哪些应用」,ReMe 沿着图谱渐进展开,回答既具体又有上下文。
|
||||
|
||||
### 9.2 个人工作 & 生活
|
||||
- 输入:日常对话、会议记录、学习笔记、思考片段
|
||||
- 产出:daily 流水 + knowledge 主题库 + proactive 主动建议
|
||||
- 体验:使用三个月后,知识库自然形成个人「第二大脑」。
|
||||
|
||||
### 9.3 Agent 长期陪伴
|
||||
- Agent 跨会话记得用户偏好、过往任务、失败教训
|
||||
- 任务复用:相似任务自动召回过去的程序化记忆作为参考
|
||||
|
||||
---
|
||||
|
||||
## 十、性能与稳定性
|
||||
|
||||
### 10.1 自研轻量内核
|
||||
- 重写 file parser / file store / file graph / file watcher
|
||||
- 自研增量 BM25 倒排索引,支持中文
|
||||
- 纯 Python + 文件持久化,无 sqlite/chroma 等三方依赖
|
||||
|
||||
### 10.2 跨平台稳定性
|
||||
- 解决 V3 在 qwenpaw 等低版本 Linux/Win 的 core dump 兼容问题
|
||||
- 老旧环境也能跑
|
||||
|
||||
### 10.3 未来:Rust / C++ 高性能内核
|
||||
- 当前 Python 版本已能覆盖个人规模知识库(万级文件)
|
||||
- 规划用 Rust/C++ 重写关键路径,支撑更大规模与更低延迟
|
||||
|
||||
---
|
||||
|
||||
## 十一、Roadmap:未来 6–12 个月
|
||||
|
||||
| 阶段 | 关键里程碑 |
|
||||
| --- | --- |
|
||||
| **Now** | 组件框架、Job/Step、Markdown 内核、混合检索、HTTP/MCP 服务(已就绪) |
|
||||
| **Next** | auto-memory / auto-dream / auto-link、记忆类型分层、resource/proactive 目录、skill.md 模板、qwenpaw SDK 集成 |
|
||||
| **Later** | 多跳渐进检索 API、领域 demo(金融产业链)、个人场景模板、Rust 内核 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、结语:ReMe 想成为什么
|
||||
|
||||
> ReMe 不止是「记忆库」。
|
||||
> 它的目标是:**让每个用户拥有一份属于自己的、可携带的、可自进化的、可被任意 Agent 调用的知识身份。**
|
||||
>
|
||||
> 当 Agent 时代真正到来时,差异化的不是模型,而是「这个 Agent 是不是了解我」。
|
||||
> ReMe 想做的,就是这份「了解」的载体。
|
||||
|
||||
---
|
||||
|
||||
## 附:建议补充材料
|
||||
|
||||
- 一张系统架构图(基于 §2.1 的 ASCII 图重绘为正式图)
|
||||
- 一张 auto-memory / auto-dream / auto-link 的时序图
|
||||
- 一张知识库三个月「自动生长」的演示截图(Obsidian Graph View)
|
||||
- 一段 30 秒 Demo 视频脚本:用户说一句话 → ReMe 自动拆事件 → 第二天看到归档好的知识库
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
# Distiller 设计方案 (v3)
|
||||
|
||||
## 1. 角色定位
|
||||
|
||||
**Distiller = 知识蒸馏器**:从 Synchronizer 写下的 `daily/<date>/<slug>/`
|
||||
工作区,提取实体/概念/论断/方法,沉淀到 `knowledge/<slug>/`,
|
||||
让主 Agent 通过 Retriever (search / graph:traverse) 反哺 Hot Context。
|
||||
|
||||
冷写侧:与 Synchronizer (热写,daily 工作区) 互补,与 Retriever (读)
|
||||
形成"对话 → 工作区 → 知识库 → 召回"闭环。
|
||||
|
||||
| 维度 | Synchronizer (热) | **Distiller (冷)** | Retriever (读) |
|
||||
|---|---|---|---|
|
||||
| 触发 | 每次对话/会话 | 显式调用 | 主 Agent 查询时 |
|
||||
| 输入 | 对话 messages | `daily_paths` 列表 | query string |
|
||||
| 输出 | `daily/<date>/<slug>/` | `knowledge/<slug>/` | 检索结果 |
|
||||
| 改 daily? | 写 daily 本身 | 只翻 `status: distilled` | - |
|
||||
|
||||
---
|
||||
|
||||
## 2. 与 reme4 现状的对齐
|
||||
|
||||
- 路径用 reme4 已配置的 `application_config.knowledge_dir = "knowledge"` (单数)
|
||||
- Frontmatter 用 `lint:schema` 已要求的 4 key (`title/lifecycle/scope/source/role`) + 现有 `_VALID_STATUS = active/distilled/archived`
|
||||
- **不新增** `schema/memory_axes.py` 或 preset Python 类 — 协议在 `protocol.md` 用文字承诺
|
||||
- **不内嵌** schema validator — 让 LLM 写完后主动调 `lint:schema` 自查
|
||||
|
||||
---
|
||||
|
||||
## 3. 物理形态
|
||||
|
||||
```
|
||||
<vault>/
|
||||
daily/<YYYY-MM-DD>/<slug>/<slug>.md Synchronizer 写
|
||||
daily/<YYYY-MM-DD>/<slug>/<material>.md sibling materials
|
||||
↓ Distiller 读
|
||||
knowledge/<slug>/<slug>.md Distiller 写 (folder note)
|
||||
knowledge/<slug>/<material>.md (可选,蒸馏过程拆出的子事实)
|
||||
```
|
||||
|
||||
`knowledge/<slug>/<slug>.md` 是 folder note,符合 reme4 path_resolver
|
||||
的 folder-note 规则,主 Agent 写 `[[<slug>]]` 即命中。
|
||||
|
||||
---
|
||||
|
||||
## 4. Frontmatter Schema (4 轴,文字约定)
|
||||
|
||||
详见 `protocol.md`。要点:
|
||||
|
||||
| key | 取值 |
|
||||
|---|---|
|
||||
| `lifecycle` | `streaming` (会衰减) / `evolving` (持续编辑) / `frozen` (不可改) |
|
||||
| `scope` | `instance` (具体) / `class` (抽象) |
|
||||
| `source` | `auto` (机器) / `curated` (人/LLM) / `derived` (推算) |
|
||||
| `role` | `profile` / `concept` / `claim` / `method` / `reference` / `observation` / `question` / `fundamentals` |
|
||||
|
||||
knowledge/ 常见组合:
|
||||
|
||||
| 用途 | role | lifecycle | scope | source |
|
||||
|---|---|---|---|---|
|
||||
| 人/项目/工具 | profile | evolving | class | curated |
|
||||
| 抽象概念 | concept | evolving | class | curated |
|
||||
| 论断 | claim | evolving | class | curated |
|
||||
| 做法 | method | evolving | class | curated |
|
||||
| 资料 | reference | frozen | instance | auto |
|
||||
|
||||
---
|
||||
|
||||
## 5. R-M-W 三段
|
||||
|
||||
### Read
|
||||
1. 取 `daily_paths` (必须显式传入,**不自动扫描**全 vault)
|
||||
2. 对每个 daily,只 read `<slug>.md` (summary note);material 文件由 LLM 按需 read
|
||||
3. 不预扫现有 knowledge — LLM 在 M 阶段按需 lookup (`list`/`graph:traverse`/`tags:list`)
|
||||
|
||||
### Modify (LLM Agent + Toolkit)
|
||||
LLM 接到打包好的 daily 内容 + protocol.md + caller hint,执行决策树:
|
||||
|
||||
```
|
||||
for each candidate (entity / concept / claim / method) in daily:
|
||||
lookup [[candidate]] # via list / graph:traverse / tags:list
|
||||
├ no hit → CREATE knowledge/<slug>/<slug>.md
|
||||
├ exact role match → UPDATE: read → merge → write overwrite=True
|
||||
├ role mismatch → CREATE new knowledge with correct role
|
||||
└ only relation → LINK: 追加 wikilink 到现有 knowledge body
|
||||
```
|
||||
|
||||
特别约束:
|
||||
- 写完后调一次 `lint:schema` 拿违规清单,用 `property:update` 修
|
||||
- 所有写成功的 daily 翻 `property:update status=distilled` (若 `flip_status=True`)
|
||||
|
||||
### Write
|
||||
- LLM 直接调 `write` / `property:update`
|
||||
- **Distiller 不内嵌校验**,`lint:schema` 兜底
|
||||
- IO 失败进 `DistillResult.failed[]`,不阻断后续 op
|
||||
|
||||
---
|
||||
|
||||
## 6. Toolkit (LLM 可见)
|
||||
|
||||
| 类 | 工具 |
|
||||
|---|---|
|
||||
| 读 | `list` `read` `stat` `property:read` |
|
||||
| 搜 | `tags:list` `tags:stat` (search_step 暂无 tool method 绑定) |
|
||||
| 图 | `graph:traverse` |
|
||||
| 质检 | `lint:dangling` `lint:collisions` `lint:schema` |
|
||||
| 写 | `write` `property:update` `property:delete` |
|
||||
|
||||
`upload` / `download` / `lint:orphans` / `search_step` 不暴露
|
||||
(`search_step` 是 step 但没暴露 tool method,等需要时再加 wrapper)。
|
||||
|
||||
---
|
||||
|
||||
## 7. 输入/输出契约
|
||||
|
||||
### Input (RuntimeContext)
|
||||
|
||||
```python
|
||||
daily_paths: list[str] # 必填; 无默认扫描
|
||||
hint: str = "" # caller 偏好 (e.g. "重点关注 auth")
|
||||
flip_status: bool = True # 处理完是否翻 daily 为 distilled
|
||||
```
|
||||
|
||||
无默认扫描 = 成本可控;批量调度由外层 wrapper step (如果需要) 负责。
|
||||
|
||||
### Output (DistillResult)
|
||||
|
||||
```python
|
||||
class DistillResult(BaseModel):
|
||||
used_llm: bool
|
||||
skipped: bool = False # daily_paths 为空 / 无 LLM / 全失败
|
||||
|
||||
daily_read: list[str] = [] # 实际读到的 daily
|
||||
|
||||
knowledge_written: list[dict] = [] # [{path, size}] — 写在 knowledge/ 下,CREATE+UPDATE 合并
|
||||
links_added: list[dict] = [] # [{src, dst, predicate}] — 暂留空,等结构化 audit
|
||||
status_flipped: list[str] = [] # daily paths flipped to distilled
|
||||
|
||||
failed: list[dict] = [] # tool call 失败
|
||||
summary: str = "" # LLM 一段话总结
|
||||
```
|
||||
|
||||
字段命名用单数 `knowledge_*` 对齐 `knowledge_dir`。
|
||||
`knowledge_written` 一栏合并 CREATE+UPDATE — audit 不携带"是否覆盖"信号,
|
||||
caller 需要可借文件系统二次区分。
|
||||
|
||||
---
|
||||
|
||||
## 8. 闭环
|
||||
|
||||
```
|
||||
对话 ──► Synchronizer ──► daily/<date>/<slug>/ (status=active)
|
||||
│
|
||||
▼
|
||||
Distiller.execute(daily_paths=[...])
|
||||
Read → Modify (LLM) → Write
|
||||
│
|
||||
┌─────────────┼─────────────────────────┐
|
||||
▼ ▼ ▼
|
||||
CREATE knowledge UPDATE knowledge LINK (追加 wikilink)
|
||||
│ │ │
|
||||
└─────────────┼─────────────────────────┘
|
||||
▼
|
||||
lint:schema (LLM 自查)
|
||||
│
|
||||
▼
|
||||
property:update status=distilled (闭环, flip_status=True 时)
|
||||
│
|
||||
▼
|
||||
主 Agent ──► search / graph:traverse ──► 反哺 Hot Context
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 降级路径
|
||||
|
||||
**无**。蒸馏强依赖 LLM (state-align / merge / 决策都不可降级)。
|
||||
无 `as_llm` 时:
|
||||
- `DistillResult.used_llm=False, skipped=True`
|
||||
- `failed[]` 写一条 `{op: "distill", error: "no as_llm configured..."}` 提示 caller
|
||||
|
||||
旧 v1 的 `_degraded` (无 LLM 时按 `target_path` mechanical 落盘) 删除 —
|
||||
单点写入是 `crud:write` 的职责,不是 distiller 的。
|
||||
|
||||
---
|
||||
|
||||
## 10. 与 v1 (旧 ingestor) 的差异
|
||||
|
||||
| 维度 | v1 (Ingestor) | v3 (Distiller) |
|
||||
|---|---|---|
|
||||
| 命名 | 数据采集语义 | 知识蒸馏语义 |
|
||||
| 角色 | SSOT 写入入口 | 知识蒸馏器 |
|
||||
| 输入 | `content` + `target_path` | `daily_paths: list[str]` |
|
||||
| 输出域 | 任意单文件 | `knowledge/` 域 + flip daily status |
|
||||
| schema 校验 | 无 | LLM 自查 `lint:schema` |
|
||||
| 降级路径 | mechanical 写 target_path | 无 (强依赖 LLM) |
|
||||
| Toolkit | crud + property + graph + tags + lint | 同 + `lint:schema` 暴露 |
|
||||
| 闭环 | 无 | flip daily `status=distilled` |
|
||||
|
||||
---
|
||||
|
||||
## 11. 不在本次范围
|
||||
|
||||
- **Maintainer** (merge / split / decay) — 独立服务,按 cron / 阈值触发
|
||||
- **`schema/memory_axes.py`** preset Python 类 — 待 vault 域足够稳定后再固化
|
||||
- **Synchronizer** — 不动,只读它的输出
|
||||
- **自动调度** — distiller 不感知阈值,caller 决定何时/对哪些 daily 调用
|
||||
|
||||
---
|
||||
|
||||
## 12. 改动文件
|
||||
|
||||
```
|
||||
reme4/steps/jobs/
|
||||
├── distiller.py R-M-W 三段, DistillResult
|
||||
├── distiller.yaml system_prompt 角色 + {protocol}/{daily_blob}/{hint}
|
||||
├── distiller.md 本文档 (设计 SSOT)
|
||||
└── protocol.md 4 key + 决策树 + wikilink + flip 协议
|
||||
```
|
||||
|
||||
tests:
|
||||
```
|
||||
tests4/unittest/test_jobs_steps.py
|
||||
- test_distiller_skipped_when_no_dailies
|
||||
- test_distiller_skipped_when_no_llm
|
||||
- test_distill_result_default_fields
|
||||
- test_distill_result_success_property
|
||||
- test_classify_audit_entry_buckets
|
||||
- test_pack_daily_*
|
||||
```
|
||||
|
|
@ -1,489 +0,0 @@
|
|||
# 🧠 AI 记忆系统
|
||||
|
||||
## 核心架构理念:Memory as Code (记忆即代码)
|
||||
|
||||
1. **文件即真理 (SSOT):** 物理存在的 Markdown 文件(及其 YAML 头部)是系统中**唯一**存储记忆原始状态的地方。
|
||||
2. **只读投影 (Read-only Projections):** 图数据库 (Graph DB) 和向量数据库 (Vector DB) 不再是独立存储介质,而是文件系统的"下游索引/缓存",完全由文件 `Change` 事件被动驱动刷新。
|
||||
|
||||
> **状态约定:** 各章节标题后括号 `[已实现 / 部分实现 / 未实现]` 反映 reme4 当前代码。未实现部分保留设计原文,后续讨论再固化。
|
||||
|
||||
---
|
||||
|
||||
## 全局架构蓝图 (Global Architecture Blueprint)
|
||||
|
||||
系统按职责自上而下分 **5 层** + **1 跨切面 (Schema)**:
|
||||
|
||||
| Layer | 模块 | 角色 | 是否含 LLM |
|
||||
|---|---|---|---|
|
||||
| 1 | Agent (Claude Code) | 上层应用,持 Hot Context / Warm Summary / Loaded Memory | LLM (主) |
|
||||
| 2 | Plugin / MCP 接口层 | reme-service 与 reme-expert 两个 tier 暴露 MCP 工具 + 钩子 + 子代理 | (子代理含 LLM) |
|
||||
| 3 | 服务层 (`reme4/steps/jobs/`) | LLM-driven 复合工作流:Synchronizer / Distiller / Maintainer [未] | LLM (内部 ReAct) |
|
||||
| 4 | 原子工具层 (`reme4/steps/{crud,property,tags,lint,graph,daily,common}/`) | 无 LLM 的纯文件/索引/工作区操作,**被 Layer 2 / Layer 3 / Layer 2 子代理三方共享** | — |
|
||||
| 5 | 核心引擎 (`reme4/components/`) | file_store (MFS) + watcher + parser + 投影 (vector/keyword/graph),域无知 | — |
|
||||
| ▭ | Schema (`reme4/steps/jobs/protocol.md` + `lint/schema.py` + `schema/file_front_matter.py`) | 跨切面契约:4 轴 + R-M-W 决策树 + 后置 validator + 开放 dict 模型 | — |
|
||||
|
||||
```plain
|
||||
==============================================================================
|
||||
【 Layer 1: Agent (Claude Code / 上层应用) 】
|
||||
==============================================================================
|
||||
[ Session 工作台 ]
|
||||
- Hot Context: 原始对话滑动窗口
|
||||
- Warm Summary: Agent 后台维护的认知进度
|
||||
- Loaded Memory: 检索注入的底层快照
|
||||
↕ 通过 MCP 唯一接触面
|
||||
==============================================================================
|
||||
【 Layer 2: Plugin / MCP 接口层 (双 tier) 】
|
||||
==============================================================================
|
||||
┌──── reme-service ─────────────┐ ┌──── reme-expert ────────────────┐
|
||||
│ 26 MCP tools: │ │ 24 MCP tools (仅原子,无 L3): │
|
||||
│ ┌ [L3] synchronizer │ │ │
|
||||
│ └ [L3] distiller │ │ │
|
||||
│ ├ [L4] 24 shared atomic │ │ ┌ [L4] 24 shared atomic │
|
||||
│ └ │ │ └ │
|
||||
│ │ │ │
|
||||
│ Hooks: PreCompact / SessionEnd │ │ Hooks: 同左 │
|
||||
│ Stop (active_daily_check)│ │ │
|
||||
│ │ │ Subagents (LLM 跑在 Claude Code,│
|
||||
│ (无 subagent / slash) │ │ 通过 MCP 调 L4): │
|
||||
│ │ │ reme-distiller (R-M-W loop) │
|
||||
│ │ │ reme-curator (lint sweep) │
|
||||
│ │ │ │
|
||||
│ │ │ Slash: /reme-distill │
|
||||
│ │ │ /reme-recall │
|
||||
│ │ │ /reme-clean │
|
||||
└────────────────────────────────┘ └─────────────────────────────────┘
|
||||
│ MCP 直调 L3 + L4 │ subagent 通过 MCP 调 L4
|
||||
▼ ▼
|
||||
==============================================================================
|
||||
【 Layer 3: 服务层 (reme4/steps/jobs/) — LLM-driven 复合工作流 】
|
||||
==============================================================================
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌────────────────────────┐
|
||||
│ Synchronizer │ │ Distiller │ │ Maintainer [未实现] │
|
||||
│ (热写 / Log) │ │ (冷写 / Distill)│ │ (治理:Decay/Merge/Split)│
|
||||
│ ───────── │ │ ───────── │ │ ───────── │
|
||||
│ in: messages │ │ in: daily_paths │ │ in: cron / threshold │
|
||||
│ 内部 ReActAgent │ │ 内部 ReActAgent │ │ out: 覆写 MFS │
|
||||
│ + toolkit │ │ + toolkit │ │ │
|
||||
│ → daily/<date>/ │ │ → knowledge/ │ │ │
|
||||
│ <slug>/.md │ │ <slug>/.md │ │ │
|
||||
│ │ │ + status flip │ │ │
|
||||
│ │ │ + lint:schema │ │ │
|
||||
│ │ │ 自查 │ │ │
|
||||
└─────────────────┘ └─────────────────┘ └────────────────────────┘
|
||||
│ ReActAgent 内部 toolkit 调 L4 │ (未来)
|
||||
▼ ▼
|
||||
==============================================================================
|
||||
【 Layer 4: 原子工具层 (reme4/steps/{crud,property,tags,lint,...}/) 】
|
||||
无 LLM,纯文件 / 索引操作
|
||||
==============================================================================
|
||||
┌──────────┬──────────────┬──────────────┬──────────┬──────────────────┐
|
||||
│ Retrieve │ Read │ Write │ Tags │ Lint │
|
||||
│ ──────── │ ────────── │ ────────── │ ──────── │ ────────── │
|
||||
│ search │ list │ write │ tags_list│ lint_dangling │
|
||||
│ graph_ │ read │ property_ │ tags_stat│ lint_orphans │
|
||||
│ traverse│ stat │ update │ │ lint_collisions │
|
||||
│ │ property_read│ property_ │ │ lint_schema │
|
||||
│ │ │ delete │ │ │
|
||||
├──────────┴──────────────┴──────────────┴──────────┴──────────────────┤
|
||||
│ File ops: move copy delete upload download │
|
||||
│ Daily: daily:read daily:list daily:write daily:status │
|
||||
└──────────────────────────────────────────────────────────────────────┘
|
||||
│ 所有原子工具走 file_store / file_graph / indexes
|
||||
▼
|
||||
==============================================================================
|
||||
【 Layer 5: 核心引擎 (reme4/components/) — 域无知 】
|
||||
==============================================================================
|
||||
┌──────────────┐ ┌──────────────────┐ ┌────────────────────────┐
|
||||
│ file_store │ → │ file_watcher + │ → │ Projections │
|
||||
│ (MFS, SSOT) │ │ file_parser │ │ (只读,可整体重建) │
|
||||
│ ───────── │ │ ───────── │ │ ───────── │
|
||||
│ Local/... │ │ lite watcher │ │ embedding_model │
|
||||
│ markdown + │ │ + md parser │ │ (向量索引) │
|
||||
│ YAML + │ │ AST 分块 + hash │ │ keyword_index │
|
||||
│ wikilinks │ │ diff → 仅 dirty │ │ (BM25 + tokenizer) │
|
||||
│ 接受所有写入 │ │ block 触发投影 │ │ file_graph │
|
||||
│ │ │ 快路线 [√] │ │ (Local/Nx/Neo4j) │
|
||||
│ │ │ 慢 LLM IE [未] │ │ │
|
||||
└──────────────┘ └──────────────────┘ └────────────────────────┘
|
||||
|
||||
══════════════════════════════════════════════════════════════════════════════
|
||||
◄═══════ Schema (跨切面契约,非"层") ═══════►
|
||||
══════════════════════════════════════════════════════════════════════════════
|
||||
reme4/steps/jobs/protocol.md — 4 轴 (lifecycle/scope/source/role)
|
||||
+ R-M-W 决策树 + wikilink 约定 (单一源)
|
||||
│
|
||||
├── Layer 2 transclude: plugin SKILL.md / subagent agent.md
|
||||
├── Layer 3 inject: distiller.yaml 内 {protocol} 占位符
|
||||
└── Layer 4 enforce: lint:schema 后置校验 (必填 4 key + status enum)
|
||||
|
||||
reme4/schema/file_front_matter.py — Pydantic 开放 dict 模型 (extra=allow)
|
||||
Python preset 类 (EVENT_PRESET / ...) [未实现] — 等 vault 域稳定再固化
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 层间数据流 (Read Path / Write Path)
|
||||
|
||||
```
|
||||
写路径 (例: Distill phase, service tier)
|
||||
─────────────────────────────────────────
|
||||
L1 Agent
|
||||
└─ MCP call distiller(daily_paths=[...]) [Layer 2 入口]
|
||||
└─ Layer 3 Distiller.execute
|
||||
└─ 内部 ReActAgent 通过 toolkit
|
||||
├─ L4 read / list / graph_traverse (调研)
|
||||
├─ L4 write / property_update (落盘)
|
||||
└─ L4 lint_schema (自查)
|
||||
└─ Layer 5 file_store (MFS 物理写)
|
||||
└─ Layer 5 file_watcher (扫到 mtime/hash 变化)
|
||||
└─ Layer 5 投影刷新 (vector/keyword/graph)
|
||||
|
||||
读路径 (例: Recall phase)
|
||||
─────────────────────────────────────────
|
||||
L1 Agent
|
||||
└─ MCP call search(query=...) / graph_traverse(path=...) [Layer 2 入口]
|
||||
└─ Layer 4 search_step / graph:traverse
|
||||
└─ Layer 5 Projections (查 embedding + BM25 + file_graph)
|
||||
▲
|
||||
│ 原文按需 crud:read 回 Layer 5 file_store
|
||||
│
|
||||
◄─ FileChunk[] 返回 Agent
|
||||
```
|
||||
|
||||
**关键不变量:** Agent 永远只看到 Layer 2 (MCP);Layer 5 永远只看到文件;Layer 3 和 Layer 4 之间用相同的 toolkit 抽象 — Layer 3 是 LLM 编排,Layer 4 是 LLM 自动机里的"动作"。
|
||||
|
||||
---
|
||||
|
||||
## 核心约束
|
||||
|
||||
1. **MFS 即真理 (Layer 5 不可绕过)** — Vector / Keyword / File Graph 都是 Layer 5 的下游投影,可整体重建;任何写都必须先落 MFS,再由 Watcher 异步重建投影。
|
||||
2. **引擎域无知 (Layer 5 不依赖 Schema)** — frontmatter 在 Layer 5 永远是开放 dict (`FileFrontMatter.model_config = extra="allow"`)。换 vault 形态 (代码笔记 / 日记 / 文献库) = 换 Schema 协议 + Layer 3 服务,Layer 5 一行不动。
|
||||
3. **Schema 是单一权威 (跨切面)** — 4 轴在 protocol.md 文字约定;新增记忆形态 = 在 protocol.md 加新组合,行为代码 (`lint:schema` / Distiller 决策树) 从轴上读取。Python preset 类未实现,以文字约定先行。
|
||||
4. **Layer 4 是共享子结构** — 同一批原子工具 (`search` / `graph_traverse` / `crud:*` / `property:*` / `tags:*` / `lint:*`) 被三方消费:Layer 3 ReAct 内部 toolkit、Layer 2 MCP 直接暴露、Layer 2 expert 子代理通过 MCP。**不存在为某一方独立实现**。
|
||||
5. **Layer 2 双 tier 分裂只在 Layer 3 暴露与否** — reme-service 把 Layer 3 当 MCP 工具直接暴露 (LLM 跑在 reme4),reme-expert 不暴露 Layer 3,改用子代理跑同一套 Layer 4 (LLM 跑在 Claude Code)。Layer 4 / 5 / Schema 完全相同。
|
||||
|
||||
---
|
||||
|
||||
## Layer 详解
|
||||
|
||||
### Layer 1: Agent (Claude Code) [外部]
|
||||
|
||||
主 LLM 应用,持有会话工作台。reme 不感知其内部状态;仅通过 Layer 2 MCP 接收读/写请求。
|
||||
|
||||
会话工作台三种内存槽:
|
||||
- **Hot Context** — 原始对话滑动窗口 (主 LLM 自管)
|
||||
- **Warm Summary** — Agent 自行维护的进度摘要 (主 LLM 自管)
|
||||
- **Loaded Memory** — 通过 Layer 2 检索回填的底层快照 (frontmatter + graph edges + blocks)
|
||||
|
||||
---
|
||||
|
||||
### Layer 2: Plugin / MCP 接口层 [已实现,双 tier]
|
||||
|
||||
唯一 Agent 接触面。两个 tier 共享 Layer 4,只差是否暴露 Layer 3 + 是否带子代理:
|
||||
|
||||
| 维度 | reme-service | reme-expert |
|
||||
|---|---|---|
|
||||
| MCP 工具数 | 26 (2 L3 + 24 L4) | 24 (仅 L4) |
|
||||
| Layer 3 暴露 | ✅ synchronizer + distiller | ❌ |
|
||||
| 子代理 | (无) | reme-distiller / reme-curator |
|
||||
| Slash | (无) | /reme-distill /reme-recall /reme-clean |
|
||||
| Hooks | PreCompact / SessionEnd / Stop | 同左 |
|
||||
| LLM 跑在 | reme4 (Layer 3 内部 ReActAgent) | Claude Code (子代理) |
|
||||
| 认知负担 | 低 (复合工作流交给 L3) | 高 (子代理用 L4 拼装 R-M-W) |
|
||||
|
||||
详见 `reme-plugin/README.md` 与各 plugin 的 SKILL.md。
|
||||
|
||||
---
|
||||
|
||||
### Layer 3: 服务层 (reme4/steps/jobs/) [部分实现]
|
||||
|
||||
LLM-driven 复合工作流。每个 job 在内部 `ReActAgent` 里编排 Layer 4 原子工具,完成单次"高语义"操作。
|
||||
|
||||
#### Synchronizer (热写 / Log phase) [已实现]
|
||||
|
||||
- **输入:** `messages: list[Msg|dict]`, `workspace: str?`
|
||||
- **职责:** 从对话切片中决定 slug、写 `daily/<YYYY-MM-DD>/<slug>/<slug>.md` summary note + sibling materials;同 slug 复用 = upsert 累积。
|
||||
- **关键不变量:** 不写 `knowledge/`;不调 `lint:schema` 自查 (热路径,延迟敏感)。
|
||||
|
||||
#### Distiller (冷写 / Distill phase) [已实现]
|
||||
|
||||
- **输入:** `daily_paths: list[str]`, `hint: str?`, `flip_status: bool = True`
|
||||
- **职责:** 把 daily 蒸馏成 knowledge node,完成 R-M-W 闭环。详见下一节。
|
||||
|
||||
#### Maintainer (治理) [未实现]
|
||||
|
||||
整服务尚未建模。设计意图见 [后台自演化算法](#后台自演化算法-maintenance--evolution-未实现) 章节。占位的物理路径已统一:写入仍走 Layer 5 file_store,行为对齐 Layer 3 其他 job 的 ReAct 模式。
|
||||
|
||||
---
|
||||
|
||||
### Layer 4: 原子工具层 (reme4/steps/{crud,property,tags,lint,graph,daily,common}/) [已实现]
|
||||
|
||||
无 LLM,纯文件/索引操作。所有 step 经 `R.register(...)` 注册,可被 Layer 2 暴露为 MCP 工具、被 Layer 3 ReActAgent 内部 toolkit 调用、或被 Layer 2 子代理通过 MCP 调用 — **同一份实现,三方共享**。
|
||||
|
||||
| 类 | 注册名 | 主要 step |
|
||||
|---|---|---|
|
||||
| Retrieve | `search_step` `graph:traverse` | RRF 混合检索 / 1-hop 图扩展 |
|
||||
| Read | `list` `read` `stat` `property:read` | 文件读 + 属性读 |
|
||||
| Tags | `tags:list` `tags:stat` | 标签聚合 / 按标签拉文件 |
|
||||
| Write | `write` `property:update` `property:delete` | 文件写 + 属性更新 |
|
||||
| File ops | `move` `copy` `delete` `upload` `download` | 文件搬移 / 复制 / 删除 + vault ↔ 本地 fs 双向传输 |
|
||||
| Daily | `daily:read` `daily:list` `daily:write` `daily:status` | 工作区 CRUDS:单个 workspace 一次读完 / 按日期+状态列表 / upsert 写入 (默认 frontmatter 自动) / 状态机迁移 |
|
||||
| Lint | `lint:dangling` `lint:orphans` `lint:collisions` `lint:schema` | 4 种诊断 |
|
||||
|
||||
详见 [检索与召回算法](#检索与召回算法-retrieval--recall) 章节 (search + graph_traverse 的现状与未实现 RAG pipeline)。
|
||||
|
||||
---
|
||||
|
||||
### Layer 5: 核心引擎 (reme4/components/) [已实现]
|
||||
|
||||
域无知。任意 markdown vault 都能跑,不知道 Daily / Knowledge 是什么。
|
||||
|
||||
```
|
||||
file_store (MFS) → file_watcher + file_parser → Projections
|
||||
───────────── ───────────────────────────── ──────────
|
||||
Local/... lite watcher embedding_model (vector)
|
||||
markdown + YAML md parser (wikilink/Dataview) keyword_index (BM25)
|
||||
SSOT, 接受所有写 AST 分块 + hash diff file_graph (Local/Nx/Neo4j)
|
||||
快路线 [√] / 慢 LLM IE [未]
|
||||
```
|
||||
|
||||
详见 [存储与投影算法](#存储与投影算法-storage--projection) 章节。
|
||||
|
||||
---
|
||||
|
||||
### Schema (跨切面) [部分实现]
|
||||
|
||||
横跨 Layer 2 / 3 / 4 的契约。文字优先,Python 类后置。
|
||||
|
||||
| 资产 | 路径 | 角色 |
|
||||
|---|---|---|
|
||||
| `protocol.md` (单一源) | `reme4/steps/jobs/protocol.md` | 4 轴 + R-M-W 决策树 + wikilink 约定 |
|
||||
| Pydantic 模型 | `reme4/schema/file_front_matter.py` | 开放 dict (`extra=allow`),仅 title/description/tags 类型化 |
|
||||
| 后置 validator | `reme4/steps/lint/schema.py` | 必填 4 key (`title/lifecycle/scope/source/role`) + status enum |
|
||||
| Python preset 类 [未实现] | — | EVENT_PRESET / PROFILE_PRESET 等;等 vault 域稳定再固化 |
|
||||
|
||||
`protocol.md` 三方消费:
|
||||
- **Layer 2 transclude:** plugin SKILL.md 与 subagent agent.md 用 `@../../protocol.md`
|
||||
- **Layer 3 inject:** `reme4/steps/jobs/distiller.yaml` 把它注入 `{protocol}` 占位符 → 进 ReActAgent sys_prompt
|
||||
- **Layer 4 enforce:** `lint:schema` 在写后扫描,Distiller 自调修复
|
||||
|
||||
**4 个驱动行为的轴:**
|
||||
|
||||
| key | 取值 |
|
||||
|---|---|
|
||||
| `lifecycle` | `streaming` (会衰减,daily) / `evolving` (持续编辑,knowledge) / `frozen` (不可改) |
|
||||
| `scope` | `instance` / `class` |
|
||||
| `source` | `auto` (机器) / `curated` (人/LLM) / `derived` (推算) |
|
||||
| `role` | `observation` / `claim` / `question` / `profile` / `concept` / `method` / `reference` / `fundamentals` |
|
||||
|
||||
**Role-conditional 字段 (protocol.md 约定,目前 lint:schema 未全部强制):**
|
||||
- `role=claim` → `confidence` (✅ / ⏳ / ❌) 推荐
|
||||
- `lifecycle=streaming` → `status` (active / distilled / archived) 强制
|
||||
- `source=auto` → `originSessionId` [未实现]
|
||||
|
||||
---
|
||||
|
||||
## Distiller 的 R-M-W 认知循环 [已实现]
|
||||
|
||||
> 本节为 Layer 3 中 Distiller 的实际行为。Distiller 在 reme4 中曾叫 Ingestor,已重命名以对齐"知识蒸馏"语义。
|
||||
|
||||
Distiller 接收到 `daily_paths` 后,不是直接写文件,而是严格执行一个**闭环的 LLM 推理过程**:
|
||||
|
||||
### 读阶段 (Read - 上下文感知)
|
||||
- Distiller 拿到 `daily_paths` (由 caller 显式传入,**不自动扫描**全 vault)。
|
||||
- 对每个 `daily/<date>/<slug>/`,优先读 summary note (`<slug>.md`);material 文件 (pdf/csv/...) 由 LLM 按需 read。
|
||||
- **不预扫现有 knowledge** — LLM 在 Modify 阶段按需用 Layer 4 的 `list` / `graph_traverse` / `tags_list` 查找相关知识节点。
|
||||
|
||||
### 修阶段 (Modify - LLM 认知裁决)
|
||||
- Distiller 将【打包好的 daily 内容】+【protocol.md】+【caller hint】一并提交给 ReActAgent。
|
||||
- **LLM 的核心任务:状态对齐与消除冗余**
|
||||
- **发现冲突:** `knowledge/项目X.md` 写着"使用 JS 开发",新 daily 说"用 TS 重构"。LLM 覆写该状态,而不是在文件末尾追加矛盾的话。
|
||||
- **合并同类项:** `knowledge/张三/张三.md` 有"擅长前端",LLM 将新事件提炼为"主导项目X的 TS 重构",归入"项目经验"段落下。
|
||||
- **决策树:**
|
||||
- no hit → CREATE `knowledge/<slug>/<slug>.md`
|
||||
- exact role match → UPDATE: read → merge → write overwrite=True
|
||||
- role mismatch → CREATE 新 knowledge node,与原节点 cross-link
|
||||
- 仅关系值得记录 → LINK: 追加 wikilink 到现有 knowledge body
|
||||
|
||||
### 写阶段 (Write - 物理落盘)
|
||||
- LLM 直接调 Layer 4 的 `write` / `property_update` 工具,逐条落盘。
|
||||
- **写后自查:** Distiller 让 LLM 主动调 `lint:schema` 拿违规清单,用 `property:update` 修。Distiller 本身**不内嵌** Schema validator。
|
||||
- **闭环 flip:** 所有 writes 成功的 daily,LLM 调 `property:update status=distilled` 翻状态。
|
||||
- 落盘完成,触发 Layer 5 的 Watcher 去更新向量和图谱投影。
|
||||
|
||||
### 与 Synchronizer (热写) 的分工
|
||||
|
||||
| 维度 | Synchronizer (热写 / Log) | Distiller (冷写 / Distill) |
|
||||
|---|---|---|
|
||||
| 触发 | 每次会话 / 任务结束 | 显式调用,batch 处理 |
|
||||
| 输入 | 对话 messages | `daily_paths: list[str]` |
|
||||
| 输出 | `daily/<YYYY-MM-DD>/<slug>/` workspace | `knowledge/<slug>/` knowledge node |
|
||||
| 改 daily? | 创建 / 更新 daily summary | 只翻 `status: distilled` |
|
||||
| Schema 校验 | 无 (待补 pre-write hook) | LLM 自查 `lint:schema` |
|
||||
|
||||
---
|
||||
|
||||
## 存储与投影算法 (Storage & Projection)
|
||||
|
||||
> 对应 **Layer 5** 实现细节。被动投影,核心算法的重点在 **File Parser** 上。
|
||||
|
||||
### 向量的增量投影 (Incremental Embedding) [已实现]
|
||||
+ **AST Markdown 语义分块:**
|
||||
|
||||
当文件变更时,Parser 通过解析 Markdown 抽象语法树 (AST),以标题 `##`、段落 `\n\n` 为界提取 Block。
|
||||
|
||||
+ **Hash Diff 计算算法:**
|
||||
1. 系统为文件的每一个 Block 计算哈希值 (如 MD5)。
|
||||
2. 对比变更前后文件的 Block Hash 列表。
|
||||
3. **仅对 Hash 发生改变或新增的 Block (Dirty Blocks)** 调用 Embedding 模型。
|
||||
4. 将新向量同步至 Vector DB,记录元数据 `{"file_id": ".../张三.md", "block_id": "b_123"}`。若某 Hash 消失,则发送 `DELETE` 指令清理 Vector DB 中的孤儿向量。
|
||||
|
||||
### 图谱关系的双态抽取 (Dual-state Relation Extraction)
|
||||
文件更新后,必须提取概念间的关联以更新 Graph DB。分为快慢两条路线:
|
||||
|
||||
+ **快路线 (显式抽取):基于规则的解析** [已实现]
|
||||
- **触发:** 文件中包含标准双链语法 (`md` parser 支持三种形式):
|
||||
- bare: `See [[张三]]`
|
||||
- line-level Dataview: `colleague:: [[李四]]`
|
||||
- inline-bracketed: `主导 [负责:: [[项目X]]] 的重构`
|
||||
- **算法:** Parser 直接使用正则提取 `FileLink(source_path, target_path, target_anchor, predicate)`,写入 `file_graph` 投影 (LocalFileGraph / NxFileGraph / Neo4jFileGraph 任选)。延迟接近 0。
|
||||
+ **慢路线 (隐式抽取):基于 LLM 的 IE (信息抽取)** [未实现]
|
||||
- **触发 (设计意图):** 文件新增了自然语言段落 (如 daily summary 写入的:"2026-05: 张三与李四发生技术冲突")。
|
||||
- **算法 (设计意图):**
|
||||
1. 提取器截取该新增 Block,传入轻量级本地 LLM (如 Llama-3-8B)。
|
||||
2. 强制 JSON 输出提取的三元组。
|
||||
3. **实体对齐 (Entity Resolution):** 将字符串 "李四" 通过极速检索匹配到 `knowledge/li-si/li-si.md`。
|
||||
4. **物理回写 (Write-back 关键步):** 为了保证 SSOT,后台将提取出的隐式关系转换为隐形元数据或双链语法,**追加回 Markdown 文件末尾**,随后再同步给 Graph DB。
|
||||
- 当前由 Distiller 在 LLM agent 中显式产出 wikilink 代替;独立的"隐式抽取 + write-back"后台进程未建。
|
||||
|
||||
---
|
||||
|
||||
## 后台自演化算法 (Maintenance & Evolution) [未实现]
|
||||
|
||||
> 对应 **Layer 3 Maintainer**。整服务尚未在 reme4 中建模,下文为设计意图。
|
||||
|
||||
记忆不能无限膨胀,系统通过独立的后台守护进程 (The Maintainer) 执行拓扑运算,由两种信号唤醒:
|
||||
|
||||
+ **周期性 Cron Job (定时):** 例如每天凌晨 2 点,扫描全局节点计算衰减公式 (Decay),或者计算全局 Embedding 相似度矩阵寻找可以合并 (Merge) 的节点。
|
||||
+ **Watcher 警报 (阈值):** 当 Parser 在处理文件时,发现 `张三.md` 已经超过了 8000 Tokens。Watcher 会向 Maintainer 发送一个"超载预警"。
|
||||
|
||||
### 实体消歧与合并 (Hierarchical Clustering Merge) [未实现]
|
||||
每天夜间低峰期,系统自动清理冗余概念文件 (如 `AI.md` 和 `人工智能.md`)。
|
||||
|
||||
+ **算法:**
|
||||
1. 提取所有文件 YAML 头部的全局摘要 Embedding。
|
||||
2. 计算全量节点对的余弦相似度矩阵。
|
||||
3. 使用 **Union-Find (并查集)** 算法,以 $Similarity > 0.95$ 为阈值,找出所有连通分量 (疑似同义词集合)。
|
||||
4. 触发物理合并:将较新文件的内容 Append 到较早创建的主文件中,较新文件转化为 Symlink (软链接)。
|
||||
5. 触发文件修改事件 -> Watcher 自动更新 Graph DB,将所有指向旧文件的边重定向至主文件。
|
||||
|
||||
### 记忆节点的细胞分裂 (K-Means Split) [未实现]
|
||||
防止单一概念文件成为包含几万字、语义混杂的"大垃圾桶"。
|
||||
|
||||
+ **算法:**
|
||||
1. 监控指标:当单一 `.md` 文件的总 Token 数或内部 Block 数量超过设定阈值 $T_{max}$。
|
||||
2. **特征提取:** 取出该文件内所有 Block 的 Embedding。
|
||||
3. **自适应聚类:** 运行 K-Means 聚类,通过计算**轮廓系数 (Silhouette Coefficient)** 自动寻找最优的分类数 $K$。
|
||||
4. 调用 LLM 为这 $K$ 个簇生成新的文件名 (如从 `编程.md` 拆分为 `前端.md` 和 `后端.md`)。
|
||||
5. 执行物理拆分,创建新文件。Watcher 随后根据每个 Block 的新归属,自动重构 Graph 中的连线。
|
||||
|
||||
### 拓扑与时间联合遗忘算法 (Topo-Temporal Decay) [未实现]
|
||||
冷门无用的临时记忆必须被清理,但不纯依赖时间。
|
||||
|
||||
+ **算法计算公式:**
|
||||
|
||||
$$Score_i = (I_i \times e^{-\lambda \Delta t}) + \alpha \log(1 + D_{in}^{(i)})$$
|
||||
|
||||
- $I_i$: 节点的初始重要性 (1-10 分)。
|
||||
- $\Delta t$: 距离最后一次被 Agent 访问的天数。
|
||||
- $\lambda$: 遗忘速率常数。
|
||||
- $D_{in}^{(i)}$: 该节点在 Graph DB 中的入度 (被引用的次数)。
|
||||
- $\alpha$: 图拓扑权重系数。
|
||||
+ **执行逻辑:** 当 $Score_i < 阈值$ 时,不执行硬删除,而是修改文件的 YAML 头 `status: archived`,并将其移动至 `/Archive/` 目录。Graph DB 随即挂起 (Suspend) 其所有相关连线。
|
||||
|
||||
> 现状:`lint:schema` 中已经接受 `status: archived` 作为合法值,但触发归档的 Decay 逻辑未建。
|
||||
|
||||
---
|
||||
|
||||
## 检索与召回算法 (Retrieval & Recall)
|
||||
|
||||
> 对应 **Layer 4 Retrieve 类** + 设计意图中的统一 Retriever。Retriever 作为统一类未建,reme4 当前以 `search_step` (RRF 融合) + `graph:traverse` (1-hop BFS) + `crud:read` 等 Layer 4 原子手动组合。意图路由 / Rerank pipeline 未建。
|
||||
|
||||
### 意图路由 (Semantic Soft Routing — Retriever 内部子策略) [未实现]
|
||||
避免每次检索前都调 LLM 算意图。
|
||||
|
||||
+ **机制 (设计意图):** 在向量空间中预埋 3 个核心意图锚点向量 ($V_{实体}, V_{事实}, V_{关系}$)。
|
||||
+ **算法 (设计意图):** 用户的 Query 转换为向量 $V_q$,计算其与 3 个锚点的余弦距离,基于最近邻 (KNN) 确定检索策略。
|
||||
+ **位置:** 跑在 Retriever 入口处,决定走哪条召回管线 (实体定位 / 三路融合 / 图谱扩展)。
|
||||
+ **现状:** 调用方 (主 Agent) 显式选 `search` 或 `graph_traverse`,无自动路由。
|
||||
|
||||
### 图谱增强三路召回 (Graph-RAG Recall Pipeline) [部分实现]
|
||||
当策略判定需要深挖细节时,执行以下三步走:
|
||||
|
||||
1. **种子 Block 召回 (Vector + BM25):** [已实现 — `search_step`]
|
||||
|
||||
使用倒数秩融合 (RRF) 算法合并稠密向量与稀疏词频的打分:
|
||||
|
||||
$$RRF\_Score = \frac{vector\_weight}{60 + Rank_{vector}} + \frac{text\_weight}{60 + Rank_{BM25}}$$
|
||||
|
||||
(reme4 实现在 `reme4/steps/common/search.py::SearchStep._rrf_merge`, 常量 `_RRF_K = 60`, 默认 vector_weight=0.7。)
|
||||
|
||||
选出分数最高的 Top-K Blocks,并上溯找到其对应的 $N$ 个**种子文件节点 (Seed Nodes)**。
|
||||
|
||||
2. **图谱游走扩展 (1-Hop Graph BFS):** [已实现 — `graph:traverse`]
|
||||
|
||||
以这 $N$ 个节点为起点,在 file_graph 中执行深度为 1 的广度优先遍历。
|
||||
|
||||
- **剪枝:** 当前按 `predicate` / `depth` 过滤;`is_active` / 时间戳剪枝 [未实现]。
|
||||
- **种子来源:** 需要 caller 把 `search` 结果手动喂进 `graph_traverse`,**没有自动串联的 pipeline 步骤**。
|
||||
|
||||
3. **动态组装与裁剪 (Rerank & Prompt Assembly):** [未实现]
|
||||
|
||||
将底层拿到的冷数据转换为 Agent 的高质量提示词片段。
|
||||
|
||||
```plain
|
||||
[🎯 核心实体背景: knowledge/zhang-san/zhang-san.md]
|
||||
(来自文件 YAML: 状态活跃, 前端架构师)
|
||||
|
||||
[🕸️ 认知关系网络]
|
||||
- 负责 -> [[knowledge/项目X]] (2026-05)
|
||||
- 冲突对象 -> [[knowledge/li-si]]
|
||||
|
||||
[🔍 命中事实切片]
|
||||
"2026-05-06: 张三与李四发生技术冲突,引入了 React。" (相关度: 0.92)
|
||||
```
|
||||
|
||||
> 现状:`search` 返回 FileChunk 列表 (含分数与片段);Schema-aware rerank + 上述格式化模板未实现。
|
||||
|
||||
---
|
||||
|
||||
## 落地状态总览
|
||||
|
||||
按 5-layer + Schema 分组:
|
||||
|
||||
| Layer | 模块 | 状态 | 备注 |
|
||||
|---|---|---|---|
|
||||
| **L1** | Agent (Claude Code) | — | 外部 |
|
||||
| **L2** | reme-service plugin | ✅ 已实现 | 24 MCP tools + Hooks; SessionEnd 走 distiller |
|
||||
| **L2** | reme-expert plugin | ✅ 已实现 | 22 MCP tools + 2 subagents (distiller/curator) + 3 slash |
|
||||
| **L2** | Hooks (PreCompact/SessionEnd/Stop) | ✅ 已实现 | `active_daily_check.py` 扫 daily/ |
|
||||
| **L3** | Synchronizer | ✅ 已实现 | 热写 daily workspace; `_coerce_messages` 支持 dict/Msg 双输入 |
|
||||
| **L3** | Distiller (原 Ingestor) | ✅ 已实现 | 冷写 knowledge;R-M-W + lint:schema 自查 + status flip |
|
||||
| **L3** | Maintainer (Merge/Split/Decay) | ❌ 未实现 | 服务未建;`status: archived` 已是合法值但无触发逻辑 |
|
||||
| **L4** | search (RRF 混合召回) | ✅ 已实现 | `reme4/steps/common/search.py` |
|
||||
| **L4** | graph_traverse (1-hop BFS) | ✅ 已实现 | `reme4/steps/graph/traverse.py` |
|
||||
| **L4** | crud (list/read/write/stat/property_*) | ✅ 已实现 | `reme4/steps/crud/` |
|
||||
| **L4** | File ops (move/copy/delete/upload/download) | ✅ 已实现 | `reme4/steps/crud/{move,copy,delete,upload,download}.py` |
|
||||
| **L4** | Daily (daily:read/daily:list) | ✅ 已实现 | `reme4/steps/daily/` — 工作区 CRUD |
|
||||
| **L4** | tags (tags_list/tags_stat) | ✅ 已实现 | `reme4/steps/tags/` |
|
||||
| **L4** | lint (dangling/orphans/collisions/schema) | ✅ 已实现 | `reme4/steps/lint/` |
|
||||
| **L4** | Retriever 统一类 (intent routing + rerank) | ❌ 未实现 | search + graph_traverse 散步式实现 |
|
||||
| **L4** | 三路融合 pipeline (search → graph → rerank) | ❌ 未实现 | 需要 caller 手动串联 |
|
||||
| **L5** | file_store (MFS) | ✅ 已实现 | LocalFileStore / 可扩展 |
|
||||
| **L5** | file_watcher + file_parser | ✅ 已实现 | lite watcher + bare/default/md parser |
|
||||
| **L5** | Projections (vector/keyword/graph) | ✅ 已实现 | embedding + BM25 + Local/Nx/Neo4j file_graph |
|
||||
| **L5** | 隐式 LLM IE 关系抽取 (慢路线) | ❌ 未实现 | 当前由 Distiller 在 prompt 内显式产出 wikilink 代替 |
|
||||
| **Schema** | protocol.md (4 轴文字契约) | ✅ 已实现 | `reme4/steps/jobs/protocol.md` |
|
||||
| **Schema** | lint:schema (后置 validator) | ✅ 已实现 | 必填 4 key + status enum |
|
||||
| **Schema** | file_front_matter (开放 dict 模型) | ✅ 已实现 | `extra=allow` |
|
||||
| **Schema** | Python preset 类 | ❌ 未实现 | 等 vault 域稳定再固化 |
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
# Synchronizer 设计方案 (v4)
|
||||
|
||||
## 1. 定位
|
||||
|
||||
**Synchronizer = Agent 的"任务工作区"周期同步器**
|
||||
|
||||
- 触发方:宿主 agent;触发时机:上下文/对话轮次达阈值(agent 自决)
|
||||
- 双重产出:
|
||||
1. **持久化**:把 in-progress 任务沉到 vault 的 workspace folder(folder + summary note + 任意类型 materials)
|
||||
2. **回灌 context**:把完整的 summary note 内容随结果一起返回,agent 可在 compact / new-session 时直接注入新 context
|
||||
- 不做:不压缩 agent context、不 distill、不动 events/topics、不感知阈值
|
||||
|
||||
对照 `structure.md`:synchronizer 写的是 **Warm Summary**,且**主动把 Warm Summary 反哺 Hot Context**。
|
||||
|
||||
---
|
||||
|
||||
## 2. 工作区物理形态
|
||||
|
||||
```
|
||||
<vault>/daily/<YYYY-MM-DD>/<slug>/
|
||||
├── <slug>.md # workspace summary note (即 folder note)
|
||||
├── <material1>.md # 文本材料
|
||||
├── <material2>.pdf # 任意类型 (pdf / doc / png / json / csv ...)
|
||||
└── ...
|
||||
```
|
||||
|
||||
- `<slug>` = task title 的 kebab-case ≤ 60 字符;同一任务在同一天 slug 必须稳定
|
||||
- `<slug>.md` 与父目录同名 — 即是 **summary note**,也是 reme L1 视角的 **folder note**(同一份文件,两个名字)
|
||||
- Materials 不限文件类型
|
||||
|
||||
> **术语统一**:本方案中 "summary note" 与 "folder note" 指同一份 `<slug>.md` 文件。前者是 synchronizer 视角的语义名(内容是 workspace summary),后者是 reme L1 视角的结构名(同名约定下的目录索引)。
|
||||
|
||||
---
|
||||
|
||||
## 3. Summary note 结构
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: <一行任务标题>
|
||||
description: <2-3 句:任务是什么、为什么>
|
||||
status: active | completed
|
||||
created: <YYYY-MM-DD>
|
||||
updated: <YYYY-MM-DD>
|
||||
inherits: [[daily/<earlier-date>/<earlier-slug>/<earlier-slug>]] # 可选,仅 INHERIT 时
|
||||
---
|
||||
|
||||
## Objective
|
||||
<长期稳定目标 — 创建时定一次,scope 变化才改>
|
||||
|
||||
## Plan
|
||||
<整体计划/方法/分阶段路线 — 滚动维护,wholesale 重写>
|
||||
|
||||
## Progress
|
||||
- <YYYY-MM-DD HH:MM> <一条进度>
|
||||
<append-only>
|
||||
|
||||
## Findings
|
||||
- <关键发现/事实/数据点 — next-session 必须知道的"已确认结论">
|
||||
<append-only>
|
||||
|
||||
## Decisions
|
||||
- <关键决策与原因>
|
||||
<append-only>
|
||||
|
||||
## Next
|
||||
- [ ] <todo>
|
||||
- [x] <done todo>
|
||||
<wholesale 替换>
|
||||
|
||||
## Materials
|
||||
- [[<material1>]] — <一句话说明> # md 用 wikilink (folder note 短链)
|
||||
- [<material2.pdf>](material2.pdf) — <说明> # 非 md 用 markdown 链接 + 显式扩展名
|
||||
<union 去重>
|
||||
```
|
||||
|
||||
字段哲学:
|
||||
- **Append-only**:Progress / Findings / Decisions
|
||||
- **Wholesale-replace**:Plan / Next
|
||||
- **Set-once**:Objective(scope shift 才改)
|
||||
- **Union**:Materials
|
||||
|
||||
---
|
||||
|
||||
## 4. Materials 来源(双轨)
|
||||
|
||||
| 来源 | 谁写 | 落盘方式 | 进 Materials list |
|
||||
|---|---|---|---|
|
||||
| **Agent 主动落盘** | Agent 在工作中通过 `write` / `upload` 把片段、文档、产物存到 `daily/<date>/<slug>/` | 任意工具 | synchronizer 触发时 `list daily/<date>/<slug>/`,把所有非 index 文件加进 Materials |
|
||||
| **Synchronizer 自动抽** | Synchronizer 从对话里抽关键文本片段(报错堆栈、用户原话、产出代码块、调研结论)| `write` 成 `daily/<date>/<slug>/<auto-name>.md` | 写完 append 到 Materials |
|
||||
|
||||
**UPDATE 路径必须先 `list`** workspace folder,把 agent 已放进去的新文件补进 Materials,避免丢失。
|
||||
非 md 材料只能由 agent 通过 `upload` 放,synchronizer 不生成非 md 文件。
|
||||
|
||||
---
|
||||
|
||||
## 5. 决策树
|
||||
|
||||
```
|
||||
[1] messages 非空? ─否─▶ SKIP, used_llm=false, return
|
||||
│是
|
||||
▼
|
||||
[2] LLM 读 messages: 是不是 in-progress 多步任务?
|
||||
否 ─▶ "[SKIP]", no tool calls
|
||||
│是
|
||||
▼
|
||||
[3] LLM 推断稳定 task title → slug
|
||||
│
|
||||
▼
|
||||
[4] list daily/<today>/
|
||||
┌── 今天已有 <slug>/ ─▶ UPDATE
|
||||
│ (a) read daily/<today>/<slug>/<slug>.md
|
||||
│ (b) list daily/<today>/<slug>/ (含非 md)
|
||||
│ (c) merge 各 section:
|
||||
│ Objective: 保留
|
||||
│ Plan: wholesale 重写
|
||||
│ Progress: append (旧 + 新)
|
||||
│ Findings: append
|
||||
│ Decisions: append
|
||||
│ Next: wholesale 替换
|
||||
│ Materials: union(旧 list, 新文件 list, 自动抽片段)
|
||||
│ (d) [可选] 写关键片段成新 md material (防冲突)
|
||||
│ (e) write 新 index (overwrite=True 覆盖旧 index 是预期)
|
||||
│
|
||||
├── 今天没有, 扫近 N (默认 7) 天 daily/ 找 status=active 同 title ─▶ INHERIT
|
||||
│ (a) property:read 候选 index 看 title/status
|
||||
│ (b) read predecessor index → 拷 Objective + Plan
|
||||
│ (c) [可选] 写关键片段 (防冲突)
|
||||
│ (d) write 新 index:
|
||||
│ Inherits: [[daily/<earlier-date>/<earlier-slug>/<earlier-slug>]]
|
||||
│ Objective: 拷
|
||||
│ Plan: 拷
|
||||
│ 其他 sections: 全新
|
||||
│ Materials: 仅自己生成 (旧 materials 通过 Inherits 链回去)
|
||||
│ (e) predecessor 的 status 不动
|
||||
│
|
||||
└── 没找到 ─▶ CREATE
|
||||
(a) [可选] 写关键片段 (防冲突)
|
||||
(b) write 新 index (各 section 全新)
|
||||
|
||||
▼
|
||||
[5] 完成态判定:
|
||||
- 默认 status=active
|
||||
- 仅当对话有非常明确的"任务结束/已交付"信号 → completed
|
||||
- 翻转能力保留, prompt 写死保守判定
|
||||
|
||||
▼
|
||||
[6] LLM 输出最终回复 (一行 summary):
|
||||
"<created|inherited|updated> daily/<date>/<slug>/<slug>.md (+M materials)"
|
||||
或 "[SKIP]"
|
||||
|
||||
▼
|
||||
[7] Step 在 LLM 完成后, 用 file_store 直接 read 出
|
||||
刚写的 daily/<date>/<slug>/<slug>.md 完整内容,
|
||||
填进 SynchronizerResult.summary 字段
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Toolkit (LLM 可用)
|
||||
|
||||
复用现有 6 个 crud,无需新增:
|
||||
|
||||
| 工具 | 用途 |
|
||||
|---|---|
|
||||
| `list(path, recursive)` | 扫今天目录、扫 workspace folder(含非 md)、扫 inherit 候选 |
|
||||
| `stat(path)` | **写前防冲突检查** |
|
||||
| `read(path)` | UPDATE 读旧 index;INHERIT 读 predecessor |
|
||||
| `write(path, content, overwrite)` | 写 index;写自动抽 material(默认 `overwrite=False`)|
|
||||
| `property:read(path)` | 扫 inherit 候选只看 frontmatter |
|
||||
| `property:update(path, **fields)` | 翻 status / 改 updated 不重写正文 |
|
||||
|
||||
`upload` 不在 toolkit 里 — synchronizer 不拷非 md 材料。
|
||||
|
||||
---
|
||||
|
||||
## 7. Step 参数 & 输出契约
|
||||
|
||||
### 7.1 `__init__` 参数
|
||||
|
||||
```python
|
||||
class Synchronizer(BaseStep):
|
||||
def __init__(
|
||||
self,
|
||||
toolkit: Toolkit | None = None,
|
||||
console_enabled: bool = False,
|
||||
timezone: str | None = None,
|
||||
inherit_window_days: int = 7, # INHERIT 扫描窗口
|
||||
**kwargs,
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
### 7.2 输出契约(扩展)
|
||||
|
||||
```python
|
||||
class SynchronizerResult(BaseModel):
|
||||
used_llm: bool
|
||||
applied: list[dict] # 成功的 tool calls
|
||||
failed: list[dict] # 失败的 tool calls
|
||||
skipped: bool # True = LLM 判定非任务
|
||||
actions: str # LLM 一行 action 陈述
|
||||
|
||||
# —— 服务 agent 上下文管理的核心字段 ——
|
||||
workspace: str | None = None # daily/<date>/<slug>/ (folder 相对路径,带尾 /)
|
||||
summary: str | None = None # summary note **完整 markdown 内容**
|
||||
# (含 frontmatter + 全部 sections)
|
||||
# SKIP 或 失败时为 None
|
||||
|
||||
success = len(failed) == 0
|
||||
```
|
||||
|
||||
**`summary` 字段是关键**:agent 在 compact context / 新 session 启动时,可直接把 `result.summary` 作为 system context 注入,不必再发 read 请求。
|
||||
|
||||
填充时机:LLM 完成所有 tool call 后,Step 在 `execute()` 末尾用 `file_store` **直接** read 出 note 文件(从 `actions` 行正则提取 path),确保拿到的是 agent 刚刚写完的最新版本。
|
||||
|
||||
> **Input/Output 字段对齐**:`workspace` 一词在两边语义统一 — 输入时是 caller 给的 hint(任务标题或 `daily/.../` 路径),输出时是确定的 folder 相对路径。
|
||||
|
||||
---
|
||||
|
||||
## 8. 冲突管理(LLM 自管)
|
||||
|
||||
`write` 默认 `overwrite=False`(已支持,见 `reme2/steps/crud/write.py:55`)。LLM 协议:
|
||||
|
||||
| 场景 | LLM 应做 |
|
||||
|---|---|
|
||||
| **写 index `<slug>.md`** | UPDATE 路径:已 `read` 确认是同一任务 → 显式传 `overwrite=True`<br>CREATE / INHERIT:`stat` 不存在再写;意外存在 → 加后缀消歧 |
|
||||
| **写自动抽的 material** | 名字 LLM 自取(描述性);`stat` 检查;若存在 → 改名(如 `auth-error-2.md`)再写;不允许 silent overwrite |
|
||||
| **agent 已写过同名** | 同上 — `stat` 拦下,LLM 改名 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 关键设计决策汇总
|
||||
|
||||
| # | 决策 | 选定 |
|
||||
|---|---|---|
|
||||
| D1 | workspace 形态 | folder + summary note(= folder note) + 同目录 materials |
|
||||
| D2 | 术语 | "summary note" / "folder note" = 同一份 `<slug>.md`,本方案统一 |
|
||||
| D3 | summary note 字段 | Objective / Plan / Progress / Findings / Decisions / Next + Materials + (Inherits) |
|
||||
| D4 | append-only | Progress / Findings / Decisions |
|
||||
| D5 | wholesale-replace | Plan / Next |
|
||||
| D6 | Materials 来源 | 双轨 — agent 主动 + synchronizer 自动抽(仅 md) |
|
||||
| D7 | Materials 文件类型 | 任意 — md 用 wikilink,非 md 用 markdown 链接 + 扩展名 |
|
||||
| D8 | INHERIT 扫描窗口 | 参数化 `inherit_window_days`,默认 7 |
|
||||
| D9 | completed 翻转 | 保留能力,prompt 写死保守判定 |
|
||||
| D10 | Predecessor status | INHERIT 时不动 |
|
||||
| D11 | Material 自动文件名 | LLM 自取(描述性) |
|
||||
| D12 | 冲突管理 | `write` 默认 `overwrite=False`,LLM 自己 `stat` 检查并改名 |
|
||||
| D13 | 触发器 | agent 自决,synchronizer 不感知阈值 |
|
||||
| D14 | 与 distiller 关系 | synchronizer 写 daily/ workspace(warm);distiller 写 knowledge/(cold)— 解耦 |
|
||||
| D15 | 输出含完整 note | `SynchronizerResult.summary` 携带刚写完的 summary note 全文,服务 agent 上下文管理 |
|
||||
| D16 | summary 字段填充 | Step 在 LLM 完成后用 `file_store` 直读,不依赖 LLM 自己回传 |
|
||||
| D17 | input/output 字段对齐 | `workspace` 一词在 input(hint) 与 output(folder path) 共用,`actions` 字段承载 LLM 一行陈述 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 改动清单
|
||||
|
||||
### `reme2/steps/jobs/synchronizer.py`
|
||||
1. `__init__` 加 `inherit_window_days: int = 7`
|
||||
2. `execute()`:
|
||||
- 输入字段:`task_hint` → `workspace`(语义统一)
|
||||
- `prompt_format("user_message", ...)` 多传 `inherit_window_days` + `workspace`
|
||||
- LLM 完成后,从 `actions`(原 `agent_summary`)解析出 note path(正则匹配)
|
||||
- 用 `path_resolver.to_absolute(file_store, note_path).read_text()` 拿完整内容
|
||||
- 填进 `SynchronizerResult.summary` / `workspace`
|
||||
- SKIP / 失败 → 两个字段 None
|
||||
3. `SynchronizerResult` 字段重命名:`agent_summary`→`actions`,`workspace_path`→`workspace`,`note`→`summary`,删除 `note_path`
|
||||
|
||||
### `reme2/steps/jobs/synchronizer.yaml`
|
||||
完全重写 `system_prompt` + `user_message`:
|
||||
- 路径模板改 folder 形态 `daily/<date>/<slug>/<slug>.md`
|
||||
- 字段扩展 Objective / Plan / Progress / Findings / Decisions / Next + Materials
|
||||
- Materials 引用规则:md wikilink,非 md markdown link + 扩展名
|
||||
- 决策树明确 UPDATE / INHERIT / CREATE
|
||||
- INHERIT 窗口用 `{inherit_window_days}` 占位
|
||||
- Workspace hint 用 `{workspace}` 占位 (替代旧的 `{task_hint}`)
|
||||
- 冲突管理协议写明 `stat` 先行 + 改名
|
||||
- 完成态保守判定
|
||||
- 输出格式 `<action> daily/<date>/<slug>/<slug>.md (+M materials)` 或 `[SKIP]`
|
||||
- 强调:LLM 输出的 path **必须用相对 vault 的形式**,Step 后续会据此 read 完整 note
|
||||
|
||||
### note path 提取协议(实施细节)
|
||||
让 LLM 在 actions 行严格输出 `<action> <relative-path> (+M materials)`,Step 用正则 `r"daily/\d{4}-\d{2}-\d{2}/[^/\s]+/[^/\s]+\.md"` 提取 path。SKIP 行不提取。提取失败 → `summary=None` 但不算 step 失败(只是回灌 context 失败,持久化已完成)。
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
1. 完善mcp_servers config
|
||||
2. 完善mcp/http的服务测试
|
||||
3. [PosixPath('.reme')]
|
||||
4. error
|
||||
5. meta信息存在一个地方
|
||||
6. 测试一个完整的Service client的框架,测试各种命令
|
||||
7. config 默认改成default
|
||||
Loading…
Add table
Reference in a new issue