From 47ffd5413db37ea9bdd4f5c4e72ca1f77d6e735b Mon Sep 17 00:00:00 2001
From: Youzini-afk <13153778771cx@gmail.com>
Date: Sun, 12 Apr 2026 17:57:49 +0800
Subject: [PATCH] =?UTF-8?q?refactor(terminology):=20=E5=B1=82=E7=BA=A7?=
=?UTF-8?q?=E6=80=BB=E7=BB=93=E4=B8=BA=E4=B8=BB=E8=B7=AF=E5=BE=84=EF=BC=8C?=
=?UTF-8?q?synopsis=20=E6=A0=87=E8=AE=B0=E4=B8=BA=E6=97=A7=E5=BC=8F?=
=?UTF-8?q?=E5=85=A8=E5=B1=80=E6=A6=82=E8=A6=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- README: 明确 summaryState 为主总结体系,legacy synopsis 为兼容兜底
- prompt-profiles: synopsis 任务标签改为「小总结」
- schema/task-graph-stats/panel: synopsis 节点显示为「全局概要(旧)」
- index.js: fallback 状态文案改为「旧式全局概要生成/更新中」
- p0-regressions: 同步更新断言字符串
---
README.md | 51 +++++++++++++++++++++------------
graph/schema.js | 6 ++--
index.js | 8 +++---
maintenance/task-graph-stats.js | 2 +-
prompting/prompt-profiles.js | 4 +--
tests/p0-regressions.mjs | 12 ++++----
ui/panel.html | 3 +-
ui/panel.js | 4 +--
8 files changed, 51 insertions(+), 39 deletions(-)
diff --git a/README.md b/README.md
index 9f07b37..064c5d2 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@ flowchart LR
- **整合** — 相似记忆合并(Mem0 精确对照 + A-MEM 进化)
- **压缩** — 太多类似的事件记忆会被层级合并
-- **概要** — 自动生成"之前发生了什么"的总结(含层级摘要折叠)
+- **层级总结** — 基于近期原文窗口生成小总结,并在前沿过厚时继续做总结折叠
- **反思** — 长期模式总结,生成叙事指导原则
- **遗忘** — 很久没被用到的记忆降低优先级
@@ -88,7 +88,7 @@ flowchart LR
注入的内容分成两层:
-- **Core(常驻层)** — 规则、概要、主线这类始终需要的
+- **Core(常驻层)** — 规则、主线,以及在没有活跃总结前沿时兜底的旧式全局概要
- **Recalled(动态层)** — 根据当前对话语境召回的
每层内进一步按用途分桶:当前状态 / 情景事件 / 反思锚点 / 规则约束。
@@ -121,12 +121,15 @@ ST-BME 的处理方式是:
### 方法一:通过 SillyTavern 扩展安装
1. 打开 SillyTavern → 扩展 → 安装扩展
-2. 输入仓库地址:
- ```text
- https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology
- ```
- 注意:请粘贴仓库根地址,不要使用像 `/graphs/code-frequency` 这样的 GitHub 子页面地址。
-3. 刷新页面
+1. 输入仓库地址:
+
+```text
+https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology
+```
+
+注意:请粘贴仓库根地址,不要使用像 `/graphs/code-frequency` 这样的 GitHub 子页面地址。
+
+1. 刷新页面
### 方法二:手动安装
@@ -161,7 +164,7 @@ git clone https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git st-bme
| 📍 地点 | 地点状态 | "废弃实验室,门被锁上了" |
| 📌 规则 | 世界观设定、约束 | "魔法会消耗生命力" |
| 🧵 主线 | 任务线/剧情线 | "寻找失踪的项链" |
-| 📜 概要 | 自动生成的前情提要 | — |
+| 📜 全局概要(旧) | 单条全局前情提要,现主要用于兼容 / 迁移兜底 | — |
| 💭 反思 | 长期规律总结 | "他们经常在夕阳下聊天" |
| 👁️ 主观记忆 | 角色视角下的记忆,含误解和情绪 | "她以为他离开了,其实他躲起来了" |
@@ -187,13 +190,17 @@ ST-BME 的记忆不是扁平的——它模拟了真实的认知分层:
- 时间线上下文可注入 prompt,帮助模型保持时间感知
- 支持软引导(`storyTimeSoftDirecting`),不强制但提示模型注意时间流
+### 总结状态
+
+当前主用的总结体系不是 `synopsis` 节点,而是 `summaryState` 中持续演化的「小总结 + 总结折叠」活跃前沿。
+
---
## 🔧 设置说明
### 记忆 LLM
-用来做提取、压缩、整合、概要、反思等任务的模型。
+用来做提取、压缩、整合、小总结、总结折叠、反思等任务的模型。
- **留空** → 复用当前 SillyTavern 的聊天模型(最简配置)
- **填写** → 你可以指定一个独立的 OpenAI-compatible 模型专门处理记忆
@@ -261,11 +268,12 @@ ST-BME 的记忆不是扁平的——它模拟了真实的认知分层:
| ------ | ------ | ------ |
| 启用整合 | 开 | 相似记忆自动合并 |
| 整合阈值 | 0.85 | 向量相似度高于此值时触发合并 |
-| 启用概要 | 开 | 定期生成前情提要 |
-| 启用层级摘要 | 开 | 摘要自动折叠合并 |
+| 启用层级总结 | 开 | 启用「小总结 + 总结折叠」主路径(兼容旧 `enableSynopsis` 命名) |
+| 小总结频率 | 3 次提取 | 每累计多少次提取生成一条新的小总结 |
+| 折叠扇入 | 3 | 同层活跃总结达到多少条时触发一次折叠 |
| 启用反思 | 开 | 让 AI 总结长期模式 |
| 启用自动压缩 | 开 | 事件/主线节点过多时自动层级合并 |
-| 启用主动遗忘 | 开 | 太久没用的记忆降低优先级 |
+| 启用主动遗忘 | 开 | 太久没被用到的记忆降低优先级 |
| 启用智能触发 | 关 | 仅在检测到关键内容时才提取 |
| 启用概率召回 | 关 | 以一定概率触发召回,减少 token 消耗 |
@@ -307,9 +315,11 @@ ST-BME 的记忆不是扁平的——它模拟了真实的认知分层:
### 操作 Tab
- 手动提取 — 立即从当前对话提取(模式选择跨会话记忆)
-- 手动压缩 — 合并重复/过时记忆
-- 执行遗忘 — 主动降级低价值记忆
-- 更新概要 — 重新生成前情提要
+- 手动压缩 — 合并重复/冗余的事件
+- 执行遗忘 — 降低长期未使用记忆的优先级
+- 生成小总结 — 基于近期原文窗口生成阶段性总结
+- 执行总结折叠 — 折叠当前活跃总结前沿
+- 重建总结状态 — 从提取批次重建小总结与折叠总结
- 导出 / 导入图谱
- 重建图谱 — 从当前聊天重新提取全部记忆
- 重建向量 — 重建全部向量索引
@@ -318,6 +328,7 @@ ST-BME 的记忆不是扁平的——它模拟了真实的认知分层:
### 配置 Tab
配置页是一个完整的工作区,分成 5 个子页:
+
- **API 配置** — 记忆 LLM、Embedding 向量源
- **功能开关** — 提取/召回/维护各项功能的启用开关
- **详细参数** — 检索流水线、认知架构、维护阈值等细粒度参数
@@ -328,7 +339,7 @@ ST-BME 的记忆不是扁平的——它模拟了真实的认知分层:
### 图谱可视化
-桌面端右侧大区域显示力导向图谱,节点可拖拽、缩放、点击查看详情。支持 4 套配色主题切换。
+桌面端右侧大区域显示力导向图谱,节点可拖拽、缩放、点击查看详情。支持 4 套主题配色切换。
---
@@ -359,7 +370,9 @@ ST-BME 的记忆不是扁平的——它模拟了真实的认知分层:
| 手动提取 | 不等自动触发,立刻提取当前对话 |
| 手动压缩 | 把重复/冗余的事件合并 |
| 执行遗忘 | 降低长期未使用记忆的优先级 |
-| 更新概要 | 重新生成全局前情提要 |
+| 生成小总结 | 基于近期原文窗口生成一条新的阶段性总结 |
+| 执行总结折叠 | 将多条同层活跃总结折叠成更高层总结 |
+| 重建总结状态 | 从提取批次重建小总结与折叠总结 |
| 导出图谱 | 下载当前图谱 JSON(不含向量) |
| 导入图谱 | 导入图谱文件(导入后需重建向量) |
| 重建图谱 | ⚠️ 清空现有图谱,从聊天记录重新提取 |
@@ -566,7 +579,7 @@ AI 回复 → 结构化消息预处理
→ [可选世界书扫描]
→ LLM 提取 → 近邻对照 → 认知归属判定
→ 写入图谱 + 同步向量 + 故事时间线
- → [后续维护:整合/压缩/概要/反思/遗忘]
+ → [后续维护:整合/压缩/层级总结/反思/遗忘]
```
### Prompt 构建架构
diff --git a/graph/schema.js b/graph/schema.js
index 6ea88cf..cd10ea0 100644
--- a/graph/schema.js
+++ b/graph/schema.js
@@ -149,15 +149,15 @@ export const DEFAULT_NODE_SCHEMA = [
// ====== v2 新增节点类型 ======
{
id: "synopsis",
- label: "全局概要",
+ label: "全局概要(旧)",
tableName: "synopsis_table",
columns: [
{
name: "summary",
- hint: "当前故事的全局概要(前情提要)",
+ hint: "旧式单条全局前情提要(兼容 / 迁移兜底)",
required: true,
},
- { name: "scope", hint: "概要覆盖的楼层范围", required: false },
+ { name: "scope", hint: "该旧式概要覆盖的楼层范围", required: false },
],
alwaysInject: true, // 常驻注入(MemoRAG 启发)
latestOnly: true, // 只保留最新版本
diff --git a/index.js b/index.js
index d9b3d4c..7c4ba36 100644
--- a/index.js
+++ b/index.js
@@ -11041,7 +11041,7 @@ async function handleExtractionSuccess(
typeof runHierarchicalSummaryPostProcess === "function"
? "层级总结"
: typeof generateSynopsis === "function"
- ? "概要生成"
+ ? "旧式全局概要生成"
: "层级总结";
const cloneMaintenanceSnapshot =
typeof cloneGraphSnapshot === "function"
@@ -11163,9 +11163,9 @@ async function handleExtractionSuccess(
? getContext().chat
: [];
updateExtractionPostProcessStatus(
- summaryStageLabel === "概要生成" ? "概要更新中" : "层级总结处理中",
- summaryStageLabel === "概要生成"
- ? `${extractionCount} 次提取,正在生成全局概要`
+ summaryStageLabel === "旧式全局概要生成" ? "旧式全局概要更新中" : "层级总结处理中",
+ summaryStageLabel === "旧式全局概要生成"
+ ? `${extractionCount} 次提取,正在生成旧式全局概要`
: `${extractionCount} 次提取,正在检查小总结与折叠总结`,
);
const summaryResult = await runSummaryPostProcess({
diff --git a/maintenance/task-graph-stats.js b/maintenance/task-graph-stats.js
index 15727e2..7e562f2 100644
--- a/maintenance/task-graph-stats.js
+++ b/maintenance/task-graph-stats.js
@@ -8,7 +8,7 @@ const DEFAULT_TYPE_LABELS = Object.freeze({
location: "地点",
rule: "规则",
thread: "主线",
- synopsis: "全局概要",
+ synopsis: "全局概要(旧)",
reflection: "反思",
pov_memory: "主观记忆",
});
diff --git a/prompting/prompt-profiles.js b/prompting/prompt-profiles.js
index 65f2974..24a49f2 100644
--- a/prompting/prompt-profiles.js
+++ b/prompting/prompt-profiles.js
@@ -26,8 +26,8 @@ const TASK_TYPE_META = {
description: "合并并压缩高层节点内容。",
},
synopsis: {
- label: "概要",
- description: "生成阶段性的全局剧情提要。",
+ label: "小总结",
+ description: "基于近期原文窗口生成阶段性小总结。",
},
summary_rollup: {
label: "总结折叠",
diff --git a/tests/p0-regressions.mjs b/tests/p0-regressions.mjs
index ece6400..5c301cf 100644
--- a/tests/p0-regressions.mjs
+++ b/tests/p0-regressions.mjs
@@ -225,7 +225,7 @@ const schema = [
},
{
id: "synopsis",
- label: "概要",
+ label: "全局概要(旧)",
columns: [{ name: "summary" }, { name: "scope" }],
},
];
@@ -2108,10 +2108,10 @@ async function testConsolidatorMergeFallbackKeepsNodeWhenTargetMissing() {
const restoreOverrides = pushTestOverrides({
embedding: {
async embedBatch() {
- return [[0.2, 0.3]];
+ return [[0.4, 0.5]];
},
async embedText() {
- return [0.2, 0.3];
+ return [0.4, 0.5];
},
searchSimilar() {
return [{ nodeId: target.id, score: 0.99 }];
@@ -2600,7 +2600,7 @@ async function testReverseJournalRollbackStateFormsReplayClosure() {
const journal = createBatchJournalEntry(before, after, {
processedRange: [4, 6],
- extractionCountBefore: before.historyState.extractionCount,
+ vectorHashesInserted: ["hash_added"],
});
const runtimeGraph = normalizeGraphRuntimeState(
@@ -2818,7 +2818,7 @@ async function testBatchStatusSemanticFailureDoesNotHideCoreSuccess() {
assert.equal(effects.batchStatus.stages.finalize.outcome, "success");
assert.equal(effects.batchStatus.outcome, "failed");
assert.equal(effects.batchStatus.completed, true);
- assert.match(effects.batchStatus.errors[0], /概要生成失败/);
+ assert.match(effects.batchStatus.errors[0], /旧式全局概要生成失败/);
}
async function testExtractionPostProcessStatusesExposeMaintenancePhases() {
@@ -2881,7 +2881,7 @@ async function testExtractionPostProcessStatusesExposeMaintenancePhases() {
const statusTexts = harness.extractionStatuses.map((entry) => entry[0]);
assert.ok(statusTexts.includes("提取收尾中"));
assert.ok(statusTexts.includes("整合/进化中"));
- assert.ok(statusTexts.includes("概要更新中"));
+ assert.ok(statusTexts.includes("旧式全局概要更新中"));
assert.ok(statusTexts.includes("反思生成中"));
assert.ok(statusTexts.includes("主动遗忘中"));
assert.ok(statusTexts.includes("自动压缩中"));
diff --git a/ui/panel.html b/ui/panel.html
index a0a9e7a..ea83d8a 100644
--- a/ui/panel.html
+++ b/ui/panel.html
@@ -291,12 +291,11 @@
-
-
+
diff --git a/ui/panel.js b/ui/panel.js
index 436ab3f..fd82632 100644
--- a/ui/panel.js
+++ b/ui/panel.js
@@ -3163,7 +3163,7 @@ function _buildLegend() {
{ key: "location", label: "地点" },
{ key: "thread", label: "主线" },
{ key: "rule", label: "规则" },
- { key: "synopsis", label: "概要" },
+ { key: "synopsis", label: "全局概要(旧)" },
{ key: "reflection", label: "反思" },
{ key: "pov_memory", label: "主观记忆" },
];
@@ -10783,7 +10783,7 @@ function _typeLabel(type) {
location: "地点",
thread: "主线",
rule: "规则",
- synopsis: "概要",
+ synopsis: "全局概要(旧)",
reflection: "反思",
pov_memory: "主观记忆",
};