Skip to content

02 · 数据模型设计(最关键,重点保存) ​

这份是整个系统的骨架。三大引擎都靠这些表运转。字段设计吸收了调研中 knowrite(时序真相库)、NovelClaw(分桶记忆/伏笔四态)、KazKozDev (读者已知/角色已知分离)的做法。

当前共 16 张表:主体 11 张 + 阶段 2 的 chapter_summaries、阶段 7 的 llm_usage、阶段 8 的 users / provider_settings(已废弃,仅作迁移 数据源)与替代它的 provider_configs(见下)。


一、项目与大纲 ​

projects — 小说项目 ​

字段类型说明
idPK
user_idFK → users?归属用户(阶段 8 数据隔离);存量数据迁移时归 admin
titlestr小说名
topictext核心主题
genrestr题材(可来自标签,如"赛博朋克")
target_chaptersint目标章节数
target_words_per_chapterint每章目标字数
global_tendencyJSON全局倾向(见 04 文档,标签组合)
style_memotext | NULL文风备忘(随书累积):本书调性 + 人物声音 + 复现意象,每章定稿后由快模型增量更新,注入后续章草稿,防长篇后段人物声音漂移;NULL=尚未累积
world_rulestext | NULL世界观硬规则(钉板):用户手填的不可违背设定/常识(如"理科不考政治""高考两天"),每行一条;注入蓝图/草稿/定稿/修改指令等生成环节,并可发起「规则扫描」逐章体检正文(engines/diagnosis.rule_scan_book,问题以 source="rules" 落 chapter_issues);NULL=未设置
statusenumdraft / outlining / writing / done
created_at / updated_atdatetime

architecture — 顶层架构(雪花写作法产出) ​

字段类型说明
idPK
project_idFK
core_seedtext核心种子(一句话故事本质)
character_dynamicstext角色动力学
world_buildingtext世界观
plot_architecturetext情节架构
versionint架构也可改,做版本

outlines — 章节大纲(每章一行,可独立编辑) ​

字段类型说明
idPK
project_idFK
chapter_numberint第几章
titlestr章节标题
chapter_rolestr本章定位(借鉴雪花蓝图字段)
chapter_purposestr核心作用
suspense_levelstr悬念密度
foreshadowingtext本章伏笔操作(自然语言描述)
plot_twist_levelstr认知颠覆程度
summarytext本章简述
beatsJSON章内场景节拍(3-5 个一句话 beat,蓝图生成时产出;空 list=未预设,草稿 prompt 回落自行拆场景;存量书可用「翻新 → 回填节拍」补齐)
characters_involvedJSON涉及角色 id 列表
key_itemsJSON关键道具
scene_locationstr场景地点
content_hashstr内容指纹,用于 diff 判断是否变更
current_versionint当前版本号
updated_atdatetime

outline_versions — 大纲版本历史(级联引擎依赖) ​

每次改大纲存一个快照,支撑"改动 diff"和"回溯"。 | 字段 | 类型 | 说明 | |---|---|---| | id | PK | | | outline_id | FK | | | version | int | | | snapshot | JSON | 该版本完整大纲内容 | | change_type | enum | minor(小改)/ major(大改) | | change_summary | text | LLM 生成的改动摘要 | | created_at | datetime | |


二、章节正文 ​

chapters — 章节正文 ​

字段类型说明
idPK
project_idFK
outline_idFK对应大纲
chapter_numberint
draft_contenttext草稿
final_contenttext定稿
word_countint
outline_version_usedint生成时基于的大纲版本号
is_stalebool大纲改了但正文没重写 → true(失配标记)
statusenumempty / drafting / drafted / finalized / stale
created_at / updated_atdatetime

is_stale 是关键:大纲级联引擎发现某章大纲变了、但正文还是旧版本生成的, 就把这一章标 stale,前端红点提醒"正文与新大纲不符,是否重写?"

chapter_summaries — 滚动前情摘要(阶段 2 新增) ​

第 N 章的行存的是「截至第 N 章的完整前情摘要」,每章定稿后把剧情合并压缩进来; 生成第 N+1 章时取 chapter_number=N 的行注入上下文。 | 字段 | 类型 | 说明 | |---|---|---| | id | PK | | | project_id | FK → projects | 级联删除 | | chapter_number | int | 摘要覆盖到第几章 | | rolling_summary | text | 截至该章的合并压缩摘要 | | created_at / updated_at | datetime | |


