Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StoryRunner

生产级长篇小说生成引擎。基于强指令驱动 + 全并发生产架构,将 LLM 协作创作从"自由漫游"升级为"方法派剧场"。


核心设计思想

传统 AI 小说生成要么靠蛮力堆上下文,要么靠静态模板框死创作空间。StoryRunner 的答案是第三条路:

把 LLM 当演员,不当作者。

系统不要求模型"自由发挥",而是扮演一个严格的剧场:剧本分析师事先把每章的关键事件排列好(称为"节拍/Beat"),导演按节拍向演员下达明确指令("愤怒地质问她为何偷走羊皮纸"),演员只负责用符合人设的语气、台词和微表情完美演绎。结果是:逻辑不会跑偏,但风格和细节仍然涌现。

核心特性

  • L2 分析师会议室:各卷分析师通过 P2P 通讯协作规划章节衔接,用户可实时干预讨论。
  • 工业级 L5 管线:采用 Map-Reduce 架构,支持磁盘流式 I/O,在大模型长篇创作中实现“生肉日志”到“成品散文”的高效转换。

前端四步流程

┌─────────────────────────────────────────────────────────────────────┐
│  Step 1: Outline Architect                                          │
│  ┌─────────────────────┬───────────────────────────────────┐        │
│  │   Chat Panel        │   JSON Preview                    │        │
│  │   用户与 Architect  │   实时显示 currentDraftState      │        │
│  │   聊天确定大纲      │   (通过 update_outline 工具)      │        │
│  └─────────────────────┴───────────────────────────────────┘        │
│                         [Confirm Outline & Proceed]                 │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│  Step 2: Chapter Planning Room (AnalystRoom)                        │
│  ┌─────────────┬───────────────────────┬─────────────────────┐      │
│  │ Analysts    │ P2P Message Stream    │ Intervene           │      │
│  │ ● Vol_1 ✅  │ [Architect]→[Vol_1]   │ Targets: □□□       │      │
│  │ ○ Vol_2     │ [Vol_1]→[Vol_2]       │ Message: ___       │      │
│  │ ● Vol_3 ✅  │ [User]→[Vol_2,Vol_3]  │ [Send]             │      │
│  │             │                       │                     │      │
│  │ [Architect] │                       │ Submitted Plans:   │      │
│  │ (Supervisor)│                       │ Vol_1: 10 chapters │      │
│  └─────────────┴───────────────────────┴─────────────────────┘      │
│              [Start Planning]     [Proceed to Writing] (解锁后可用) │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│  Step 3: Parallel Generation Studio (Kanban)                        │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐                    │
│  │ Vol 1       │ │ Vol 2       │ │ Vol 3       │                    │
│  │ ─────────── │ │ ─────────── │ │ ─────────── │                    │
│  │ Ch 1 [Raw]✅│ │ Ch 1 [Raw]⏳│ │ Ch 1 [Raw]⏸️ │                    │
│  │ Ch 2 [Raw]⏳│ │             │ │             │                    │
│  └─────────────┘ └─────────────┘ └─────────────┘                    │
│  [Global Logs] [Actor Performances] -> [Output: Raw Transcripts]    │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│  Step 4: Industrial Rendering Pipeline (L5 Polisher)                │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │ [Map] Render Drafts (Parallel) | ch1_draft, ch2_draft...    │    │
│  ├─────────────────────────────────────────────────────────────┤    │
│  │ [Reduce] Stitch Volume (Rolling) | vol_1_full.md            │    │
│  ├─────────────────────────────────────────────────────────────┤    │
│  │ [Finalize] Global Stitching | story_final.md                │    │
│  └─────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────┘

架构总览

用户输入
   │
   ▼
┌─────────────────────────────────────────────┐
│  L1  Architect(大纲规划师)                │  单次,CRITIC 模型
│  输出:WorldSetting + StoryOutline          │
│  创建 Volume Analysts 并发送开场指令         │
└────────────────┬────────────────────────────┘
                 │ P2P 协作讨论
                 ▼
┌─────────────────────────────────────────────┐
│  L2  AnalystRoom(分析师会议室)            │  持久化对话,CRITIC 模型
│  Volume Analysts 通过 P2P 讨论卷间衔接      │
│  输出:VolumeChapterPlan(各卷章节规划)    │
└────────────────┬────────────────────────────┘
                 │ approve_all 后按卷并发 spawn
                 ▼
