Skip to main content
V

dsh-anima-rag

vv5v5/dsh-anima-rag

Anima-style vector memory for DSH: injects retrieved historical summaries into the system prompt each turn, exposes an anima_query semantic-search tool, and isolates the vector store per playthrough. SiliconFlow embeddings sent as array-shaped requests; timeouts and provider errors surface as honest, classified notes in the injection slot — never silent.

Install

dsh plugin --profile web add github:vv5v5/dsh-anima-rag

README

dsh-anima-rag

把 SillyTavern 侧 Anima 的检索核心搬进 DeepSeek Harness,做成一个 DSH 插件: 向量检索、策略步与 rerank 拦截、echo(本地回响),检索结果经 system-prompt/assemble 瀑布注入 RP 会话;既是独立的检索工具,也是这套酒馆 agent 的记忆库检索端。

★ 2026-09-26:上游那份是「向量 + BM25 双轨」,BM25(minisearch)那条支线已于本日整条退役 (用户口径「fts5目前看用处不大,摘除吧」)—— 索引构建、读侧打分、data/bm25Root 配置段、 minisearch / jieba-wasm 依赖、面板的「删除 BM25 库」动作与状态字段全部摘掉。 ➜ 检索只剩向量一条路(没有备用轨:嵌入渠道不通 ⇒ 检索整个不通,读侧会如实说明)。

⚠️ 本仓库不并入 dsh-memory-archive 的代码 —— 两者是各自独立的插件:记忆库管读用与面板,本插件管检索与入库。它们只通过文件和官方扩展点配合。


它做什么

检索每轮装配时按会话取词 → 向量检索 → 策略步(base / important / diversity)→ rerank 拦截 → 注入 system 段 anima:memory
检索工具anima_query:模型可主动查历史(返回命中条数、正文、以及为什么是 0 命中的一行诊断)
入库把摘要目录里的摘要写进记忆库(写向量,写完回读核对):压缩后自动入库,也可手动触发
周目隔离只召回属于当前周目的切片(切片带 pt:<周目id> 标签);拿不到周目 ⇒ 本轮不注入(宁可不出场,也不串味)
回响echo:把已经在上下文里的历史与本轮命中对齐,避免重复注入;共享回响索引
入库维护账本(文件名 + 内容签名,内容没变不重入)、孤儿元数据回收与隔离、被改名切片的对账
向量面板的那半边读 dsh-memory-archive 写来的请求单执行动作(立即入库 / 重建(向量)/ 删向量库),并把状态快照与回执写回去给它显示

向量生成的时机(明确只有两处):① 自动压缩入库时(摘要进库 ⇒ 写向量); ② 工具/检索调用时(发现目标集合的向量库不存在 ⇒ 当场排队补建)。两处都有反馈: 给 agent 的(anima_query 的返回里带 diagnostics)与给人的(状态快照 + 面板回执)。

配置从哪来

密钥与端点不读环境变量,只来自记忆库的设置(<DSH_HOME>/dsh-memory-archive/config.json 的 retrieval 段)。 两个模型各一套接口(2026-09-20 起)—— 可以落在不同服务商上:

向量模型重排模型
接口地址(baseURL)urlrerankUrl(空 ⇒ 沿用 url)
模型名modelrerankModel
密钥keyrerankKey(空 ⇒ 沿用 key)

端点由 baseURL 推导:向量 = url + /embeddings;重排 = rerankUrl + /rerank (已经以 /rerank 结尾就不再拼)。另有 chatEnabled = 是否参与检索。 ⚠️ 重排那两项留空 ⇒ 逐条退回改版前的行为(同一把 key、url + /rerank),老配置一字不用改。 读不到就回落本插件的默认值(不吞环境凭据)。

★ 「哪个周目」是会话优先,认不出来的会话当新会话(2026-09-20):检索的隔离闸与自动入库的目标, 按这个会话在 Tavern catalog.json/timeline.json 里归入的那个周目算;认不出 ⇒ 不检索、不入库、 不注「最近 N 条总结」(fail-closed,⛔ 不拿面板绑定值兜底 —— 那会让一条新会话去读/写上一轮的库)。 ★ 会话若同时被两个周目引用(一个是它的 rootSessionId、另一个只是 timeline 里的 variant/继续) ⇒ 判给它是根的那个(顺序无关)—— 否则会把一条会话判到别的角色/周目去(真机踩过)。

数据根默认指向 ST 侧现役 Anima 的数据(vectors/ + data/sessions/)—— 即「继承现有库」而不是新建一套;本插件自己的落点只有三个文件: ingest-ledger.json(账本)· ingest-state.json(入库状态)· panel-request/result.json + vector-info.json(面板通道), 全在 <DSH_HOME>/dsh-anima-rag/。

安装

dsh plugin --profile <你的 profile 名> add github:vv5v5/dsh-anima-rag

装完重启一次宿主。本包没有构建步骤(lib/ 里就是可直接运行的 JS)。

配套:记忆库面板在 dsh-memory-archive, 角色卡 / 世界书 / 周目在 pmp-dsh-tavern。两者都可选。

已知限制(如实)

#限制说明
1拿不到当前周目 ⇒ 本轮不注入这是故意的:宁可漏,也不跨周目串味
2向量库里的切片属于哪个周目看标签绑定换了周目而库里切片没重打标 ⇒ 会一条都召不回(面板的体检行会明说这一点)
3面板动作要等一轮面板写请求单,本插件在下一次装配取走执行(进度与回执都在面板上)
4单测覆盖的是纯逻辑与源码级判据真机行为靠自检台 + 真机验收两步,⛔ 不靠"自述"

开发

node _selftest-panel-request.mjs      # 面板通道的纯逻辑
node _selftest-ingest-kick.mjs        # 入库触发时机(含反证)
node _selftest-playthrough-isolate.mjs

改完记得:同步到部署副本 → 换进程重启 → 全量自检门跑一遍。


上游与署名(许可义务,不是客套)

原项目Anima-Memory-System
原作者Ellina
原项目地址https://gitee.com/Ellinav/Anima-Memory-System
原项目版本3.3.6
原项目许可Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)

本项目与上游的关系:

独立重写;检索核心与摘要准则移植自 Ellina 的 Anima-Memory-System(CC BY-NC 4.0); 本仓库为 DSH 侧的维护方。

⚠️ 刻意不叫"上游的分支" —— 这里不是 fork 的延续,是照它的算法重写一遍 DSH 插件。

移植范围

  • 检索核心:向量检索、策略步、rerank 拦截 (上游那份还有 BM25 第二轨;本仓那条轨 2026-09-26 已摘除,见文件开头那段)
  • echo(回响)机制:上游 processEchoLogic 逐字搬运(它在引擎内部跑, 候选池 = 本轮的向量命中;BM25 退役后这一点没有变)
  • 摘要准则:压缩指令模板的措辞(逐字对齐上游)
  • ⛔ 不含上游的任何预置私域数据

逐块搬运映射见 docs/ENGINE-NOTES-B.md。

许可

CC BY-NC 4.0(package.json 的 license 字段同为 CC-BY-NC-4.0)—— 派生自 NC 作品,⛔ 不能整体挂 MIT。全文与场景限制见 LICENSE。

场景限制(沿用上游条件):仅限个人学习与非商业性用途;禁止闭源商用、禁止转为付费插件/服务;不重新分发任何预置私域数据。

Related plugins