三、时序故事圣经(借鉴 knowrite Temporal Truth DB + graphify 图谱) ​

核心思想:事实不是静态的,而是带"有效章节区间"的。 查询"第 N 章时角色 X 状态如何",只返回 valid_from ≤ N ≤ valid_until 的事实。

entities — 实体(角色/地点/物品/势力,知识图谱的"节点") ​

字段类型说明
idPK
project_idFK
entity_typeenumcharacter / location / item / faction
namestr
aliasesJSON别名(防止 LLM 换称呼认不出)
base_profileJSON基础档案(角色:外貌/性格/初始能力等)

facts — 时序事实(Temporal Truth,系统心脏) ​

字段类型说明
idPK
project_idFK
entity_idFK该事实属于哪个实体
fact_typeenumstate / ability / possession / relationship / location
contenttext事实内容(如"左手截肢")
valid_fromint从第几章起成立
valid_untilint?到第几章失效(null = 一直有效)
importanceenumcritical / major / minor
source_chapterint由哪章的正文抽取而来
created_atdatetime

例:角色A第5章受伤 → fact(valid_from=5, valid_until=11);第12章痊愈 → 新 fact(valid_from=12, valid_until=null)。查第8章 → 命中"受伤"。

relationships — 关系边(知识图谱的"边") ​

字段类型说明
idPK
project_idFK
from_entity_idFK
to_entity_idFK
relationstr如"师徒""仇敌""恋人"
valid_fromint关系带时序(关系会变)
valid_untilint?

knowledge_states — 谁知道什么(借鉴 KazKozDev 读者/角色已知分离) ​

字段类型说明
idPK
project_idFK
fact_idFK针对哪条事实
knowerstr"reader" 或 角色 entity_id
known_from_chapterint从第几章起知道
knower_stateenumknown / suspected / blind

写悬疑必备:同一真相,读者第3章就知道、但角色B到第10章才知道。 生成时据此控制"这个角色现在不该说出他还不知道的事"。


四、伏笔调度(借鉴 NovelClaw 四态 + KazKozDev 揭示调度) ​

foreshadowings — 伏笔 ​

字段类型说明
idPK
project_idFK
descriptiontext伏笔内容
chapter_plantedint埋设章节
expected_payoff_chapterint?预期回收章
earliest_payoff_chapterint?最早不能早于(KazKozDev minimumChapter)
statusenumplanted / reinforced / paid_off / abandoned
payoff_chapterint?实际回收章
reinforcement_chaptersJSON强化出现的章节列表
importanceenumcritical / major / minor
required_hintsJSON回收前需要的前置铺垫
notestext

调度规则(借鉴 NovelClaw):status in (planted, reinforced) 且 expected_payoff_chapter <= 当前章+2 → 进入"该回收"提醒列表, 生成该章时注入 prompt:"以下伏笔应在近期回收:…"。


四·五、桥段台账 + 雷区清单(跨章重复描写治理) ​

writing_motifs — 描写母题(一张表两种行) ​

治「连续章节写同一描写」:n-gram 查重只抓字面重复,抓不住「换措辞复用同一桥段」 (铁锈玫瑰/扎胸膛/躺下等天亮)。章后抽取顺带把本章标志性描写母题沉淀成短标签 (只记标签不记原句——原句进 prompt 会被逐字照抄),按标签跨章聚合;写新章前 已复现 ≥2 次的母题注入草稿 prompt 禁止复用。作者也可把写烦的桥段登记为雷区, 一次标注全书生效(注入 style_block,草稿/定稿/守卫/去味全链路规避)。

字段类型说明
idPK
project_idFK
labelstr(100)短标签(聚合键,归一化去空白后比对,≥2 字)
detailtext一句话说明(注入 prompt 时帮模型对上号)
chapter_numberint标签来自哪章;0=非章节来源(用户手动)
sourceenumauto(章后抽取/全书扫描)/ user(用户手动)
bannedboolTrue=雷区行((project,label) 唯一);False=台账行((project,chapter,label) 一行)

引擎与 API:engines/consistency/motifs.py(聚合/渲染/软报/扫描)、 api/motifs.py(清单增删/升格/scan-async)。事后软报 source="repeat" (雷区命中 major、台账 ≥2 次再现 minor,一律 advisory 不阻断)。