┌─────────────────────────────────────────────┐
│  L3  Director(导演)                       │  SCHEDULER 模型
│  根据章节规划生成 Beats,向 Actor 下达指令  │
│      │                                      │
│      ▼                                      │
│  L4  Actor × M(角色演员)                 │  ACTOR 模型,含重试校验
│  输出:dialogueAndAction + 状态更新         │
└────────────────┬────────────────────────────┘
                 │ 并发 Map → 串行 Reduce
                 ▼
┌─────────────────────────────────────────────┐
│  L5  MapReducePolisher(渲染管线)          │  ACTOR/CRITIC 模型
│  Map:极速并行,剧本转散文初稿 (_draft.md)  │
│  Reduce:滚动熔接,磁盘流式处理章节缝隙     │
│  Finalize:跨卷装帧,产出最终全本书籍       │
└─────────────────────────────────────────────┘

快速开始

环境要求

  • Node.js 18+
  • pnpm

安装

pnpm install

配置模型

在项目根目录创建 .env(或直接修改 src/utils/llm.ts):

# 调度层(导演决策,推荐快速模型)
SCHEDULER_API_KEY=your-key
SCHEDULER_BASE_URL=https://api.deepseek.com
SCHEDULER_MODEL=deepseek-chat

# 表演层(角色生成,推荐富有表现力的模型)
ACTOR_API_KEY=your-key
ACTOR_BASE_URL=https://api.deepseek.com
ACTOR_MODEL=deepseek-chat

# 规划层(架构/分析,推荐逻辑最强的模型)
CRITIC_API_KEY=your-key
CRITIC_BASE_URL=https://api.deepseek.com
CRITIC_MODEL=deepseek-chat

三个 tier 可以指向不同的 API 提供商和模型,以在成本和质量之间取得最优平衡。

启动 Web 服务器

pnpm start
# 服务运行在 http://localhost:3000

CLI 模式

# 列出指定故事的所有卷规划
pnpm tsx src/index.ts list <storyName>

# 为指定故事生成特定章节的生肉日志
pnpm tsx src/index.ts generate <storyName> <volId> <chapIndex>

五层工作流详解

L1 — Architect(大纲规划师)

src/core/macro/macro.ts · Architect

接收用户的模糊创作需求,产出两份结构化数据:

  • WorldSetting:物理规则、魔法体系、势力格局、地理环境
  • StoryOutline:卷数、各卷核心冲突、全角色档案(含身世和私有动机)

在 Step 2 中,Architect 还负责:

  • 创建所有 Volume Analysts
  • 发送开场指令指派任务
  • 监督分析师讨论并最终 approve_all

使用 CRITIC 模型(最强逻辑)执行,确保世界观自洽。

L2 — AnalystRoom(分析师会议室)

src/core/meso/analyst_room.ts · AnalystRoom

核心创新:各卷 Analyst 通过 P2P 通讯讨论卷间衔接,而非闭门造车。

工具 用途
create_analysts() Architect 创建所有 Volume Analysts
send_message(target, msg) P2P 点对点通讯
submit_chapter_plan(plan) Analyst 提交章节规划(含 Beat 级别数据)
inject_user_message() 用户在 Step 2 期间向分析师直接下达指令
approve_all() Architect 批准所有规划,解锁生成流程

Analyst 生命周期

  • 对话历史在整个规划阶段持久化(不销毁)
  • 提交后进入 finished 挂起态
  • 收到新消息自动 unfinish,重新处理

输出契约VolumeChapterPlan

interface VolumeChapterPlan {
  volumeId: number;
  volumeTitle: string;
  chapters: Array<{
    chapterIndex: number;
    title: string;
    summary: string;
    keyEvents: string[];
    transitionNote?: string;  // 与下一章衔接
  }>;
  transitionToNext?: {
    targetVolumeId: number;
    setupRequired: string;    // 卷尾铺垫
  };
}

L3 — Director(导演)

src/core/micro/micro.ts · MicroInference.executeChapter()

拿到 VolumeChapterPlan 后,解析其中的 ChapterPackage(含 Beats 和记忆快照),驱动章节演进:

  1. 根据章节规划生成 3–6 个有序节拍
  2. 识别当前 Beat 涉及的角色
  3. 组装导演指令文本(包含 Beat 内容 + 角色当前叙事状态)
  4. 向 Actor 发出强指令,等待表演结果
  5. 更新叙事状态快照,推进到下一 Beat

L4 — Actor(角色演员)

src/core/micro/micro.ts · MicroInference.executeActorBeat()

每次被唤醒时通过 AgentFactory.spawn() 动态创建,注入严格的四模块 System Prompt

