diff --git a/README.md b/README.md index 60cc4b2..4309ef4 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,75 @@ --- +## 🧭 它是怎么工作的 + +整个插件可以拆成三件事:**写入**(把对话变成记忆)、**读取**(把记忆送回给 AI)、**安全**(出了问题能恢复)。 + +```mermaid +flowchart LR + subgraph 写入["✏️ 写入:对话 → 记忆"] + A["AI 回复了一条消息"] --> B["提取器读取最近几轮对话"] + B --> C["让 LLM 识别出角色/事件/地点等"] + C --> D["对比已有记忆,去重或更新"] + D --> E["写入图谱 + 同步向量"] + end + + subgraph 读取["🔍 读取:记忆 → 注入"] + F["用户准备发送下一条"] --> G["用向量搜索找相关记忆"] + G --> H["沿关系网络扩散,发现关联"] + H --> I["综合打分排序"] + I --> J["格式化后注入 prompt"] + end + + subgraph 安全["🛡️ 安全:历史变动 → 恢复"] + K["用户删楼/编辑/切 swipe"] --> L["检测到哪些楼层变了"] + L --> M["回滚受影响的记忆和向量"] + M --> N["从变动点重新提取"] + end + + E -.-> F + N -.-> E +``` + +### 写入阶段(对话 → 记忆) + +每次 AI 回复后,插件会把最近几轮对话打包发给 LLM(可以是你聊天用的同一个模型,也可以单独配一个),让它识别出"这段对话里出现了哪些角色、发生了什么事、在哪里、有什么新规则"等等。 + +识别出来的结果不是直接塞进去——插件会先跟已有记忆做对比(通过向量搜索找相似的),如果已经有了就更新,如果是真正的新内容才创建。 + +写入之后,还可能触发一些后续处理: +- **压缩** — 太多类似的事件记忆会被合并 +- **进化** — 新信息会影响旧记忆的理解(比如"原来他当时是在演戏") +- **概要** — 自动生成"之前发生了什么"的总结 +- **遗忘** — 很久没被用到的记忆降低优先级 + +### 读取阶段(记忆 → 注入) + +当你准备发送下一条消息时,插件会抢在 AI 生成之前做一轮"召回": + +1. **向量搜索** — 根据当前对话内容,用 Embedding 找到语义最相关的记忆 +2. **图扩散** — 找到相关记忆后,沿着关系往外扩散(比如某个角色参与了某个事件,那个事件发生在某个地点...) +3. **混合评分** — 把向量相似度、图扩散能量、节点重要性、时间新旧综合排序 +4. **格式化注入** — 选出最终入围的记忆,分类整理后注入到 prompt 里 + +注入的内容分成两层: +- **常驻层** — 规则、概要、主线这类始终需要的 +- **动态层** — 根据当前对话语境召回的 + +### 安全机制(历史变动 → 恢复) + +这是很多记忆插件忽略的问题:如果用户删了某条消息、编辑了内容、或者切了 swipe,已经基于那条消息提取的记忆就变成"脏"的了。 + +ST-BME 的处理方式是: +1. 给每条已处理的消息计算 hash(指纹) +2. 发现 hash 变了 → 找到最早受影响的位置 +3. 把那之后产生的记忆和向量全部回滚 +4. 从变动点重新走一遍提取流程 + +如果恢复日志损坏了,会退化为全量重建——慢一点但保证正确。 + +--- + ## 🚀 安装 ### 方法一:通过 SillyTavern 扩展安装