chapter_marks — 跨章标记(作者随手记的「这里不行」,落库批注) ​

治「批注是内存状态、切章/刷新即丢」:标记落库后可边读边攒、跨章不丢, 再由「全书批修」一句总描述统一驱动逐标记锁情节改写(engines/marks.py、 api/marks.py,job 只产出待验收替换对不落库,前端逐条 diff 验收接受后 走 PUT content 写回并 DELETE 销账)。

字段类型说明
idPK
project_idFK
chapter_numberint哪一章
para_idxint段落下标(与前端 splitParas 同口径:\n 分段、trim、去空行)
snapshottext段落原文快照(正文变动后据此判失效,批修时跳过)
notetext一句话意见
statusenumopen / fixed(验收接受后由前端 DELETE 落实销账)

五、倾向预设(你的标签系统,详见 04 文档) ​

tendency_presets — 用户存的倾向模板 ​

字段类型说明
idPK
namestr如"我的爽文模板"
scopeenumoutline / chapter / polish
tagsJSON标签组合(含自定义输入)
is_builtinbool内置 or 用户自建

六、用量与多用户(阶段 7/8 新增) ​

llm_usage — LLM 用量记录(阶段 7) ​

字段类型说明
idPK
user_idint?记账归属:哪个用户烧的 token(NULL = 多用户迁移前的历史记录)
modelstr实际调用的模型
prompt_tokens / completion_tokensint本次调用的输入/输出 token
created_at / updated_atdatetime

llm/base.ask 统一埋点,所有生成链路自动记账;GET /api/usage 汇总, 前端顶栏实时显示累计用量。

users — 用户账号(阶段 8) ​

字段类型说明
idPK
usernamestr唯一
password_hashstrbcrypt 哈希,不存明文
is_adminbool初始 admin 由启动迁移(migrate.py)自动创建
created_at / updated_atdatetime

数据隔离:projects.user_id / provider_configs.user_id / llm_usage.user_id 均按用户过滤,跨账号访问返回 404。

provider_configs — 每用户 LLM 模型配置(cc-switch 风格,多套命名) ​

字段类型说明
idPK
user_idFK → users每用户多套,级联删除
namestr显示名(如「DeepSeek 官方」「中转站 A」)
interface_formatstr协议卡:deepseek / openai / gemini,决定用哪个适配器
api_key / base_url / modelstrkey 落库为密文;在站点设置页配置
timeout / max_tokensint0 = 跟随全局 default_* 与任务级默认
is_defaultboolquality 档(主)配置,全用户唯一
is_default_fastboolfast 档配置,全用户唯一;未设则 fast 跟随 quality
created_at / updated_atdatetime

旧表 provider_settings(每用户 × provider 一行)已废弃,启动迁移 (migrate._migrate_provider_settings_to_configs)把老行一次性拷入本表, 老表保留不删。数据隔离说明同上(按 user_id 过滤,跨账号 404)。

优先级:数据库里当前用户的配置 > .env / 环境变量(.env 仅作开发兜底)。


七、长程记忆(无向量库) ​

早期设计规划过 Chroma 向量库 + 6 桶加权记忆,但因 embedding 来源始终不稳(中转站 /embeddings 返 403),且现代模型上下文窗口已足够长,该方案已整体移除。长程一致性 现由时序故事圣经(结构化事实,见第三节)+滚动摘要(chapter_summaries)+ 最近章节正文尾部三者承担,全部落在 SQL 里,不再有独立向量存储。


八、数据流转关系图 ​

生成一章正文的数据流:
  outline(本章) + architecture
      + 故事圣经查询(相关 entity 在"当前章"的 facts)
      + 最近章节结尾 + 滚动前情摘要(直接上下文)
      + 伏笔调度(该回收的 foreshadowings)
      + 倾向拼装(global_tendency + 本次临时标签)
   → 拼装 Prompt → LLM 草稿 → 定稿
   → 存 chapters.final_content
   → 抽取器 extractor 从正文抽新 facts / 更新伏笔状态(写回故事圣经)

改一章大纲的数据流(级联引擎):
  编辑 outline → 存 outline_version(diff 出 change_type)
   → 若 major:impact 分析下游章节依赖
   → 提示用户"第 X-Y 章受影响,是否重生成大纲?"
   → 已有正文的受影响章 → chapters.is_stale = true

基于 Apache License 2.0 开源