diff --git a/README.md b/README.md
index 046a807d..7cfbc067 100644
--- a/README.md
+++ b/README.md
@@ -1,273 +1,102 @@
-
-

+
+
+
-
Remember Me, Refine Me
-
面向 Agent 的、文件优先的自进化记忆系统。
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
-
- GitHub
- ·
- DeepWiki
- ·
- 设计文档
- ·
- 历史 README
-
+
+ A memory management toolkit for AI agents — Remember Me, Refine Me.
+
-
-
-
-
-
-
- 历史版本:
- 0.3.x
- ·
- 0.2.x
- ·
- memoryscope
-
-
+> 历史版本 [0.3.x](https://github.com/agentscope-ai/ReMe/tree/v0.3.1.10)
+> [0.2.x](https://github.com/agentscope-ai/ReMe/tree/v0.2.0.6)
+> [MemoryScope](https://github.com/agentscope-ai/ReMe/tree/memoryscope_branch)
---
-🧠 ReMe 是一个专为 **AI Agent** 打造的记忆管理框架。它把记忆保存为 vault 目录中的普通文件,并通过 Markdown、front matter、wikilink、BM25 索引、文件图谱和后台 Agent 管线,把对话与外部资料逐步沉淀为可读、可查、可追溯的长期记忆。
+🧠 ReMe 是一个专为 **AI 智能体** 打造的记忆管理工具,以 **Memory as File** 为核心,将对话、资料和长期知识沉淀为可读、可编辑、可检索的文件化记忆。
-它解决 Agent 记忆中的两类核心问题:**会话无状态**(新会话无法自然继承历史)和 **长期记忆不可控**(记忆被锁在黑盒数据库里,难以审查、迁移和修正)。
-
-ReMe 的当前实现以 `reme/config/default.yaml` 为中心装配:启动 `Application` 后,默认暴露 HTTP 服务,后台监听 `daily/`、`digest/`、`resource/` 的变化,并提供检索、文件读写、daily note、自进化记忆等 Job。
+ReMe 让智能体拥有可持续维护的记忆库:历史对话可归档,外部资料可索引,重要信息可沉淀为长期记忆,并通过关键词、语义检索和
+wikilink 图谱重新找到。
你可以用 ReMe 做什么
-- **个人助理**:把用户偏好、长期事实和历史上下文写入可读的 daily/digest 记忆。
-- **编程助手**:沉淀项目约定、排错经验、操作流程和长期决策。
-- **研究助理**:把报告、网页、日志、会议纪要等文本资源解读为 daily note。
-- **知识图谱**:通过 Markdown、front matter 和 `[[wikilink]]` 维护本地知识网络。
-- **主动记忆**:从 daily 输入中抽取兴趣主题,生成 `interests.yaml` 给上层 Agent 使用。
-- **服务化工具**:通过 HTTP、MCP 或 CLI 调用同一组 Job。
+- **个人助理**:为 [QwenPaw](https://github.com/agentscope-ai/QwenPaw) 等智能体提供长期记忆,记住用户偏好和历史对话。
+- **编程助手**:记录代码风格偏好、项目上下文,跨会话保持一致的开发体验。
+- **客服机器人**:记录用户问题历史、偏好设置,提供个性化服务。
+- **任务自动化**:从历史任务中学习成功/失败模式,持续优化执行策略。
+- **知识问答**:构建可检索的知识库,支持语义搜索和精确匹配。
---
-## 📁 文件优先的记忆系统
+## 📁 基于文件的记忆系统
-> 记忆即文件,文件即记忆。
+> Memory as files, files as memory.
-ReMe 的默认运行目录来自 `ApplicationConfig`。应用启动时会自动创建 vault 根目录和主要子目录。
+将**记忆视为文件**:原始对话和外部资料先进入输入层,再加工成 daily note,最后沉淀为可长期复用的 digest 记忆。
+
+| 层级 | 目录 | 内容 |
+|------|-----------------------------|-------------------------|
+| 原始输入 | `reme_session/`、`resource/` | 原始对话、Agent session、外部资料 |
+| 浅加工 | `daily/` | 当天事实、对话摘要、资源解读、兴趣主题 |
+| 深加工 | `digest/` | 用户画像、长期事实、流程经验、知识节点 |
```text
/
-├── reme_metadata/ # 索引、图谱、catalog 等持久状态
-├── reme_session/ # Agent session 与原始对话
+├── reme_metadata/ # 系统索引、图谱、catalog 等持久状态
+├── reme_session/ # 原始对话和 Agent session
│ ├── dialog/
-│ │ └── .jsonl # auto_memory 保存的对话消息
+│ │ └── .jsonl
│ ├── agentscope/
│ └── claude_code/
-├── resource/ # 外部文本资源
+├── resource/ # 外部原始材料
│ └── YYYY-MM-DD/
│ └── .
-├── daily/ # 浅加工记忆
-│ ├── YYYY-MM-DD.md # 当天索引页
+├── daily/ # 浅加工记忆:当天事实、对话摘要、资源解读
+│ ├── YYYY-MM-DD.md
│ └── YYYY-MM-DD/
-│ ├── .md # 对话或资源加工后的 daily note
-│ └── interests.yaml # auto_dream 产出的主动兴趣主题
-└── digest/ # 深加工记忆
+│ ├── .md
+│ ├── .md
+│ └── interests.yaml
+└── digest/ # 长期记忆:个人事实、流程经验、知识节点
├── personal/
├── procedure/
└── wiki/
```
-| 层级 | 内容 | 主要写入方 |
-| --- | --- | --- |
-| `resource/` | 外部文本材料,默认监听 `md/txt/json/jsonl/csv/yaml/html` | 手动同步、`resource_watch_loop` |
-| `reme_session/dialog/` | 原始对话 JSONL | `auto_memory` |
-| `daily/` | 当天索引页、对话笔记、资源解读、兴趣主题 | `daily_create`、`auto_memory`、`auto_resource`、`auto_dream` |
-| `digest/personal/` | 用户画像、偏好、长期个人事实 | `auto_dream` |
-| `digest/procedure/` | 方法论、流程、操作经验 | `auto_dream` |
-| `digest/wiki/` | 通用知识、概念、决策先例 | `auto_dream` |
+
---
-## 📝 Markdown、Front Matter 与 Wikilink
+### 🚀 快速开始
-ReMe 的核心读写对象是 Markdown 文件。写入类 Job 会处理 front matter;索引时,front matter 会进入 `FileNode.front_matter`,供检索、图谱和 Agent 判断使用。
+#### 安装
-```markdown
----
-name: 光伏产业链研究
-description: 从硅料到组件的全链条梳理
-tags: [新能源, 光伏, 产业链]
----
-```
+ReMe 要求 Python 3.11+。
-`WikilinkHandler` 是统一的 wikilink 解析和改写入口:
-
-| 写法 | 示例 | 含义 |
-| --- | --- | --- |
-| 标准链接 | `[[digest/wiki/光伏.md]]` | 指向 vault-relative 目标 |
-| 锚点链接 | `[[digest/wiki/钴.md#应用]]` | 指向目标章节 |
-| 别名链接 | `[[digest/wiki/宁德时代.md\|宁德]]` | 显示别名,目标不变 |
-| 嵌入引用 | `![[resource/2026-06-01/report.md]]` | 作为 wikilink 记录边 |
-| 行级属性 | `industry:: [[digest/wiki/新能源.md]]` | 提取 predicate |
-| 内联属性 | `[competitor:: [[digest/wiki/比亚迪.md]]]` | 提取 predicate |
-
-当前实现采用**字面路径语义**:`[[X]]` 的 target 就是 `X`,不会自动补 `.md`,不会做 basename 搜索,也不会做 folder note 解析。推荐使用带扩展名的 vault-relative 路径。
-
----
-
-## 🔍 索引、图谱与检索
-
-默认 `file_store` 是 `local`,组合了:
-
-| 子组件 | 默认后端 | 说明 |
-| --- | --- | --- |
-| `file_graph` | `local` | 维护文件节点、outlinks、inlinks 和 pending links |
-| `keyword_index` | `bm25` | 基于 tokenizer 的全文检索 |
-| `embedding_store` | 空字符串 | 代码支持向量检索,但默认配置未启用 |
-
-因此默认行为是:**BM25 全文检索 + wikilink 图谱扩展**。如果配置了 `embedding_store`,`search_step` 会并行执行向量检索和 BM25,并用 RRF 融合结果。
-
-### Markdown 分块
-
-`MarkdownFileChunker` 使用 `mistletoe` 构建 Markdown AST,并按标题层级生成 chunk:
-
-- 按 H1/H2/H3 等章节递归分块。
-- 每个 chunk 带完整标题骨架,便于理解命中位置。
-- 表格、代码块、列表会按结构拆分,过长片段会标记 `[Part X/N]`。
-- 默认 `chunk_chars=10000`,`embed_toc=true`。
-- front matter 和 wikilink 会在同一轮 chunk 中提取。
-
-### Search
-
-`search` Job 面向外部问答和检索:
-
-1. 读取 `query`、`limit`、`min_score` 和可选 `search_filter`。
-2. 并行调用 `vector_search` 与 `keyword_search`。
-3. 默认未启用 embedding 时,实际返回 BM25 结果。
-4. 如果两路都有结果,用 RRF 融合。
-5. 对命中文件做 link expansion,返回 chunk 正文、行号、分数和出入链目录。
-
-`node_search` 是 `auto_dream` 集成阶段使用的专用召回:只返回 `digest/` 下的节点,并附带 front matter 中的 `name` 和 `description`;它不返回正文,也不做 link expansion。
-
----
-
-## 🧬 自进化记忆管线
-
-ReMe 的自进化流程由默认 Job 组合完成:
-
-```text
-对话 messages ── auto_memory ──> daily/YYYY-MM-DD/.md
-外部 resource ── auto_resource ─> daily/YYYY-MM-DD/.md
-daily notes ── auto_dream ────> digest/personal|procedure|wiki + interests.yaml
-```
-
-### Auto Memory
-
-`auto_memory` 接收 `messages` 和可选 `session_id`:
-
-1. 把输入标准化为 AgentScope `Msg`。
-2. 如果有 `session_id`,保存到 `reme_session/dialog/.jsonl`。
-3. 调用 `daily_create` 创建或复用 daily note。
-4. 通过 Agent 使用 `read`、`edit`、`frontmatter_update`、`write` 工具整理记忆。
-5. 写入 `source_conversation` front matter,关联原始对话 JSONL。
-6. 刷新当天索引页。
-
-保存对话时会移除 base64 数据块,并把超长 tool result 截断到约 2KB。
-
-### Auto Resource
-
-`auto_resource` 处理 `resource/` 下的变更批次。默认后台 `resource_watch_loop` 监听:
-
-```yaml
-watch_dirs: [resource_dir]
-watch_suffixes: [md, txt, json, jsonl, csv, yaml, html]
-```
-
-资源路径约定为:
-
-```text
-resource/YYYY-MM-DD/
-```
-
-`added/modified` 会读取资源文本,创建或更新同名 daily note,并让 Agent 解读内容;`deleted` 会删除对应 daily note、更新 file_store,并刷新当天索引页。
-
-### Auto Dream
-
-`auto_dream` 扫描指定日期的 daily 输入,将值得长期保存的内容整合进 `digest/`,并写出主动兴趣主题。
-
-默认步骤:
-
-```yaml
-auto_dream:
- steps:
- - dream_extract_step
- - dream_integrate_step
- - dream_topics_step
- - dream_finish_step
-```
-
-| 阶段 | 实际行为 |
-| --- | --- |
-| Extract | 刷新当天索引页,比较 dream catalog,只处理 changed daily 输入,抽取 memory units 和 topics |
-| Integrate | 对每个 unit 调用 Agent,使用 `node_search/read/frontmatter_read/write/edit/frontmatter_update` 整合进 digest |
-| Topics | 写入 `daily//interests.yaml`,默认最多 3 个 topic,并参考过去 7 天去重 |
-| Finish | checkpoint 成功处理的 changed paths,持久化 dream catalog,返回摘要 |
-
-Extract 和 Integrate 需要可用 LLM;如果未配置 LLM,会返回失败。Topics 阶段在部分情况下可以退化为本地去重,但完整 `auto_dream` 仍依赖 LLM 完成抽取与整合。
-
-### Proactive
-
-`proactive` 读取:
-
-```text
-daily//interests.yaml
-```
-
-它返回 topics,并可按 `include_content` 返回 YAML 原文,供上层 Agent 获取当天值得主动关注的主题。
-
----
-
-## ⚙️ 默认 Job
-
-默认 Job 由 `reme/config/default.yaml` 注册。后台 Job 会随应用启动自动运行;普通 Job 会通过 HTTP/MCP/CLI 暴露。
-
-| 类别 | Job | 说明 |
-| --- | --- | --- |
-| 后台索引 | `index_update_loop` | 监听 `daily/`、`digest/` Markdown 变更,增量更新 file_store |
-| 后台资源 | `resource_watch_loop` | 监听 `resource/` 文本资源,更新 catalog 并触发 `auto_resource_step` |
-| 后台 catalog | `digest_watch_loop` | 监听 `daily/`、`digest/`,更新 digest catalog |
-| 系统 | `version`、`health_check`、`help` | 版本、健康检查、Job 列表 |
-| 检索 | `search`、`node_search` | chunk 级检索、digest 节点召回 |
-| 图谱 | `traverse` | 从指定 path 遍历 wikilink 图 |
-| 索引维护 | `reindex` | 清空 file_store 并重建索引 |
-| Daily | `daily_create`、`daily_list`、`daily_reindex` | 创建、列出、刷新 daily note |
-| 文件读写 | `read`、`read_image`、`write`、`edit`、`delete`、`move`、`list`、`stat` | 操作 vault 内文件 |
-| Front Matter | `frontmatter_read`、`frontmatter_update`、`frontmatter_delete` | 读取、合并更新、删除 front matter 字段 |
-| 自进化 | `auto_memory`、`auto_resource`、`auto_dream` | 对话、资源、daily 输入的自动加工 |
-| 主动记忆 | `proactive` | 读取 `interests.yaml` |
-
-代码中还包含 `ingest`、`upload`、`download` 等 transfer step,但它们没有在默认配置中注册为 Job。
-
----
-
-## 🚀 快速开始
-
-### 安装
+从 pip 安装:
```bash
-pip install reme-ai
+pip install "reme-ai[core]"
```
从源码安装:
@@ -275,116 +104,127 @@ pip install reme-ai
```bash
git clone https://github.com/agentscope-ai/ReMe.git
cd ReMe
-pip install -e ".[full]"
+pip install -e ".[core]"
```
-### 启动服务
+`core` extra 建议安装:当前代码会导入 AgentScope wrapper,自进化记忆也依赖它。
+
+#### 环境变量
+
+配置环境变量:
+
+```bash
+cat > .env <<'EOF'
+EMBEDDING_API_KEY=sk-xxx
+EMBEDDING_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
+LLM_API_KEY=sk-xxx
+LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
+EOF
+```
+
+#### 启动
```bash
reme start
```
-指定配置或覆盖参数:
+默认服务地址是 `127.0.0.1:2333`。如果端口被占用:
```bash
-reme start config=default service.port=8090
+reme start service.port=23333
+# reme start vault_dir=/tmp/reme-demo service.port=8181
```
-配置解析支持:
-
-- 默认加载 `reme/config/default.yaml`。
-- `config=` 指定配置文件。
-- dot notation 覆盖,如 `service.port=8090`。
-- `${ENV_VAR:-default}` 环境变量展开。
-
-### CLI 调用
-
-CLI 入口在 `reme/reme.py`:
-
```bash
-reme find_reme
reme version
-reme health_check
-reme search query="用户偏好" limit=5
-reme daily_create date=2026-06-20
-reme proactive date=2026-06-20
+curl -s http://127.0.0.1:23333/version -H 'Content-Type: application/json' -d '{}'
```
-`reme start` 启动服务;`reme find_reme` 探测服务;其它 action 会作为 Job 名称,通过 client 调用已运行服务。
+更多细节见 [快速开始](docs/zh/quick_start.md)。
---
-## 🌐 服务接口
+## 核心能力
-### HTTP Service
+| 能力 | 说明 |
+|---------------------------------------------|-------------------------------------------------------------------------------|
+| [Memory as File](docs/zh/memory_as_file.md) | 用 vault 目录、Markdown、frontmatter 和 wikilink 表达记忆分层与文件关系。 |
+| [Memory Search](docs/zh/memory_search.md) | 持续索引 `daily/`、`digest/`、`resource/`,支持 BM25、可选向量召回和链接展开。 |
+| [Auto Memory](docs/zh/auto_memory.md) | 将对话按 `session_id` 保存为原始 JSONL,并整理成 daily 记忆卡片。 |
+| [Auto Resource](docs/zh/auto_resource.md) | 将 `resource/` 中的外部资料解读为 daily 资源卡片,保留原始资料出处。 |
+| [Auto Dream](docs/zh/auto_dream.md) | 从 daily 输入中抽取长期记忆单元,沉淀到 `digest/personal`、`digest/procedure` 和 `digest/wiki`。 |
+| [Auto Link](docs/zh/auto_link.md) | 在写入 digest 时召回相关节点,完成去重、来源链接和 digest 之间的 wikilink 织入。 |
+| [Proactive](docs/zh/proactive.md) | 读取 `auto_dream` 生成的 `interests.yaml`,向上层 Agent 暴露当天值得主动关注的主题。 |
-默认服务后端是 FastAPI:
+### Memory as File
-- 非 stream Job 注册为 `POST /`。
-- 请求体是 `Request`,响应是 `Response`。
-- StreamJob 注册为 `POST /`,返回 `text/event-stream`。
-- CORS 默认开放。
-- lifespan 中启动和关闭整个 `Application`。
+
+
+
-### MCP Service
+### Auto Memory & Auto Resource(BETA)
-`MCPService` 使用 FastMCP:
+
+
+
-- 非 stream Job 注册为 MCP tool。
-- 支持 `stdio`、`sse`、`streamable-http`。
-- StreamJob 当前不注册为 MCP tool。
-- MCP 服务内置 `claim_channel` 相关通道机制,用于把 vault 变更通知发送给最近 claim 的客户端会话。
+### Auto Dream & Auto Link & Proactive
+
+
+
+
+
+### Memory Search
+
+
+
+
---
-## 💾 持久化状态
+## ⭐ 社区与支持
-除 vault 正文文件外,ReMe 会在 `reme_metadata/` 下保存组件状态:
+- **问题反馈与需求**:请先查看 [Open Issues](https://github.com/agentscope-ai/ReMe/issues);如无相关讨论,可新建 Issue
+ 说明背景、目标行为和影响范围。
+- **代码贡献**:改动前建议阅读 [贡献指南](docs/zh/contributing.md) 和 [代码框架](docs/zh/framework.md),遵循 CLI /
+ Service / Application / Job / Step / Component 的分层。
+- **文档贡献**:用户可见的安装、配置、调用或行为变化,请同步更新 `docs/zh/` 或 `README.md`。
+- **提交规范**:建议使用 Conventional Commits,例如 `feat(search): add link expansion option`、
+ `docs(zh): update quick start`。
+- **提交前检查**:提交 PR 前请尽量运行 `pre-commit run --all-files` 和 `pytest`;如有依赖 LLM、embedding 或外部服务的测试无法运行,请在
+ PR 中说明。
+- **获取帮助**:Bugs 和功能请求使用 [GitHub Issues](https://github.com/agentscope-ai/ReMe/issues)
+ ,项目文档见 [https://reme.agentscope.io/](https://reme.agentscope.io/)。
-| 组件 | 持久化内容 |
-| --- | --- |
-| `file_store` | `file_chunks__v1.jsonl.zst`,保存 chunk 元数据 |
-| `file_graph` | `.jsonl.zst`,保存 `FileNode` 和 links |
-| `keyword_index` | `bm25_*.pkl`,保存 vocab、posting list、doc meta |
-| `file_catalog` | `.jsonl.zst`,保存已处理文件 mtime checkpoint |
+### 贡献者
-应用关闭时会按启动顺序反向关闭组件,并触发 file_store、keyword index、file graph 和 catalog 的持久化。
+感谢所有为 ReMe 做出贡献的朋友们:
+
+
+
+
---
-## 🧩 关键数据模型
+## 📄 引用
-```text
-Response
- success: bool
- answer: str
- metadata: dict
-
-FileNode
- path: str
- st_mtime: float
- links: list[FileLink]
- chunk_ids: list[str]
- front_matter: FileFrontMatter
-
-FileChunk
- id: str
- path: str
- start_line: int
- end_line: int
- text: str
- metadata: dict
- scores: dict[str, float]
-
-FileLink
- source_path: str
- target_path: str
- target_anchor: str | None
- predicate: str | None
+```bibtex
+@software{AgentscopeReMe2026,
+ title = {AgentscopeReMe: Memory Management Kit for Agents},
+ author = {ReMe Team},
+ url = {https://reme.agentscope.io},
+ year = {2026}
+}
```
---
-## 📄 License
+## ⚖️ 许可证
-This project is open-sourced under the Apache License 2.0. See [LICENSE](./LICENSE) for details.
+本项目基于 Apache License 2.0 开源,详情参见 [LICENSE](./LICENSE) 文件。
+
+---
+
+## 📈 Star 历史
+
+[](https://www.star-history.com/#agentscope-ai/ReMe&Date)
diff --git a/docs/figure/auto-dream.svg b/docs/figure/auto-dream.svg
new file mode 100644
index 00000000..43da1b27
--- /dev/null
+++ b/docs/figure/auto-dream.svg
@@ -0,0 +1,110 @@
+
diff --git a/docs/figure/auto-memory-resource.svg b/docs/figure/auto-memory-resource.svg
new file mode 100644
index 00000000..38c35063
--- /dev/null
+++ b/docs/figure/auto-memory-resource.svg
@@ -0,0 +1,106 @@
+
diff --git a/docs/figure/framework-structure.svg b/docs/figure/framework-structure.svg
new file mode 100644
index 00000000..279f2775
--- /dev/null
+++ b/docs/figure/framework-structure.svg
@@ -0,0 +1,158 @@
+
diff --git a/docs/figure/memory-as-file.svg b/docs/figure/memory-as-file.svg
new file mode 100644
index 00000000..50a4d574
--- /dev/null
+++ b/docs/figure/memory-as-file.svg
@@ -0,0 +1,110 @@
+
diff --git a/docs/figure/memory-search.svg b/docs/figure/memory-search.svg
new file mode 100644
index 00000000..45a5acbb
--- /dev/null
+++ b/docs/figure/memory-search.svg
@@ -0,0 +1,98 @@
+
diff --git a/docs/figure/reme-overview.svg b/docs/figure/reme-overview.svg
new file mode 100644
index 00000000..a828f6ba
--- /dev/null
+++ b/docs/figure/reme-overview.svg
@@ -0,0 +1,186 @@
+
diff --git a/docs/reme_design.md b/docs/old/reme_design_v2.md
similarity index 100%
rename from docs/reme_design.md
rename to docs/old/reme_design_v2.md
diff --git a/docs/reme_scene.md b/docs/old/reme_scene.md
similarity index 100%
rename from docs/reme_scene.md
rename to docs/old/reme_scene.md
diff --git a/docs/todo.md b/docs/old/todo.md
similarity index 100%
rename from docs/todo.md
rename to docs/old/todo.md
diff --git a/docs/zh/auto_dream.md b/docs/zh/auto_dream.md
new file mode 100644
index 00000000..c6f95b58
--- /dev/null
+++ b/docs/zh/auto_dream.md
@@ -0,0 +1,196 @@
+# Auto Dream
+
+`auto_dream` 是 ReMe 的 daily 到 digest 的长期记忆沉淀流程。它扫描指定日期的 daily 输入,只处理相对上次 dream
+发生变化的文件,把值得长期保留的内容抽取成 memory units,整合进 `digest/`,再生成当天可供主动提醒使用的 `interests.yaml`。
+
+
+
+它消费的 daily 输入通常来自 [Auto Memory](./auto_memory.md) 和 [Auto Resource](./auto_resource.md)。`digest/`、`derived_from::`
+和 wikilink 的文件语义见 [Memory as File](./memory_as_file.md);Integrate 阶段的链接策略详见 [Auto Link](./auto_link.md)。
+`interests.yaml` 的读取接口见 [Proactive](./proactive.md)。
+
+## 配置入口
+
+默认配置在 `reme/config/default.yaml`:
+
+```yaml
+auto_dream:
+ backend: base
+ parameters:
+ date:
+ type: string
+ default: ""
+ hint:
+ type: string
+ default: ""
+ topic_count:
+ type: integer
+ default: 3
+ topic_diversity_days:
+ type: integer
+ default: 7
+ steps:
+ - backend: dream_extract_step
+ file_catalog: dream
+ topic_session_id: interests
+ - backend: dream_integrate_step
+ - backend: dream_topics_step
+ topic_count: 3
+ topic_diversity_days: 7
+ - backend: dream_finish_step
+ file_catalog: dream
+```
+
+参数含义:
+
+| 参数 | 作用 |
+|------------------------|------------------------------------------------|
+| `date` | 要处理的日期,格式为 `YYYY-MM-DD`。为空时使用应用时区中的今天。 |
+| `hint` | 调用方给抽取和整合阶段的额外指导。 |
+| `topic_count` | 最终写入 `interests.yaml` 的 topic 上限,默认 3。 |
+| `topic_diversity_days` | 选择 topic 时参考过去多少天的 `interests.yaml` 避免重复,默认 7。 |
+
+## 输入和输出
+
+输入来自指定日期的 daily markdown:
+
+```text
+daily/.md
+daily//**/*.md
+```
+
+`daily//interests.yaml` 不作为抽取输入,避免上一轮主动主题反过来污染下一轮抽取。
+
+主要输出有三类:
+
+| 输出 | 说明 |
+|-------------------------------------|-------------------------------------|
+| `digest/procedure/*.md` | 方法、流程、runbook、可执行经验。 |
+| `digest/personal/*.md` | 用户、团队、项目相关的偏好、事实、长期上下文。 |
+| `digest/wiki/*.md` | 通用知识、概念、观察、决策先例。 |
+| `daily//interests.yaml` | 当天值得上层 Agent 主动关注的兴趣主题。 |
+| `reme_metadata/file_catalog/dream*` | dream 专用 catalog,用于判断 daily 输入是否变化。 |
+
+## 四个阶段
+
+### 1. Extract
+
+`dream_extract_step` 做三件事:
+
+1. 刷新当天索引页 `daily/.md`。
+2. 扫描 `daily/.md` 和 `daily//**/*.md`,与 `file_catalog: dream` 中记录的 mtime 对比。
+3. 只把 changed files 交给 LLM,全局抽取两类结构化结果:`units` 和 `topics`。
+
+`units` 是准备沉淀进 digest 的长期记忆单元,包含 `name`、`bucket`、`summary`、`paths`。`bucket` 只允许 `procedure`、
+`personal`、`wiki`;未知值会路由到 `wiki`。
+
+`topics` 是当天主动兴趣候选,包含 `title`、`reason`、`evidence`、`keywords`、`paths`,后续由 Topics 阶段再筛选。
+
+如果没有 changed files,流程会提前成功结束后续抽取工作;如果有变化但没有配置 LLM,Extract 会失败,因为抽取依赖 LLM。
+
+### 2. Integrate
+
+`dream_integrate_step` 对每个 unit 独立调用 Agent,将一个 unit 整合成一个 digest 节点。它会给 Agent 暴露这些工具:
+
+```text
+node_search, read, frontmatter_read, write, edit, frontmatter_update
+```
+
+这一阶段承担 `auto_link` 的核心职责:先用 `node_search` 在 digest 节点级召回相似或相关节点,再判断是新建还是更新,最后把来源和相关
+digest 节点写成 wikilink。具体召回、去重和写边规则见 [Auto Link](./auto_link.md)。
+
+整合动作只有四种:
+
+| 动作 | 含义 |
+|---------------|-------------------------|
+| `CREATE` | 没有相同抽象,创建新的 digest 节点。 |
+| `CORROBORATE` | 同一记忆再次出现,追加来源或强化表述。 |
+| `REFINE` | 新材料补充了边界、步骤、前提、适用范围或细节。 |
+| `CORRECT` | 新材料修正了旧节点的错误、遗漏或冲突。 |
+
+Integrate 成功的 unit 会记录到 `integrate_results`;失败的 unit 会进入 `failed_units`,其来源路径会进入 `failed_paths`。
+Finish 阶段不会 checkpoint 失败路径,保证下次还能重试。
+
+### 3. Topics
+
+`dream_topics_step` 将 Extract 阶段产生的 topic candidates 变成当天最终的 `daily//interests.yaml`。
+
+它会读取:
+
+```text
+daily//interests.yaml
+daily//interests.yaml
+```
+
+同一天已有 topics 会被保留,最近 `topic_diversity_days` 天出现过的相似主题会被去重。默认最多写 3 个 topic。配置了 LLM 时会让
+LLM 选择更具体、可行动、非重复的主题;没有 LLM 时会退化成本地规范化去重。
+
+写入格式示例。读取这个文件的接口见 [Proactive](./proactive.md):
+
+```yaml
+date: 2026-06-20
+topic_count: 3
+diversity_days: 7
+topics:
+ - title: 记忆检索链路的质量回归
+ reason: 用户近期持续修改 search、node_search 和 dream 集成链路。
+ evidence: daily/2026-06-20/session.md
+ keywords:
+ - memory search
+ - auto dream
+ paths:
+ - daily/2026-06-20/session.md
+```
+
+### 4. Finish
+
+`dream_finish_step` 负责收尾:
+
+1. 将成功处理的 changed paths 写入 `file_catalog: dream`。
+2. 将 `daily//interests.yaml` 和 `daily/.md` 也写入 catalog。
+3. 如果有 upsert 或 delete,持久化 dream catalog。
+4. 返回包含 scanned、changed、integrated、topics、checkpoint 等计数的摘要。
+
+失败路径不会被 checkpoint。这样下一次 `auto_dream` 仍会把它们视作 changed input,直到整合成功。
+
+## 运行方式
+
+CLI:
+
+```bash
+reme auto_dream date=2026-06-20
+```
+
+带调用提示:
+
+```bash
+reme auto_dream date=2026-06-20 hint="优先沉淀工程决策和长期偏好"
+```
+
+也可以在配置中把同一组 step 放进 `cron` job,例如每天凌晨运行:
+
+```yaml
+jobs:
+ daily_auto_dream:
+ backend: cron
+ cron: "30 3 * * *"
+ steps:
+ - backend: dream_extract_step
+ file_catalog: dream
+ - backend: dream_integrate_step
+ - backend: dream_topics_step
+ - backend: dream_finish_step
+ file_catalog: dream
+```
+
+## 关键边界
+
+`auto_dream` 只消费 daily 输入,不改写 daily 正文。daily 是事实和现场记录,digest 才是抽象后的长期记忆层。
+
+`digest` 不是原文复制。正文应保留可复用抽象,细节通过 `derived_from:: [[daily//...]]` 指回来源。链接写法遵循
+[Memory as File](./memory_as_file.md) 中的 vault-relative wikilink 语义。
+
+`auto_dream` 不凭空生成总览。只有 daily 输入中确实出现、并被抽取为 unit 或 topic 的内容,才会进入 digest 或
+`interests.yaml`。
+
+完整流程依赖 LLM 完成 Extract 和 Integrate。Topics 可以在没有 LLM 时做本地去重,但这不等于完整 dream 能离线运行。
diff --git a/docs/zh/auto_link.md b/docs/zh/auto_link.md
new file mode 100644
index 00000000..44675c3f
--- /dev/null
+++ b/docs/zh/auto_link.md
@@ -0,0 +1,136 @@
+# Auto Link
+
+当前实现中,`auto_link` 不是一个单独注册的 Job,而是 `auto_dream` 的 Integrate 阶段能力:`dream_integrate_step` 在把 memory
+unit 写入 `digest/` 时,同时完成 digest 节点召回、去重判断、来源链接和相关节点 wikilink 织入。
+
+完整 dream 流程见 [Auto Dream](./auto_dream.md)。通用 wikilink、frontmatter 和 vault-relative 路径语义见
+[Memory as File](./memory_as_file.md)。面向问答的检索能力见 [Memory Search](./memory_search.md)。
+
+## 所在位置
+
+`auto_dream` 的默认流程如下:
+
+```yaml
+auto_dream:
+ steps:
+ - dream_extract_step
+ - dream_integrate_step # auto_link 的实际发生位置
+ - dream_topics_step
+ - dream_finish_step
+```
+
+Integrate 阶段对每个 unit 独立运行。一个 unit 只落到一个目标 digest 节点,但这个目标节点可以链接多个来源和多个相关 digest
+节点。
+
+## 目标
+
+`auto_link` 解决的是写入时的图谱质量问题:
+
+| 问题 | 处理方式 |
+|--------------|----------------------------------------------------|
+| 已有相同记忆 | 召回后更新旧节点,而不是重复创建。 |
+| 新旧材料有关联 | 在正文中写入 vault-relative wikilink。 |
+| digest 与来源断开 | 用 `derived_from:: [[...]]` 指回 daily/resource 原始材料。 |
+| 节点只有孤立正文 | 在 CREATE 和 UPDATE 时都补充相关 digest 节点链接。 |
+
+## 工具链
+
+`dream_integrate_step` 暴露给 Agent 的工具是:
+
+```text
+node_search
+read
+frontmatter_read
+write
+edit
+frontmatter_update
+```
+
+其中 `node_search` 是为 dream 集成设计的 digest-only 节点召回。它返回 digest 节点的 `path`、front matter 中的 `name`、
+`description` 等节点级信号,不展开正文,也不做普通 search 的 link expansion。
+
+`read` 和 `frontmatter_read` 只用于可能相关的候选节点,避免把召回结果全部展开成大上下文。
+
+## 链接流程
+
+### 1. 召回候选节点
+
+Agent 先用 unit 的触发条件、动词、名词、同义词和可能的 failure modes 调用 `node_search`。默认建议用较宽召回,例如
+`limit=20-30`,因为这一步同时服务去重和链接发现。
+
+召回结果会被内部分成三类:
+
+| 分类 | 含义 | 后续动作 |
+|--------------------|-----------------------------|----------------|
+| `same_abstraction` | 触发条件或抽象本质相同,内容实质重叠。 | 作为 UPDATE 目标。 |
+| `related` | 相邻流程、前置条件、失败模式、概念、偏好或上下游知识。 | 写入正文 wikilink。 |
+| `unrelated` | 只是表面相似或无关。 | 忽略。 |
+
+### 2. 选择写入动作
+
+每个 unit 必须选择一个动作:
+
+| 动作 | 链接含义 |
+|---------------|-----------------------------------------------------|
+| `CREATE` | 写入新的 `digest//.md`,并在新正文里加入来源和相关节点链接。 |
+| `CORROBORATE` | 同一抽象再次出现,追加新的 `derived_from:: [[...]]`,必要时强化描述。 |
+| `REFINE` | 新材料扩展了旧节点,把补充内容插入合适段落,并保留旧链接。 |
+| `CORRECT` | 新材料修正旧节点,用来源链接标出修正依据。 |
+
+UPDATE 必须尽量只增不删:不要删除已有 wikilink 或 `derived_from`。这是为了让后续图谱索引和检索不会丢边。
+
+### 3. 写来源边
+
+来源边使用 markdown wikilink:
+
+```markdown
+derived_from:: [[daily/2026-06-20/session.md]]
+derived_from:: [[resource/2026-06-20/paper.md]]
+```
+
+这些边表示 digest 节点的证据来源。纯文本描述不算来源边,因为只有 wikilink 能被 file graph 稳定解析。更完整的 wikilink
+解析规则见 [Memory as File](./memory_as_file.md#wikilink)。
+
+### 4. 写 digest 关联边
+
+digest 之间的关联也使用完整 vault-relative 路径:
+
+```markdown
+relates_to:: [[digest/wiki/hybrid-search.md]]
+depends_on:: [[digest/procedure/rebuild-index.md]]
+blocks_on:: [[digest/personal/team-review-preference.md]]
+```
+
+谓词是开放的,常见写法包括 `relates_to::`、`depends_on::`、`blocks_on::`。谓词在括号外,目标路径在 `[[...]]` 内,并且应包含
+`.md` 后缀。
+
+## Bucket 差异
+
+`auto_link` 的规则会随 unit bucket 调整写入形态:
+
+| Bucket | 写入重点 |
+|-------------|---------------------------------------------|
+| `procedure` | 写成 runbook:触发条件、步骤、输入、失败模式。链接前置流程、子步骤、相关偏好。 |
+| `personal` | 写用户、团队、项目特定事实或偏好。链接相关项目、习惯、决策背景。 |
+| `wiki` | 写通用知识、原则、观察、决策先例。链接概念、方法、相邻知识。 |
+
+无论 bucket 是什么,都要保留来源边,并尽量把召回到的相关 digest 节点织入正文。
+
+## 与 search 的关系
+
+`auto_link` 使用的是 `node_search`,不是面向问答的 `search`。
+
+| 能力 | 用途 |
+|---------------|-------------------------------------------|
+| `search` | 面向外部问答,返回 chunk,并可展开上下游 link context。 |
+| `node_search` | 面向 dream 集成,只召回 digest 节点级摘要,用来判断去重和相关链接。 |
+
+这个边界很重要:Integrate 阶段需要的是“是否已有相同抽象,以及应该链接哪些节点”,而不是直接把大量正文片段塞进上下文。
+[Memory Search](./memory_search.md) 负责面向用户问题的 chunk 召回、RRF 融合和链接展开。
+
+## 失败和重试
+
+如果某个 unit 整合失败,`dream_integrate_step` 会记录 `failed_units` 和 `failed_paths`。`dream_finish_step` 不会
+checkpoint 这些来源路径,因此下一次 `auto_dream` 仍会重新处理它们。
+
+这保证了 auto_link 的写入具有可重试性:失败不会把输入标成已完成,也不会静默丢失应该建立的 digest 边。
diff --git a/docs/zh/auto_memory.md b/docs/zh/auto_memory.md
new file mode 100644
index 00000000..5229f0e3
--- /dev/null
+++ b/docs/zh/auto_memory.md
@@ -0,0 +1,70 @@
+# Auto Memory
+
+Auto Memory 是 ReMe 的对话记忆入口:每段对话先按 `session_id` 沉淀成一张 daily 记忆卡片,再由当天的 `YYYY-MM-DD.md`
+统一索引。它负责把“聊过”变成“记住”,并把原始对话留好出处。
+
+关于 `daily/`、`reme_session/`、frontmatter 和 wikilink 的通用文件语义,见 [Memory as File](./memory_as_file.md)。
+
+```text
+Conversation
+ ├─ step 1: daily/YYYY-MM-DD/.md # 每段对话先成卡片
+ ├─ step 2: daily/YYYY-MM-DD.md # 当天索引再串起来
+ └─ source: reme_session/dialog/.jsonl # 原始对话
+```
+
+## 它记录什么
+
+它不记录聊天流水账,只记录以后可能还会用到的内容:
+
+- 用户偏好:喜欢什么风格、习惯怎么协作、长期要求是什么。
+- 关键事实:项目背景、重要数字、明确结论、限制条件。
+- 过程决定:发生了什么,为什么这么选,哪些方案被放弃。
+- 当前状态:做到哪一步,卡在哪里,下一步是什么。
+- 可复用经验:命令、流程、排查方法、解决方案。
+
+## 写入位置
+
+Auto Memory 会把整理后的记忆放进 `daily/`。当天发生的对话会先被整理成一张张小卡片:
+
+示例目录:
+
+```text
+vault/
+ daily/
+ 2026-06-20.md
+ 2026-06-20/
+ session-a.md
+ session-b.md
+```
+
+其中 `daily/2026-06-20/session-a.md`、`daily/2026-06-20/session-b.md` 是不同对话整理出的记忆卡片,
+`daily/2026-06-20.md` 是当天索引页。资源文件也会进入同一个 daily 工作台,见 [Auto Resource](./auto_resource.md)。
+
+当调用时带上 `session_id`,Auto Memory 会按这个 id 单独记录这段对话:
+
+```text
+daily/2026-06-20/session-a.md
+```
+
+这样不同对话不会混在一起。一次需求讨论、一次问题排查、一次文档修改,都可以拥有自己的记忆卡片。以后想知道这一天发生了什么,先看
+`YYYY-MM-DD.md`;想看某段对话沉淀了什么,再进入对应的 `.md`。
+
+## 同时保存原始信息
+
+整理后的 daily note 负责“好读”,原始对话负责“可信”。
+
+Auto Memory 在生成记忆卡片的同时,也会保存原始会话:
+
+```text
+reme_session/
+ dialog/
+ session-a.jsonl
+ session-b.jsonl
+```
+
+daily note 会指向对应的原始对话。需要核对某条记忆时,可以顺着链接回到当时的完整上下文。
+
+## 后续流向
+
+Auto Memory 只生成 daily 层记忆。要把这些材料进一步沉淀为长期 `digest/` 节点,使用 [Auto Dream](./auto_dream.md);要搜索
+daily 和 digest,使用 [Memory Search](./memory_search.md)。
diff --git a/docs/zh/auto_resource.md b/docs/zh/auto_resource.md
new file mode 100644
index 00000000..02e49c80
--- /dev/null
+++ b/docs/zh/auto_resource.md
@@ -0,0 +1,79 @@
+# Auto Resource `Beta`
+
+Auto Resource 是 ReMe 的资源解读入口,目前处于 **Beta**。资源文件先按日期进入 `resource/`,再被解读成同名 daily
+资源卡片,最后由当天的 `YYYY-MM-DD.md` 统一索引。
+
+关于 vault 分层、`resource/` 和 `daily/` 的通用文件语义,见 [Memory as File](./memory_as_file.md)。对话进入 daily 的流程见
+[Auto Memory](./auto_memory.md)。
+
+```text
+resource/YYYY-MM-DD/
+ ├─ step 1: daily/YYYY-MM-DD/.md # 资源解读卡片
+ ├─ step 2: daily/YYYY-MM-DD.md # 当天索引再串起来
+ └─ source: resource/YYYY-MM-DD/ # 原始资源保留原位
+```
+
+## 它记录什么
+
+它不只是搬运文件内容,而是把资料里以后方便检索和理解的信息提炼出来:
+
+- 核心内容:这份资料主要讲什么。
+- 结构脉络:章节、表格、字段、数据组织方式。
+- 关键细节:重要数字、名称、日期、结论。
+- 背景用途:这份资料为什么存在,和当前工作有什么关系。
+- 可行动项:任务、截止时间、后续跟进。
+
+简单说,它负责把“文件存档”变成“资料可用”。
+
+## 原始资料入口
+
+Auto Resource 以 `resource/` 作为原始资料入口。资源需要按日期放置,这个日期会决定它进入哪一天的 daily 工作台。
+
+示例目录:
+
+```text
+vault/
+ resource/
+ 2026-06-20/
+ market-report.md
+ meeting-notes.csv
+```
+
+当前 Beta 版本更适合处理文本类资源,例如 `md`、`txt`、`json`、`jsonl`、`csv`、`yaml`、`html`。
+
+## 资源卡片
+
+每个资源文件会生成一张同名 daily 资源卡片。文件名 stem 会成为卡片名:
+
+```text
+resource/2026-06-20/market-report.md
+ ↓
+daily/2026-06-20/market-report.md
+```
+
+如果资源文件更新,Auto Resource 会重新解读并更新这张卡片;如果资源文件删除,对应的 daily note 也会被清理。
+
+## 当天索引
+
+资源卡片会进入和 Auto Memory 相同的 daily 工作台。当天的 `YYYY-MM-DD.md` 会作为索引页,把这些资源卡片组织起来:
+
+```text
+daily/
+ 2026-06-20.md
+ 2026-06-20/
+ market-report.md
+ meeting-notes.md
+```
+
+以后想回看这一天处理过哪些资料,先看 `YYYY-MM-DD.md`;想看某份资料沉淀了什么,再进入对应的资源卡片。
+
+## 同时保留原始资料
+
+解读后的 daily note 负责“好读”,原始资源负责“可信”。
+
+Auto Resource 不会把原始文件挪走:它仍然留在 `resource/YYYY-MM-DD/`。这样,文本资料会进入 daily 记忆流,原始文件也始终保留在它来时的位置。
+
+## 后续流向
+
+Auto Resource 只生成 daily 层的资源解读。要把资源中的长期知识沉淀进 `digest/`,使用 [Auto Dream](./auto_dream.md);要检索原始资源、
+daily 卡片和 digest 节点,使用 [Memory Search](./memory_search.md)。
diff --git a/docs/zh/contributing.md b/docs/zh/contributing.md
new file mode 100644
index 00000000..87396ff2
--- /dev/null
+++ b/docs/zh/contributing.md
@@ -0,0 +1,206 @@
+# 开源与贡献
+
+ReMe 已开源,项目仓库托管于 GitHub:
+
+**https://github.com/agentscope-ai/ReMe**
+
+---
+
+## 如何参与贡献
+
+感谢你对 ReMe 的关注。ReMe 是一个面向 Agent 的、文件优先的自进化记忆系统,欢迎通过问题反馈、文档改进、测试补充、Bug
+修复和新能力开发参与贡献。
+
+如果是第一次本地运行,先看 [快速开始](./quick_start.md)。如果改动涉及运行时分层、Job、Step 或组件,先看
+[ReMe 代码框架](./framework.md);如果改动涉及 vault 目录、frontmatter、wikilink 或 chunking,先看
+[Memory as File](./memory_as_file.md)。
+
+### 1. 开始之前
+
+在投入实现前,建议先完成以下检查:
+
+- 查看 [Open Issues](https://github.com/agentscope-ai/ReMe/issues),确认是否已有相关问题或讨论。
+- 如果相关 Issue 已存在且仍开放,请在评论中说明你想处理它,避免重复工作。
+- 如果没有相关 Issue,请新建 Issue 描述背景、目标行为、可能的实现方向和影响范围。
+- 对较大的功能变更,建议先和维护者对齐接口、配置、兼容性和测试策略,再提交实现。
+
+### 2. 本地开发环境
+
+ReMe 的核心代码位于:
+
+- `reme/`:Python 包源码,包括配置、组件、服务、Job、Step、schema 和工具函数。
+- `pyproject.toml`:项目元数据、依赖、可选依赖、命令入口和测试配置。
+- `tests/`:单元测试和集成测试。
+
+项目要求 Python 3.11 及以上。建议使用虚拟环境开发:
+
+```bash
+python -m venv .venv
+source .venv/bin/activate
+pip install -e ".[dev,full]"
+pre-commit install
+```
+
+### 3. 代码开发范式
+
+开发 ReMe 代码前,请先阅读 [ReMe 代码框架](./framework.md)。新增或修改核心能力时,应遵照其中描述的分层与调用链:
+
+```text
+CLI / Client -> Service -> Application -> Job -> Step -> Component / Vault
+```
+
+也就是说:
+
+- 面向用户或外部系统暴露的能力,优先通过 Job 编排,再由 Service 暴露为 CLI、HTTP 或 MCP 可调用接口。
+- 可复用基础设施放在 `reme/components/`,通过 `BaseComponent.bind()` 声明组件依赖。
+- 业务原子操作放在 `reme/steps/`,通过 `BaseStep.Ref` 访问 file store、agent wrapper、catalog、LLM 等组件。
+- 请求、响应和持久化数据结构放在 `reme/schema/` 或 `reme/enumeration/`,不要把隐式结构散落在 Step 内部。
+- 配置驱动的默认行为写入 `reme/config/default.yaml`,并保持默认配置可启动、可测试。
+
+新增 Step 或 Job 时,特别注意以下约定:
+
+- 使用 `@R.register("")` 注册实现,注册名应稳定、清晰,并与配置中的 `backend` 对齐。
+- 新增 Step 文件后,确认所在包的 `__init__.py` 会 import 该模块,否则注册表不会加载它。
+- Step 只处理单个业务原子操作;跨步骤流程应放在 Job 配置或专门的编排 Step 中。
+- Job 负责组合 Step,并决定普通、流式、后台或定时执行方式;是否对外暴露由 `enable_serve` 控制。
+- Step 需要组件时优先使用 `BaseStep.Ref`,不要在 Step 内重新构造全局组件或绕过 `ApplicationContext`。
+- 涉及文件、索引、图谱、front matter、wikilink 的行为,应保持 vault-relative 路径语义一致。
+- 新能力应补充 `tests/unit/` 中的快速测试;跨组件、LLM、embedding 或服务行为再放入 `tests/integration/`。
+
+### 4. 代码与文档修改建议
+
+根据改动类型选择合适的入口:
+
+| 改动类型 | 主要位置 | 建议 |
+|------------|-----------------------------------------------------|---------------------------------------------------------------------------|
+| 配置或启动行为 | `reme/config/`、`reme/application.py`、`reme/reme.py` | 保持默认配置可运行,避免破坏现有 CLI、HTTP 和 MCP 入口 |
+| 组件能力 | `reme/components/` | 优先复用 `BaseComponent`、registry 和上下文对象 |
+| Job 或 Step | `reme/components/job/`、`reme/steps/` | 遵照 [ReMe 代码框架](./framework.md) 的 Job -> Step 范式,保持请求、响应 schema 清晰,并补充对应测试 |
+| 数据结构 | `reme/schema/`、`reme/enumeration/` | 注意序列化兼容性和已有 front matter、wikilink 语义 |
+| 工具函数 | `reme/utils/` | 保持函数边界小,并用单元测试覆盖边界情况 |
+| 用户文档 | `docs/zh/`、`README.md` | 当用户可见行为变化时同步更新文档 |
+
+如果改动涉及 LLM、embedding、外部服务、文件监听或后台任务,请同时说明依赖条件、失败行为和本地验证方式。
+
+### 5. 提交信息格式
+
+建议遵循 [Conventional Commits](https://www.conventionalcommits.org/) 规范,以保持历史记录清晰。
+
+格式:
+
+```text
+():
+```
+
+常用类型:
+
+- `feat`:新功能
+- `fix`:Bug 修复
+- `docs`:仅文档
+- `style`:代码风格调整,不改变行为
+- `refactor`:重构,不修复 Bug 也不添加功能
+- `perf`:性能改进
+- `test`:添加或更新测试
+- `chore`:构建、工具或维护工作
+
+示例:
+
+```bash
+feat(search): add link expansion option
+fix(file-graph): handle pending wikilinks after move
+docs(memory): update auto memory guide
+test(config): cover default yaml parsing
+chore(pre-commit): update lint hooks
+```
+
+### 6. Pull Request 标题
+
+PR 标题建议使用相同格式:
+
+```text
+():
+```
+
+要求:
+
+- 类型使用 `feat`、`fix`、`docs`、`test`、`refactor`、`chore`、`perf`、`style`、`build` 或 `revert`。
+- 作用域使用小写字母、数字、连字符或下划线。
+- 描述保持简短,说明这次 PR 的实际效果。
+
+示例:
+
+```text
+feat(auto-memory): persist source conversation metadata
+fix(markdown): keep wikilink aliases during edit
+docs(zh): add contribution guide
+```
+
+### 7. 提交前检查
+
+提交或发起 PR 前,请至少运行:
+
+```bash
+pre-commit run --all-files
+pytest
+```
+
+如果只改了局部代码,可以先运行更小范围的测试:
+
+```bash
+pytest tests/unit/test_search_step.py
+pytest tests/unit/test_reme_cli.py
+```
+
+如果 `pre-commit` 自动修改了文件,请提交这些修改后重新运行检查,直到全部通过。
+
+当前 pre-commit 配置包括 YAML/TOML/JSON 检查、私钥检测、尾随空格检查、`black`、`flake8`、`pylint` 和 `pyroma`。代码格式主要遵循:
+
+- `black --line-length=120`
+- `flake8 --max-line-length=120`
+- `pylint --max-line-length=120`
+
+部分集成测试可能依赖 LLM、embedding 或外部服务配置。若无法在本地完整运行,请在 PR 描述中说明跳过原因和已完成的替代验证。
+
+### 8. 测试要求
+
+请根据改动风险补充测试:
+
+- 修复 Bug 时,优先添加能复现问题的回归测试。
+- 新增 Step、Job 或组件时,至少补充核心路径和失败路径测试。
+- 修改索引、图谱、wikilink、front matter、文件读写等共享逻辑时,补充边界用例。
+- 修改 CLI、服务或配置解析时,覆盖用户可见入口。
+- 文档-only 改动通常不需要新增测试,但仍建议运行 `pre-commit run --all-files`。
+
+测试文件按现有结构放置:
+
+- `tests/unit/`:无需真实外部服务的快速测试。
+- `tests/integration/`:跨组件或依赖外部配置的集成测试。
+
+### 9. 文档贡献
+
+当你的修改会影响用户如何安装、配置、调用或理解 ReMe 时,请同步更新文档。
+
+文档位于:
+
+```text
+docs/
+```
+
+建议文档保持:
+
+- 标题明确,直接说明能力或流程。
+- 命令可以复制运行。
+- 涉及路径时使用仓库内真实路径,例如 `reme/config/default.yaml`、`reme/steps/`、`tests/unit/`。
+- 涉及默认行为时,以当前代码和 `pyproject.toml`、默认配置为准。
+
+---
+
+## 获取帮助
+
+- Bugs 和功能请求:[GitHub Issues](https://github.com/agentscope-ai/ReMe/issues)
+- 项目主页:[GitHub Repository](https://github.com/agentscope-ai/ReMe)
+- 文档站点:[https://reme.agentscope.io/](https://reme.agentscope.io/)
+
+---
+
+感谢你为 ReMe 做出贡献。你的改进会帮助 Agent 的长期记忆更可读、可控、可维护。
diff --git a/docs/zh/framework.md b/docs/zh/framework.md
new file mode 100644
index 00000000..395e91e6
--- /dev/null
+++ b/docs/zh/framework.md
@@ -0,0 +1,763 @@
+# ReMe 代码框架
+
+## 1. 总览
+
+ReMe 的运行时可以理解为:**配置驱动的 Application 把组件和 Job 装配起来,Service 把可服务的 Job 暴露给 CLI、HTTP 或 MCP,Job
+再按顺序执行 Step**。
+
+
+
+如果只想先运行和使用 ReMe,见 [快速开始](./quick_start.md)。vault 文件语义见 [Memory as File](./memory_as_file.md);检索、
+自动记忆和主动读取的用户侧说明分别见 [Memory Search](./memory_search.md)、[Auto Memory](./auto_memory.md)、
+[Auto Resource](./auto_resource.md)、[Auto Dream](./auto_dream.md) 和 [Proactive](./proactive.md)。
+
+```mermaid
+flowchart LR
+ CLI["reme CLI
reme/reme.py"] --> Client["Client
http / mcp"]
+ Client --> Service["Service
HTTP / MCP"]
+ Service --> App["Application
reme/application.py"]
+ App --> Jobs["Jobs
base / stream / background / cron"]
+ Jobs --> Steps["Steps
reme/steps/**"]
+ Steps --> Ctx["RuntimeContext
data + Response + stream queue"]
+ Steps --> Components["Components
store / graph / index / llm / agent / catalog"]
+ Components --> Vault["Vault
daily / digest / resource / reme_metadata"]
+```
+
+核心分层:
+
+| 层 | 主要目录 | 职责 |
+|-------------|----------------------------|--------------------------------------------------------------|
+| CLI | `reme/reme.py` | 解析命令;`start` 启动服务;其他 action 通过 client 调用服务 |
+| Service | `reme/components/service/` | 把 Job 注册成 HTTP endpoint 或 MCP tool |
+| Application | `reme/application.py` | 读取配置后的对象装配、依赖拓扑启动、关闭、Job 调用 |
+| Job | `reme/components/job/` | 编排一组 Step;决定同步、流式、后台、定时运行方式 |
+| Step | `reme/steps/` | 业务原子操作,例如读写文件、检索、索引、自进化 |
+| Component | `reme/components/` | 可复用基础设施,例如 file_store、file_graph、keyword_index、agent_wrapper |
+| Schema | `reme/schema/` | `Request`、`Response`、`FileChunk`、`FileNode`、配置模型等数据结构 |
+| Config | `reme/config/` | 默认 YAML 配置和命令行覆盖解析 |
+
+## 2. 目录结构
+
+```text
+reme/
+ reme.py # CLI 入口
+ application.py # Application 装配与生命周期
+ config/
+ default.yaml # 默认 service / jobs / components
+ config_parser.py # config=、dot notation、env 占位符解析
+ components/
+ component_registry.py # 全局注册表 R
+ base_component.py # ComponentMixin / BaseComponent / bind 依赖声明
+ runtime_context.py # 单次 Job 执行上下文
+ job/ # BaseJob / StreamJob / BackgroundJob / CronJob
+ service/ # HTTP / MCP 服务
+ client/ # HTTP / MCP 客户端
+ file_store/ # 文件索引协调层
+ file_graph/ # wikilink 图谱
+ keyword_index/ # BM25 等关键词索引
+ file_chunker/ # Markdown / 默认文本分块
+ file_catalog/ # 变更 checkpoint
+ as_llm/, as_embedding/ # 模型封装
+ agent_wrapper/ # AgentScope / Claude Code wrapper
+ steps/
+ base_step.py # BaseStep、Ref、dispatch_steps
+ common/ # version、help、health_check、demo
+ file_io/ # read/write/edit/delete/move/frontmatter/daily
+ index/ # watch/init/update/search/traverse
+ evolve/ # auto_memory、auto_resource、auto_dream、proactive
+ transfer/ # upload/download/ingest
+ channel/ # MCP channel 工具
+```
+
+默认 vault 目录由 `ApplicationConfig` 定义:
+
+```text
+/
+ reme_metadata/ # file_store、file_graph、keyword_index、file_catalog 等持久状态
+ reme_session/ # Agent session 与原始对话
+ resource/ # 外部资源
+ daily/ # 浅加工记忆
+ digest/ # 长期 digest 记忆
+```
+
+`Application.__init__()` 会先确保这些目录存在,然后初始化 service、components、jobs。
+
+## 3. 启动与调用链
+
+### 3.1 CLI
+
+入口是 `reme/reme.py::main()`:
+
+```mermaid
+flowchart LR
+ A["main()"] --> B["parse_args(*sys.argv[1:])"]
+ B --> C{action}
+ C -->|" start "| D["load_env()"]
+ D --> E["resolve_app_config(**kwargs)"]
+ E --> F["precheck_start(service)"]
+ F --> G["ReMe(**config).run_app()"]
+ C -->|" find_reme "| H["cli_find_reme()"]
+ C -->|" 其他 action "| I["call_server(action, **kwargs)"]
+ I --> J["R.get(ComponentEnum.CLIENT, backend)"]
+ J --> K["client(action=action, **kwargs)"]
+```
+
+常用命令:
+
+```bash
+reme start
+reme start service.port=8181
+reme version
+reme search query="memory" limit=5
+reme search query="memory" backend=mcp
+```
+
+配置解析支持:
+
+| 能力 | 源码 | 说明 |
+|--------------|-------------------------|---------------------------------------------|
+| 默认配置 | `resolve_app_config()` | 未指定 `config` 时加载 `reme/config/default.yaml` |
+| 指定配置 | `config=` | 可传内置配置名或 YAML/JSON 文件路径 |
+| dot notation | `parse_dot_notation()` | 例如 `service.port=8181` |
+| 环境变量 | `_expand_env_vars()` | 支持 `${VAR}` 和 `${VAR:-default}` |
+| 值转换 | `_convert_value()` | bool、int、float、JSON list/dict/null 会自动转换 |
+
+### 3.2 Service
+
+`BaseService.run_app()` 的顺序:
+
+```mermaid
+flowchart LR
+ A["Service.build_service(app)"] --> B["读取 app.context.jobs"]
+ B --> C{"job.enable_serve == true?"}
+ C -->|是| D["Service.add_job(job)"]
+ C -->|否| E["跳过注册"]
+ D --> F["Service.start_service(app)"]
+ E --> F
+ F --> G["lifespan 中 app.start()"]
+ G --> H["Application 启动 jobs"]
+```
+
+HTTP service 行为:
+
+| Job 类型 | HTTP 暴露方式 |
+|--------------------------------------|-------------------------------------------|
+| 非 `StreamJob` 且 `enable_serve: true` | `POST /`,返回 `Response` JSON |
+| `StreamJob` | `POST /`,返回 `text/event-stream` |
+| `enable_serve: false` | 不注册 endpoint |
+
+MCP service 行为:
+
+| Job 类型 | MCP 暴露方式 |
+|--------------------------------------|---------------------------------|
+| 非 `StreamJob` 且 `enable_serve: true` | 注册为 MCP tool |
+| `StreamJob` | 当前跳过,不注册 |
+| `BackgroundJob` | 构造时强制 `enable_serve=False`,不会暴露 |
+
+## 4. Registry 与依赖注入
+
+### 4.1 全局注册表 R
+
+ReMe 使用进程级单例 `R = ComponentRegistry()`。所有组件、Job、Step 都通过 `@R.register("name")` 注册。
+
+```python
+from ...components import R
+
+
+@R.register("version_step")
+class VersionStep(BaseStep):
+ ...
+```
+
+注册表 key 是:
+
+```text
+(component_type, register_name) -> class
+```
+
+其中 `component_type` 来自类属性,例如:
+
+| 类型 | 类属性 |
+|-----------|-----------------------------------------------------------|
+| Step | `BaseStep.component_type = ComponentEnum.STEP` |
+| Job | `BaseJob.component_type = ComponentEnum.JOB` |
+| Service | `BaseService.component_type = ComponentEnum.SERVICE` |
+| FileStore | `BaseFileStore.component_type = ComponentEnum.FILE_STORE` |
+
+所以同名 backend 在不同 component type 下可以共存。例如 `http` 同时可以是 service backend 和 client backend。
+
+### 4.2 模块导入触发注册
+
+注册发生在模块 import 时。`reme/components/__init__.py` 会 import 各组件包,`reme/steps/__init__.py` 会 import
+`channel/common/evolve/file_io/index/transfer`。这些包的 `__init__.py` 再 import 具体模块,从而执行 `@R.register(...)`。
+
+新增 Step 文件后,必须保证它所在包的 `__init__.py` 会 import 该模块,否则注册表里找不到这个 backend。
+
+### 4.3 Component.bind
+
+组件之间的依赖用 `BaseComponent.bind()` 声明。启动时 `Application._topological_order()` 读取每个组件的 `dependencies`
+,按拓扑顺序启动。
+
+```mermaid
+flowchart LR
+ A["Component.__init__
self.keyword_index = self.bind(...)"] --> B["Dependency placeholder"]
+ B --> C["Application._topological_order()"]
+ C --> D["component.start()"]
+ D --> E["_resolve_bindings()"]
+ E --> F["self.keyword_index = app_context.components[type][name]"]
+ F --> G["component._start()"]
+```
+
+`BaseComponent.bind(name, BaseClass, optional=True)` 的规则:
+
+| 场景 | 行为 |
+|------------------------|--------------------------------------------|
+| `name` 为空 | 返回 `None`,跳过依赖 |
+| `app_context` 存在 | 从 `app_context.components[ctype][name]` 查找 |
+| 依赖缺失且 `optional=True` | 解析为 `None` |
+| 依赖缺失且 `optional=False` | 启动时报错 |
+| standalone 模式 | 可用 `default_factory` 创建自有组件 |
+
+### 4.4 Step.Ref
+
+Step 不参与组件拓扑启动,它每次 Job 调用时临时创建。Step 访问组件主要靠 `BaseStep.Ref`:
+
+```python
+file_store: BaseFileStore = Ref(BaseFileStore, ComponentEnum.FILE_STORE)
+agent_wrapper: BaseAgentWrapper = Ref(BaseAgentWrapper, ComponentEnum.AGENT_WRAPPER, optional=True)
+```
+
+解析优先级:
+
+```mermaid
+flowchart LR
+ A["访问 self.file_store"] --> B{"kwargs 里有同名对象?"}
+ B -->|是| C["使用 kwargs 对象"]
+ B -->|否| D{"context.data 里有同名对象?"}
+ D -->|是| E["使用 context 对象"]
+ D -->|否| F["读取 kwargs['file_store'] 名称,默认 default"]
+ F --> G["app_context.components[FILE_STORE][name]"]
+```
+
+因此在 step 配置里可以写:
+
+```yaml
+steps:
+ - backend: update_catalog_step
+ file_catalog: resource
+```
+
+这里 `file_catalog: resource` 表示解析名为 `resource` 的 `file_catalog` 组件。
+
+## 5. Application 生命周期
+
+`Application` 的职责是把配置转换成运行时对象,并按顺序启动和关闭。
+
+```mermaid
+flowchart LR
+ A["Application(**kwargs)"] --> B["ApplicationContext(**kwargs)
解析 ApplicationConfig"]
+ B --> C["_setup_vault_directories()"]
+ C --> D["_init_service()"]
+ D --> E["_init_components()"]
+ E --> F["_init_jobs()"]
+ F --> G["run_app()"]
+ G --> H["service.run_app(app)"]
+```
+
+启动顺序在 `Application._start()` 中:
+
+```mermaid
+flowchart LR
+ A["创建 thread_pool,可选"] --> B["components 拓扑排序"]
+ B --> C["启动 components"]
+ C --> D["启动 BaseJob"]
+ D --> E["启动 StreamJob"]
+ E --> F["启动 BackgroundJob"]
+ F --> G["启动 CronJob"]
+```
+
+关闭时按 `_started_components` 的反序关闭,保证依赖方先关闭,被依赖方后关闭。
+
+## 6. Job 模型
+
+Job 是外部可调用能力或后台任务的编排单元。配置位置是 `reme/config/default.yaml` 的 `jobs:`。
+
+### 6.1 BaseJob
+
+`BaseJob` 是最常见的请求型 Job:
+
+```mermaid
+flowchart LR
+ Caller["Caller"] --> Job["BaseJob
job(**kwargs)"]
+ Job --> Ctx["RuntimeContext
merged_kwargs"]
+ Ctx --> S1["Step 1
await step(context)"]
+ S1 --> D1["读写 context.data / response"]
+ D1 --> S2["Step 2
await step(context)"]
+ S2 --> D2["读写 context.data / response"]
+ D2 --> Resp["context.response"]
+ Resp --> Caller
+```
+
+关键源码行为:
+
+| 源码 | 行为 |
+|------------------|-------------------------------------------------|
+| `_start()` | 把 YAML 中每个 step config 解析成 `(step_cls, params)` |
+| `_build_steps()` | 每次调用都创建新的 Step 实例,避免跨请求共享状态 |
+| `__call__()` | 创建 `RuntimeContext`,按顺序执行 step |
+| 异常处理 | 捕获异常,`response.success=False`,`answer=str(e)` |
+
+### 6.2 StreamJob
+
+`StreamJob` 继承 `BaseJob`,但返回流式 chunk:
+
+| 行为 | 说明 |
+|---------|---------------------------------------------------------|
+| context | 带 `stream_queue` |
+| Step 输出 | 调用 `context.add_stream_string(text, ChunkEnum.CONTENT)` |
+| 异常 | 写入 `ChunkEnum.ERROR` |
+| 结束 | 总是发送 `DONE` chunk |
+
+### 6.3 BackgroundJob
+
+`BackgroundJob` 用于长运行循环,例如文件监听。它在构造时强制 `enable_serve=False`。
+
+```mermaid
+flowchart LR
+ A["Application 启动 BackgroundJob"] --> B["_start() 创建 stop_event 和 task"]
+ B --> C["_run_with_supervisor()"]
+ C --> D["await self()"]
+ D --> E{"异常?"}
+ E -->|否,正常返回| F["结束"]
+ E -->|是且 supervisor = True| G["指数退避 + jitter"]
+ G --> C
+ E -->|是且 supervisor = False| H["抛出异常"]
+ I["close()"] --> J["stop_event.set()"]
+ J --> K["等待 close_timeout,超时 cancel"]
+```
+
+默认 `BackgroundJob.__call__()` 也会按顺序执行配置里的 steps,但异常不会被吞掉,便于 supervisor 重启。
+
+### 6.4 CronJob
+
+`CronJob` 继承 `BackgroundJob`,增加 `cron` 表达式:
+
+```yaml
+jobs:
+ nightly_dream:
+ backend: cron
+ cron: "0 3 * * *"
+ steps:
+ - backend: dream_extract_step
+ - backend: dream_integrate_step
+ - backend: dream_topics_step
+ - backend: dream_finish_step
+```
+
+当前实现使用 `croniter` 计算下一次触发时间,时区来自 `app_config.timezone`。
+
+### 6.5 默认 Job 类型分布
+
+```mermaid
+flowchart LR
+ Jobs["default.yaml jobs"] --> BG["background
index_update_loop
resource_watch_loop
digest_watch_loop"]
+ Jobs --> Base["base
version / help / health_check
search / node_search / traverse / reindex
read / write / edit / delete / move / list / stat
daily_create / daily_list / daily_reindex
auto_memory / auto_resource / auto_dream / proactive"]
+```
+
+## 7. Step 模型
+
+Step 是具体业务动作。所有 Step 都继承 `BaseStep` 并实现 `execute()`。
+
+```mermaid
+flowchart LR
+ A["Job._build_steps()"] --> B["Step.__init__()"]
+ B --> C["加载 prompt
类名对应 YAML + prompt_dict override"]
+ C --> D["Step.__call__(context, **kwargs)"]
+ D --> E["清理 Ref cache"]
+ E --> F["RuntimeContext.from_context()"]
+ F --> G["input_mapping"]
+ G --> H["execute()"]
+ H --> I["output_mapping"]
+ I --> J["返回 result"]
+```
+
+### 7.1 RuntimeContext
+
+`RuntimeContext` 是一次 Job 调用内所有 Step 共享的上下文:
+
+| 字段 | 说明 |
+|----------------|---------------------------------------------|
+| `response` | 最终返回的 `Response(answer, success, metadata)` |
+| `data` | 自由字典,保存输入参数和中间结果 |
+| `stream_queue` | 流式 Job 的输出队列 |
+| `stop_event` | 后台 Job 的停止信号 |
+
+Step 里常见写法:
+
+```python
+assert self.context is not None
+query = self.context.get("query", "")
+self.context["processed_query"] = query.strip().lower()
+self.context.response.answer = "..."
+self.context.response.metadata["key"] = "value"
+return self.context.response
+```
+
+### 7.2 input_mapping / output_mapping
+
+`BaseStep.__call__()` 会在执行前后调用 `RuntimeContext.apply_mapping()`:
+
+```yaml
+steps:
+ - backend: some_step
+ input_mapping:
+ user_query: query
+ output_mapping:
+ result: final_result
+```
+
+语义是把 `context.data[source]` 复制到 `context.data[target]`。
+
+### 7.3 dispatch_steps
+
+部分 Step 会产生批量事件,然后把事件分发给其他 Step。`BaseStep.dispatch_steps()` 会按配置解析并执行子 Step。
+
+默认配置中的例子:
+
+```yaml
+index_update_loop:
+ backend: background
+ watch_dirs: [ daily_dir, digest_dir ]
+ watch_suffixes: [ md ]
+ steps:
+ - backend: init_changes_step
+ monitor_type: file_store
+ monitor_name: default
+ dispatch_steps: [ update_index_step ]
+ - backend: watch_changes_step
+ dispatch_steps: [ update_index_step ]
+```
+
+流程图:
+
+```mermaid
+flowchart LR
+ Init["init_changes_step"] --> Batch["changes batch"]
+ Watch["watch_changes_step"] --> Batch
+ Batch --> Dispatch["dispatch_steps(...)"]
+ Dispatch --> Update["update_index_step"]
+ Update --> Store["file_store"]
+```
+
+## 8. 默认配置里的组件
+
+`reme/config/default.yaml` 当前默认组件:
+
+| ComponentEnum | 名称 | backend | 说明 |
+|-------------------|---------------------------------|--------------------------------|------------------------------------------------------|
+| `service` | 单例 | `http` | 默认 HTTP 服务 |
+| `tokenizer` | `default` | `regex` | BM25 分词器 |
+| `as_embedding` | `default` | `${EMBEDDING_BACKEND:-openai}` | embedding 模型封装 |
+| `embedding_store` | `default` | `local` | embedding 存储,依赖 `as_embedding: default` |
+| `as_llm` | `default` | `${LLM_BACKEND:-openai}` | LLM 模型封装 |
+| `agent_wrapper` | `default` | `agentscope` | AgentScope wrapper |
+| `agent_wrapper` | `claude_code` | `claude_code` | Claude Code wrapper |
+| `file_graph` | `default` | `local` | wikilink 图谱 |
+| `file_catalog` | `default/resource/digest/dream` | `local` | 文件变更 checkpoint |
+| `file_chunker` | `markdown` | `markdown` | Markdown AST 分块 |
+| `file_chunker` | `default` | `default` | 默认文本分块,当前支持 `jsonl` |
+| `keyword_index` | `default` | `bm25` | BM25 关键词索引 |
+| `file_store` | `default` | `local` | 组合 file_graph、keyword_index;默认 `embedding_store: ""` |
+
+注意:`search` step 的配置含 `vector_weight`,但默认 `file_store.default.embedding_store` 为空,因此实际是否有向量检索取决于运行配置是否启用
+embedding store。
+
+## 9. 新增 Step
+
+### 9.1 最小 Step
+
+假设要新增一个把输入文本转大写的 Step。
+
+新建文件,例如 `reme/steps/common/uppercase.py`:
+
+```python
+from ..base_step import BaseStep
+from ...components import R
+
+
+@R.register("uppercase_step")
+class UppercaseStep(BaseStep):
+ async def execute(self):
+ assert self.context is not None
+ text = self.context.get("text", "")
+ result = str(text).upper()
+
+ self.context["uppercase_text"] = result
+ self.context.response.answer = result
+ self.context.response.metadata["length"] = len(result)
+ return self.context.response
+```
+
+### 9.2 让 Step 被注册
+
+确认 `reme/steps/common/__init__.py` import 了新模块。新增:
+
+```python
+from . import uppercase
+```
+
+原因:`@R.register("uppercase_step")` 只有在模块被 import 后才会执行。
+
+### 9.3 访问组件
+
+如果 Step 需要访问已有组件,优先使用 `BaseStep` 已提供的 Ref:
+
+```python
+class MySearchStep(BaseStep):
+ async def execute(self):
+ assert self.context is not None
+ results = await self.file_store.keyword_search(
+ self.context.get("query", ""),
+ limit=5,
+ )
+ ...
+```
+
+可直接用的常见属性:
+
+| 属性 | 默认解析的组件 |
+|----------------------|------------------------------|
+| `self.as_llm` | `as_llm: default` 的 `.model` |
+| `self.agent_wrapper` | `agent_wrapper: default`,可选 |
+| `self.file_catalog` | `file_catalog: default`,可选 |
+| `self.file_store` | `file_store: default` |
+
+如果希望 Job 配置指定非 default 组件:
+
+```yaml
+steps:
+ - backend: my_step
+ file_catalog: dream
+```
+
+### 9.4 Step 设计建议
+
+| 建议 | 原因 |
+|--------------------------------------------|--------------------------------------------|
+| 从 `context` 读取输入,向 `context` 写中间结果 | 多 Step Job 依赖同一个上下文传递数据 |
+| 最终结果写到 `context.response` | Service 和 client 只关心标准 `Response` |
+| 不在 Step 实例上保存请求级状态 | 每次 Job 调用会重建 Step,但保持无状态更容易测试 |
+| 需要中断的后台循环检查 `context.stop_event` | `BackgroundJob.close()` 依赖 stop_event 优雅退出 |
+| 流式输出只在 StreamJob 中调用 `add_stream_string()` | 普通 Job 没有 stream queue |
+
+### 9.5 单测示例
+
+可以直接实例化 Step 并传入 `RuntimeContext`:
+
+```python
+import pytest
+
+from reme.components.runtime_context import RuntimeContext
+from reme.steps.common.uppercase import UppercaseStep
+
+
+@pytest.mark.asyncio
+async def test_uppercase_step():
+ ctx = RuntimeContext(text="hello")
+ resp = await UppercaseStep()(ctx)
+ assert resp.answer == "HELLO"
+ assert ctx["uppercase_text"] == "HELLO"
+```
+
+## 10. 新增 Job
+
+Job 通常不需要写 Python 类,只需要在配置里编排已有 Step。只有需要新的运行方式时,才新增 Job backend。
+
+### 10.1 新增普通请求型 Job
+
+在 YAML 配置的 `jobs:` 下新增:
+
+```yaml
+jobs:
+ uppercase:
+ backend: base
+ description: "Convert text to uppercase."
+ parameters:
+ type: object
+ properties:
+ text:
+ type: string
+ description: "input text"
+ required:
+ - text
+ steps:
+ - backend: uppercase_step
+```
+
+启动后调用:
+
+```bash
+reme start
+reme uppercase text="hello"
+```
+
+调用链:
+
+```mermaid
+flowchart LR
+ CLI["CLI
reme uppercase text=hello"] --> HTTP["HTTP Client"]
+ HTTP --> Req["POST /uppercase"]
+ Req --> S["HttpService"]
+ S --> J["uppercase BaseJob
job(text='hello')"]
+ J --> Step["uppercase_step
await step(context)"]
+ Step --> Resp["context.response.answer = HELLO"]
+ Resp --> JSON["Response JSON"]
+ JSON --> CLIOut["CLI print answer"]
+```
+
+### 10.2 新增多 Step Job
+
+一个 Job 可以串联多个 Step:
+
+```yaml
+jobs:
+ demo_echo:
+ backend: base
+ description: "Normalize query, then echo it."
+ parameters:
+ type: object
+ properties:
+ query:
+ type: string
+ default: ""
+ min_score:
+ type: number
+ default: 0.5
+ steps:
+ - backend: demo_echo_step1
+ - backend: demo_echo_step2
+```
+
+第一个 Step 写入:
+
+```text
+context["processed_query"]
+context["adjusted_min_score"]
+```
+
+第二个 Step 再读取这些字段并写最终 `response`。
+
+### 10.3 新增 Stream Job
+
+配置使用 `backend: stream`:
+
+```yaml
+jobs:
+ stream_uppercase:
+ backend: stream
+ description: "Stream uppercase text."
+ parameters:
+ type: object
+ properties:
+ text:
+ type: string
+ required:
+ - text
+ steps:
+ - backend: uppercase_prepare_step
+ - backend: uppercase_stream_step
+```
+
+流式 Step 示例:
+
+```python
+from ..base_step import BaseStep
+from ...components import R
+from ...enumeration import ChunkEnum
+
+
+@R.register("uppercase_stream_step")
+class UppercaseStreamStep(BaseStep):
+ async def execute(self):
+ assert self.context is not None
+ for ch in self.context.get("uppercase_text", ""):
+ await self.context.add_stream_string(ch, ChunkEnum.CONTENT)
+ return self.context.response
+```
+
+### 10.4 新增后台 Job
+
+配置使用 `backend: background`:
+
+```yaml
+jobs:
+ my_watch_loop:
+ backend: background
+ watch_dirs: [ daily_dir ]
+ watch_suffixes: [ md ]
+ steps:
+ - backend: init_changes_step
+ monitor_type: file_store
+ monitor_name: default
+ dispatch_steps: [ update_index_step ]
+ - backend: watch_changes_step
+ dispatch_steps: [ update_index_step ]
+```
+
+后台 Job 的特点:
+
+| 特点 | 说明 |
+|--------------|----------------------------------------------------|
+| 不对外暴露 | `BackgroundJob.__init__()` 强制 `enable_serve=False` |
+| 有 supervisor | 默认异常后指数退避重启 |
+| 有 stop_event | close 时通知循环退出 |
+| 适合监听/消费 | 文件监听、队列消费、周期性长循环 |
+
+### 10.5 新增 Cron Job
+
+配置使用 `backend: cron`:
+
+```yaml
+jobs:
+ daily_auto_dream:
+ backend: cron
+ cron: "30 3 * * *"
+ steps:
+ - backend: dream_extract_step
+ file_catalog: dream
+ - backend: dream_integrate_step
+ - backend: dream_topics_step
+ - backend: dream_finish_step
+ file_catalog: dream
+```
+
+`cron` 表达式无效时会在启动时报错。
+
+### 10.6 什么时候需要新增 Job backend
+
+大多数场景只需要新增 Step + YAML Job。只有这些情况才考虑新增 `reme/components/job/*.py`:
+
+| 需求 | 是否需要新 Job 类 |
+|----------------|---------------------------|
+| 新增一个业务命令 | 否,用 `backend: base` |
+| 串联多个已有步骤 | 否,用 `steps:` |
+| 要 SSE/流式输出 | 否,用 `backend: stream` |
+| 要后台循环 | 否,用 `backend: background` |
+| 要 cron 定时 | 否,用 `backend: cron` |
+| 要全新的调度/并发/事务语义 | 是,新增 Job backend |
+
+新增 Job backend 的最小形态:
+
+```python
+from .base_job import BaseJob
+from ..component_registry import R
+
+
+@R.register("my_job_backend")
+class MyJob(BaseJob):
+ async def __call__(self, **kwargs):
+ # 自定义调度逻辑
+ return await super().__call__(**kwargs)
+```
+
+同样需要确保模块被 `reme/components/job/__init__.py` import。
diff --git a/docs/zh/memory_as_file.md b/docs/zh/memory_as_file.md
new file mode 100644
index 00000000..589b5ab8
--- /dev/null
+++ b/docs/zh/memory_as_file.md
@@ -0,0 +1,356 @@
+# Memory as File
+
+ReMe 的核心思想是:**Memory as File, File as Memory**。
+
+
+
+**Memory as File**:长期记忆不是藏在黑盒数据库里,而是落在 vault 目录中的 Markdown 文件、资源文件和索引快照里。用户和 Agent
+都可以直接读、写、移动、删除这些文件。
+
+**File as Memory**:每个文件不只是普通文本,也是一个可索引、可链接、可演化的记忆节点。ReMe 会从文件中解析 frontmatter、正文
+chunk、wikilink 边,并把它们组织成检索和图谱。
+
+换句话说,文件是人的可读界面,也是 Agent 的操作接口;目录结构负责承载记忆分层,Markdown 语法负责表达内容、元数据和关系。
+
+## 设计目标
+
+ReMe 把记忆设计成文件,不只是为了“方便存储”,而是为了让长期记忆具备几个基本性质:
+
+| 目标 | 含义 |
+|----------|----------------------------------------------------------------------|
+| 可读 | 用户可以直接打开 vault,像读普通笔记一样读 daily、digest 和原始材料。 |
+| 可编辑 | 用户和 Agent 都能用文件操作修正、补充、移动或删除记忆,不必依赖专用数据库客户端。 |
+| 可追溯 | digest 中的长期结论可以通过 `derived_from:: [[...]]` 回到 daily、resource 或 session 原文。 |
+| 可迁移 | vault 是普通目录,Markdown、JSONL、YAML 和资源文件可以被备份、同步、版本管理或迁移到其他工具。 |
+| 可索引 | 文件虽然是普通文本,但 ReMe 会解析 frontmatter、chunk、wikilink,构建检索索引和文件图谱。 |
+| 可协作 | 人负责判断和修正,Agent 负责整理、链接和检索;二者看到和操作的是同一套文件。 |
+
+因此,ReMe 的记忆不是“数据库里的一条隐藏记录”,也不是“只给 LLM 看的 prompt 片段”。它首先是用户拥有的文件,其次才被系统索引成可召回的记忆。
+
+## 记忆分层
+
+ReMe 的 vault 把记忆分成四层:
+
+```text
+raw input -> reme_session/ + resource/
+working memory -> daily/
+long memory -> digest/
+system state -> reme_metadata/
+```
+
+这四层解决的是不同问题。
+
+`reme_session/` 和 `resource/` 保存原始输入。它们强调“不要丢现场”:对话、Agent session、上传资料、网页或报告先原样留下,作为以后核对的证据。
+
+`daily/` 是浅加工层。它把当天发生的对话和资源整理成更适合阅读的 daily note:什么事情发生了、有哪些结论、留下了哪些后续任务、对应原文在哪里。
+daily 不追求最终抽象,它更像当天工作台。
+
+`digest/` 是深加工层。这里保存的是可以长期复用的记忆节点,例如用户偏好、项目背景、流程经验、概念知识、决策先例。digest
+不应该只是复制 daily,而应该把多次出现的事实、方法和关系合并成更稳定的表述。
+
+`reme_metadata/` 是系统索引层。它保存 file catalog、chunk 索引、图谱快照等运行状态。用户通常不需要手写这里的内容;真正的人工编辑入口是
+`daily/`、`digest/` 和必要时的 `resource/`。
+
+这个分层让 ReMe 可以同时保留“现场”和“抽象”:daily 负责还原当时发生了什么,digest 负责回答以后还能复用什么。
+
+## 目录结构
+
+ReMe 用目录表达记忆组织和记忆分层。原始材料先进入 `resource/` 或 `reme_session/`,再沉淀到 `daily/`,最后由 `auto_dream`
+整合到 `digest/`。
+
+对应的自动流程分别是 [Auto Memory](./auto_memory.md)、[Auto Resource](./auto_resource.md) 和 [Auto Dream](./auto_dream.md)。
+检索这些文件时使用 [Memory Search](./memory_search.md)。
+
+```text
+/
+├── reme_metadata/ # 系统索引层;ReMe 索引、图谱、catalog 等持久状态,不作为人工编辑入口
+├── reme_session/ # 原始输入层;原始对话和 Agent session
+│ ├── dialog/
+│ │ └── .jsonl # auto_memory 保存的对话消息
+│ ├── agentscope/
+│ │ └── .jsonl
+│ └── claude_code/
+│ └── .jsonl
+├── resource/ # 原始输入层;外部原始材料
+│ └── YYYY-MM-DD/
+│ └── .
+├── daily/ # 浅加工层;按日期组织当天事实、对话摘要、资源解读
+│ ├── YYYY-MM-DD.md # 当天索引页
+│ └── YYYY-MM-DD/
+│ ├── .md # 对话加工后的 daily note
+│ ├── .md # 资源加工后的 daily note
+│ └── interests.yaml # auto_dream 产出的主动兴趣主题
+└── digest/ # 深加工层;可长期复用的个人事实、流程经验、知识节点
+ ├── personal/
+ │ └── .md # 用户画像、偏好、长期个人事实
+ ├── procedure/
+ │ └── .md # 流程、方法论、操作经验
+ └── wiki/
+ └── .md # 通用知识、概念、决策先例
+```
+
+典型流转如下:
+
+```text
+对话
+ -> reme_session/dialog/.jsonl
+ -> daily/YYYY-MM-DD/.md
+ -> digest/personal | digest/procedure | digest/wiki
+
+外部资料
+ -> resource/YYYY-MM-DD/.
+ -> daily/YYYY-MM-DD/.md
+ -> digest/wiki | digest/procedure
+```
+
+前两步偏向记录和整理,最后一步偏向长期沉淀。`auto_memory` 和 `auto_resource` 负责从原始输入生成 daily,`auto_dream`
+负责从 daily 抽取并整合 digest。
+
+## Markdown 格式
+
+ReMe 优先使用 Markdown 表达记忆,因为它同时适合人读、Agent 编辑和程序解析。
+
+一个典型记忆文件:
+
+```markdown
+---
+name: 光伏产业链研究
+description: 从硅料到组件的全链条梳理
+tags: [新能源, 光伏]
+---
+
+# 结论
+
+光伏产业链可以拆成 [[digest/wiki/硅料.md]]、硅片、电池片和组件。
+
+upstream:: [[digest/wiki/硅料.md]]
+[company:: [[digest/wiki/隆基绿能.md|隆基]]]
+```
+
+### Frontmatter
+
+Frontmatter 是文件开头的 YAML 块,用 `---` 包住:
+
+```markdown
+---
+name: 文档名
+description: 文档描述
+source_conversation: [[reme_session/dialog/abc.jsonl]]
+---
+```
+
+当前代码固定识别 `name` 和 `description`,其他字段会作为额外 metadata 保留。写入接口会把 `name`、`description` 和
+`metadata` 合并成 frontmatter。
+
+推荐把 frontmatter 当作“节点级摘要”,把正文当作“证据、解释和关系”。例如:
+
+```markdown
+---
+name: 用户偏好:文档说明风格
+description: 用户偏好直接、工程化、有上下文但不冗长的中文技术说明。
+kind: preference
+confidence: observed
+---
+
+用户多次要求文档补充动机、边界和例子,但避免营销式表述。
+
+derived_from:: [[daily/2026-06-20/session-a.md]]
+related:: [[digest/procedure/技术文档写作.md]]
+```
+
+这样做有三个好处:
+
+1. `name` 和 `description` 可以在列表、召回结果和 Agent 判断中作为轻量摘要。
+2. 正文可以承载更完整的事实、条件、反例和来源。
+3. `derived_from::`、`related::` 这类 typed wikilink 可以被图谱解析,后续移动文件时也能被维护。
+
+Frontmatter 适合放稳定、短小、结构化的字段;正文适合放需要人读的解释。不要把大段正文塞进 YAML 字段。
+
+### Wikilink
+
+Wikilink 用 `[[...]]` 表达文件之间的关系:
+
+```text
+[[digest/wiki/光伏.md]]
+[[digest/wiki/光伏.md#产业链]]
+[[digest/wiki/光伏.md|光伏]]
+![[resource/2026-06-01/report.md]]
+```
+
+ReMe 的 wikilink 是**字面路径语义**:
+
+```text
+[[X]] -> target_path = "X"
+```
+
+它不会自动补 `.md`,不会按文件名搜索,也不会自动解析 folder note。推荐写完整的 vault 相对路径,并带上扩展名。
+
+Wikilink 的作用:
+
+```text
+正文链接 -> 建立 FileLink
+predicate:: 链接 -> 建立带关系名的 FileLink
+move 文件 -> 默认改写入边中的 [[旧路径]]
+delete 文件 -> 返回仍存在的入边,提示清理引用
+search 命中 -> 可展开出入链,帮助理解上下文
+```
+
+支持的关系写法:
+
+```markdown
+industry:: [[digest/wiki/新能源.md]]
+[competitor:: [[digest/wiki/比亚迪.md]]]
+```
+
+解析结果:
+
+```text
+FileLink
+ source_path = 当前文件
+ target_path = digest/wiki/新能源.md
+ predicate = industry
+```
+
+### 来源和关系
+
+ReMe 里最重要的两类链接是来源链接和概念关系链接。
+
+来源链接说明“这条长期记忆从哪里来”:
+
+```markdown
+derived_from:: [[daily/2026-06-20/session-a.md]]
+derived_from:: [[resource/2026-06-20/report.pdf]]
+```
+
+概念关系链接说明“这个节点和哪些长期记忆有关”:
+
+```markdown
+related:: [[digest/wiki/光伏产业链.md]]
+depends_on:: [[digest/procedure/调研报告拆解流程.md]]
+contrasts_with:: [[digest/wiki/集中式逆变器.md]]
+```
+
+普通正文 wikilink 也会建立图边,但当关系本身有语义价值时,推荐使用 `predicate:: [[path]]`。这能让搜索、图遍历和后续 Agent
+整合更容易理解链接含义。
+
+## 人工编辑和 Agent 编辑
+
+因为记忆就是文件,用户可以直接在编辑器里改 vault;Agent 也可以通过 ReMe 的文件工具读写同一批文件。两者遵守同一套约定:
+
+| 操作 | 建议 |
+|--------|--------------------------------------------------------------------|
+| 新增记忆 | 写入合适目录,Markdown 使用 frontmatter,并尽量写完整 vault-relative wikilink。 |
+| 修改正文 | 保留已有来源和关键 wikilink;如果是修正旧结论,在正文里说明新材料如何改变旧判断。 |
+| 移动文件 | 使用 ReMe 的 move 工具时会默认改写入边中的旧路径;手工移动后建议重新检查入链。 |
+| 删除文件 | 删除前检查入链;ReMe 的 delete 会返回仍然指向目标的来源文件,方便清理悬空引用。 |
+| 修改元数据 | 用 frontmatter 表达短字段;正文发生实质变化时同步更新 `description`。 |
+
+一个实用规则是:**可以让 Agent 重写表达,但不要让它丢掉证据边**。尤其是 digest 节点中的 `derived_from:: [[...]]` 和已有
+digest-to-digest wikilink,是长期记忆可追溯和可扩展的基础。
+
+## 路径语义
+
+所有文件工具和 wikilink 都以 vault-relative path 为基本单位:
+
+```text
+digest/wiki/光伏.md
+daily/2026-06-20/session-a.md
+resource/2026-06-20/report.pdf
+```
+
+这带来一个明确边界:ReMe 不把 `[[光伏]]` 当作全库标题搜索,也不假设 Obsidian 式的同名解析。`[[digest/wiki/光伏.md]]`
+就是指向这个具体路径。
+
+推荐习惯:
+
+1. 链接 Markdown 文件时带上 `.md`。
+2. 从 digest 指向 daily 或 resource 时写完整来源路径。
+3. 文件重命名或移动尽量通过 ReMe 的 move 工具完成,避免留下旧路径。
+4. 对外部资源使用 `resource/YYYY-MM-DD/...`,对长期抽象使用 `digest/...`,不要把原始资料直接塞进 digest。
+
+这种显式路径语义牺牲了一点手写便利性,但换来的是可预测、可迁移和可自动维护。
+
+## Memory Chunking
+
+Memory chunking 是把一个文件拆成可检索片段的过程。ReMe 不是直接按固定长度切 Markdown,而是尽量保持语义结构。
+
+本节说明文件如何被切成检索 chunk;索引更新、BM25、向量召回和链接展开流程见 [Memory Search](./memory_search.md)。
+
+传统 RAG 常见做法是固定窗口切分:
+
+```text
+Document
+ |
+ | every N tokens + overlap
+ v
+chunk 1 | chunk 2 | chunk 3 | ...
+```
+
+这种方式简单,但容易把标题、表格、代码块、列表和 `[[wikilink]]` 从中间切开。检索命中后,Agent
+往往只看到一段孤立文本,不知道它属于哪个章节,也不清楚它和其他记忆节点的关系。
+
+ReMe 的 chunking 更接近“按文件结构切记忆”:
+
+```text
+Markdown file
+ |
+ | frontmatter + headings + blocks + wikilinks
+ v
+semantic chunks with document skeleton
+```
+
+对比:
+
+```text
+传统 RAG chunk
+ = 固定长度文本片段 + overlap
+
+ReMe memory chunk
+ = 章节结构 + 正文片段 + 行号范围 + wikilink 关系上下文
+```
+
+Markdown 文件使用 `MarkdownFileChunker`:
+
+```text
+Markdown
+ |
+ | mistletoe AST
+ v
+Document
+ └─ H1 section
+ ├─ paragraph / list / table / code
+ └─ H2 section
+ └─ ...
+ |
+ v
+FileChunk[]
+```
+
+分块规则:
+
+```text
+1. 先解析 frontmatter,正文单独进入 chunker。
+2. 按标题层级构建章节树。
+3. 优先让一个完整章节成为一个 chunk。
+4. 章节过长时,向下递归拆子章节和正文块。
+5. 表格拆分时重复表头。
+6. 代码块拆分时重复 fence。
+7. 列表按 item 打包。
+8. 最后才按行贪心拆分,并添加 [Part X/N]。
+```
+
+每个 chunk 默认会带上标题骨架:
+
+```text
+# 一级标题
+
+## 当前章节
+
+命中的正文片段
+
+## 后续章节标题
+```
+
+这样检索命中时,Agent 不只看到孤立段落,还能看到它在原文件中的结构位置。
+
+非 Markdown 默认走 `DefaultFileChunker`:按字节大小切分,并保留少量 overlap;对 Markdown 则会避免把 `[[wikilink]]` 从中间切开。
diff --git a/docs/zh/memory_search.md b/docs/zh/memory_search.md
new file mode 100644
index 00000000..94fa972e
--- /dev/null
+++ b/docs/zh/memory_search.md
@@ -0,0 +1,195 @@
+# Memory Search
+
+Memory Search 是 ReMe 的记忆检索入口。它先把 `daily/`、`digest/`、`resource/` 里的文件持续构建成可搜索的 chunk 索引和
+wikilink 图谱;查询时先召回最相关的片段,再沿着片段所在文件的双向链接展开上下文。
+
+
+
+文件分层、frontmatter、wikilink 和 chunking 的通用语义见 [Memory as File](./memory_as_file.md)。这里重点说明索引维护和查询执行。
+
+```text
+vault files
+ ├─ index_update_loop: 发现 added / modified / deleted
+ ├─ update_index_step: 文件 -> FileNode + FileChunk[]
+ ├─ file_store: 保存 chunk、BM25、可选 embedding、wikilink graph
+ └─ search_step: BM25 / vector 召回 -> RRF 融合 -> link expansion
+```
+
+## 它搜索什么
+
+默认配置里的 `index_update_loop` 监听三类记忆目录:
+
+- `daily_dir`:Auto Memory 生成的每日工作记忆和 session 记忆卡片。
+- `digest_dir`:长期沉淀后的 digest 节点。
+- `resource_dir`:外部资源或导入资料。
+
+默认后缀是 `md` 和 `jsonl`。其中 Markdown 用 `markdown` chunker,能解析 frontmatter、标题结构和 `[[wikilink]]`;`jsonl` 用
+`default` chunker,按字节大小做重叠切块。
+
+## 索引怎么构建
+
+索引由后台 Job `index_update_loop` 维护,配置来自 `reme/config/default.yaml`:
+
+```yaml
+index_update_loop:
+ backend: background
+ watch_dirs: [ daily_dir, digest_dir, resource_dir ]
+ watch_suffixes: [ md, jsonl ]
+ steps:
+ - backend: init_changes_step
+ monitor_type: file_store
+ monitor_name: default
+ dispatch_steps: [ update_index_step ]
+ - backend: watch_changes_step
+ dispatch_steps: [ update_index_step ]
+```
+
+启动时先跑 `init_changes_step`。它扫描 watch 目录,把磁盘上的文件 mtime 和 `file_store` 里已有的 `FileNode.st_mtime`
+对比,算出新增、修改、删除三类变化,然后把 `context["changes"]` 交给 `update_index_step`。
+
+服务运行期间由 `watch_changes_step` 接手。它用 `watchfiles.awatch()` 监听同一批目录,按 quiet window 聚合文件事件,再用
+`coalesce_changes()` 把同一路径上的重复事件压成一批稳定变化。
+
+`update_index_step` 真正写索引:
+
+1. 按后缀选择 file chunker。
+2. 把文件解析成一个 `FileNode` 和多个 `FileChunk`。
+3. 对新增或修改的文件,先删除旧 chunk,再 upsert 新 chunk。
+4. 对删除的文件,从 `file_store`、`keyword_index` 和 `file_graph` 清掉对应记录。
+5. 有变化时 dump 到 `reme_metadata/`,让下次启动可以恢复。
+
+Markdown chunker 会解析 YAML frontmatter、标题结构和 `[[...]]`,产出 `FileNode`、`FileChunk` 和 `FileLink`。更细的分块规则见
+[Memory as File](./memory_as_file.md#memory-chunking)。
+
+## file_store 里有什么
+
+默认 `file_store.default` 是 `local`:
+
+```yaml
+file_store:
+ default:
+ backend: local
+ embedding_store: ""
+ keyword_index: default
+ file_graph: default
+```
+
+它组合三类能力:
+
+| 部件 | 默认状态 | 作用 |
+|-------------------------|------|--------------------------------------|
+| `file_chunks` | 启用 | 保存 `FileChunk` 文本、行号、分数、可选 embedding |
+| `keyword_index.default` | 启用 | BM25 倒排索引,chunk id 是 doc id |
+| `file_graph.default` | 启用 | 保存 `FileNode` 和 wikilink 边 |
+| `embedding_store` | 默认关闭 | 开启后为 chunk 生成 embedding,并支持向量召回 |
+
+所以开箱搜索主要是 BM25 + 链接展开。把 `embedding_store: default` 打开后,`SearchStep` 会同时跑向量召回和关键词召回。
+
+## 怎么搜索
+
+`search` Job 也是在 `default.yaml` 中配置:
+
+```yaml
+search:
+ backend: base
+ description: "Hybrid vault search (vector + BM25, RRF-fused)."
+ parameters:
+ query: string
+ limit: integer
+ min_score: number
+ steps:
+ - backend: search_step
+ vector_weight: 0.7
+ candidate_multiplier: 3.0
+ expand_links: true
+ max_links_per_direction: 10
+```
+
+调用时:
+
+```bash
+reme search query="最近关于索引的讨论" limit=5
+```
+
+`search_step` 的执行顺序是:
+
+```mermaid
+flowchart LR
+ A["query + limit"] --> B["candidates = limit * candidate_multiplier"]
+ B --> C["file_store.vector_search(...)"]
+ B --> D["file_store.keyword_search(...)"]
+ C --> E["RRF 融合"]
+ D --> E
+ E --> F["min_score 过滤"]
+ F --> G["截断到 limit"]
+ G --> H["expand_links(...)"]
+ H --> I["Response.answer + metadata"]
+```
+
+如果只有 BM25 有结果,就直接返回 BM25 排名;如果只有向量有结果,就直接返回向量排名;两边都有结果时,用 RRF 融合。RRF 不直接比较
+BM25 分数和 cosine 分数,而是比较两个列表里的名次:
+
+```text
+fused_score = vector_weight / (60 + vector_rank)
+ + keyword_weight / (60 + keyword_rank)
+```
+
+默认 `vector_weight=0.7`,所以启用 embedding 后语义召回权重更高;关键词仍能把精确词命中的 chunk 拉上来。
+
+## BM25 怎么工作
+
+`keyword_search()` 调用 `keyword_index.retrieve(query, limit)`。BM25 索引里每个 chunk 是一篇文档:
+
+- `doc_id` 是 `FileChunk.id`。
+- `content` 是 `FileChunk.text`。
+- tokenizer 把文本切成 token。
+- 倒排表记录 token 出现在哪些 chunk 里、每个 chunk 的词频是多少。
+- 查询时只对 query token 命中的 posting list 打分,再返回分数最高的 chunk id。
+
+当文件被修改时,`LocalFileStore.upsert()` 会先删除该文件旧 `chunk_ids` 对应的 BM25 doc,再添加新 chunk 文本。删除采用 lazy
+delete,后续可通过 optimize 压缩索引。
+
+## 渐进式展开怎么看
+
+Memory Search 的“渐进式”不是一次把全库内容塞进结果,而是分三层展开:
+
+1. 第一层是 chunk 召回:只返回最相关的 `limit` 个文本片段。
+2. 第二层是文件定位:每个结果带 `path:start_line-end_line`,可以继续用 `read` 精读原文件。
+3. 第三层是链接邻居:对命中文件调用 `expand_links()`,展开最多 `max_links_per_direction` 个 outlinks 和 inlinks。
+
+展开的数据来自 `file_graph`,不是重新扫文件:
+
+```text
+命中 chunk
+ -> chunk.path
+ -> file_store.get_outlinks(path)
+ -> file_store.get_inlinks(path)
+ -> file_store.get_nodes(neighbor_paths)
+ -> 渲染邻居的 path、name、description、predicate、anchor
+```
+
+这让搜索结果既保持短,又能看到“这条记忆连接到哪些长期节点、资源或其他 daily note”。如果某条结果值得继续追,可以用
+`read path=...` 打开原文,或用 `traverse path=... depth=2` 沿 wikilink 图谱继续扩展。
+
+## 返回结果长什么样
+
+`SearchStep` 会把结果写到两个地方:
+
+- `response.answer`:给人看的文本,每个命中块包含路径、行号、分数和 chunk 内容,后面跟 outlinks / inlinks。
+- `response.metadata`:给程序看的结构化结果,包括 `results`、`link_expansion`、`counts`。
+
+典型文本结构:
+
+```text
+========== daily/2026-06-20/session-a.md:12-28 [score=0.0317 keyword=4.8120] ==========
+...命中的记忆片段...
+ outlinks (2):
+ -> digest/indexing.md name="Indexing" description="..."
+ via predicate=related
+ inlinks (1):
+ <- daily/2026-06-19.md name="..."
+ via plain
+```
+
+`counts` 会告诉你本次向量、关键词各召回了多少候选,以及最终返回多少条。默认 embedding 关闭时,`vector` 通常是 `0`,`hybrid` 是
+`false`。
diff --git a/docs/zh/proactive.md b/docs/zh/proactive.md
new file mode 100644
index 00000000..adf2b23b
--- /dev/null
+++ b/docs/zh/proactive.md
@@ -0,0 +1,132 @@
+# Proactive
+
+`proactive` 是 ReMe 的主动记忆读取接口。它不重新分析 daily,也不调用 LLM,只读取 `auto_dream` 写出的当天兴趣主题:
+
+```text
+daily//interests.yaml
+```
+
+上层 Agent 可以用它获取“今天值得主动关注什么”,再决定是否提醒、追问、推荐下一步或生成主动洞察。
+
+`interests.yaml` 由 [Auto Dream](./auto_dream.md) 的 Topics 阶段生成;`proactive` 只负责读取和暴露结果。
+
+## 配置入口
+
+默认配置在 `reme/config/default.yaml`:
+
+```yaml
+proactive:
+ backend: base
+ description: "Proactive: read daily//interests.yaml and expose the latest user-interest topics."
+ parameters:
+ date:
+ type: string
+ default: ""
+ include_content:
+ type: boolean
+ default: true
+ steps:
+ - backend: proactive_step
+```
+
+参数含义:
+
+| 参数 | 作用 |
+|-------------------|----------------------------------------|
+| `date` | 要读取的日期,格式为 `YYYY-MM-DD`。为空时使用应用时区中的今天。 |
+| `include_content` | 是否在 metadata 中返回 YAML 原文,默认 `true`。 |
+
+## 输入契约
+
+典型格式如下:
+
+```yaml
+date: 2026-06-20
+topic_count: 3
+diversity_days: 7
+topics:
+ - title: 记忆检索链路的质量回归
+ reason: 用户近期持续修改 search、node_search 和 dream 集成链路。
+ evidence: daily/2026-06-20/session.md
+ keywords:
+ - memory search
+ - auto dream
+ paths:
+ - daily/2026-06-20/session.md
+```
+
+只有 `topics` 列表会被解析成结构化结果。每个 topic 至少需要 `title` 和 `reason`;`evidence`、`keywords`、`paths` 是辅助字段。
+
+## 返回结果
+
+成功读取时,`proactive_step` 会把结果写入标准 response metadata:
+
+| 字段 | 说明 |
+|-----------|----------------------------------------|
+| `date` | 实际读取的日期。 |
+| `path` | `daily//interests.yaml`。 |
+| `topics` | 解析后的 topic 列表。 |
+| `content` | YAML 原文;仅在 `include_content=true` 时返回。 |
+| `skipped` | 文件不存在时为 `true`。 |
+| `error` | 读取或解析异常。 |
+| `summary` | 简短摘要。 |
+
+文件存在且解析成功时,answer 类似:
+
+```text
+Read 3 proactive topic(s) from daily/2026-06-20/interests.yaml
+```
+
+文件不存在时不会报错,而是成功返回 skipped:
+
+```text
+Skipped: interests file not found at daily/2026-06-20/interests.yaml
+```
+
+这让上层 Agent 可以把“今天还没有 dream 结果”当作正常空状态处理。
+
+## 运行方式
+
+CLI:
+
+```bash
+reme proactive date=2026-06-20
+```
+
+不返回 YAML 原文:
+
+```bash
+reme proactive date=2026-06-20 include_content=false
+```
+
+## 与 auto_dream 的关系
+
+`proactive` 是 `auto_dream` 的下游读取步骤:
+
+```text
+daily notes
+ -> auto_dream
+ -> daily//interests.yaml
+ -> proactive
+ -> upper-level agent
+```
+
+职责边界如下。更完整的 Extract、Integrate、Topics、Finish 说明见 [Auto Dream](./auto_dream.md):
+
+| 模块 | 职责 |
+|----------------------|----------------------------------------|
+| `dream_extract_step` | 从 changed daily 输入抽取 topic candidates。 |
+| `dream_topics_step` | 去重、筛选并写入 `interests.yaml`。 |
+| `proactive_step` | 读取 `interests.yaml`,暴露给上层 Agent。 |
+
+`proactive` 不修改任何文件,不更新 catalog,也不负责判断是否应该主动打扰用户。它只提供当天主题材料;是否推送、何时推送、用什么语气推送,应由调用方根据产品策略决定。
+
+## 失败模式
+
+| 场景 | 行为 |
+|----------------------|--------------------------------------------|
+| `interests.yaml` 不存在 | `success=true`,`skipped=true`,`topics=[]`。 |
+| YAML 无法读取或解析异常 | `success=false`,answer 返回错误摘要。 |
+| YAML 存在但没有合法 topics | `success=true`,`topics=[]`。 |
+
+因此推荐调用方先检查 `success`,再检查 `skipped`,最后检查 `topics` 是否为空。
diff --git a/docs/zh/quick_start.md b/docs/zh/quick_start.md
new file mode 100644
index 00000000..90ba99cc
--- /dev/null
+++ b/docs/zh/quick_start.md
@@ -0,0 +1,210 @@
+# 快速开始
+
+---
+
+## 安装
+
+ReMe 要求 Python 3.11+。
+
+从 pip 安装:
+
+```bash
+pip install "reme-ai[core]"
+```
+
+从源码安装:
+
+```bash
+git clone https://github.com/agentscope-ai/ReMe.git
+cd ReMe
+pip install -e ".[core]"
+```
+
+`core` extra 建议安装:当前代码会导入 AgentScope wrapper,自进化记忆也依赖它。
+
+如果要使用 `auto_memory`、`auto_resource`、`auto_dream` 这类 Agent 流程,再配置 LLM:
+
+```bash
+cat > .env <<'EOF'
+LLM_BACKEND=openai
+LLM_MODEL_NAME=qwen3.7-plus
+LLM_API_KEY=your_api_key
+LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
+EOF
+```
+
+只跑基础文件读写和 BM25 检索,可以先不配。
+
+---
+
+## 启动
+
+```bash
+reme start
+```
+
+默认服务地址是 `127.0.0.1:2333`。如果端口被占用:
+
+```bash
+reme start service.port=8181
+```
+
+```bash
+reme version
+reme health_check
+reme list
+```
+
+`reme list` 会列出服务端 action。普通命令会通过 HTTP 调用服务端 Job。
+
+---
+
+## Vault 目录
+
+默认 vault 是当前目录下的 `.reme/`,启动时会自动创建:
+
+```text
+.reme/
+├── reme_metadata/ # 索引、图谱、catalog 等持久状态
+├── reme_session/ # Agent session 与原始对话
+├── resource/ # 外部资料
+├── daily/ # daily note
+└── digest/ # 长期记忆
+```
+
+目录分层、Markdown frontmatter 和 wikilink 语义见 [Memory as File](./memory_as_file.md)。
+
+也可以启动时指定:
+
+```bash
+reme start vault_dir=/tmp/reme-demo service.port=8181
+```
+
+---
+
+## 写入、索引、检索
+
+```bash
+reme write \
+ path=digest/wiki/quick-start-demo \
+ name="Quick Start Demo" \
+ description="快速开始示例记忆" \
+ content="# Quick Start Demo
+
+ReMe 会索引 daily、digest 和 resource 目录中的 Markdown。
+
+相关链接:[[digest/wiki/search-demo.md]]"
+```
+
+`path` 是 vault 内路径;没有后缀时会自动补 `.md`;Markdown 文件会写入 `name` 和 `description` front matter。
+
+后台 watcher 会自动建索引;也可以手动重建:
+
+```bash
+reme reindex
+```
+
+搜索:
+
+```bash
+reme search query="快速开始 示例 记忆" limit=5
+```
+
+读取:
+
+```bash
+reme read path=digest/wiki/quick-start-demo start_line=1 end_line=20
+```
+
+默认配置下,检索主要是 BM25 + wikilink 图谱扩展;向量检索能力在代码中支持,但默认未启用 embedding store。完整检索流程见
+[Memory Search](./memory_search.md)。
+
+---
+
+## 文件与 Daily Note
+
+```bash
+reme stat path=digest/wiki/quick-start-demo
+reme edit path=digest/wiki/quick-start-demo old="会索引" new="会持续索引"
+reme frontmatter_read path=digest/wiki/quick-start-demo
+reme frontmatter_update path=digest/wiki/quick-start-demo metadata='{"tags":["demo"]}'
+```
+
+`list` 这个名字在 CLI 中用于 action 列表,所以文件列表 Job 需要用 HTTP 调:
+
+```bash
+curl -s http://127.0.0.1:2333/list \
+ -H 'Content-Type: application/json' \
+ -d '{"path":"digest","recursive":true,"limit":50}'
+```
+
+Daily note:
+
+```bash
+reme daily_create session_id=demo-session
+reme daily_list
+reme daily_reindex
+```
+
+`daily_create` 会创建 `daily//.md`,并刷新 `daily/.md`。
+
+---
+
+## 自动记忆
+
+```bash
+reme auto_memory \
+ session_id=chat-demo \
+ messages='[{"role":"user","content":"我偏好把项目经验沉淀成 Markdown。"},{"role":"assistant","content":"已记录。"}]' \
+ memory_hint="记录用户偏好"
+```
+
+外部资料放入 `resource/YYYY-MM-DD/` 后,默认后台会监听 `md/txt/json/jsonl/csv/yaml/html`。也可以手动触发:
+
+```bash
+reme auto_resource changes='[{"path":"resource/2026-06-20/report.md","change":"added"}]'
+```
+
+把 daily 整理到长期 digest:
+
+```bash
+reme auto_dream date=2026-06-20
+reme proactive date=2026-06-20
+```
+
+这些流程需要可用 LLM;未配置 LLM 时请先使用 `write/read/search/daily_create` 这类基础能力。
+
+更多细节见 [Auto Memory](./auto_memory.md)、[Auto Resource](./auto_resource.md)、[Auto Dream](./auto_dream.md) 和
+[Proactive](./proactive.md)。
+
+---
+
+## HTTP 与配置
+
+每个可服务 Job 都暴露为 `POST /`:
+
+```bash
+curl -s http://127.0.0.1:2333/version \
+ -H 'Content-Type: application/json' \
+ -d '{}'
+
+curl -s http://127.0.0.1:2333/search \
+ -H 'Content-Type: application/json' \
+ -d '{"query":"快速开始","limit":5}'
+```
+
+默认配置来自 `reme/config/default.yaml`。启动时可以用 dot notation 覆盖:
+
+```bash
+reme start \
+ vault_dir=/tmp/reme-demo \
+ service.host=127.0.0.1 \
+ service.port=8181 \
+ enable_logo=false
+```
+
+也可以指定 YAML/JSON 配置文件:
+
+```bash
+reme start config=/path/to/custom.yaml
+```
diff --git a/README_old.md b/old.md
similarity index 99%
rename from README_old.md
rename to old.md
index 8d4c947d..210a11ce 100644
--- a/README_old.md
+++ b/old.md
@@ -29,6 +29,14 @@
---
+## 📰 最新文章
+
+| 日期 | 标题 |
+|------------|----------------------------------------------------|
+| 2026-03-30 | [CoPaw 上下文管理设计解析](docs/copaw_context_design_zh.md) |
+
+---
+
🧠 ReMe 是一个专为 **AI 智能体** 打造的记忆管理框架,同时提供基于[文件系统](#-基于文件的记忆系统-remelight)
和基于[向量库](#-基于向量库的记忆系统)的记忆系统。
diff --git a/pyproject.toml b/pyproject.toml
index bd5cbb8f..8023c378 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -72,6 +72,7 @@ include-package-data = true
[tool.setuptools.package-data]
"*" = ["py.typed", "**/*.yaml", "**/*.json"]
+"reme" = ["skills/**/*"]
"reme.components.tokenizer" = ["stopwords"]
[tool.setuptools.dynamic]
diff --git a/reme/config/default.yaml b/reme/config/default.yaml
index 158acc99..5f486064 100644
--- a/reme/config/default.yaml
+++ b/reme/config/default.yaml
@@ -4,10 +4,10 @@ service:
jobs:
index_update_loop:
backend: background
- # watch_dirs: [daily_dir, digest_dir, resource_dir]
- watch_dirs: [daily_dir, digest_dir]
- # watch_suffixes: [md, jsonl]
- watch_suffixes: [md]
+ watch_dirs: [daily_dir, digest_dir, resource_dir]
+# watch_dirs: [daily_dir, digest_dir]
+ watch_suffixes: [md, jsonl]
+# watch_suffixes: [md]
steps:
- backend: init_changes_step
monitor_type: file_store
diff --git a/reme/skills/qwenpaw_memory/SKILL.md b/reme/skills/qwenpaw_memory/SKILL.md
new file mode 100644
index 00000000..b5a84c11
--- /dev/null
+++ b/reme/skills/qwenpaw_memory/SKILL.md
@@ -0,0 +1,51 @@
+---
+name: qwenpaw_memory
+description: 记录、检索、更新重要信息
+---
+
+## 记忆
+
+每次会话都是全新的。工作目录下的文件是你的记忆延续:
+
+- **每日笔记:** `memory/YYYY-MM-DD.md`(按需创建 `memory/` 目录)— 发生事件的原始记录
+- **长期记忆:** `MEMORY.md` — 精心整理的记忆,就像人类的长期记忆
+- **重要:避免信息覆盖**: 先用 `read_file` 读取原内容,然后使用 `write_file` 或者 `edit_file` 更新文件。
+
+用这些文件来记录重要的东西,包括决策、上下文、需要记住的事。除非用户明确要求,否则不要在记忆中记录敏感的信息。
+
+### 🧠 MEMORY.md - 你的长期记忆
+
+- 出于**安全考虑** — 不应泄露给陌生人的个人信息
+- 你可以在主会话中**自由读取、编辑和更新** MEMORY.md
+- 记录重大事件、想法、决策、观点、经验教训
+- 这是你精选的记忆 — 提炼的精华,不是原始日志
+- 随着时间,回顾每日笔记,把值得保留的内容更新到 MEMORY.md
+
+### 📝 写下来 - 别只记在脑子里!
+
+- **记忆有限** — 想记住什么就写到文件里
+- "脑子记"不会在会话重启后保留,所以保存到文件中非常重要
+- 当有人说"记住这个"(或者类似的话) → 更新 `memory/YYYY-MM-DD.md` 或相关文件
+- 当你学到教训 → 更新 AGENTS.md、MEMORY.md 或相关技能文档
+- 当你犯了错 → 记下来,让未来的你避免重蹈覆辙
+- **写下来 远比 用脑子记住 更好**
+
+### 🎯 主动记录 - 别总是等人叫你记!
+
+对话中发现有价值的信息时,**先记下来,再回答问题**:
+
+- 用户提到的个人信息(名字、偏好、习惯、工作方式)→ 更新 `PROFILE.md` 的「用户资料」section
+- 对话中做出的重要决策或结论 → 记录到 `memory/YYYY-MM-DD.md`
+- 发现的项目上下文、技术细节、工作流程 → 写入相关文件
+- 用户表达的喜好或不满 → 更新 `PROFILE.md` 的「用户资料」section
+- 工具相关的本地配置(SSH、摄像头等)→ 更新 `MEMORY.md` 的「工具设置」section
+- 任何你觉得未来会话可能用到的信息 → 立刻记下来
+
+**关键原则:** 不要总是等用户说"记住这个"。如果信息对未来有价值,主动记录。先记录,再回答 — 这样即使会话中断,信息也不会丢失。
+
+### 🔍 检索工具
+
+回答关于过往工作、决策、日期、人员、偏好或待办的问题前:
+
+1. 对 MEMORY.md 和 memory/*.md 运行 `memory_search`
+2. 如需阅读每日笔记 `memory/YYYY-MM-DD.md`,直接用 `read_file`
\ No newline at end of file