Co-authored-by: Cursor <cursoragent@cursor.com>
19 KiB
笔临 P4.1 自动写作 + 向导式写作设计规格
版本:1.0
日期:2026-07-09
范围:P4.1 — 实装 §6.5.2 自动写作 + §6.5.3 向导式写作(统一写作流引擎)
前置:P4 交互式写作已交付(v0.4.0,a8e0ba9)
参考:design/readme.md v1.1 §6.5.2–§6.5.3、design/ui_pc.html AI 面板模式 Tab
目标版本:v0.5.0
1. 背景与目标
1.1 阶段定位
v0.4.0 已交付交互式写作(§6.5.1);「自动写作」「向导」Tab 仍为 feature.comingSoon 占位。本阶段在同一 AI 会话体系下实装:
- 自动写作:用户设定章节目标与字数范围 → AI 规划场景顺序 → 连续流式生成 → 达标或手动停止 → 成章落盘
- 向导式写作:5 步引导收集参数 → AI 策略预览 → 自动生成 → handoff 至交互面板做场景微调
两模式共享 P4 的场景存储、命名暂停、流式推送与成章逻辑,并通过 handoff 与交互写作衔接。
1.2 已确认决策(Brainstorming 2026-07-09)
| 维度 | 决策 |
|---|---|
| 范围 | P4.1:§6.5.2 + §6.5.3 同时交付;§6.3 / §6.6 / §6.7 仍排除 |
| 架构 | 方案 1:统一写作流引擎,扩展 P4 表与 Service,不重写 |
| 向导第 4 步 | 选项 A:复用 ContextEditorModal 确认上下文(含大纲/设定中的伏笔线索),不引入知识库表 |
| 向导风格 | 节奏三选一(舒缓/紧张/混合)+ 可选自由文本 styleNote;不做文风滑杆 |
| 向导生成后 | 自动切入 InteractivePanel(toast「已进入交互微调」) |
| 自动暂停 | 可「继续自动」或「转入交互微调」(handoff,保留 scenes) |
| 成章落盘 | 活跃卷新建章节;origin=auto 或 origin=wizard;合并全部场景 HTML |
| AI 快照 | 成章时创建 type='ai' 快照(标签「自动写作成章」/「向导写作成章」;顺带补齐 P4 interactive 成章快照) |
| 状态持久化 | schema v5:interactive_flows 增 flow_mode / mode_config_json;interactive_scenes 不变 |
| 启动门槛 | 硬拦截:复用 P4 checkInteractiveGate 逻辑(无正文且无大纲/设定时 Tab 禁用) |
| 同会话 flow | 每 session_id 仅一个 status=in_progress flow;按 flow_mode 区分模式 |
| AI 后端 | LM Studio(延续 P3/P4),http://127.0.0.1:1234,gemma-4-e4b-it |
| 测试原则 | 禁止 Mock;集成 / E2E 打真实 LM Studio |
| 测试超时 | Vitest AI 用例 240s;Playwright 全局 180s;auto/wizard E2E 300s |
1.3 验收标准
用户能完成:
- 在有足够上下文的书籍中进入「自动写作」或「向导」Tab(门槛不满足时 Tab 禁用并 tooltip 提示)
- 自动写作:设定本章目标(大纲选取和/或手写)+ 目标字数范围 → AI 返回场景规划 → 连续流式生成场景(支持命名暂停)→ 字数达范围或点击「结束本章」→ 新建章节
origin=auto,编辑器自动打开 - 自动写作干预:生成中点击「暂停」→ flow 进入
paused;可「继续自动」或「转入交互微调」→ 交互面板可见已生成场景并可微调/续写 - 向导写作:依次完成 5 步(目标 → 节奏/风格 → 视角人物 → 上下文确认 → 策略预览)→ 确认后开始生成 → 生成完成后自动显示交互面板,可微调场景
- 向导成章后章节
origin=wizard;自动成章origin=auto - 关闭应用并重启后,未完成的 auto/wizard flow 恢复到上次步骤
- 切换回「对话」模式时同会话聊天历史仍可见;再次进入 auto/wizard/interactive 时 恢复已有 flow(不无条件 reset)
- 所有成章路径均创建
type='ai'快照
1.4 本规格不实现(明确排除)
| 项 | 归属 |
|---|---|
| §6.3 文风学习与风格滑杆 | P4.2+ |
| §6.6 大纲生成章节骨架 | P4.2+(可独立 spec) |
| §6.7 知识自动抽取与审核工作流 | P4.2+ |
| §6.4 Skill / MCP | P4+ |
| 知识库伏笔追踪 UI | P4.2+ / P5 |
| 导入导出、驾驶舱等 | P5+ |
| 命名结果自动写入设定库 | 本阶段仅写入正文 |
2. 架构
2.1 进程模型
┌──────────────────────────────────────────────────────────────────┐
│ 主进程 │
│ · schema v5:interactive_flows.flow_mode / mode_config_json │
│ · chapters.origin:manual | interactive | auto | wizard │
│ · SceneGenerationCore(从 P4 抽取:流式、命名暂停、HTML 规范化) │
│ · AutoWritingService(目标→规划→连续生成→暂停/成章/handoff) │
│ · WizardWritingService(5 步→策略预览→委托 Auto→handoff) │
│ · InteractiveWritingService(P4 不变;handoff 目标) │
│ · checkWritingGate(复用 interactive-gate 逻辑,三模式共用) │
│ · AiClientService / AiContextBuilder(复用) │
│ · IPC:auto:* / wizard:* + interactive:streamChunk(增 flowMode) │
└────────────────────────────┬─────────────────────────────────────┘
│ contextBridge
┌────────────────────────────▼─────────────────────────────────────┐
│ 渲染进程 │
│ · AiPanel:writingMode=auto|wizard 时挂载 AutoPanel/WizardPanel │
│ · handoff 后 writingMode 保持或切 interactive,显示 InteractivePanel│
│ · useAutoStore / useWizardStore + useInteractiveStore │
│ · ContextEditorModal(向导步骤 4 + 自动可选编辑上下文) │
└────────────────────────────────────────────────────────────────────┘
约束(延续 P0–P4):
- 渲染进程禁止直接
fetchAI API - 流式通过
webContents.send推送,不阻塞 IPC invoke - 写作 flow 绑定
ai_session_id;关键轮次可写入ai_messages作审计(可选,非阻塞)
2.2 Handoff 规则
从 auto 或 wizard 转入交互微调时:
interactive_scenes列表 不变flow_mode更新为'interactive'step设为:- 若
scene_draft_html非空 →'scene_review' - 否则若已有 scenes →
'plot_suggest'(进入下一场景循环) - 否则 →
'context_confirm'
- 若
mode_config_json保留(只读参考),不删除- 渲染进程
setWritingMode('interactive')+ toast
自动模式 暂停(非 handoff)时:step='paused',flow_mode 仍为 'auto'。
2.3 步骤机
2.3.1 interactive(P4 不变)
| Step | 名称 |
|---|---|
context_confirm |
上下文确认 |
plot_suggest |
剧情走向 |
plot_select |
用户选择 |
scene_generate |
场景生成 |
naming_pause |
命名暂停 |
scene_review |
场景确认/微调 |
completed |
成章完成 |
2.3.2 auto
| Step | 名称 | AI |
|---|---|---|
goal_setup |
目标/字数/大纲 | 无 |
scene_plan |
等待用户触发规划 | JSON 场景列表 |
auto_generate |
连续生成(含 naming_pause 子状态) | 流式 |
paused |
用户暂停 | 无 |
completed |
成章完成 | 无 |
生成循环:按 scenePlan 顺序逐场景生成;每场景完成后追加 interactive_scenes;累计字数(stripHtml 计)≥ wordMin 且 AI 判定目标达成或用户点击「结束本章」时停止。
2.3.3 wizard
| Step | 名称 | AI |
|---|---|---|
wizard_goal |
步骤 1:本章目标 | 无 |
wizard_rhythm |
步骤 2:节奏 + styleNote | 无 |
wizard_pov |
步骤 3:视角人物(设定 character) | 无 |
wizard_context |
步骤 4:ContextEditorModal | 无 |
wizard_preview |
步骤 5:策略预览 | 非流式摘要 |
wizard_generating |
委托 Auto 引擎生成 | 流式 |
| → handoff | 见 §2.2 | — |
3. Schema v5
3.1 DDL(每本书 .sqlite)
-- schema-v5.sql
ALTER TABLE interactive_flows ADD COLUMN flow_mode TEXT NOT NULL DEFAULT 'interactive';
ALTER TABLE interactive_flows ADD COLUMN mode_config_json TEXT NOT NULL DEFAULT '{}';
-- chapters.origin 在应用层扩展为 manual | interactive | auto | wizard
-- v4 已有 origin 列,v5 迁移不 ALTER(字符串枚举扩展)
migrate.ts:CURRENT_VERSION=5;v4→v5 应用上述 ALTER。
3.2 mode_config_json
export type WritingFlowMode = 'interactive' | 'auto' | 'wizard'
export type AutoRhythm = 'relaxed' | 'tense' | 'mixed'
export interface ScenePlanItem {
label: string
summary: string
}
export interface AutoWritingConfig {
chapterGoal: string
outlineItemIds?: string[]
wordMin: number // 默认 2000
wordMax: number // 默认 4000
scenePlan?: ScenePlanItem[]
currentPlanIndex?: number // auto_generate 进度
}
export interface WizardWritingConfig extends AutoWritingConfig {
rhythm: AutoRhythm
styleNote?: string
povSettingId?: string
strategyPreview?: string // HTML
contextBinding?: AiContextBinding // 步骤 4 确认结果
}
3.3 共享类型扩展
export type ChapterOrigin = 'manual' | 'interactive' | 'auto' | 'wizard'
export type AutoStep =
| 'goal_setup'
| 'scene_plan'
| 'auto_generate'
| 'paused'
| 'completed'
export type WizardStep =
| 'wizard_goal'
| 'wizard_rhythm'
| 'wizard_pov'
| 'wizard_context'
| 'wizard_preview'
| 'wizard_generating'
// InteractiveFlow 扩展:
// flowMode: WritingFlowMode
// modeConfig: AutoWritingConfig | WizardWritingConfig | Record<string, never>
// step: InteractiveStep | AutoStep | WizardStep
4. 服务层
4.1 SceneGenerationCore
从 InteractiveWritingService 抽取(或内部组合):
generateSceneStream(flowId, planItem, config, onChunk, signal)resolveNaming(flowId, chosenName, ...)normalizeSceneHtml(raw: string): string- 命名暂停检测:复用
tryParseNamingFromBuffer
4.2 AutoWritingService
| 方法 | 说明 |
|---|---|
start(sessionId) |
创建 flow_mode=auto, step=goal_setup |
getFlow(sessionId) |
按 session 查 in_progress |
setGoal(flowId, config: Partial<AutoWritingConfig>) |
写入 mode_config,step=scene_plan |
planScenes(flowId) |
AI JSON → scenePlan,step=auto_generate |
generateNext(flowId, onChunk, signal) |
生成当前 plan 项;处理 naming;追加 scene;更新 index |
pause(flowId) |
step=paused,abort 进行中的生成 |
resume(flowId) |
step=auto_generate,继续下一项 |
handoffToInteractive(flowId) |
§2.2 |
finishChapter(flowId, volumeId, title?) |
合并 scenes → 新建章 origin=auto + AI 快照 |
shouldStop(flowId) |
字数 ≥ wordMin 且(最后一项 plan 完成 或 AI 返回 stop 标记) |
4.3 WizardWritingService
| 方法 | 说明 |
|---|---|
start(sessionId) |
flow_mode=wizard, step=wizard_goal |
setGoal / setRhythm / setPov |
逐步写入 mode_config,推进 step |
confirmContext(flowId, binding) |
步骤 4;step=wizard_preview |
buildPreview(flowId) |
AI 生成 strategyPreview HTML |
startGenerate(flowId, onChunk, signal) |
step=wizard_generating;构建 AutoWritingConfig 并调用 AutoWritingService 全量生成 |
handoffToInteractive(flowId) |
生成完成后自动调用 §2.2 |
4.4 成章与快照(三模式统一)
finishChapter 路径均:
- 合并
interactive_scenes.content_html chapters.create(..., origin)snapshots.create(chapterId, merged, type='ai', label=...)flow.status=completed,step=completed
5. IPC
5.1 通道(ipc-channels.ts 追加)
// auto
AUTO_CHECK_GATE: 'auto:checkGate' // 实际复用 gate service
AUTO_GET_FLOW: 'auto:getFlow'
AUTO_START: 'auto:start'
AUTO_SET_GOAL: 'auto:setGoal'
AUTO_PLAN_SCENES: 'auto:planScenes'
AUTO_GENERATE: 'auto:generate' // 生成下一场景或批量至 pause/stop
AUTO_PAUSE: 'auto:pause'
AUTO_RESUME: 'auto:resume'
AUTO_HANDOFF_INTERACTIVE: 'auto:handoffInteractive'
AUTO_FINISH_CHAPTER: 'auto:finishChapter'
AUTO_GET_SCENE_DRAFT: 'auto:getSceneDraft'
AUTO_ABORT: 'auto:abort'
// wizard
WIZARD_GET_FLOW: 'wizard:getFlow'
WIZARD_START: 'wizard:start'
WIZARD_SET_GOAL: 'wizard:setGoal'
WIZARD_SET_RHYTHM: 'wizard:setRhythm'
WIZARD_SET_POV: 'wizard:setPov'
WIZARD_CONFIRM_CONTEXT: 'wizard:confirmContext'
WIZARD_BUILD_PREVIEW: 'wizard:buildPreview'
WIZARD_START_GENERATE: 'wizard:startGenerate'
WIZARD_HANDOFF_INTERACTIVE: 'wizard:handoffInteractive'
WIZARD_ABORT: 'wizard:abort'
流式事件 interactive:streamChunk payload 扩展:
{ flowId, flowMode: WritingFlowMode, phase: 'scene' | 'naming' | 'refine', delta: string, done: boolean }
5.2 Preload / electron-api.d.ts
暴露 window.electronAPI.auto.* 与 window.electronAPI.wizard.* 命名空间。
6. Prompt 设计
6.1 场景规划(auto planScenes)
输入:章节目标、大纲条目摘要、已有上下文摘要、wordMin/wordMax。
输出 JSON:
{
"scenes": [
{ "label": "场景1", "summary": "…≥80字…" },
{ "label": "场景2", "summary": "…" }
],
"estimatedWords": 3200
}
约束:3–6 个场景;总预估字数在 [wordMin, wordMax] 内。
6.2 自动场景生成
输入:当前 plan item、累计 scenes 摘要、AutoWritingConfig。
输出:HTML 段落(600–1500 字/场景);命名暂停格式同 P4。
6.3 向导策略预览(wizard buildPreview)
输入:WizardWritingConfig 全量 + AiContextBuilder 摘要。
输出 HTML 一段,模板语义:
我将以 [视角人物] 视角,用 [节奏] 节奏,写一段达成 [目标] 的剧情。风格说明:…。重点上下文:…。
7. 渲染进程 UI
7.1 AiPanel
- 移除
auto/wizard的comingSoon handleModeClick('auto'|'wizard'):checkGate → loadFlow → 无 flow 则 start(不无条件 reset 已有 flow)writingMode === 'auto'→<AutoPanel />writingMode === 'wizard'→<WizardPanel />;handoff 后writingMode='interactive'→<InteractivePanel />
7.2 AutoPanel
| data-testid | 元素 |
|---|---|
auto-panel |
根容器 |
auto-goal-input |
本章目标 |
auto-outline-picker |
大纲多选 |
auto-word-min / auto-word-max |
字数范围 |
auto-plan-scenes |
触发规划 |
auto-start-generate |
开始/继续生成 |
auto-scene-preview |
流式预览 |
auto-pause |
暂停 |
auto-handoff-interactive |
转入交互 |
auto-finish-chapter |
结束本章 |
步骤条:目标 → 规划 → 生成 → 完成
7.3 WizardPanel
| data-testid | 元素 |
|---|---|
wizard-panel |
根容器 |
wizard-step-indicator |
1–5 步指示 |
wizard-goal-input |
步骤 1 |
wizard-rhythm-* |
步骤 2 节奏选项 |
wizard-style-note |
步骤 2 风格说明 |
wizard-pov-select |
步骤 3 |
wizard-context-edit |
步骤 4 打开 ContextEditorModal |
wizard-preview |
步骤 5 策略摘要 |
wizard-start-generate |
开始生成 |
生成完成后隐藏 WizardPanel,显示 InteractivePanel(同 session)。
7.4 i18n 键(zh-CN / en)
auto.gateBlocked、auto.gateTooltip、auto.step.*、auto.pause、auto.resume、auto.handoffInteractive、auto.finishChapter、auto.chapterCreated
wizard.step.*、wizard.rhythm.*、wizard.previewTitle、wizard.startGenerate、wizard.handoffToast
及步骤条、placeholder、错误 toast 文案。
8. 错误处理
| 场景 | 行为 |
|---|---|
| planScenes JSON 解析失败 | 重试一次(追加「仅返回 JSON」);仍失败 → toast + 保持 scene_plan |
| 生成中用户 pause | AbortController abort;step=paused;已生成 scenes 保留 |
| 无活跃卷 finishChapter | IPC 错误码;toast「请先创建分卷」 |
| 离线 / 非 lmstudio 且无网络 | 同 P3/P4:disabled + offline banner |
| wizard 某步必填缺失 | 下一步按钮 disabled |
| handoff 时无 scenes 且无 draft | 仍 handoff 到 context_confirm,toast 提示可手动续写 |
9. 测试
9.1 单元 / 集成(Vitest,真实 LM Studio)
| ID | 场景 | 超时 |
|---|---|---|
| UT-MIG-05 | v4 DB 迁移到 v5,flow_mode 列存在 | — |
| IT-AUTO-01 | planScenes 返回 ≥2 个 scene | 240s |
| IT-AUTO-02 | generateNext 写入非空 scene | 240s |
| IT-AUTO-03 | pause 后 step=paused;resume 继续 | 240s |
| IT-AUTO-04 | handoff 后 flow_mode=interactive | — |
| IT-WIZ-01 | buildPreview 非空 HTML | 240s |
| IT-WIZ-02 | startGenerate 完成后 scenes.length ≥ 1 | 300s |
| IT-FIN-01 | auto finishChapter → origin=auto + ai 快照 | — |
| IT-FIN-02 | interactive finishChapter → ai 快照(P4 补齐) | — |
9.2 E2E(Playwright,300s)
| ID | 场景 |
|---|---|
| E2E-AUTO-01 | 自动:设目标 → 规划 → 生成 → 成章 → 编辑器非空 |
| E2E-AUTO-02 | 自动:暂停 → 转交互 → accept scene 可见 |
| E2E-WIZ-01 | 向导 5 步 → 生成 → InteractivePanel 可见 |
| E2E-AUTO-03 | 空书 auto tab disabled(门槛,无 AI) |
10. 文件清单(实现参考)
| 文件 | 职责 |
|---|---|
src/main/db/schema-v5.sql |
v5 DDL |
src/main/db/migrate.ts |
v4→v5 |
src/main/db/repositories/interactive.repo.ts |
flow_mode / mode_config CRUD |
src/main/services/scene-generation-core.service.ts |
共享生成逻辑 |
src/main/services/auto-writing.service.ts |
自动写作步骤机 |
src/main/services/wizard-writing.service.ts |
向导步骤机 |
src/main/services/auto-prompt-builder.service.ts |
plan / scene / preview prompt |
src/main/ipc/handlers/auto.handler.ts |
auto IPC |
src/main/ipc/handlers/wizard.handler.ts |
wizard IPC |
src/renderer/components/ai/AutoPanel.tsx |
自动 UI |
src/renderer/components/ai/WizardPanel.tsx |
向导 UI |
src/renderer/stores/useAutoStore.ts |
auto 状态 |
src/renderer/stores/useWizardStore.ts |
wizard 状态 |
tests/main/migrate-v5.test.ts |
迁移 |
tests/main/auto-*.test.ts |
集成 |
tests/main/wizard-*.test.ts |
集成 |
e2e/auto-writing.spec.ts |
E2E |
e2e/wizard-writing.spec.ts |
E2E |
11. Spec 自检
| 检查项 | 结果 |
|---|---|
| Placeholder 扫描 | 无 TBD/TODO;排除项已列 §1.4 |
| 内部一致性 | handoff / 步骤机 / IPC / UI testid 对齐 |
| 范围 | 单阶段可交付 v0.5.0;§6.7 已通过 ContextEditor 降级 |
| 歧义 | 成章 origin 三分;同 session 单 in_progress flow;恢复 flow 不 reset |
本规格为笔临 P4.1 子项目。知识抽取、大纲骨架等各自在后续 spec 中增量修订。