如果这样,那章节越多,后续要传递给api的参数就越多? 是的,**如果你每次都把前面所有章节正文传给 API,章节越多,参数一定越来越大,成本会爆,速度也会慢。** 但真正的长篇小说系统**不能这么做**。 正确做法是: > **不是把全部正文传给模型, > 而是把“压缩后的关键记忆 + 当前章节相关内容”传给模型。** 也就是说,后面写第 100 章,不需要把前 99 章全文都传进去,只需要传: ```text 小说圣经摘要 当前卷纲 最近 3-5 章摘要 本章相关人物状态 本章相关伏笔 本章章节卡 禁止改动规则 文风规则 ``` 这样 API 输入会长期保持稳定,不会随着章节无限增长。 --- # 一、错误做法:全文堆上下文 比如写第 80 章时,你把第 1–79 章全部塞进去: ```text 第1章全文 第2章全文 第3章全文 ... 第79章全文 请写第80章 ``` 这个做法有几个问题: 1. token 成本越来越高; 2. 请求越来越慢; 3. 模型容易被大量旧内容干扰; 4. 真正重要的信息反而被淹没; 5. 超过上下文长度后直接无法调用; 6. 多模型协作时更难稳定。 所以长篇流水线绝对不能靠“全文传递”。 --- # 二、正确做法:三层记忆压缩 你要做的是**分层记忆**。 ## 第一层:永久核心记忆 每次都传,但内容要很短。 包括: ```text 小说一句话核心 世界观规则 主角核心人设 主要角色不可改动项 文风规则 禁用桥段 短剧改编规则 ``` 控制在 **1000–2000 字**。 这部分相当于小说宪法。 --- ## 第二层:近期记忆 每次只传最近 3–5 章摘要。 比如写第 80 章,只传: ```text 第75章摘要 第76章摘要 第77章摘要 第78章摘要 第79章摘要 ``` 不传全文。 每章摘要控制在 150–300 字。 总共大概 **1000–1500 字**。 --- ## 第三层:检索记忆 这部分不是每次都传全部,而是按本章需要查。 比如第 80 章出场人物是: ```text 岑青 陈淑蘅 姚知知 ``` 那就只查这几个人的状态: ```text 岑青当前知道了什么 陈淑蘅隐瞒了什么 姚知知上次出现在哪里 她们之间的关系变化 ``` 如果本章涉及某个伏笔,就只查相关伏笔。 比如: ```text F012:被撕掉的签到簿缺页 F018:姚知知画本里的第五只手 ``` 不相关的伏笔不传。 --- # 三、写第 100 章时,真正传给 API 的应该是这样 不是: ```text 前99章全文 + 请写第100章 ``` 而是: ```json { "bible_summary": "小说核心设定摘要,约1500字", "style_rules": [ "克制", "电影感", "不狗血", "不打脸复仇", "对白短而有张力" ], "current_volume_outline": "当前第3卷卷纲摘要,约800字", "recent_chapter_summaries": [ "第95章摘要", "第96章摘要", "第97章摘要", "第98章摘要", "第99章摘要" ], "active_character_states": [ { "name": "岑青", "current_state": "已经确认林照不是一个人,但还缺最后证据" }, { "name": "陈淑蘅", "current_state": "知道周榕真名,但仍不愿公开其他女工身份" } ], "active_foreshadows": [ { "code": "F012", "title": "签到簿缺页", "status": "developing", "expected_reveal": "第102章" } ], "chapter_card": { "chapter_no": 100, "title": "缺页", "goal": "岑青找到签到簿缺失页的线索", "must_happen": [ "姚知知交出画本", "岑青发现画本夹层里有一页旧纸", "陈淑蘅第一次失控" ], "ending_hook": "纸页上不是一个名字,而是五个名字" } } ``` 这个上下文即使写到第 500 章,也可以控制在 **4000–8000 字**以内。 --- # 四、上下文不是越多越好,而是越准越好 很多人误以为: > 传越多,AI 越不会乱。 其实不一定。 真正有效的是: ```text 重要信息完整 无关信息少 当前任务明确 禁止事项清楚 ``` 你给模型塞 30 万字前文,它不一定抓得住重点。 但你给它一份高质量上下文: ```text 当前主线 当前人物状态 当前伏笔 上一章结尾 本章目标 不能写什么 ``` 它反而更稳。 --- # 五、你系统里要做“记忆压缩器” 每写完一章,就让 AI 或程序生成一份压缩记忆。 比如第 20 章正文有 3000 字,压缩成: ```json { "chapter_no": 20, "summary": "岑青在旧仓库找到签到簿,发现林照名下有五种笔迹。", "character_updates": [ { "name": "岑青", "update": "开始怀疑林照不是单一人物" }, { "name": "陈淑蘅", "update": "看到签到簿后明显紧张,但拒绝解释" } ], "new_foreshadows": [ { "code": "F020", "title": "被撕掉的一页", "surface": "签到簿中间缺了一页", "hidden_truth": "缺页记录了火灾当晚真实值班名单" } ], "next_chapter_must_continue": [ "岑青需要追查缺页", "陈淑蘅不能立刻说出全部真相" ] } ``` 以后第 50 章、第 100 章需要这个信息时,系统从数据库查这条摘要,不用查完整正文。 --- # 六、上下文传递应该有 4 个等级 ## L1:每次必传 ```text 小说圣经摘要 文风规则 禁用规则 本章章节卡 ``` --- ## L2:经常传 ```text 最近 3-5 章摘要 当前卷纲 当前主线进度 ``` --- ## L3:按需传 ```text 本章出场人物状态 本章相关伏笔 本章相关场景 本章相关道具 ``` --- ## L4:特殊情况才传 ```text 某一章原文片段 某个角色上次出场完整段落 某个伏笔首次出现原文 某段重要对白 ``` 只有当模型需要复刻细节时,才传原文片段。 比如本章要回收第 12 章的一句台词,那就检索第 12 章相关原文片段传进去。 --- # 七、成本大概怎么控制? 假设一章 3000 字。 错误做法: ```text 写第100章时传前99章全文 ≈ 30万字上下文 ``` 这非常贵,也不稳定。 正确做法: ```text 固定核心上下文:1500字 最近5章摘要:1500字 人物状态:800字 伏笔:800字 章节卡:800字 风格规则:500字 ``` 总共大概: ```text 5900字上下文 ``` 后续写到第 300 章,也还是差不多 5000–8000 字上下文。 成本是可控的。 --- # 八、你要加一个 Context Budget 机制 系统里要给每次调用设置上下文预算。 比如: ```json { "max_context_tokens": 12000, "budget": { "bible_summary": 2000, "recent_summaries": 2000, "character_states": 2000, "foreshadows": 1500, "chapter_card": 1500, "style_rules": 1000, "retrieved_original_snippets": 2000 } } ``` 如果超过预算,系统自动压缩。 优先级: ```text 本章章节卡 > 人物当前状态 > 最近章节摘要 > 相关伏笔 > 小说圣经摘要 > 原文片段 ``` 不是所有东西都平等。 --- # 九、你现有系统可以这样落地 你当前项目已经有 `MemoriesModule`,也有小说章节管理、故事圣经、角色、分集、脚本、分镜这些模块。文档里也提到后续需要把小说、故事圣经、角色抽取、分集、脚本、分镜等文本步骤统一成更严格的 schema、重试、验证和 Prompt 版本管理。 所以你现在应该补: ```text NovelContextBuilderService NovelMemoryCompressorService NovelRetrievalService NovelContextBudgetService ``` 职责如下: ```text NovelMemoryCompressorService: 每章写完后,把正文压缩成摘要、人物变化、伏笔变化。 NovelRetrievalService: 写新章前,从数据库检索相关人物、伏笔、场景、章节片段。 NovelContextBudgetService: 控制本次 API 输入不要超预算。 NovelContextBuilderService: 把所有信息拼成最终 Prompt。 ``` --- # 十、一个稳定的 Context Builder 流程 ```text 准备写第 N 章 ↓ 读取小说圣经摘要 ↓ 读取当前卷纲 ↓ 读取最近 5 章摘要 ↓ 读取章节卡 ↓ 根据章节卡识别出场人物 ↓ 读取这些人物当前状态 ↓ 根据章节卡识别相关伏笔 ↓ 读取这些伏笔状态 ↓ 如有需要,检索原文片段 ↓ 按 token 预算压缩 ↓ 拼成最终 API prompt ↓ 调用模型写作 ``` 这样章节再多,也不会爆。 --- # 十一、最重要的数据库设计 你至少需要这几个表: ```text NovelContextMemory NovelCharacterState NovelForeshadow NovelChapterSummary NovelAgentRunContext ``` 如果你不想多建表,也可以先把它们合并进一个 `NovelContextMemory`,用 `memory_type` 区分。 例如: ```text memory_type = bible_summary memory_type = chapter_summary memory_type = character_state memory_type = foreshadow memory_type = style_rule memory_type = timeline ``` 第一版这样就够。 --- # 十二、最终答案 你的担心是对的: > **如果每次都传全部章节,章节越多,API 参数一定越来越多。** 但专业系统不会这么做。 专业系统是: ```text 全文入库 摘要常用 相关内容检索 上下文预算控制 每章写完更新记忆 每次调用只传必要信息 ``` 一句话: > **小说全文存在数据库里,不存在 Prompt 里。 > Prompt 里只放当前模型完成任务必须知道的内容。** 这样写 30 章、300 章、1000 章,API 输入都可以保持稳定。