写小说最容易卡住的地方,不在文笔,也不在没有灵感。很多人一开始就忽略了一个更基础的问题:故事没有建立成一套可维护、可回溯、可批量推进的创作流程。大纲写在手机备忘录,人物设定散落在聊天记录里,世界观改了三版却没有保留历史,等到第三天想续写时,连主角的年龄都不确定。这种状态下,卡住是必然的。
这次我们从工程的角度重新拆一次“卡文”。先讲清卡文为什么会发生,再给出一套可以直接落地的本地写作工作流:用 Markdown 管理大纲和人物卡,用目录隔离草稿与修订,用本地模型提供可控的 AI 场景草稿,并把批量生成和接口调用串起来。读完你可以照着搭一套,不依赖在线工具,也不用担心把未公开稿件传给第三方平台。
1. 卡文不是文笔问题,是创作链路缺少可维护性
大多数作者把“卡文”归结为状态问题:今天没灵感、情绪不好、写出来的东西自己不满意。但从技术博客的角度看,这更像是一个系统设计问题。你让一个没有索引、没有版本控制、没有模块边界的系统持续输出内容,它当然会频繁崩溃。
写小说时,最常见的卡文场景是“信息不在它应该在的位置”:
- 主角的年龄在第一章出现,但三十章后突然记混了。
- 世界观规则在三稿里改了方向,但前两稿的内容没有归档,导致新老设定互相污染。
- 章节标题写好了,但这一章到底要达成什么目标,没有一句话能说清。
- 人物行动的理由散落在角色小传里,真正写作时根本来不及翻。
这些问题的共同点是什么?它们都是“可维护性”问题,不是“灵感”问题。任何一套稍微复杂的系统,如果入口散乱、数据源不统一、输出没有验证标准,都会越跑越慢。小说本质上是一个超大规模的长期内容系统,只是大多数人没有把它当成一个系统来维护。
一旦把卡文看成系统故障,解决策略就清晰了:先建目录,再建模板,再把“写正文”这个动作拆成“定位场景、填充目标、生成草稿、统一修订”四个阶段。你不会再在凌晨三点对着空白文档痛苦,而是会打开场景卡,检查这一场的目标、冲突和结果,然后针对缺失项去处理。
2. 写小说最容易忽略的技术点:故事工程化
“故事工程化”听起来很反直觉,但它和软件工程里的模块化思想高度一致。你不需要把小说写成代码,但你可以把一整本书拆成可以独立验证的单元,每个单元都有明确的输入、处理和输出。
对应到小说创作中,最小的可执行单元不是“句号后面的句子”,而是“场景”。一个场景应该具备三个要素:
- 目标:角色在这一场里想要什么。
- 冲突:谁在阻碍他,阻力是什么。
- 结果:目标达成或失败,并引向下一场。
很多人开写第一章时,脑子里只有情绪,没有这些。结果就是写到一半,控制不住角色行为,为了金句硬凹转折,最后整个章节偏离主线。卡住的那一刻,其实已经不是写作能力不够,而是结构输入缺失。
“一开始就忽略”的真正含义就在这里:你跳过了故事骨架的设计阶段,直接进入文字装修阶段。地基不牢,后面任何一层都会卡。
为了避免这个坑,我推荐的落地方案是:在动笔写任何正文前,先把全书拆成场景卡。一张场景卡只做一件事:说明这一场的目标、冲突、结果以及时间线位置。写作时,你的工作不是凭空创造内容,而是把一张结构完整的场景卡扩写成符合语感的段落。
3. 写作工作流核心能力速览
这里把整套方案的核心能力整理成一张表,方便判断它适不适合你。
| 能力项 | 说明 |
|---|---|
| 故事结构管理 | 用 Markdown 大纲将全书拆分到场景级别,支持多版本归档 |
| 素材唯一来源 | 人物卡、世界观卡、时间线统一存放在固定目录,避免信息散落 |
| 草稿批量生成 | 通过本地模型 API 批量生成场景草稿,适合思路卡住时的破冰输出 |
| 数据归属 | 所有内容和调用记录保存在本地,未定稿内容不上传第三方平台 |
| 环境要求 | 支持 CPU 推理,有 GPU 可加速;具体显存占用需要按所选模型实测 |
| 启动方式 | 本地服务用命令行启动,编辑器或脚本通过 HTTP 接口调用 |
| 批量任务 | 支持按场景清单批量生成,失败可重试,输出按目录归档 |
| 适合场景 | 长篇小说、连载更新、剧本大纲、设定集整理、AI 辅助写作验证 |
这套工作流的重点不是“让 AI 替你写小说”,而是把创作过程变成一条可回滚、可观测、可控的本地流水线。你依然拥有最终决策权,但不再依赖状态和灵感去启动。
4. 本地写作工作区准备
先准备一个规范的目录结构。这一步不依赖任何软件,但能解决大部分“文件找不到”导致的卡文。
mkdir -p novel/{00_idea,01_outline,02_world,03_characters,04_drafts,05_revision,06_archive}如果你使用的是 Windows PowerShell,花括号展开不一定生效,可以逐行创建:
mkdir novel mkdir novel\00_idea mkdir novel\01_outline mkdir novel\02_world mkdir novel\03_characters mkdir novel\04_drafts mkdir novel\05_revision mkdir novel\06_archive目录说明:
| 目录 | 用途 |
|---|---|
| 00_idea | 存放所有灵感和碎片想法,不要求格式 |
| 01_outline | 存放全书大纲、分卷大纲、场景卡 |
| 02_world | 世界观设定,包括地理、规则、阵营 |
| 03_characters | 人物卡,包括外貌、目标、性格弧光 |
| 04_drafts | 正在推进的正文草稿,按章节编号存储 |
| 05_revision | 精修后的稳定版本,与草稿隔离 |
| 06_archive | 已废弃或替换掉的旧设定,只存档不删除 |
这个结构在后续接入 AI 生成时非常有用。脚本只需要指定输入文件路径和输出目录,就能批量处理,而不必担心把草稿和修订版混在一起。
5. 用 Markdown 搭建小说工作台
纯文本格式最大的好处是可检索、可版本管理、可脚本处理。Markdown 尤其适合写作工作流,因为它不需要复杂编辑器,任何电脑上都能读,而且和 Git 配合良好。
5.1 全书大纲模板
在01_outline/plot_outline.md中建立全书骨架:
# 全书主线 一句话梗概:一个被误解的见习医师,必须在七天之内证明自己不是叛徒。 ## 第一幕:危机降临 ### 场景 1:主角被诬陷 - 目标:让主角认清自己的处境 - 冲突:所有证据都指向他 - 结果:他被迫离开医馆,踏上逃亡之路 ### 场景 2:意外同伴 - 目标:找到一个能帮助主角的人 - 冲突:对方只愿意交易,不愿意信任 - 结果:主角用自己的医术换取了暂时庇护写正文的时候,你不再需要思考“这一章写什么”,只需要找到对应的场景卡,把目标、冲突、结果补全,然后开始扩写。过程就像阅读需求文档然后实现功能。
5.2 人物卡模板
在03_characters/main_character.md中维护主角信息:
# 姓名:陆沉 ## 身份 - 职业:见习医师 - 所属势力:临江医馆 - 当前状态:被通缉 ## 核心目标 在审判前找到真正的叛徒,并洗清嫌疑。 ## 性格弧光 从“相信制度”到“怀疑制度”,再到“重建制度”。 ## 能力边界 - 擅长:诊断、配药 - 限制:每次用药后需要时间恢复精神力 ## 当前变化 - 时间线第 2 天:救下乞丐儿童,暴露了藏身点。人物卡的价值在于,它是唯一的事实来源。当剧情推进到第三十天后,你不需要痛苦回忆主角左臂的伤是怎么来的,只需要去查人物卡的“当前变化”。
5.3 伏笔与时间线管理
我建议在01_outline/foreshadowing.md里维护一张伏笔表:
| 伏笔编号 | 埋设章节 | 状态 | 回收章节 | 说明 | | --- | --- | --- | --- | --- | | F-001 | 第 3 章 | 已埋设 | 未回收 | 医馆丢失的药方 | | F-002 | 第 7 章 | 未埋设 | 未回收 | 反派的真实身份 |这张表可以避免“挖坑不填”导致的后期卡文。每次推进正文前,先扫一眼伏笔表,你会发现很多自然的剧情衔接。
6. 本地 AI 辅助写作的部署思路
搭建好结构化工作区后,可以考虑接一个本地 AI 模型来降低启动成本。很多人不敢用 AI 辅助写作,是因为担心稿件外泄。本地部署可以规避这个风险:模型文件在本地运行,请求不经过第三方服务器,适合处理未公开的剧情和设定。
6.1 本地模型选型原则
不要一上来就追求超大模型。写作辅助场景对实时性要求不高,但对稳定性和可控性要求高。建议先选择一个 7B 左右、量化过的小模型验证整个 API 流程。流程跑通后,再根据自己的硬件条件和生成质量决定是否升级到更大模型。
“先小后大”是一个非常稳妥的落地方式。小模型占用的内存和显存更低,生成速度更快,即使出错了,调整成本也小。等你把提示词模板调好、批量脚本跑通,再换大模型,只是改一个配置字段的事。
6.2 服务启动与环境检查
这里以本地模型服务为例,具体安装方式需要以对应官方文档为准:
# 拉取一个适合写作辅助的模型,模型名需要按你的环境替换 ollama pull <model_name> # 启动本地服务 ollama serve启动后可以在另一个终端确认服务状态:
curl http://127.0.0.1:11434如果返回正常连接信息,说明服务已经跑起来了。这个端口是本地默认监听的,后面所有 Python 脚本都会调用这个地址。如果你修改了默认端口,脚本里的 url 也要同步修改。
环境检查清单:
- 操作系统:Windows / Linux / macOS 均可,但模型推理和脚本调用需要对应平台版本。
- Python:建议安装 3.9 以上版本,用于运行批量生成脚本。
- 内存:至少 8GB 以上,具体取决于模型大小,更大的模型需要更多内存。
- GPU:不是必须,但如果有 NVIDIA GPU,可以用
nvidia-smi观察显存占用,推理速度会更快。 - 磁盘空间:模型文件通常有几个 GB,请预留足够空间。
6.3 观察资源占用
当你第一次调用模型生成草稿时,重点关注三个指标:
- 响应速度:从发送请求到返回第一个字符,大约需要多久。
- 内存/显存峰值:运行
nvidia-smi或任务管理器,确认模型不会挤占其他程序。 - CPU/GPU 切换:部分环境默认用 CPU 推理,生成速度会明显慢;如果想用 GPU,需要按模型文档调整启动参数。
这些数字没有统一标准,因为不同模型、不同量化等级、不同硬件差异非常大。你只需要在一开始记录一次基线数据,后续换模型时就能对比,做出理性的升级决策。
7. 批量生成与 API 调用示例
本地模型服务跑起来后,下一步就是把场景卡变成可调用的 prompt,并批量生成草稿。这是整个工作流里最能提升效率的环节。
7.1 单个场景草稿生成
先准备一个最简单的 Python 脚本,验证本地 API 是否可用。以下代码是通用模板,接口路径和请求字段需要按你使用的本地模型服务文档调整:
import requests import json url = "http://127.0.0.1:11434/api/generate" payload = { "model": "your_model_name", "prompt": "请根据以下场景信息,写一段300字左右的小说草稿。" "目标:主角意识到自己被人设局。" "冲突:他找不到任何证据证明自己的判断。" "结果:他决定主动接近反派试探。" "请用人称视角写作,避免空泛总结。", "stream": False, } try: resp = requests.post(url, json=payload, timeout=300) data = resp.json() print(data.get("response", "")) except Exception as e: print("调用失败:", e)这里的重点是提示词结构。不要只写“帮我写一段小说”,而是把场景卡的三个核心要素全部塞进去:目标、冲突、结果。AI 返回的草稿会明显更聚焦,你的后期修订量也会小很多。
7.2 批量场景草稿生成
写长篇时,瓶颈通常不是单个场景,而是几十个场景需要连续推进。批量生成的核心思路是:把场景清单放在一个 JSONL 文件里,脚本逐条读取、逐条调用、逐条写入草稿目录。
准备输入文件batch_scenes.jsonl:
{"id": "scene_001", "goal": "主角找到第一份证据", "conflict": "证据被反派销毁", "result": "主角决定潜入档案馆", "pov": "主角视角"} {"id": "scene_002", "goal": "主角与同伴汇合", "conflict": "同伴已经叛变", "result": "主角没有察觉并说出藏身点", "pov": "主角视角"}批量生成脚本:
import requests import json import time from pathlib import Path url = "http://127.0.0.1:11434/api/generate" input_file = Path("batch_scenes.jsonl") output_dir = Path("04_drafts") output_dir.mkdir(exist_ok=True) def generate_draft(scene: dict) -> str: payload = { "model": "your_model_name", "prompt": ( "请根据以下信息写一段300字的小说草稿。\n" f"场景目标:{scene['goal']}\n" f"核心冲突:{scene['conflict']}\n" f"场景结果:{scene['result']}\n" f"视角:{scene['pov']}\n" "要求:具体、有画面感,不要只给概要。" ), "stream": False, } resp = requests.post(url, json=payload, timeout=300) resp.raise_for_status() return resp.json().get("response", "") with input_file.open("r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue scene = json.loads(line) try: draft = generate_draft(scene) out_path = output_dir / f"{scene['id']}.md" out_path.write_text(f"# {scene['id']}\n\n{draft}\n", encoding="utf-8") print(f"生成成功:{scene['id']}") except Exception as e: print(f"生成失败:{scene['id']},错误:{e}") time.sleep(1)这段脚本有四个关键设计:
- 每条场景独立调用,单个失败不影响其他任务。
- 输出文件按场景 ID 命名,方便对照场景卡。
- 每次调用后加
time.sleep(1),避免请求过于密集导致服务卡死。 - 使用
try/except捕获异常,失败场景可以单独重跑。
7.3 把草稿接回写作工作台
批量生成出来的草稿不要直接进入正文。先把草稿放入04_drafts,这些内容仅作为破冰素材和情节参考。你在正式修订时,提取其中能用的段落,重写后放入05_revision。
这个流程的收益非常明显:卡文的时候,你只需要跑一遍批量脚本,就能得到十几段不同角度的草稿。即使 AI 的句子用得不多,它提供的冲突走向也能让你看见卡点所在。
8. 验证工作流是否有效
很多工具搭完之后就吃灰了,原因是缺少验收标准。下面是一套适合写作工作流的验证方法,你可以在连续创作两周后自检。
- 启动成本:从打开电脑到产出第一段可用的草稿,能否控制在十分钟内?
- 设定检索:能否在三分钟内找出主角在某一天的具体行动记录?
- 版本回滚:上一版大纲改坏后,能否恢复到修改前的状态?
- 批量产出:一次生成十个场景草稿,是否每个都能定位到对应目录?
- 卡文归类:当卡住时,能否明确说出是“目标缺失、冲突不足、结果不清”中的哪一类?
如果以上五项全部通过,说明你的创作链路是稳定可维护的。此时你才有资格说,卡文问题已经从“情绪问题”转化成了“可排查的技术问题”。
这里顺便提供一个最简单的版本管理思路:在01_outline目录里维护plot_outline_v1.md、plot_outline_v2.md,而不是只保留一个“最终版”。每次大幅调整设定前,把当前版本复制到06_archive。这个方法比 Git 简单,但已经能解决大多数倒退需求。
9. 常见卡文场景与排查方法
即便工作流搭建完成,也会遇到各种问题。下面按现象给出排查方向,定位路径必须基于自己的实际环境,因为模型、参数、目录结构不同,现象会有差异。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 坐到电脑前不知道写什么 | 场景卡没有目标 | 打开当前场景卡,检查“目标/冲突/结果”三要素 | 先补全场景卡,再动笔 |
| AI 草稿质量不稳定 | 提示词缺少上下文 | 查看请求日志中的 prompt | 增加人物视角、字数、冲突方向的限制 |
| 调用接口超时 | 模型过大或热启动慢 | 查看服务日志与资源占用 | 换小模型,或降低并发次数 |
| 生成过程中显存不足 | 模型量化等级偏高 | 用任务管理器确认显存峰值 | 换更小规模模型,或调整上下文长度 |
| 人物前后矛盾 | 人物卡没有单一来源 | 检索03_characters目录 | 统一维护人物卡,删除重复文件 |
| 修改剧情后写不下去 | 版本被覆盖 | 检查06_archive当前是否存在 | 大改前先复制当前版本到归档目录 |
| 批量脚本中途卡住 | 本机服务并发能力不足 | 查看日志中失败跳数 | 降低请求频率,增加失败重试逻辑 |
在排查时注意,不要凭感觉乱改。先看日志,再改参数。一次只改一个变量,生成结果对比后再决定下一步。这正是写作工程化与凭感觉写作的最大区别。
10. 最佳实践与合规使用建议
10.1 写作侧的工程实践
把故事工程化坚持到完稿,需要一些纪律性。
第一,先搭骨架再写正文。哪怕只写一千字的短篇,也建议先写一句话梗概和三个关键场景。场景不清晰之前,不进入正文。
第二,保持草稿与修订分离。草稿是“允许混乱”的地方,修订是“对外输出”的地方。混在一起会导致你反复修改同一段话,越写越疲惫。
第三,AI 生成内容只作为初稿参考。AI 可以提供冲突方向、情节转折和场景画面,但它不了解你的完整人物弧光。最终文本必须由你验证、重写和定稿。
第四,定期归档。每次明显改变设定或大纲时,保留一个历史版本。这会让你在改错方向时能迅速退回,而不是因为舍不得推翻而硬写。
10.2 合规与安全边界
使用 AI 辅助写作,必须明确几个边界:
- AI 生成内容可能存在版权归属争议,发布前应确认你对最终文本做了实质性创作和修订,而不是直接复制生成内容。
- 如果作品中涉及现实人物、品牌或受版权保护的素材,需要先获得合法授权,不应当用 AI 生成指向真实人物的不实内容。
- 不要将未公开的手稿投喂给不可信的在线平台;本地模型部署可以有效降低内容外泄风险。
- 发布作品前应人工复核,避免 AI 生成内容包含错误信息、偏见或不当表述。
11. 总结与下一步
对“写小说总是卡住”这个问题,最有效的处理方式不是等灵感,而是把创作过程改造成一条可维护、可回溯、可批量推进的本地工作流。先建目录,再写场景卡,再接入本地模型批量生成草稿,最后人工修订定稿。整个流程不复杂,但需要对故事做工程化拆解。
最先应该验证的是:把当前写到一半的故事拆成一张场景卡,卡上写明目标、冲突、结果,然后尝试用本地模型 API 把它扩写成一个三百字草稿。跑通这一步后,你就能真正感受到“卡文”从情绪问题变成技术问题的转变。
最容易踩的坑有两个。一是跳过步骤直接装大模型,结果模型太大跑不动,脚本始终报错;二是不做场景卡,直接让 AI 输出整个章节,导致内容失控。更稳妥的路径是先用小模型跑通 API,再逐步调大模型,同时把场景卡作为提示词的固定输入。
如果你也被“没灵感”困住过,建议先用这套方法搭一个最小可用环境。把所有设定放进一个目录,把卡文点变成场景卡,把空白文档替换成接口调用。很多时候,你能写下去,不是因为灵感突然降临,而是因为系统在低阻力状态下正常工作。建议收藏备用,下次卡文时按清单排查。