DSH HUB
首页插件商店插件包社区排行榜资源发布指南
插件源码
返回插件目录

jonah791 /

jonah791/dsh-dream-tavern

仅 Topic 仓库

基于 DeepSeek Harness 的文字游戏宿主:每次模型请求都产出逐字节可验的上下文装配单(SillyTavern 人物卡/世界书迁移 + 三 Agent 职责互斥 + 原子回退)

★ 0 Stars0 Forks0 IssuesN/A 社区评分0 已确认安装
查看 GitHub
README来源: main@4dfd27ef

dsh-dream-tavern(梦境酒馆)

运行在 DeepSeek Harness 上的文字游戏/角色扮演宿主,两个并列目的:

  1. 娱乐:导入手里的 SillyTavern 人物卡,自由游玩或沿剧本推进;
  2. 研究:作为上下文编排的可测量实验台——「上下文对模型表现的影响」的受控实验载体。

与上游 flizzywine/dsh-tavern 的关系:独立实现,不 fork(上游为 AGPL-3.0)。 只借鉴接口、行为与文件格式,不复制其源码片段。许可:MIT(自持)。

与其它酒馆的根本差别:装配单

每一次模型请求都由纯函数 assemble() 产出一份装配单(assembly manifest):每个片段来自哪个槽位、 命中哪个关键词、占多少字节、sha256 是多少、最终 hash 是多少。装配单落盘后从磁盘回读, 用于校验「实际发出的 body 逐字节等于装配单重建的 body」(判据 A1)。

因此上下文编排的每次变化都是一笔可复核的字节账,不是黑箱。这条判据同时是本项目的 研究价值所在:任何「换了编排、模型表现变好」的说法,都必须先过这一关。

工具面

工具 意图
tavern_cards 卡库清点(只读)
tavern_card 读一张卡的字段与原文键集
tavern_worldbooks 世界书清点/按 ST 格式导入(只读源)
tavern_assemble 装配一轮并落盘装配单(不调模型),返回字节账与 A1 自检
tavern_play 玩一轮:装配 → 真调模型 → 落盘 → 回报 token/缓存读数
tavern_rollback 原子回退(正文与状态同生共死;无完整快照则响亮拒绝)

面板(依赖 dsh-panel 宿主,缺席时工具面不受影响):/panel → 「梦境酒馆」。 面板动作:开局 / 玩一轮 / 行动候选 / 后台结算 / 装配单读数 / 回退。

三个 Agent,职责互斥

Agent 产出 写权限
正文 Agent(runTurn) 叙事正文 对状态只读
候选 Agent(runCandidates) N 个行动选项 对状态只读,不写历史
结算 Agent(runSettlement) 结构化状态 唯一状态写者

三者共用同一装配路径(判据 A7 用行为级测试:工具路径与面板路径产出同一 manifest hash)。

配置(cordis.yml)

代码里的默认值一律为空——部署相关的取值全部走配置(宿主公约:插件不得硬编码可调项; 默认值若写死某台机器的目录,公开仓库还会连带泄漏路径)。

字段 默认 说明
dataDir '' 我们写的一切(会话/装配单/快照)。空 ⇒ 解析为 <DSH_HOME>/dream-tavern-data
cardDirs [] 只读卡库(ST characters/ 目录)。空 ⇒ 卡库为 0,工具如实报 0 并告警
worldbookDirs [] 只读世界书库(ST worlds/ 目录)
provider / model '' 模型路由。空 ⇒ tavern_play 响亮失败(不猜默认模型)
maxTokens 1600 单轮输出上限
temperature 0.9 采样温度
budgetChars 24000 单次请求字符预算(超出按优先级确定性裁剪并记账)

部署示例(放在 profile patch 里,不要写进源码):

- id: agent-dream-tavern
  name: dsh-dream-tavern
  config:
    dataDir: <你的数据目录>
    cardDirs: [<你的 ST characters/ 目录>]
    worldbookDirs: [<你的 ST worlds/ 目录>]
    provider: <provider>
    model: <model>

⚠ 迁移源只读:插件不写回酒馆目录;ST 的 secrets.json 一律不读。

验收

node scripts/acceptance.mjs          # 一条命令:判据表 + 真实数据读数 + A7 旁路面
node scripts/preset-cost.mjs --preset "E:/alice/tavern/色欲之罪.json"   # 迭代预设第一步:块级成本表(不调模型)
npm test                             # 仅判据测试

全流程透明:一轮到底发了什么、回了什么

每一轮的四类证据都在盘上,且 turns/<轮>.json 把实验条件(卡 / 预设 / 路由 / maxTokens / temperature / budgetChars)与读数(finishKind / truncated / usage / A1 / 字数)钉在一起 ——否则换过参数之后两轮读数不是一回事,失败也事后查不到当时的结束原因。

# 逐轮摊开:条件 → 请求(逐 entry)→ 响应(正文/思维链)→ 读数 → 落点
node scripts/turn-report.mjs --session <会话id> --dataDir <dataDir> [--turn N] [--entries]

