数字花园
道渊拆弹记:工具包 2.1 的诞生与三颗自家地雷
有些病,症状在树上,病根在schema里。这一夜的排查像一次地层钻探:从一条被污染的时间线往下钻,穿过 deepseek-flash 的 8192 之墙、自动清理变量的嫌疑、ACU 纪要的幻影,最终触到基岩——卡内 Zod schema 里的 .catch({})。
一、钻探:时间为什么倒退八天
斗破苍穹·萧宁传 v3.1 的变量树出了怪事:msg1–msg30 全部冻结(时间锁死 1000-04-23 23:00),msg31 突变——时间退到 1000-04-15 14:30(比初始值还早八天)、世界线偏差从字符串 “9%” 变数字 18、动向列表变 {}、红颜榜字段改名、储物袋”类别”全剥。msg33 时间修回但地点仍留在旧轮。逐层 stat_data 指纹(bb28d8576e → 7b8a6443e3 → 175671cefe)钉死了突变点。
新api 日志还原了时间线:msg33 轮 MVU 解析三连试——deepseek-flash 第一次失败、第二次 ct 撞上 8192 上限(patch 被截断在思维链后,一条 op 都没落地但界面报”解析完成”)、step-3.7-flash 第三次成功落地三条。但 msg31 轮主生成之后三十七分钟内没有任何 MVU 解析请求——那轮到底是谁写的树?
线索在卡内嵌的 tavern_helper.scripts[1]:那份 Zod schema 里 当前时间 prefault('1000-04-15 14:30')、红颜榜用旧字段(排名/头衔/姿容/传闻)、储物袋无类别——msg31 的树就是这份 schema 重建出来的。下载 MagVarUpdate 的 bundle 读源码,机制完全破解:registerMvuSchema 把 schema 包成 looseObject 并挂钩 mag_command_parsed_for_zod——每应用一条 patch 命令,就对整棵树做一次 safeParse,成功则用解析结果(剥离未知字段加填 prefault 默认值)整体覆盖,失败则丢弃该命令。而卡内 schema 的世界段带了 .catch({}):冻结树里”动向”是列表 → z.record 解析失败 → 整个”世界”被 catch 重置成默认——1000-04-15 就是 prefault 的默认时间。元凶归案:不是模型写错,是 schema 的地雷在每次校验时自动重置。
二、全卡池普查:谁带雷,谁安全
带着这份家谱,全卡池扫了一遍:带雷待拆的只有道渊 v5.2 与 4.9(各十处 catch 地雷)和逆天邪神原版(九处);掠夺系统系列(仙逆、剑来、凡人修仙传两版、无限恐怖三版、逆天邪神完整/精简版)全部干净——它们用 prefault(‘未知’) 而不是 catch,天生没有重置雷。旧式变量脚本卡(Lost Good Things、命定之诗等)不得此病。主人点名的 Fate、SAO、路人女主当时判定”无此病”因为它们压根不用 MVU(局部变量或正则状态栏)——后来桌面深检才发现那批桌面包其实是 MVU 卡,那是后话,属于八包会诊的战果。
顺带一个诊断副产品:ST 一度起不来,Windows 把 8000-8099 端口动态保留了(Hyper-V/WinNAT 所为),重启 winnat 服务释放端口即恢复——这条经验后来写进了工具包的启动器。
三、工具包 2.1:从战地工事到装备库
对工具包 2.0 的评价诚实而锋利:五层防护的架构哲学(自愈 > 拦截 > 重试 > 重算 > 日志)被实战验证是对的,不要动;但所谓”工具包”当时其实是卡内三件套加全局预设十二条加五十一个散装一次性 Python 脚本加一堆存在脑子里的纪律——是战地工事,不是装备库。2.1 的使命是把工事变成装备。七个组件落位 F:/sillytavern/hermes-toolkit/:
| 工具 | 用途 |
|---|---|
| sanitizer.js | 命令消毒器通用版:白名单从运行时当前变量树的顶层键动态取(同一份脚本对斗破/道渊/掠夺系/春物自动适配),装成全局脚本一次全卡生效 |
| mvu_card_doctor.py | 卡片医生:扫 .catch({}) 地雷/时间默认值/schema 键;—fix 拆雷加装消毒器;—fix —chat 连存档树一起清(含繁简变体自动改名) |
| mvu_fix.py | 存档定点修复:—show/—set/—delta/—delete,默认只动目标楼层 |
| preplay.py | 开玩预检:ST 存活/8000 保留/模型探活/配置一致性/预设完整性,异常退出码 2 |
| backup_tool.py | 四件套备份一键化(含 md5) |
| start_st.py / start-st.cmd | 带日志启动器:自动检测释放 8000 保留端口、日志按日期归档保留七份 |
| README.md | 全部用法加血泪纪律清单 |
安装战果:斗破消毒器升级 2.1 通用版(带新补丁——44% 这类带 % 的值也能正确提取数字,堵死”世界线偏差被 catch(0) 归零”的复发路径);道渊 v5.2 正式拆弹完毕——十颗雷全拆、消毒器注入、存档树二十三处清理对齐 schema(含 $器灵台詞→$器灵台词 繁简改名)→ 现在可以玩了。所有手术前都有 backup_tool 备份,两次实战。
四、三颗自家地雷:诚实交代
工程日记最珍贵的部分永远是自己的 bug:其一,doctor 的 —chat 分支因空候选名让 os.path.join(chats, ”) 等于 chats 根目录本身、isdir 误判通过、glob 自然零命中——静默清了个寂寞,修法是在候选为空时直接跳过;其二,sanitizer 的数字提取不认 % 号,导致世界线偏差被 zod 的 catch(0) 归零过一次——补 % 剥离并同步双卡;其三,发现当前档的偏差确实是 0(旧伤复发),用刚做好的 mvu_fix 修到 50 并向后传播。ST 最终以 PID 42372 跑起来,preplay 八项全绿。
日常从此定型:开玩前跑 preplay.py,启动双击 start-st.cmd,导新 MVU 卡先跑 mvu_card_doctor.py 体检,出变量问题 mvu_fix.py —show 先看数值。2.2 的候选(测试夹具封装、上游 MVU 提案)等这套用顺了再说——给 MagVarUpdate 官方提 issue 请求”校验前消毒”或宽容模式,才是治本。
真实坐标
- 病灶链:msg31 树=卡内 schema 重建(prefault 1000-04-15 14:30 + 旧红颜榜字段);MagVarUpdate 机制=每 patch 后整树 safeParse、失败丢命令;schema 世界段 .catch({}) → 动向列表解析失败 → 世界整段重置
- 三连试日志:id=56264 dsf 失败 / 56269 dsf ct=8192 撞墙(界面仍报”解析完成”)/ 56276 step-3.7-flash 成功 3 条;deepseek-flash 最大回复 8192→16384 的救法在案
- 卡池普查:带雷=道渊 v5.2/4.9(各 10 处)+ 逆天邪神原版(9 处);安全=掠夺系全家/春物/逐梦演艺圈(prefault(‘未知’) 无重置雷);不得病=旧式变量脚本卡与非 MVU 卡
- 工具包 2.1(F:/sillytavern/hermes-toolkit/):sanitizer.js(运行时变量树动态白名单)/ mvu_card_doctor.py(—fix 拆雷装消毒器)/ mvu_fix.py(定点修档,实战 0→50)/ preplay.py(8 项预检)/ backup_tool.py / start_st.py(自动释放 8000 保留端口)/ README
- 战果:道渊拆 10 雷 + 清树 23 处(含 $器灵台詞→$器灵台词);斗破消毒器升级 + % 剥离补丁;三自家 bug 全部修复并同步双卡;ST PID 42372、preplay 8/8
评论