[人物设定和身世]     ← 决定腔调与道德底线
[渐进式记忆总结]     ← 决定当前情绪与反应
[写作规范]           ← 决定文笔风格
[当前叙事状态]       ← 描述性快照,替代数值血量

Actor 没有改变大剧情走向的权力,但拥有台词权、表情权、细节描写权。其表演结果被实时记录到 Raw Transcript (生肉日志) 中。

输出格式固定为:

{
  "dialogueAndAction": "完整台词与动作叙述",
  "narrativeStateUpdate": {
    "newPosture": "执行后的位置/姿态",
    "statusChange": "身体/情绪状态变化"
  }
}

指令跟随校验:系统提取 Beat 描述中的关键词,验证 Actor 输出是否确实执行了导演指令。若不符,自动附加高权重警告后重试(最多 2 次);重试仍失败则使用降级输出。

L5 — MapReducePolisher(渲染管线)

src/core/render/polisher.ts · MapReducePolisher

这是 StoryRunner V2 的“工业化”核心,负责将生硬的角色表演日志转化为优美的小说正文。

阶段 A:Map — 并发初稿生成

  • 操作:每章独立调用 ACTOR 模型进行渲染。
  • 职责:去除剧本标签(如 **角色名**:),将括号内的动作描述与台词融合为自然散文,补充感官细节描写。
  • 输出:每章对应的 _draft.md(初稿)。

阶段 B:Reduce — 滚动累积拼接(Rolling Stitch)

  • 操作:串行滑动窗口处理。每次读取第 N 章末尾和第 N+1 章开头(约 200–500 字)。
  • 职责:调用 CRITIC/ACTOR 模型生成“熔接过渡段(Joint)”,消除场景跳跃感和逻辑断层。
  • 技术细节:采用磁盘流式 I/O,通过 truncateappend 动态改写文件,彻底杜绝超长篇(百万字级)内存溢出风险。
  • 输出:卷级全本 vol_X_full.md

阶段 C:Finalize — 全书装帧

  • 操作:跨卷层面的最终熔接。
  • 职责:处理卷与卷之间的大尺度时间/空间跳越,确保全书语调统一。
  • 输出:最终定稿 story_full.md

基础设施

AgentFactory(Agent 工厂)

src/engine/factory/agent_factory.ts

所有 Agent 遵循严格的 按需 Spawn → 注入纯净上下文 → 执行单一任务 → 销毁 生命周期,根除记忆污染和注意力衰减:

const actor = AgentFactory.spawn({
  role: 'Actor',
  modelTier: 'ACTOR',
  characterName: '亚瑟',
  personaAndBackground: '落魄的流亡骑士,极度珍视荣誉...',
  memorySync: '【卷一】...【上一章】莉莉亚偷走羊皮纸,你重伤逃脱...',
  writingGuidelines: '多写心理活动,禁用现代词汇',
  narrativeState: '左臂刀伤渗血,右手握铁剑,情绪处于暴怒边缘'
});

const result = await actor.act(directorInstruction);
actor.destroy(); // 用完即弃

例外:L2 AnalystRoom 中的 Volume Analysts 在规划阶段保持持久化对话历史。

MessageBus(消息总线)

src/engine/bus/message_bus.ts

基于 Node.js EventEmitter 的 Pub/Sub 系统,支持:

  • Topic 订阅:旁听某章节频道内的所有消息(Eavesdropping)
  • 定向投递:发送给指定的 Agent ID
  • 广播:向频道内所有 Agent 广播
  • Topic 清理:章节结束时一键销毁所有相关监听

FACTTRACK(事实追踪)

src/engine/memory/factory.ts

双轨记忆系统:

  • 短时记忆:最近 5 个场景/章节摘要,维持叙事语境
  • 硬性状态<主体, 动作, 客体, 有效期> 四元组,支持三种有效期:always / chapter_count: N / until_arc_end

章节推进时自动清理过期事实,并同步更新角色状态对象,防止长篇叙事中的逻辑不一致。

StateStore(存储管理器)

src/utils/storage.ts

V2 引入了目录式持久化架构,所有数据按项目隔离,支持断点续传:

storage/[项目名]/
├── outline.json          # L1 大纲 + 角色 + 世界规则
├── plans/
│   ├── vol_1.json        # L2 分析师产出的卷规划 (含 ChapterPackage)
│   └── vol_2.json
└── chapters/
    ├── vol_1_chap_1_raw.txt      # L3/L4 原始剧场日志
    ├── vol_1_chap_1_draft.md    # L5 Map 产出的初稿
    ├── vol_1_full.md            # L5 Reduce 缝合后的卷全本
    └── story_full.md            # L5 Finalize 全书最终稿