# 导出可度量稿:思维链落 drafts/reasoning/ 子目录(同层会被度量器当语料),
# --prose-only 只取 <dream_body> 内的散文(协议包装约占输出 40%,混进去读数不成立),原始另存 drafts/raw/
node scripts/export-draft.mjs --session <会话id> --dataDir <dataDir> --reasoning --prose-only

tavern_play 的返回值同样带 finishKind / reasoningChars / reasoningPath / turnRecordPath ——失败时也带(空正文判失败但思维链仍落盘:它是唯一诊断证据)。

退出码:0 全量通过 | 1 判据失败 | 2 判据通过但真数据不可达(PASS 降级)。

判据:A1 装配单逐字节可重建 | A2 同输入同 hash | A3 原子回退(字节级 + 行为级重放) | A4 缓存命中读数 | A5 ST 卡往返不丢字段且不改卡 | A6 世界书匹配为纯函数 | A7 各路径共用装配器(无旁路)。

A4 实验:只追加 ⇒ 缓存命中率不塌

bash scripts/cache-experiment.sh <会话名> 6 <卡 id>   # 需 web 在线且面板宿主已挂载

判据跑之前写死:① 每轮 A1 为真 ② requestChars 单调不减 ③ cacheRead 命中比不塌。

实测(2026-09-22 · 修复「世界书重复注入」后重跑,读数为干净值):

轮 请求字数 新增 tok 缓存读 tok 命中比 A1
2 3986 219 896 80.4% ✓
4 4477 425 1024 70.7% ✓
6 4935 367 1408 79.3% ✓
8 5474 494 1664 77.1% ✓
10 6018 497 2048 80.5% ✓

⇒ 三条判据全过:命中比在 70–81% 波动、无下降趋势(requestChars 与 cacheRead 均单调不减)。

⚠ 命中比按服务端 usage 原样计算(cacheRead / (cacheRead + input)),未核对该 provider 的字段口径。

上下文编排报告(研究线第一件产物)

node scripts/context-report.mjs --data <dataDir> <session>

把一个会话的装配单聚合成「钱花在哪」的账:逐轮总账与增量、来源构成(按片段自身字数)、 槽位构成、世界书触发、增长与裁剪。

实测样例(会话 a4fixed,5 轮,修复重复注入后的干净读数):

来源 字数 占比
card 14220 57.2%
history 8885 35.8%
preset 1650 6.6%
input 75 0.3%
state 10 0.0%

⇒ 卡定义一项就占 57.2%——它既是最大的可控自变量,也是预算裁剪时最先该被讨论的对象。 (记账按片段自身 text.length 累加;均分会把 system 块的字节错配到别的来源, 实测曾把 2 字的 state 报成 2655 字。)

已知限制(诚实边界)

  • 推理模型的思维链也算进 maxTokens:实测上限 1600 时 usage 报满 1600,而正文只剩 195 字 就断在句子中间(预算被思维链吃掉)。tavern_play 与面板 play 动作会返回 truncated 标记, 不静默(判据:outputTokens >= maxTokens)。建议 maxTokens ≥ 3000。
  • 卡内格式约定会盖过默认预设的格式纪律:卡的世界书若自带输出模板(如 <response><now_plot>), 模型会照它写——这是酒馆语义下正确的行为,但意味着模板类卡不能靠预设纠正格式。
  • 面板宿主需调大动作超时:dsh-panel 的 actionTimeoutMs 默认 10 000 ms,而酒馆一轮 (装配 + 模型调用)常规 10–20 s,卡越大越慢 ⇒ 必须把它提到 ≥60000,否则长卡的动作会被 宿主判超时(实测:一张 24 条卡内世界书的卡在默认值下返回 动作超时(>10000ms))。 ⚠ 且超时 ≠ 撤销:服务端回合仍会跑完并落盘,客户端只看到超时。 这是跨插件契约问题(宿主决定超时、贡献方决定耗时),不是酒馆自身的缺陷。
  • ST 生态广度不追:MVU / 正则美化 / 小手机 / 生图 / 多平台(Android)均未实现。
  • 世界书语义部分建模:递归控制、冷却/延迟、按角色字段匹配、宏出口、分组评分共 20 种字段 已知未建模——原样留档在 raw 里,tavern_worldbooks 会逐项报出,不假装支持。
  • 结算质量依赖模型:结算 Agent 要求模型输出 JSON,解析失败即响亮失败(不静默吞)。
  • data.alternate_greetings:目前只取第一个作为回落开场,尚未做多开场切换。
  • 卡内联变量协议不被解析:部分卡的正文末尾会自带变量更新块(实测见 <VariableEdit>{...}</VariableEdit>)。 这是卡自带的 MVU 风格协议,本插件不消费它——状态走独立的结算 Agent(面板「后台结算」/ runSettlement),职责互斥(正文不写状态)。因此这类卡的变量不会自动同步;要支持需显式建模该协议。
  • 面板依赖 dsh-panel;未挂载该宿主时没有图形界面(工具面仍可用)。
—/ 5

暂无评分

需要先验证清单

Commit 4dfd27ef4746

社区评论

还没有评论,来写第一条。

DSH HUB

社区维护的 DSH 插件索引。不是 GitHub 或 DeepSeek AI 的官方产品。

社区资源API关于