Skip to content

03 · 三大引擎设计 ​

这三块是本项目的真正价值所在(调研发现全网没人把它们拼齐)。 生成文字交给 LLM + 现成 Prompt,我们只做外面这层"控制系统"。


引擎 A · 长程一致性引擎 ​

目标:写到几十万字,人设/伏笔/世界观不崩。三支柱协作。

支柱 1:时序故事圣经(硬约束) ​

  • 数据来自 entities / facts / relationships(见 02 文档)。
  • 写前注入:生成第 N 章时,查询本章涉及角色/地点在"第 N 章"的有效事实 (valid_from ≤ N ≤ valid_until),作为硬约束塞进 prompt: 「角色张三当前状态:左手已截肢(第5章起)。写作时必须遵守。」
  • 事实库是"确定性断言",作为硬约束注入远比让模型自行回忆可靠。

角色资源账本(资源类事实的专用视图) ​

possession / ability 两类事实本来就在 facts 表里,但混在支柱 1 的硬约束块里一起 注入时,三件事都做不到,所以给它们一份自己的渲染(engines/consistency/ledger.py, 现查派生、不新增表)。

  • 闭集红线:角色那边早有"已登场角色名册"防凭空冒人,资源这边一直没有—— 账本把在册的关键道具/本事列清,并立三条硬规则:不许凭空掏出(本章蓝图【关键道具】 点名的不算)、新增必须当场交代来源、用掉/送出/损毁要在正文写明。
  • 独立预算:硬约束块只按 importance 截到 40 行,长篇后期状态事实一多,minor 的 "持有"行最先被挤掉——恰恰资源最该被一直记着。账本另有 24 行上限,critical 不被砍。
  • 收口:抽取侧要求"失去"也报一条 fact_changes + replaces;replaces 的匹配 三级宽容(精确 → 去空白 → 唯一子串),未命中留 warning 不静默——原先只做精确 相等,模型多写个括号补注旧事实就永久挂在开区间,于是"干粮吃完三章账本还挂着"。
  • 同一份账本喂草稿、定稿与一致性门禁(检查维度 2「角色资源」),三处看到的是一份东西。
  • 与常驻装置(宪法里预先登记、断档要催场)分工:账本管故事里挣来的东西, 只治"别凭空掏出、别忘了收口",不催场——没有 per-chapter 资源出场契约可算断档,硬猜等于乱催。

支柱 2:滚动摘要(软上下文) ​

早期设计过"分桶加权向量记忆"(6 个 Chroma collection),已整体移除。软上下文 现由"最近若干章正文结尾 + 滚动前情摘要"承担:每章定稿后 LLM 更新一份累积摘要, 生成下一章时连同最近章节结尾一起注入。硬事实仍走支柱 1 的故事圣经,确定性更强。

支柱 3:写后抽取器(闭环,让圣经自我更新) ​

  • 每章定稿后,用 LLM 做结构化抽取(强制 JSON 输出):
    • 新增/变更的事实 → 写入 facts(旧事实设 valid_until,新事实开区间)
    • 伏笔状态变化 → 更新 foreshadowings
    • 新出现的实体 → 建 entities
  • 这一步是一致性能"滚起来"的关键:不抽取,圣经就是死的。

一致性检查(体检) ​

  • 定稿后 + 抽取前,跑一次校验:新章内容 vs 故事圣经,LLM 找矛盾 (人设冲突/时间线错乱/能力越界/关系矛盾),输出问题列表 + 修改建议。
  • 严重矛盾可阻断,让用户决定改正文还是改设定。

规则扫描(世界观硬规则钉板) ​

  • 体检只查"与圣经/契约/上文矛不矛盾",错得前后一致就抓不到(典型: 理科生背政治、高考天数写错这类全文性事实错误)。
  • 规则扫描互补:项目里的 world_rules(钉板,用户手填)既注入蓝图/草稿/ 定稿/修改指令等生成环节做预防,又可发起全书逐章扫描(rule_scan_book), 违反项带原文证据落各章问题清单(source="rules"),走既有"按建议修订 → 重写"链路逐章修复。

引擎 B · 大纲级联更新引擎(全网空白,核心差异化) ​

目标:改任意一处大纲,系统自动告诉你"哪些地方会跟着变",绝不出现 "这里改了那里还是旧的"。

流程 ​

1. 用户编辑第 K 章大纲并保存
2. diff:新旧内容比对 → 存 outline_versions,判定 change_type
   - minor(措辞/细节微调):仅更新本章,结束
   - major(情节走向/伏笔/人物命运变化):进入影响分析
3. 影响分析(LLM):
   输入 = 改动摘要 + 下游章节(K+1..N)的大纲摘要 + 相关伏笔/事实
   输出 = 受影响章节列表 + 每章受影响原因 + 建议动作
4. 呈现给用户:"第 6-10 章依赖了'张三还活着'这个设定,现已改为死亡,
   建议重新生成这些章的大纲。是否执行?"
5. 用户拍板:
   - 全部重生成 / 选择性重生成 / 忽略(仅记录)
6. 若受影响章节已写正文 → chapters.is_stale = true(红点提醒重写)

major / minor 判定 ​

  • 先用规则粗筛(改了 summary/foreshadowing/plot_twist 字段 → 疑似 major)。
  • 再用 LLM 精判:给出改动前后文本,问"这是否影响后续情节逻辑?"
  • 判定结果写入 outline_versions.change_type。

关键约束 ​

  • 级联永远不自动执行重生成,只分析+提示,由用户决定。避免"AI 自作主张 把用户手改的东西又覆盖了"。
  • 重生成时保留用户手动标记为"锁定"的章节(不动)。

引擎 C · 润色引擎 ​

目标:文笔润色,但锁死情节事实(否则破坏一致性)。

流程 ​

1. 选择范围:整章 / 选中段落
2. 选择风格标签(chips):更文艺 / 更口语 / 增强画面感 / 强化张力 / 精简冗余
   (+ 我要输入自定义)
3. 润色前:从故事圣经提取本段涉及的"事实清单"作为不可变约束
4. LLM 润色,prompt 强约束:
   「只改文笔表达,不得改变以下情节事实:[事实清单]。
    不得新增/删除人物动作和对话内容的实质。」
5. 润色后跑一次轻量一致性校验兜底:比对事实是否被动过,动了就警告
6. 用户 diff 对比,接受 / 拒绝 / 局部采纳

增强(借鉴 KazKozDev) ​

  • 重复用词检测:润色时附带扫描本章与前几章的高频比喻/描写/情绪短语, 分类统计,提示"'心如刀绞'已用 4 次",引导换表达。

去 AI 味引擎(双向锚定 + 自愈闭环,2026-08 重构) ​

目标:把"一眼读得出是 AI 写的"作为头号敌人,从旧版"只检测、只提示"升级为 "双向锚定 → 量化门禁 → 自愈闭环"的一整套机制。

双向锚定(喂进生成/润色的 prompt) ​

  • 正向锚(render_voice_block):给笔法一个具体的"人"去学。
    • 内置文风胶囊:luxun / yuhua / wangzengqi / jinyong / wangxiaobo / hemingway / cooldry / plain,每个含语感描述 + 自撰仿写范本(sample)。
    • 也可喂用户自己的范文,或从已认可章节自动提取文风。
    • 正向锚由 voice_block_of(global_tendency) 铺满所有入口:续写 continue_tail、片段润色 polish_fragment / craft_fragment、整章润色 polish_text、批注重写 revise_annotated——续写此前完全裸奔,现在也吃锚。
  • 负向锚(pairwise_examples_block):✗AI 腔 → ✓人话 配对反例,把神态套话 / 升华点题 / 论文式罗列 / 比喻堆砌逐条摆成"这样写 → 改成这样",让模型照着划掉。

版权红线:在世作家(余华等)绝不嵌原文,sample 一律本项目自撰仿写, UI / 接口统一标注"风格参考·非原作节选"。

量化检测(ai_flavor_report) ​

  • 9 类套话规则:神态套话(权重最高 2.0)、升华点题、论文式罗列、比喻堆砌、空洞比喻堆砌(脑内涟漪 / 远方呼唤 / 无形的手等无锚点空镜,权重 1.5)等, 命中即计分并留证据句。
  • 4 项句式统计:句长 burstiness(真人句长忽长忽短)、节拍器句组(等长句堆叠)、 段落结构均质、长重复。
  • 汇总为 AI 味指数(score,越低越干净),看板 / 结果卡展示,超标章节一目了然。