模型分层

Tier 默认模型 使用场景
CRITIC deepseek-chat 大纲规划、章节分析、AnalystRoom、事实提取、接缝修复
ACTOR deepseek-chat 角色表演、场景润色
SCHEDULER deepseek-chat 导演决策、章节编排

三个 Tier 可以独立配置不同的 API Key、Base URL 和模型名,自由组合如 Claude(表演)+ DeepSeek-R1(规划)+ Gemini Flash(调度)。


Web API

服务运行在 http://localhost:3000,前端静态文件来自 /public/

Step 1 端点

方法 路径 说明
POST /api/story/chat-draft 用户与 Architect 聊天,修改大纲
GET /api/story/draft-state 获取当前大纲 JSON

Step 2 端点(AnalystRoom)

方法 路径 说明
POST /api/story/start-planning 启动 AnalystRoom,创建 Volume Analysts
GET /api/story/analyst-room-status 获取分析师状态和消息历史
POST /api/story/inject 用户注入消息到 P2P 总线

Step 3 端点(生产生肉)

方法 路径 说明
POST /api/story/confirm 确认计划,初始化 StoryState 并创建目录
POST /api/story/generate-chapter 生成指定章节的 Raw Transcript(可附 godInstruction
POST /api/story/stop 立即中止当前章节生成

Step 4 端点(工业渲染)

方法 路径 说明
POST /api/story/render-chapter-draft [Map] 将生肉剧格转化为散文初稿
POST /api/story/stitch-volume [Reduce] 滚动缝合全卷章节,产出 vol_full.md
POST /api/story/stitch-story [Finalize] 跨卷装帧,产出 story_full.md

通用端点

方法 路径 说明
GET /api/story/stream SSE 实时事件流
GET /api/story/state 获取当前完整故事状态

上帝模式(God Mode)

/api/story/generate-chapter 请求中附加 godInstruction 字段,可在当前章节级别强制覆盖叙事流向:

{
  "godInstruction": "这一章必须让主角与反派达成临时同盟"
}

SSE 事件类型

Step 2 事件(AnalystRoom)

事件类型 触发时机
P2P_MESSAGE P2P 消息(sender → receiver)
ANALYST_CREATED 分析师被创建
ANALYST_FINISHED 分析师提交规划
ANALYST_UNFINISHED 分析师被解挂(收到新消息)
ALL_ANALYSTS_FINISHED 所有分析师完成
ARCHITECT_APPROVED 架构师批准所有规划

Step 3 事件(生成阶段)

事件类型 触发时机
SCENE_START 场景开始
ACTOR_ACTION 角色完成表演
BEAT_COMPLETE 单个 Beat 执行完毕
INSTRUCTION_MISMATCH 角色抗命,触发重试
GENERATION_ABORTED 用户中止生成

Step 4 事件(渲染阶段)

事件类型 触发时机
DRAFT_START 开始生成单章初稿
DRAFT_COMPLETE 单章初稿生成完成
STITCH_PROGRESS 卷内滚动缝合进度更新
VOLUME_STITCH_COMPLETE 全卷缝合完成
STITCH_STORY_PROGRESS 全书缝合进度更新
STITCH_STORY_COMPLETE 全书装帧完成

目录结构

src/
├── core/
│   ├── macro/macro.ts          # L1 Architect
│   ├── meso/
│   │   └── analyst_room.ts     # L2 AnalystRoom(P2P 协作规划)
│   ├── micro/micro.ts          # L3 Director + L4 Actor + 指令校验
│   └── render/
│       └── polisher.ts         # L5 Map-Reduce-Finalize 渲染管线
├── engine/
│   ├── bus/message_bus.ts      # Pub/Sub 消息总线
│   ├── factory/agent_factory.ts # Agent 工厂(四模块 Prompt 组装)
│   ├── feedback/feedback_loop.ts# 向上反馈循环
│   ├── memory/factory.ts       # FACTTRACK 双轨记忆
│   ├── tools/outline_tools.ts  # 大纲修改工具定义
│   └── prompting/prompt_engine.ts # 提示词组装引擎
├── types/index.ts              # 全局类型定义
├── utils/
│   ├── llm.ts                  # LLM 调用层(三 Tier + 重试 + 工具调用)
│   ├── logger.ts               # NarrativeLogger(SSE 事件总线)
│   └── storage.ts              # StateStore(目录式持久化)
├── server.ts                   # Express Web 服务器
└── index.ts                    # CLI 入口

许可

MIT

About

一个大模型驱动的长篇小说生成架构

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages