integrations/deepseek-harness
tt-a1i/archify从仓库或系统描述生成经过校验的自包含交互式架构图、流程图、时序图、数据流图和生命周期图。
长文创作一致性守卫:扫描会话正文,发现人物年龄、等级、境界、年份等设定跨章节矛盾,点击直接跳转到冲突原文位置。
DeepSeek Harness(dsh)长文创作一致性守卫插件:扫描会话正文中的人物设定、时间线、数值型设定,自动发现跨章节矛盾,并点击直接跳转到冲突原文位置。
背景:百万字长篇创作中,人物年龄/等级/境界、时间线、数值设定在数十次对话迭代后极易失控。dsh 内置没有跨章节内容审计能力,现有写作类插件做的是编辑与导出,本插件补上「一致性守卫」这一环。
| 能力 | 说明 |
|---|---|
| 实体提取引擎 | 纯前端规则引擎,从会话正文中提取属性设定:年龄(25 岁 / 二十七岁)、年份(1998 年 / 星历 412 年)、身高(180cm / 身高 180)、等级、境界。中英文数字统一归一化,25岁 与 二十七岁 可正确比对。 |
| 实体归属 | 优先匹配设定字典中的已知人名,其次按常见姓氏识别,最后用「动词/属性词邻接」启发式回退;内置停用词拦截,避免把「境界三层的修士」误判成人名。 |
| 设定字典 | settings.section 插槽提供编辑器:维护 实体 / 属性 / 标准值 条目,保存在浏览器本地存储(localStorage),编辑后 dock 面板即时生效,无需重载。 |
| 两级冲突检测 | 数值矛盾(numeric):同一实体同一属性出现两个不同数值——硬性矛盾,如林默第 1 轮 25 岁、第 7 轮 27 岁。 表述差异(wording):非数值属性的表述漂移,低置信度提示。 无归属的 mention 归入 (unattributed) 桶,只给提示、不误报硬冲突。 |
| 冲突 dock 面板 | 输入框上方( conversation.input.dock 插槽)显示冲突数胶囊:无冲突为绿色、有冲突为红色;点击展开冲突列表(portal 到页面根部,不受布局容器裁剪),按「数值矛盾优先 + 轮次」排序。 |
| 点击定位跳转 | 点击任意冲突项 → 切回「对话」视图 → 平滑滚动到第二个冲突值所在消息并红色高亮。若目标在未加载的更早记录中,自动调用 loadOlder(最多 3 次)后重试。 |
dsh plugin --profile web add file:/path/to/dsh-consistency-guard
然后在 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 数组中加入 "dsh-consistency-guard",重启 DSH.app(或硬刷新浏览器窗口)生效。
dsh plugin --profile web remove dsh-consistency-guard
ctx.slots 注册两个服务——
conversation.input.dock(id consistency-guard-dock):输入框上方的冲突胶囊 + 展开列表。settings.section(id consistency-guard-settings):设定字典编辑区。snapshot.chat.order / snapshot.chat.nodes,取 assistant 的 data.blocks[kind=text] 与 user/steering 的文本作为正文来源;工具调用与代码输出刻意跳过,避免把代码里的数字当成设定。年龄/岁/身高/cm/等级/境界/年份)→ 值归一化 → 实体归属 → 按 (实体, 属性) 分组 → 组内出现两个及以上不同值即判定冲突。境界/修为 与 等级/级别 是中文类型小说中两个独立维度,刻意不合并,否则「境界三层,等级 9」会被误判为矛盾。data-chat-anchor-key="<key>",跳转 = 找到该行 → scrollIntoView + 红色高亮;点击胶囊先按 label 点击 [role="tab"] 切回「对话」(中文「对话」/ 英文「Chat」,回退首个 Tab),再轮询等待目标行挂载。apply 内维护一个极简订阅器(subscribe/getDict/setDict),设置区保存后即时广播给 dock 面板。dsh-consistency-guard/
├── package.json # dsh.bundle.patch + dsh.client + exports["./client"]
├── cordis.patch.yml # 挂载插件到 profile 层叠
├── lib/
│ ├── index.js # 服务端挂载入口(UI-only,最小实现)
│ └── client.js # 客户端 bundle(window.__ModuleLoader__.load 格式)
└── test/
└── smoke.cjs # 冒烟测试(mock ModuleLoader + ctx + 纯函数断言)
react,零构建步骤),格式遵循 dsh web 的 lazy-CJS 模块表契约:window.__ModuleLoader__.load({ id, factory })。dsh.client.inject 声明了插件可用的客户端服务:slots / sessions / locale。exports.__test 暴露给冒烟测试。node --check lib/client.js;冒烟测试 node test/smoke.cjs(覆盖工厂物化、两个插槽注册、中文数字归一、实体归属、去重、人名校验、端到端冲突检测)。factory materialized; exports: [ 'apply', 'inject', '__test' ]
registered slots: ["conversation.input.dock[consistency-guard-dock]","settings.section[consistency-guard-settings]"]
cnNumToInt: ok
normalizeValue: ok
extractMentions attribution + dedup: ok
plausibleName: ok
mentions: 8 conflicts: 2
detectConflicts end-to-end: ok
loadDict without localStorage: ok
ALL CHECKS PASSED
端到端用例模拟《归墟》修订场景:林默第 1 轮 25 岁 / 第 7 轮 27 岁(报数值矛盾)、沈砚青等级 9 → 12(报数值矛盾)、苏晚晴两处均为 27 岁(不误报)、境界三层与等级 9 不合并(不误报)。
MIT