自愈闭环(deai_self_heal) ​

  • 定稿时把检测从"只展示"升级为门禁(DEAI_GATE_SCORE=6.0)。
  • 超标触发定向去味重写 → 复测 → 收敛,最多 2 轮。
  • 安全阀:没改好(分数没降)、长度跑偏(出 0.75~1.25 区间)、或空回复,一律 回退原文——绝不落更差的版本。

生成质量增强(2026-07 加入) ​

不是独立引擎,而是叠加在生成管线上的四件事,统一解决"千章一面、结构松散":

  • 场景节拍(beats):蓝图阶段为每章产出 3-5 个一句话场景节拍 (outlines.beats,解析时只按 | 分隔——节拍内部含逗号顿号)。 草稿 prompt 按节拍逐个铺场景,治"一句 100 字简述撑几千字"的结构松散; 无节拍时回落为模型自行拆场景(向后兼容存量大纲)。
  • 文风备忘(style_memo):与滚动摘要互补——摘要记"发生了什么",备忘记 "这本书怎么写"(调性/人物声音/复现意象,≤600 字)。每章定稿后由快模型 增量更新,拼进后续章的 style_block,防长篇后段人物声音漂移、调性变淡。 更新失败不阻塞主流程。
  • 创作初衷回注:concept 的原始火花(钩子/反转/主角/冲突/基调)随 chapter_architecture_brief 注入每章,缓解 concept → 种子 → 蓝图 → 正文 链路的信息减损;角色动力学给足篇幅并点明"据此区分人物声音"。
  • 任务分档温度:_TASK_TEMPERATURE 按任务定采样温度(草稿 0.95 发散、 抽取 0.2 求准、摘要 0.3 忠实),替代此前全局 0.7;事实抽取上 QUALITY 档 (抽错污染全书圣经)。上游软错误(HTTP 200 但 body 夹 error,如中转站 "无可用渠道")在 check_upstream 直接抛出,不再退化成"空回复"。

引擎 D · 翻新引擎(已有书重构) ​

目标:老书/旧逻辑写的章节,也能享受新生成管线,不必推倒重来。 四个异步能力(api/refresh.py,都走 job,前端轮询):

① 回填节拍 backfill_beats     依已成文正文(优先)或蓝图简述反推 beats,
                              只写 outline.beats,不动正文/圣经;单章失败
                              进 failed 列表,不中断整批
② 初始化文风备忘 seed_style_memo  扫前几章正文增量累积出基线备忘;
                              已有备忘不覆盖(existed/seeded 区分)
③ 轻度重润 light_refresh      复用润色引擎(锁事实→去AI味→校验),
                              不改剧情不重抽圣经;留快照可回滚
④ 重度重写 heavy_refresh      带 beats/concept/文风备忘重跑 generate_chapter
                              (自带重抽圣经 + 重建下游摘要);按章串行,
                              单章失败即停但已完成章进度保留,
                              返回 remaining 供前端"续跑"

关键约束:

  • 与逐章生成/连写队列互斥(chapter-{pid}- / refresh-{pid}- 前缀锁)。
  • 每章独立事务提交:任何中断都不丢已完成章的进度。

引擎间协作总览 ​

                 ┌──────────────┐
   标签倾向 ────→│  Prompt 拼装器      │←──── 现成写作 Prompt(雪花法等)
                 └──────┬───────┘
                              │
   故事圣经(硬)──────┤
   滚动摘要(软)──────┼──→ [LLM 生成正文]
   伏笔调度  ────────┤          │
                              │          ▼
                              │    [一致性检查] ← 引擎A
                              │          │
                              │          ▼
                              │    [写后抽取器] → 更新圣经/伏笔(引擎A闭环)
                              │
   [大纲级联引擎B] 独立触发:改大纲 → 影响分析 → 标记 stale
   [润色引擎C]     独立触发:选范围 → 锁事实 → 风格改写
   [翻新引擎D]     独立触发:回填节拍/文风备忘 → 轻度重润(复用C) / 重度重写(复用生成管线)
   
   生成质量增强(内嵌管线):节拍 beats + 文风备忘 style_memo + 任务分档温度

基于 Apache License 2.0 开源