# dsh-humanizer 工程结构(ARCHITECTURE) > 这份文档讲工程:每个文件为什么存在,运行时会话怎么流转,哪些决定被反复讨论过, > 以及程序层为什么故意保持这么小。 > 理论见 docs/THEORY.md,设计推理见 docs/WHY.md,使用说明见 README。 --- ## 一、插件的位置 dsh-humanizer 挂在 DeepSeek Harness 的 web profile 上,分两半。 Node half 是 `index.mjs`。它在启动时向 system prompt 注入一段常驻文本,并注册几个工具。常驻文本不描述流程,只立一个姿态:模型要读全理论,成为作者,然后写作。工具负责把书递过去,以及核对内容有没有坏。 浏览器 half 是 `lib/client.js`。它在设置页挂一个面板,给用户看这个插件在做什么。面板不参与执行,执行只发生在模型那一侧。 插件不持有模型,也不调用检测器;它不联网,也不写用户文件。它做的事情可以概括成:把书递到模型手里,然后守住内容没有坏。 --- ## 二、会话怎么流转 先看创作。 用户说「用 humanizer 写这一章」。常驻引导已经在 system prompt 里,所以模型知道下一步该做什么:调用 `humanize_study(fiction, authoring)`。工具从 references 目录读出全部二十一章,按小说的阅读顺序排好,附上三篇风格完全不同的示范文,渲染成一段连续文本返回。模型读完,在思考里成为这一章的作者,然后一次写完。写完听一遍,改掉真实的不适,交付。 润色多一步「反推」。用户说「用 humanizer 润色这段文本」,模型先调 `humanize_study(体裁, polishing)`,完整读一遍理论,然后不是急着找问题,而是从原文反推作者:他是什么声音,他在乎什么,哪里只是没写到位。只改那些地方,其余不动。改完读接缝,交付。 两条链路里都没有程序状态机。插件不记录「当前第几步」,不检查「有没有读全」,不验证「作者状态是否建立」。这个决定在早期被争论过。担心是模型会跳读,会偷懒。后来我们判断,门禁拦得住表格,拦不住心不在焉;与其让模型花力气对付检查,不如让阅读包本身足够完整、足够有说服力。成品里的生硬和机械感,就是最诚实的门禁。 --- ## 三、每个组件为什么是这个样子 ### 常驻引导 它在 system prompt 里,注意力最高。内容很短,只做一件事:规定模型和工作之间的关系。 之所以不写长流程,是因为任何流程写进 system prompt,模型就会把它当任务清单。清单会跨会话稳定地执行,稳定执行的东西会变成指纹。所以常驻引导只讲姿态:你不执行方法,你学习全部理论,然后成为这次要写的人;理论放在思考层,文本层不许露出理论的形状。 ### humanize_study 核心工具,背后是 `lib/study.mjs`。它按体裁和模式组装阅读包。 体裁决定阅读顺序。小说先从十维叙事进入,文章先从论证知识进入,但两者都从总协议和作者感开始,以失败证据和后处理禁令收尾。顺序只是认知路径,不是执行步骤,全部章节必须读完。 模式决定契约文本。创作模式要求一口气写完;润色模式要求把原文当认真作者的草稿。除此之外,正文里还有三篇示范文。示范文风格差得很远,一篇贴着人物,一篇隔着距离看渡口,一篇在论证里守着证据边界。它们不供模仿,只让模型感受「背后有人」在不同体裁里长什么样。 阅读包约四万字符。大是有意的。摘要、清单、门禁都是对理论的降维,降维会把约束之间的牵制丢掉。这个判断在 docs/WHY.md 里有完整的推演。 工具输出被渲染成连续文本,不做 JSON 转义。这里有个工程细节:如果返回结构化对象,模型容易把它当表格去填;渲染成书的样子,它才更像「读」,而不是「执行」。 ### humanize_guard 程序层唯一的内容检查,背后是 `lib/guard.mjs`。只做三件事:锚点比对,文字完好性,段落变化提示。 锚点是数字、书名、术语、等级这些内容里不能丢的东西。润色最怕的不是风格跑偏,是事实悄悄没了。文字完好性查乱码、控制字符和引号成对。段落变化只提示,不判对错,因为段落该不该拆,程序说了不算。 这里没有评分、检测、画像和文体扫描。文体扫描在前两版都被证明会诱导机械替换。模型看见「仿佛出现三次」,就会去消灭「仿佛」;消灭的动作会变成新的稳定动作,稳定动作就是新指纹。 ### humanize_reference 单章查阅工具。写作后需要单独回查某一章时使用。动笔前的完整阅读仍以 `humanize_study` 为准,单章查阅不能替代,因为它重新把理论切成碎片。 ### humanize_profile 旧版分布画像工具已经退役,现在只返回内容锚点,让旧调用不报错。任何画像和表面指标都不再进入执行。 ### 浏览器面板 设置页里的静态说明:核心理念、两个模式、怎么用。它不参与执行。 --- ## 四、文件结构 ``` dsh-humanizer/ ├── package.json # npm 包 manifest + dsh bundle/client 声明 ├── index.mjs # Node half:Config/apply/作家宪法 + 工具注册 ├── invariant.js # ./invariant 配套入口(官方惯例) ├── cordis.patch.yml # bundle patch:向 web profile 插入本插件 ├── lib/study.mjs # 理论阅读包组装器与文本渲染器 ├── lib/guard.mjs # 内容忠实守卫 + 旧工具兼容替身 ├── lib/reference.mjs # references/ 单章读取器 ├── lib/client.js # 浏览器 half:设置页面板 ├── references/ # 00—20 章方法论全文 ├── scripts/guard-humanizer.mjs # CLI:guard / study 冒烟 ├── test/ # node:test 测试 ├── docs/THEORY.md # 理论总纲 ├── docs/WHY.md # 设计推理 ├── docs/ARCHITECTURE.md # 本文档 └── README.md # 使用说明 ``` --- ## 五、程序层为什么这么小 程序规则是固定规则。固定规则能安全地做两件事:核对内容有没有坏,以及把文本塑成规则能识别的形状。 第一件是 `humanize_guard`。第二件被全部删掉了。 这不是能力限制。判断一个排比在这里有没有功能,判断一处重复是口癖还是机械复述,判断一句短句是真停顿还是假节奏,只有模型能做。程序一旦替模型做这些判断,产出的是固定规则驱动的文本;固定规则驱动的文本,正是这套理论要消除的东西。 所以工程上的原则是:程序不判断写作,只核对损坏。 --- ## 六、配置 ```yaml workflowEnabled: true # 是否注入常驻作家宪法 toolsEnabled: true # 是否注册工具;false 时也停用依赖工具的作家宪法 sectionOrder: 50 # system prompt 段顺序,数字越小越靠前 ``` 配置键保持自第一版以来的名字,旧 profile patch 不需要改。 --- ## 七、兼容与迁移 `humanize_validate_decision` 和 `humanize_validate_artifact` 不再注册,程序化思考校验退役。`humanize_profile` 保留为只返回内容锚点的兼容替身。`humanize_guard` 行为与 v0.2 相同:只守内容与文字完好性。安装后需要重启 web,bundle 层栈在 boot 时合成。 --- ## 八、已知边界 客户端面板依赖官方 `__ModuleLoader__` 与 slots 机制。manifest 的 `dsh.client.inject` 使用 renderer 和 settings-general 包名;运行时的 `inject` 使用 `slots` 服务名。已在 DSH 0.1.2-rc.1 的真实 Web UI 验证浅色与深色面板,版本矩阵见 [COMPATIBILITY.md](COMPATIBILITY.md)。 完整阅读包保留所有 21 章。`reference` 和 `study` 共享只读正文缓存,每次返回独立的数组和对象;缓存有效期为当前模块生命周期,更新插件后重启。宿主 spill 策略可能转存长结果,常驻引导要求按宿主提示读完全文;PTC 模式使用宿主工具 SDK。只读工具声明可并行,注册与卸载仍交给 Cordis 管理。 理论验证的强证据集中在长篇小说,跨体裁与跨语言的系统检验仍是开放工作。这个边界同时写在 docs/THEORY.md 里,避免工程文档和理论文档各说各话。 --- ## 九、收束 工程上的一切决定,都服从同一条:程序只递书,只守内容,不教模型怎么把字写像人。