尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI辅助网文创作理论研究笔记(十一):文档库——生成产出的版本管理与组织

AI辅助网文创作理论研究笔记(十一):文档库——生成产出的版本管理与组织 笔记11文档库——生成产出的版本管理与组织一、问题的发现当前系统的覆盖式存储审视现有代码L1~L4 各层 API 的存储逻辑如下l1.py: outputs/l1_vision.json ← POST generate 覆盖 l2.py: outputs/l2_outline.json ← SSE stream 完成后覆盖 l3.py: outputs/l3_chapter_plan.json ← POST generate 覆盖 l4.py: outputs/l4_text.json .txt ← SSE stream 完成后覆盖每次重新生成旧文档直接消失。用户对第一次产出不满意想再试一次却发现前一次的版本已经不可恢复。这在网文创作中尤其致命——很多时候第一版的某个点子反而值得保留或者需要对比三个版本挑最好的一个。需要的功能每份产出都存档不论 L1 愿景、L2 大纲、L3 章纲、L4 正文每次生成都新增一份旧版本不删除可浏览的文档栏像 VS Code 文件浏览器一样一个可折叠的侧边栏展示文档树用户可自由整理创建目录移动、重命名、删除文档外部文件导入用户可以塞自己的 .md/.json 文件进去后续可从文档库里导入随机编号或 AI 命名不必用户每次手动起名系统自动生成可辨识的标题二、概念命名暂定名称文档库 (Document Library)。在 ACENTS.md 目录结构中的位置data/projects/{id}/ ├── project.json ├── worldbook.json ├── outputs/ ← 当前固定文件名存储废弃 ├── library/ ← 新增文档库 │ ├── manifest.json ← 元数据索引 │ └── files/ ← 实际文件uid 命名 │ ├── a1b2c3d4.json ← L1 愿景 v1 │ ├── e5f6g7h8.json ← L1 愿景 v2 │ ├── i9j0k1l2.json ← L2 大纲 │ └── ... └── logs/三、数据模型3.1 文档条目 (DocEntry)每份文档在 manifest.json 中存一条记录{ uid: a1b2c3d4, name: 废土倒爷 v1 — 双界贸易 丧尸末世, layer: l1, format: json, source: generate, // generate | import | manual parent_uid: null, // 从哪份文档衍生如 L2 大纲衍生自 L1 愿景 directory: /, // 用户创建的目录路径/ 表示根 tags: [末世, 双界贸易], created_at: 2026-04-30T10:30:00, word_count: 2500, status: active // active | archived }字段说明字段类型说明uidstr(8)8位随机 hex作为文件名namestr显示名称系统自动生成用户可改layerstrl1/l2/l3/l4/imported标识来源层formatstrjson/md/txtsourcestrgenerate(系统生成) / import(用户导入) / manual(手动创建)parent_uidstr?链路追溯这份 L2 大纲是从哪个 L1 愿景生成的directorystr用户创建的目录路径tagslist用户或 AI 打的标签created_atstrISO 时间戳word_countint字数统计statusstractive / archived归档后不在主视图中显示3.2 文档库清单 (LibraryManifest){ project_id: abc12345, directories: [/, /备份, /L1草稿, /L2方案/剧情流, /L2方案/人物流], documents: [ ...DocEntry... ], updated_at: 2026-04-30T10:30:00 }3.3 自动命名策略系统生成文档时自动按规则命名。命名不要纯随机用户看到的是一堆乱码也不应该全靠用户手动输入增加摩擦。命名公式{层级前缀} — {AI 摘要短语}前缀示例L1 愿景L1 愿景 — 废土双界倒爷 修真物资流L2 大纲L2 大纲 — 拍卖会打脸 势力初探L3 章纲L3 章纲 — 第12章 拍卖场风波L4 正文L4 正文 — 第12章 拍卖场风波 (3200字)导入导入 — 原文件名AI 摘要由 LLM 在生成内容时同步产生。以 L1 为例VisionDocument增加一个可选字段summary_phrase: str 生成时让 LLM 用 10-15 字概括这份愿景。摘要短语放在name字段完整内容放library/files/{uid}.json。如果不想每次都调 LLM 生成摘要可以退化为L1 愿景 — 2026-04-30 10:30时间戳命名。用户在界面里可以随时重命名。四、文档溯源链 (Provenance)这是文档库区别于普通文件夹管理器的关键特性。L1 愿景 (uidaaa) ←── L1 愿景 (uidbbb) [两个并行的 L1 尝试] │ ├── L2 大纲 (uidccc, parent_uidaaa) ← 基于 aaa 生成 │ │ │ ├── L3 章纲 (uidddd, parent_uidccc) │ │ │ │ │ └── L4 正文 (uideee, parent_uidddd) │ │ │ └── L3 章纲 (uidfff, parent_uidccc) [同一个大纲两种章纲方案] │ └── L2 大纲 (uidggg, parent_uidaaa) [同一个愿景不同大纲方案]parent_uid记录的是生成此项时使用的是哪个文档作为输入。这个链路有两个作用追溯L4 正文有问题顺着链找到 L3 章纲是哪份再找到 L2 大纲是哪份找到决策节点回退选择L2 讨论完毕、L3 已经开始做了发现不如之前的方案可以沿着链回到 L2 的分叉点重新走实现方式每次生成 APIL2/L3/L4接受一个可选参数source_doc_uid: str指定以哪份文档为输入源。如果不传默认取该层最新的一份兼容当前的单文件覆盖行为。生成后新文档的parent_uid自动设为source_doc_uid。# L2 生成时 POST /api/projects/{id}/l2/stream?source_doc_uidaaa # 新文档 uidccc, parent_uidaaa五、与现有生成 API 的集成5.1 改造点当前 API 的存储模式l1/generate ──→ 覆盖 outputs/l1_vision.json l2/stream ──→ 完成后覆盖 outputs/l2_outline.json l3/generate ──→ 覆盖 outputs/l3_chapter_plan.json l4/stream ──→ 完成后覆盖 outputs/l4_text.json .txt改造后每个 API 在产出时调用library.add_document(entry, content)存入文档库。同时保留一份当前活动文档的指针兼容前端各处按固定路径读取的逻辑。活动文档指针outputs/current_l1.json,current_l2.json等内容为{uid: a1b2c3d4}指向当前选中的文档。前端页面默认加载当前活动文档。前端增加一个文档选择器dropdown 或从文档栏点击来切换当前活动文档。5.2 API 新增端点文档库管理CRUD GET /api/projects/{id}/library 列出文档树 GET /api/projects/{id}/library/{uid} 获取文档内容 POST /api/projects/{id}/library 新增文档导入/手动 PUT /api/projects/{id}/library/{uid} 更新文档元数据重命名/移动/标签 DELETE /api/projects/{id}/library/{uid} 删除文档 PUT /api/projects/{id}/library/{uid}/archive 归档/取消归档 活跃文档 GET /api/projects/{id}/library/active/{layer} 获取某层当前活跃文档 PUT /api/projects/{id}/library/active/{layer} 设置某层活跃文档 (body: {uid})六、前端 UI 设计6.1 文档栏布局参考 VS Code 的侧边栏设计┌──────────────────────────────────────────────────────────────┐ │ [] [] [] 页面内容区 │ │ ┌──────────┐ ┌──────────────────────────────────────────────┐ │ │ 文档库 │ │ │ │ │ │ │ │ │ │ / │ │ 当前页面主内容区域 │ │ │ L1 — │ │ │ │ │ L1草稿 │ │ (L1/L2/L3/L4/世界书/设置) │ │ │ L1 — │ │ │ │ │ L1 — │ │ │ │ │ L2方案│ │ │ │ │ 剧情流│ │ │ │ │ L2 —│ │ │ │ │ L2 —│ │ │ │ │ 人物流│ │ │ │ │ 备份 │ │ │ │ │ 导入 —│ │ │ │ │ │ │ │ │ │ [新建目录]│ │ │ │ │ [导入文件]│ │ │ │ └──────────┘ └──────────────────────────────────────────────┘ │ ▲ 可拖拽边缘调整宽度 △ 点击标签折叠/展开侧边栏 │ └──────────────────────────────────────────────────────────────┘6.2 侧边栏状态侧边栏有三种状态折叠状态只显示一个竖条图标类似 IDE 的 Activity Bar鼠标悬停或点击展开展开状态显示完整目录树宽度可拖拽调整默认 280px弹窗状态在小屏幕上以浮层形式出现默认状态折叠。用户需要时点击展开。6.3 目录树交互展开/折叠点击目录名展开或折叠子节点选中文档点击文档高亮右侧显示预览标题、元数据、前 500 字内容、溯源链右键菜单重命名、移动到目录、复制 UID、导出、归档、删除拖拽文档可拖拽到不同目录下双击文档如果是对应层的文档在当前页面加载该文档作为输入跳转到对应层的页面并将该文档设为活跃文档6.4 文档详情预览点击文档后在右侧区域展示┌─────────────────────────────────────────────┐ │ L2 大纲 — 拍卖会打脸 势力初探 │ │ │ │ 层级: L2 格式: JSON 字数: 3500 │ │ 创建: 2026-04-30 10:30 │ │ 标签: [末世] [打脸] [拍卖会] │ │ 源文档: ← L1 愿景 — 废土双界倒爷 (uidaaa) │ │ 衍生文档: → L3 章纲 — 第12章 (uidddd) │ │ → L3 章纲 — 第12章 备选 (uidfff) │ │ │ │ 内容预览: │ │ ┌─────────────────────────────────────────┐ │ │ │ { sequences: [{ name: 拍卖会进场, │ │ │ │ functions: [铺垫, 阻碍], ... │ │ │ └─────────────────────────────────────────┘ │ │ │ │ [在L2页面打开] [设为活跃] [导出] [归档] │ └─────────────────────────────────────────────┘6.5 文档图标不同类型文档用不同图标区分图标类型L1 愿景文档️L2 精修大纲L3 章纲细纲L4 正文文本用户导入文档目录七、外部文件导入7.1 导入场景用户有一份自己写的设定 .md想纳入文档库统一管理用户从别处拿了一份大纲草稿想导入后作为 L2 的参考或起点用户在别处写了片段想拖进来供 L4 参考7.2 导入方式拖拽导入将 .md/.json/.txt 文件拖入文档栏区域按钮导入点击文档栏底部的[ 导入文件]弹出文件选择对话框剪贴板导入粘贴文本内容输入文档名存入文档库7.3 导入后的处理自动识别格式.md/.json/.txtsource import,layer imported文件名为导入文件名自动提取 word_count自动放在当前浏览的目录下默认根目录八、归档机制文档越积越多后会混乱。提供归档功能归档 文档status改为archived不出现在目录树的默认视图中归档的文档不删除可随时恢复目录树下增加一个 已归档节点点击可展开查看已归档文档九、实现路径9.1 后端backend/services/library_manager.py一个LibraryManager类封装 manifest 的读写和文件操作class LibraryManager: def __init__(self, project_path: Path): self.library_path project_path / library self.manifest_path self.library_path / manifest.json self.files_path self.library_path / files self.manifest: LibraryManifest def add_document(self, entry: DocEntry, content: str | dict) - str: 添加文档返回 uid def get_document(self, uid: str) - tuple[DocEntry, dict]: 获取文档元数据和内容 def update_entry(self, uid: str, **kwargs) - None: 更新元数据重命名、移动、标签等 def delete_document(self, uid: str) - None: 删除文档及其文件 def get_tree(self, include_archivedFalse) - dict: 返回文档树结构供前端渲染目录树 def set_active(self, layer: str, uid: str) - None: 设置某层的活跃文档 def get_active(self, layer: str) - str | None: 获取某层的活跃文档 uid def list_by_layer(self, layer: str) - list[DocEntry]: 按层级列出文档9.2 改造现有 APIL1~L4 的 generate 方法在产出时改为调用library.add_document()# l1.py 改造后 vision generator.generate(input_data) summary generator.summarize(vision) # 调用 LLM 生成 10-15 字摘要 entry DocEntry( uidgenerate_uid(), namefL1 愿景 — {summary}, layerl1, sourcegenerate, ... ) library LibraryManager(project.project_path) uid library.add_document(entry, vision.model_dump()) library.set_active(l1, uid)9.3 前端改动新增DocumentSidebar.vue组件目录树渲染、展开/折叠、右键菜单、拖拽App.vue增加侧边栏插槽左侧增加可折叠面板各页面增加当前文档指示器显示当前活跃文档名点击可打开文档选择下拉菜单或跳转文档库Dashboard 增加文档库入口项目卡片增加文档链接9.4 迁移策略旧数据outputs/l1_vision.json等在第一次加载文档库时自动导入如果library/目录不存在且outputs/下有文件自动迁移为每个旧文件生成 DocEntry 并复制到library/files/下迁移完成后在原outputs/文件旁写一个.migrated标记文件十、双轨存储章节管理器与文档库的分工10.1 理论基础工业流水线中的两类数据回顾笔记5中提出的数据海概念——原始小说库作为输入经过三道过滤最终进入向量数据库。这是一个从数据到知识的萃取流程。文档库与章节管理器的分工本质上也是同一个逻辑在系统内部的复现外部数据海 (笔记5) 400G 网文 txt → 三道过滤 → 向量数据库 ↓ 供 Agent 检索 系统内部数据流 (本章) Agent 产出的正文 │ ├──→ 章节管理器结构化、可查询、Agent 所见 │ ↓ │ 供 RAG-历史回顾检索 │ 供世界书管理员提取状态变化 │ └──→ 文档库自由组织、用户所见 ↓ 用户浏览、对比、导出的工作空间两条线在结构化程度和使用者面向上互补不存在谁取代谁的问题。10.2 章节管理器为 Agent 设计章节管理器关心的问题是第 12 章写到哪了下章开头需要衔接什么主角在 12-45 章之间的修为变化轨迹是什么第 45 章埋的伏笔在第 78 章回收了吗这些都是结构化查询。章节管理器必须维护章节编号的严格顺序每章的状态标记草稿/定稿/需修改与 RAG 向量索引的同步每完成一章即增量索引与世界书的联动章节完成后世界书管理员自动提取状态变化数据格式天然是结构化的chapters/ ├── manifest.json ← 章节索引编号、标题、状态、字数、关联人物 ├── ch001.json ← 正文 元数据视角、节奏标注、关联伏笔 ├── ch002.json └── ...10.3 文档库为用户设计文档库关心的问题是这三个版本的 L2 大纲哪个最好放一起对比看看。上面写废了四个版本我把它们归档到废稿文件夹。朋友发了我一份他写的人设我拖进来参考。这些都是自由浏览型操作。文档库不关心顺序、不关心章节间的因果链——它就是一个文件管理器只是加了溯源链和自动入库的便利。10.4 两者如何交互两者不是嵌套关系而是平行关系有点对点传递章节管理器 ──(用户触发导出到文档库)──→ 文档库 ↑ 用户手动导入 ←──用户在章节管理器中看到 L4 生成的正文觉得这一章写得好点一下导出到文档库这章的副本就出现在文档库里。文档库里的这份副本从此和章节管理器断开联系——它是一个不可变的快照除非用户手动编辑。反过来用户也可以从文档库把一份导入的大纲设为 L2 活跃文档流水线会用这份大纲来生成——这时候文档库的角色是输入端的选择器。十一、已决问题11.1 AI 摘要命名可选轻量 LLM10.2 AI 摘要命名可选轻量 LLM决策不强制要求 LLM。提供三种命名方式用户可选择。方式效果成本适用场景时间戳L1 愿景 — 20260430_1030零默认不需要 LLM轻量 LLML1 愿景 — 废土双界倒爷一次小模型调用用户配置了 LLM 且开启手动命名用户输入任意名称零人力用户双击即改或生成时弹输入框轻量 LLM 策略使用一个极短 prompt~50 token调 LLM只做摘要不生成其他内容如果用户配置了 embedding 模型也可考虑用向量聚类关键词不调 LLM前端提供一个开关自动命名 (需 LLM)11.2 草稿机制决策支持存草稿。未完成的产出也入库。DocEntry 增加两个字段{ status: draft, // draft | completed checkpoint: { // 断点续传信息 layer: l2, current_round: 2, last_expert: editor, meeting_history: [...] } }草稿的生命周期用户启动 L2 会议 │ ├── 第一轮发言完成 → 自动存草稿 ├── 用户关闭页面 → 草稿保留 ├── 下次打开 → 检测到有草稿提示用户 │ 检测到未完成的 L2 会议进度第2轮/3轮最后发言网络编辑。 │ [继续上次] [重新开始] [查看草稿] │ └── 会议完成 → status 变为 completed, checkpoint 清空各层存草稿的时机层何时存草稿断点信息L1每个聊天气泡发送后已有的 auto-save消息历史L2每轮专家发言完成后当前轮次、最后发言人、会议历史L3用户每次修改场景标签后已选择的标签组合、已填写的字段L4每生成一个场景后SSE 流已产出部分场景已生成的场景索引、已生成文本草稿与已完成文档的区分草稿在目录树中显示为灰色/虚线图标 草稿不参与活跃文档指针只有completed的文档才能设为活跃用户可以手动将草稿标记为完成十二、尚待讨论的问题文档数量上限不设硬限制依赖归档功能保持整洁。全文搜索文档数量增长后通过关键词搜索文档内容。可考虑在 RAG 系统建立时顺带索引文档库内容统一检索入口。多项目间的文档共享暂不做每个项目独立。后续若需要可在文档库 API 加一个POST /library/copy跨项目复制。版本历史文档库本身不内置版本管理。如果用户的某份文档被反复修改需要版本追溯可依赖章节管理器侧保留的中间版本用户自己手动复制一份再修改文档库的目录结构天然支持后期可考虑接入世界书的 commit/revert 机制文档库数据量上限如果用户疯狂导入几百 MB 的文件怎么办建议在导入时检查文件大小单文件上限 10MB并在 manifest 中记录总大小前端显示用量。创建时间2026-04-30 状态十(双轨存储)、十一(已决)已讨论十二节继续讨论
返回列表