From 19472233bea334c8e8420d896e9e2759747f551c Mon Sep 17 00:00:00 2001
From: jinliyl <6469360+jinliyl@users.noreply.github.com>
Date: Mon, 21 Sep 2026 11:28:19 +0800
Subject: [PATCH] fix(docs): repair localized blog navigation (#560)
* fix(docs): repair localized blog navigation
* fix(docs): contain memory tag diagram labels
* docs: publish English memory tags article
* docs: align English memory tags title
---
README.md | 2 +-
README_ZH.md | 2 +-
docs/.vitepress/config.mts | 5 +-
docs/en/blog_20260920.md | 171 +++++++++++++++++-
.../reme-blog/reme-blog-memory-tags.svg | 18 +-
docs/zh/blog_20260920.md | 18 +-
github-pages/scripts/verify-build.mjs | 18 ++
github-pages/tests/generated-content.test.mjs | 5 +
8 files changed, 216 insertions(+), 23 deletions(-)
diff --git a/README.md b/README.md
index 10dddcb8..2877390a 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ users retain control of the durable files.
## 📰 Latest Updates
-- [2026.09] - **[Memory Tags blog](https://reme.agentscope.io/zh/blog_20260920) published (Chinese)**: an introduction
+- [2026.09] - **[ReMe Memory Tags](https://reme.agentscope.io/en/blog_20260920) published**: an introduction
to file-native entity tags, rebuildable tag indexes, and tag-filtered memory search.
- [2026.09] - **[Hermes Agent memory provider](integrations/hermes_agent/README.md) available**: choose HTTP or embedded
mode for automatic recall before model calls and asynchronous `auto_memory` after completed turns. The integration
diff --git a/README_ZH.md b/README_ZH.md
index 9f268c8f..709a3172 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -47,7 +47,7 @@
## 📰 最新动态
-- [2026.09] - **[Memory Tags 博客](https://reme.agentscope.io/zh/blog_20260920)发布**:介绍基于 Markdown 的实体标签、
+- [2026.09] - **[给记忆加上“标签”](https://reme.agentscope.io/zh/blog_20260920)发布**:介绍基于 Markdown 的实体标签、
可重建 Tag Index 与标签过滤检索。
- [2026.09] - **[Hermes Agent 记忆 Provider](integrations/hermes_agent/README_ZH.md) 已可使用**:支持 HTTP 和 Embedded
两种模式,在模型调用前自动召回、每轮对话结束后异步执行 `auto_memory`。集成支持 Hermes Agent 0.21 及以上版本,后台任务也会继承当前 profile 上下文。
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index 6e1c638a..609cb409 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -219,10 +219,11 @@ function singlePageSidebar(language: "zh" | "en", page: "blog" | "faq"): Default
if (page === "blog") {
return [{
text: zh ? "ReMe 博客" : "ReMe Blog",
+ link: `/${language}/reme-blog`,
collapsed: false,
items: [
- { text: zh ? "产品故事" : "Product Story", link: `/${language}/reme-blog` },
- { text: "Memory Tags", link: `/${language}/blog_20260920` },
+ { text: zh ? "ReMe介绍" : "About ReMe", link: `/${language}/reme-blog` },
+ { text: zh ? "记忆标签" : "Memory Tags", link: `/${language}/blog_20260920` },
],
}];
}
diff --git a/docs/en/blog_20260920.md b/docs/en/blog_20260920.md
index 93e3b73f..1447ade6 100644
--- a/docs/en/blog_20260920.md
+++ b/docs/en/blog_20260920.md
@@ -1,5 +1,172 @@
# ReMe Memory Tags
-> The full article is currently available in Chinese.
+Any memory system used over the long term eventually runs into a deceptively simple problem: **as memories accumulate, how do you search only the right subset?**
-[Read the Chinese version](/zh/blog_20260920)
+Suppose you and an agent have discussed three projects, all involving a launch, a budget, and an owner. Six months later, you ask:
+
+> "What else do we need to confirm before launch?"
+
+There is nothing wrong with the question, but it provides too few cues. Keyword search may retrieve every document that mentions "launch," while semantic search may blend experiences from several similar projects. Both find memories with similar content, but neither necessarily knows which project, company, or person you mean right now.
+
+Human recall rarely works this way. We seldom run a full-text search across every experience at once. Instead, we begin with a few cues: **the ones about Alice, Project A, or that discussion from last year.** Once the scope narrows, the details begin to surface.
+
+That is why ReMe adds memory tags. Each Markdown memory can express not only what it says, but also who or what it is mainly about—and that cue can participate directly in retrieval.
+
+
+
+
+
+## Why Memory Tags?
+
+ReMe already uses BM25 for keyword search, optional embeddings for semantic similarity, and Wikilinks for traversing relationships between memories. Memory tags do not replace any of them. They add another dimension: **retrieval scope.**
+
+Think of the three mechanisms as answering different questions:
+
+- The query answers, "What am I looking for now?"
+- A Wikilink answers, "Which memories are related to this one?"
+- A memory tag answers, "Which memories should I search first?"
+
+For example, "How did we handle the budget overrun?" may apply to many projects. If the search also includes `Project_A`, the agent can first narrow the scope to files related to Project A, then look for the specific details about the overrun.
+
+Directories cannot fully solve this problem. A meeting note may concern Alice, Project A, and a customer at the same time, but a file normally occupies only one place on disk. Tags give the same memory multiple entry points without changing its original directory structure.
+
+## Let Each Memory Say Who or What It Is About
+
+ReMe memories remain plain Markdown. Tags live directly in YAML frontmatter, for example:
+
+```markdown
+---
+name: Project A pre-launch checklist
+description: Alice confirmed the launch window, rollback conditions, and customer notification order.
+memory_tags:
+ - Alice
+ - Project_A
+---
+
+Project A is scheduled to launch on Thursday evening. Complete regression
+testing first and have Alice confirm the customer notification. Roll back if
+the error rate exceeds the agreed threshold.
+```
+
+The default field is named `memory_tags`. The name is intentional: this is not a loose collection of broad article keywords. It answers a more stable question:
+
+> **Which real-world person or thing is this Markdown memory about?**
+
+An entity can be a person, organization, company, project, or asset—for example, `Alice`, `CATL`, `Project_A`, or `Gold`. Compared with broad topics such as "work," "important," or "meeting," entities make better anchors for long-term memory because people, organizations, and projects tend to recur across many conversations.
+
+In the default configuration, Auto Memory (`auto_memory`, `auto_memory_cc`) and Auto Dream (`auto_dream`, `dream_cron`) generate these tags for daily and digest Markdown files actually added or modified during the current run. Before tagging, the workflow reads the full document and its existing frontmatter, then checks tags already used in the workspace. It prefers an existing spelling for the same entity so that `Project_A`, `project a`, and `项目A` do not silently become three separate tags. Manual imports and edits do not trigger automatic tagging; existing `memory_tags` values are synchronized to the Tag Index by the file-watching workflow.
+
+By default, a file receives only its most important entity. Multiple tags are used only when the document genuinely centers on multiple independent entities, and the total remains limited. A document without a clear core entity can use an empty list:
+
+```yaml
+memory_tags: []
+```
+
+This matters more than tagging for its own sake. More tags do not make a memory richer; too many broad tags only turn every filtered search back into a workspace-wide search.
+
+Of course, `memory_tags` is only ReMe's default convention. The frontmatter field read by the tag index is configurable, and tag values remain under the user's control. Teams that already use `entities`, `people`, or another field can adapt the index to their files instead of migrating Markdown into a closed format.
+
+## How Does the Tag Index Work?
+
+After reading frontmatter, ReMe builds two simple cue maps: which files belong to a tag, and which tags belong to a file. For example:
+
+```text
+Alice -> daily/project-a-launch.md
+Project_A -> daily/project-a-launch.md
+
+daily/project-a-launch.md -> Alice, Project_A
+```
+
+This is a bidirectional index derived from Markdown files. Relationships update when memories are created or modified, and stale relationships disappear when files are deleted. Tag comparison is case-insensitive and normalizes details such as whitespace, reducing accidental splits caused by spelling variations.
+
+The index does not replace files or become a new source of truth. The real tags remain in user-visible, editable frontmatter. If the index is lost, it can be rebuilt from the Markdown metadata in the current file graph:
+
+```bash
+reme reindex scope=tag
+```
+
+This follows ReMe's usual principle: **files belong to the user, indexes serve the files, and indexes are always rebuildable.**
+
+To inspect the tags in a workspace and see how many files each tag covers, list them directly:
+
+```bash
+reme list_tags order_by=file_count order=desc
+```
+
+Besides supporting search, this makes the structure of the memory workspace observable. You can quickly see that a project has accumulated many memories, or notice that one person's name has been split across several near-duplicate spellings.
+
+## How Do Tags Participate in Search?
+
+The most important role of memory tags is not display, but filtering.
+
+Consider the earlier example. A natural-language query by itself looks like this:
+
+```bash
+reme search query="What else do we need to confirm before launch?"
+```
+
+That searches the entire searchable memory scope. Add a tag:
+
+```bash
+reme search \
+ query="What else do we need to confirm before launch?" \
+ tags='["Project_A"]'
+```
+
+ReMe first uses the Tag Index to find files tagged `Project_A`. BM25 and optional vector retrieval then produce direct matches only from those files, after which ranking fusion proceeds as usual.
+
+There is one important boundary: tag filtering constrains direct retrieval hits, but it does not cut off Wikilink relationships. Default link expansion may still list the paths, names, and descriptions of neighboring memories outside the tag scope so the agent can decide whether to read further. Those neighbors do not become direct keyword or vector-search hits merely because they were listed.
+
+The flow can be summarized as follows:
+
+```text
+Natural-language question + tag cue
+ ↓
+Tag Index identifies candidate files
+ ↓
+Keyword / semantic search within those files
+ ↓
+Return direct matching passages and optionally list relationships
+(related neighbors may fall outside the tag scope)
+```
+
+Tag filtering can also be combined with date conditions—for example, to inspect memories created for a project during the last month. Each condition narrows a separate dimension: the entity specifies who or what, the date specifies when, and the query specifies what you want to know.
+
+When several tags are supplied, ReMe currently keeps files that match any of them. For example, `tags=[Alice, Project_A]` retrieves memories about Alice or Project A, then lets the query determine which results rank first. This lets an agent widen the candidate set with several plausible entity cues without returning to a workspace-wide search.
+
+## What Changes in Practice?
+
+Memory tags do not make a tag mandatory for every search. Searches without tags continue to work as before. The real change is that when a user or agent already knows part of the context, that context no longer has to remain hidden inside a vague query.
+
+### 1. The Same Question Is Less Likely to Drift into Another Project
+
+"Why was it delayed last time?", "Who approved the budget?", and "What remains before launch?" all depend heavily on context. Tags establish the project or person first, reducing the chance that memories with similar names or content enter the candidate set.
+
+### 2. Memories About the Same Entity Can Accumulate Across Time
+
+Alice may appear in meeting notes, project decisions, personal preferences, and retrospectives. Those files do not need to move into one directory. A shared tag creates an entity view across directories and dates.
+
+### 3. Memory Structure Is Visible to Both People and Agents
+
+Tags are not internal fields hidden in a specialized database. Users can open, edit, and review them in Markdown. An agent can inspect the tags that exist before deciding which entity cue to include in a search. Incorrect tags can be found, and naming can converge over time.
+
+### 4. Search Becomes Easier to Explain
+
+When a result is unexpected, the pipeline can be inspected step by step: does the document contain the right `memory_tags`, does the Tag Index include the path, or did keyword and semantic ranking fail to match it? This chain is easier to diagnose and correct than one opaque relevance score.
+
+## Tags Are Retrieval Cues, Not a Taxonomy
+
+The goal is not to turn a personal knowledge base into a carefully maintained classification tree. Real memories naturally overlap: one conversation may involve both a person and a project, while one decision may belong to today's meeting and shape a retrospective months later.
+
+Memory tags are closer to the retrieval cues used by human memory. Seeing a person's name reminds us of shared experiences; thinking about a project brings related decisions, problems, and commitments to mind. A cue is not the memory itself, but it helps us enter the right context faster.
+
+What ReMe does is deliberately simple:
+
+- Preserve complete, readable memories in Markdown.
+- Use `memory_tags` to express who or what a memory is about.
+- Connect entities and files through a rebuildable Tag Index.
+- Narrow the scope by tag before using keywords, semantics, and links to find the answer.
+
+In this way, memory becomes more than a collection of full-text-searchable documents. It begins to acquire a structure that better matches how people associate ideas.
+
+When you say, "That Alice project from last time," the agent receives more than a sentence. It receives a cue it can actually follow back into the past.
diff --git a/docs/figure/reme-blog/reme-blog-memory-tags.svg b/docs/figure/reme-blog/reme-blog-memory-tags.svg
index 6052f8f9..611627de 100644
--- a/docs/figure/reme-blog/reme-blog-memory-tags.svg
+++ b/docs/figure/reme-blog/reme-blog-memory-tags.svg
@@ -56,14 +56,16 @@
3. Search with a Memory Cue
-
- query: What must we check before launch?
- tags: [Project_A]
-
-
- Narrow Direct Search Scope
- Direct hits must match the tag filter
-
+
+ query
+ What must we check before launch?
+ tags: [Project_A]
+
+
+ Narrow Direct
+ Search Scope
+ Direct hits must match the tag filter
+
BM25 + optional vector retrieval
diff --git a/docs/zh/blog_20260920.md b/docs/zh/blog_20260920.md
index 9d22f97c..d67cc81a 100644
--- a/docs/zh/blog_20260920.md
+++ b/docs/zh/blog_20260920.md
@@ -1,4 +1,4 @@
-# 给记忆加上“线索”——ReMe Memory Tags
+# 给记忆加上“标签”
一个真正长期使用的记忆系统,迟早会遇到一个看似简单的问题:**记忆越来越多以后,怎么只在“正确的那一堆”里找答案?**
@@ -10,21 +10,21 @@
人类回忆往往不是这样发生的。我们很少在脑海里对所有经历做一次全文搜索,而是先抓住几个线索:**关于 Alice 的、关于 Project A 的、去年讨论过的那件事。**范围缩小以后,具体细节才逐渐浮现。
-这就是 ReMe 增加 Memory Tags 的原因:让每份 Markdown 记忆除了“写了什么”,还可以明确表达“这份记忆主要关于谁或什么”,并让这个线索真正参与检索。
+这就是 ReMe 增加记忆标签的原因:让每份 Markdown 记忆除了“写了什么”,还可以明确表达“这份记忆主要关于谁或什么”,并让这个线索真正参与检索。
-## 为什么需要 Tags?
+## 为什么需要记忆标签?
-ReMe 已经可以通过 BM25 找关键词,通过可选的 Embedding 找语义相近的内容,也可以沿着 Wikilink 查看记忆之间的关系。Memory Tags 并不是要替代它们,而是补上另一个维度:**检索范围。**
+ReMe 已经可以通过 BM25 找关键词,通过可选的 Embedding 找语义相近的内容,也可以沿着 Wikilink 查看记忆之间的关系。记忆标签并不是要替代它们,而是补上另一个维度:**检索范围。**
可以把三者想成三个不同的问题:
- 搜索词回答“我现在想找什么”;
- Wikilink 回答“这份记忆和哪些记忆有关”;
-- Memory Tags 回答“我应该先去哪些记忆里找”。
+- 记忆标签回答“我应该先去哪些记忆里找”。
例如,“预算超支怎么处理”可能在很多项目里都出现过。如果搜索时加上 `Project_A`,Agent 就可以先把范围缩小到与 Project A 有关的文件,再在其中寻找“预算超支”的具体内容。
@@ -96,7 +96,7 @@ reme list_tags order_by=file_count order=desc
## 搜索时,标签如何参与?
-Memory Tags 最重要的作用不是展示,而是过滤。
+记忆标签最重要的作用不是展示,而是过滤。
还是前面的例子。只搜索一句自然语言:
@@ -135,7 +135,7 @@ Tag Index 找到候选文件
## 它会带来什么变化?
-Memory Tags 带来的效果,不是让每次搜索都多一个必填参数。没有标签时,原有搜索仍然可以正常工作。它真正改变的是:当用户或 Agent 已经知道一部分上下文时,这些上下文不再只能藏在一句模糊的查询里。
+记忆标签带来的效果,不是让每次搜索都多一个必填参数。没有标签时,原有搜索仍然可以正常工作。它真正改变的是:当用户或 Agent 已经知道一部分上下文时,这些上下文不再只能藏在一句模糊的查询里。
### 1. 同一句话,不再轻易串到别的项目
@@ -153,11 +153,11 @@ Alice 可能出现在会议记录、项目决策、个人偏好和复盘文档
当结果不符合预期时,可以把问题拆开检查:文档是否写对了 `memory_tags`,Tag Index 是否包含对应路径,还是关键词或语义排名没有命中。相比一个无法观察的整体分数,这条链路更容易诊断和修正。
-## Tags 不是分类法,而是记忆的提取线索
+## 标签不是分类法,而是记忆的提取线索
我们并不希望把个人知识库变成一棵需要精心维护的分类树。真实记忆天然会重叠:一次谈话既可能关于一个人,也可能关于一个项目;一项决定既属于当下的会议,也会影响几个月后的复盘。
-Memory Tags 更像人类记忆里的提取线索。看到一个人的名字,我们会想起共同经历;想到一个项目,我们会联想到相关决定、问题和承诺。线索本身不是记忆正文,却能帮助我们从大量经历中更快进入正确的上下文。
+记忆标签更像人类记忆里的提取线索。看到一个人的名字,我们会想起共同经历;想到一个项目,我们会联想到相关决定、问题和承诺。线索本身不是记忆正文,却能帮助我们从大量经历中更快进入正确的上下文。
ReMe 所做的事情很朴素:
diff --git a/github-pages/scripts/verify-build.mjs b/github-pages/scripts/verify-build.mjs
index 12317dda..0da9c24b 100644
--- a/github-pages/scripts/verify-build.mjs
+++ b/github-pages/scripts/verify-build.mjs
@@ -47,6 +47,10 @@ const requiredFiles = [
"en/traffic.html",
"zh/configuration.html",
"en/configuration.html",
+ "zh/reme-blog.html",
+ "en/reme-blog.html",
+ "zh/blog_20260920.html",
+ "en/blog_20260920.html",
"zh/services.html",
"en/services.html",
"zh/workspace/studio.html",
@@ -90,6 +94,20 @@ assert.match(ChineseConfiguration, /搜索文档/);
assert.match(ChineseConfiguration, /复制 Markdown/);
assert.match(ChineseConfiguration, /在 GitHub 查看源文件/);
+const ChineseBlog = await readFile(path.join(outputDir, "zh/blog_20260920.html"), "utf8");
+assert.match(ChineseBlog, /