尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LLM小说创作工作流:本地部署、批量生成与文风统一实战

LLM小说创作工作流:本地部署、批量生成与文风统一实战 写作是件很矛盾的事灵感来的时候手速跟不上脑子灵感不在的时候模型、大纲、角色弧光全卡在那里屏幕比墙还冷。这两年我试过的解法很多从“硬写”到“换工具”都折腾过真正让创作状态稳定下来的反而是 LLM。它解决的其实不是“帮你写小说”这件事而是把写作链条里最消耗心力的环节拆开素材整理、脑洞发散、情节分支、批量试写、统一文风。全串起来之后LLM 不再是聊天框里的“自动续写机器”而是一套可以本地部署、批量调接口、按自己节奏调参的创作流水线。这篇文章就是把这套流水线讲清楚。我会先说它到底能干什么、门槛在哪然后按“环境准备 - 模型部署 - 功能测试 - 接口与批量任务 - 性能观察 - 常见问题”的顺序把从零搭一套小说创作 LLM 工作流的过程完整过一遍。文章结尾会留一套可以直接照着做的验收清单方便你收藏后逐步落地。如果你只是想看它能不能帮自己节省试错时间答案是可以如果你关心的是本地推理、OpenAI 兼容接口、批量生成、RAG 风格库这些工程细节下面这些内容可以直接对号入座。1. 核心能力速览能力项说明项目类型面向小说/故事/剧本创作者的 LLM 写作辅助工作流核心作用灵感发散、设定生成、章节大纲、批量试稿、文风拆分与统一模型来源可使用商用 API也可使用开源 LLM 本地部署部署形式本地推理服务 / OpenAI 兼容 API / 单机命令行脚本支持任务单条生成、批量任务、基于风格库的 RAG 增强、Agent 式计划分解推理方式GPU / CPU 均可速度差异明显显存需求视模型参数量与量化精度而定小模型 4-8G 可跑大模型需更高启动方式命令行一键启动或脚本启动无强制 WebUI接口能力兼容 OpenAI 风格的chat/completions接口便于接入自己的工具链批量任务支持通过脚本遍历章节/设定/场景批量生成适合读者小说作者、编剧、文案团队、AI 应用开发者、对本地 LLM 感兴趣的工程师有一点要说明这里的“项目”不是某个特定 GitHub 仓库而是一条相对完整的 LLM 创作链路。它把开源模型、推理服务、提示词管理、批量任务和风格资料库组合在一起最终落成一套可以持续产出的工具系统。2. 用 LLM 创作小说适用场景与使用边界先聊边界是因为很多朋友把 LLM 写作想成了“给一句话出一本小说”。实际用下来它更擅长的是给创作过程提供“无限草稿”和“低成本的错误选项”。2.1 适合谁有明确创作目标但缺素材的作者需要人物名、世界观设定、情节冲突、反转设计的灵感库。需要批量试稿的创作者比如一章内容写五个开头比较节奏和语气用 LLM 批量生成可以大幅降低时间成本。想把写作流程工程化的团队漫画脚本、短剧分集、网文章节需要固定格式输出LLM 能按 JSON 模板稳定返回。对数据隐私敏感的创作者故事框架、未发表章节不方便传到外部 API本地部署就很有价值。2.2 能解决什么问题LLM 写作最有价值的地方不在“最后成稿”而在过程把创作者从空白页焦虑里拉出来先给一个粗糙版本再进行人工修改比自己从零开始轻松得多。把文风统一问题从“凭感觉”变成“可量化”把一段范文交给模型让它提取句式特征、用词习惯、段落节奏写出来的内容会明显贴近。把“大纲—细纲—正文”的层级拆开处理每个环节由不同的提示词模板负责比让模型一次性写完整章节稳定。2.3 不适合什么场景追求绝对原创性、文字带有强烈个人审美标记的严肃文学创作LLM 容易把语言改“平”丢失风格锐度。需要严格考据的历史小说、专业知识高度密集的行业小说LLM 会一本正经地编造必须人工核对。已有完整定稿、只需要“快点写完”的项目LLM 对叙事节奏和伏笔回收的理解并不可靠。2.4 版权、隐私与合规边界用 LLM 辅助写作有几条红线建议先理清楚不要把未公开的完整稿件、客户委托文本、真实人物隐私信息发送到不可控的外部接口。使用“风格模仿”功能时只对自己拥有版权或已获得授权的文本做参考不要仿写他人作品并对外发布。面向平台投稿、商业出版、剧本出售前确认平台对“AI 辅助创作”的要求很多内容平台有自己的披露规则。批量生成的内容要经过人工复核避免输出歧视、暴力或违反公序良俗的段落。3. 环境准备与前置条件铺垫完了进入部署部分。先看一眼需要准备哪些东西再根据你的实际情况选一条路。3.1 通用环境清单项目建议操作系统Windows 10/11、Ubuntu 20.04、macOS 均可Python3.10 或 3.11用于跑调用脚本和数据处理运行内存16G 起步32G 更从容显卡可选如果做本地推理NVIDIA 显卡优先显存越大越好CUDA本地 GPU 推理时需要版本与推理框架匹配即可磁盘空间模型权重变量最大量化小模型约 4-8G大模型几十 G 起步预留至少 30G端口本地推理服务常用 11434、8000、8080、7860 等注意冲突如果你用的是商用 API 路线环境准备会简单很多只需要 Python 环境、网络连接和 API 密钥即可。3.2 本地推理框架选型目前比较流行的本地 LLM 部署方式有几种按使用场景选就行框架特点适用场景Ollama安装简单命令少自带模型仓库兼容 OpenAI API个人日常使用首选llama.cpp纯 C/C 实现CPU 推理效率高支持量化老显卡或无显卡的场景LM Studio图形界面适合不太想写命令行的用户快速验证模型效果vLLM高性能推理支持并发请求吞吐高作为服务端给批量任务用对小说创作这种“单次生成短文本、随机性较高”的任务Ollama 和 llama.cpp 已经够用。如果后续要做大批量章节试稿再考虑 vLLM 这类服务化框架。3.3 模型选择思路写小说和写代码不一样对数学推理能力要求低但语文能力、长文本理解能力、叙事连贯性要求高。选模型时可以按这个思路来轻量优先7B-14B 级别的中文模型配合量化能在消费级显卡上运行适合日常场景草稿。中文优先关注中文语料占比高的开源模型输出的人名、成语、古风词汇更自然。长上下文优先如果一次要生成七八千字的长章节模型上下文窗口最好在 32K 以上。风格可控性优先选择指令遵循能力强的模型因为写作工作流高度依赖提示词。这里不绑定具体某个模型版本因为实际效果受量化方式、提示词写法影响很大。稳妥做法是同一批指令在多个模型上各跑一轮人工对比后固定一个作为创作主力。4. 部署与启动LLM 本地推理与 API 接入环境准备好之后选一条主要路线跑通。下面以 Ollama 和 Python 调用为例演示“本地模型服务 - 接口接入 - 批量脚本”的完整链路。4.1 安装并启动 OllamaOllama 的安装很简单官方支持 Windows、macOS 和 Linux。装完后先确认服务可用。# 查看版本 ollama --version # 拉取一个适合中文写作的模型具体模型名需按 Ollama 仓库实际支持情况填写 ollama pull qwen2.5:7b # 启动服务 ollama serveollama serve会默认监听本地11434端口并提供一个 OpenAI 兼容接口。如果你不想让服务占用终端也可以让它常驻后台。启动后可以直接聊天验证ollama run qwen2.5:7b输入一句“给一个仙侠小说的开头两百字气氛要冷”看返回内容是否稳定。这一步通过本地推理链路就通了。4.2 用 curl 验证 OpenAI 兼容接口Ollama 的 OpenAI 兼容接口一般在下面这个路径curl http://127.0.0.1:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5:7b, messages: [ {role: system, content: 你是一个擅长都市悬疑小说的编辑善于铺陈氛围和塑造人物。}, {role: user, content: 请为一个短篇设计三个不同走向的开头。} ], temperature: 0.8 }返回结果里会有choices[0].message.content字段这就是模型生成的文本。这一步验证的核心是能否通过标准 HTTP 请求拿到创作结果。能拿到后面接自己的 Python 脚本、批量任务、Web 工具都没有障碍。4.3 接入商用 API 作为备选如果你短期没有本地显卡但又想先跑通完整创作流程可以注册商用大模型 API 服务拿到密钥后写一套统一的调用层。from openai import OpenAI client OpenAI( base_urlhttps://api.example.com/v1, # 以你的服务商实际地址为准 api_keyyour-api-key ) response client.chat.completions.create( modelyour-model-name, messages[ {role: system, content: 你是小说共创编辑输出克制、具体、有画面感。}, {role: user, content: 写一个推理小说中金库失窃案的案发现场描述。} ], temperature0.9 ) print(response.choices[0].message.content)注意base_url、model、api_key必须换成服务商提供的字段不同服务商之间会有差异。这个步骤的意义是把“本地模型”和“API 模型”统一成同一套调用方式将来想切换部署方式只改配置不拆代码。5. 功能测试与效果验证服务跑通之后不要急着写整本小说先把能力拆成小块验证。下面这套测试维度基本覆盖小说创作 LLM 工作流的核心环节。5.1 灵感发散从一句话设计三个前提测试目的确认模型能否根据一个模糊想法输出多个有效前提。curl http://127.0.0.1:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5:7b, messages: [{role: user, content: 请根据“深夜便利店的收银员能看见每个人的死期”这一设定设计三个立意不同的故事前提每个 150 字以内。}], temperature: 0.9 }判断标准三个前提是否各不相同而不是同一句话换措辞。是否包含“人物-冲突-悬念”的基础结构。是否出现可延展的画面或道具。常见失败原因提示词里没有要求“立意不同”模型会围绕同一主题反复打转。改进方法是在提示词里拆维度一个偏人情、一个偏悬疑、一个偏黑色幽默。5.2 章节大纲把故事梗概拆成可写清单测试目的确认模型能按结构输出章节化大纲。curl http://127.0.0.1:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5:7b, messages: [{role: user, content: 这是一个短篇的梗概主角在整理已故父亲的遗物时发现一封写给二十年后的信。请把它拆成 5 章大纲每章包含本章目标、主要场景、关键冲突、结尾钩子。}], temperature: 0.6 }判断标准是否出现“章节目标”而不是简单复述梗概。是否每章都有明确冲突和下一章的钩子。是否能把大纲直接用于后续扩写。这套提示词模板稳定之后建议保存成 Markdown 文件后续批量套用。5.3 文风迁移与统一写作工作流里文风统一是最难搞的一环。测试方法是给模型一段参考文字要求它提取风格特征再用同样风格写新内容。参考文本 风从巷口灌进来卷起地上干枯的梧桐叶贴着青石板滑出沙沙声。男人把领口紧了紧却没有加快脚步他知道巷子尽头那盏灯迟早会灭。 任务按照上面文本的句式节奏和用词习惯写一个同样氛围的 200 字片段场景是雨夜地铁站。判断标准句式长度是否接近参考文本短句与长句节奏是否一致。是否沿用类似的感觉词如声音、温度、光线的描写方式。是否出现明显“AI 腔”比如“仿佛”“宛如”“跃然纸上”这类高频词。如果风格不稳定可以在提示词里强制加入“禁止词清单”{ messages: [ {role: system, content: 写作要求避免使用“仿佛”“宛如”“同时”“值得一提的是”等词汇。使用具体名词和动作描写少用形容词堆砌。} ] }5.4 细纲到正文长文生成的稳定性写完整章节是压力最大的测试。长文本生成容易在中途出现三个问题人物名字变化、时间线错乱、重复描述。要缓解这个问题需要在提示词里注入“事实基线”。messages [ {role: system, content: 小说事实基线如下主角名叫陈默地铁维修工凶手名叫周岚事件发生时间2023 年 11 月 3 日地名统一为北滨市。以上信息如有冲突以本条信息为准。}, {role: user, content: 根据这段细纲扩写完整章节控制在 1500 字以内陈默在隧道检修时发现一只不属于当晚作业的手套手套内衬绣着周岚的名字缩写。} ]判断标准出现的人名、地名、日期是否与事实基线一致。叙事视角是否保持稳定。章节是否自然结束有没有“突然停止”或“强行总结”的迹象。5.5 批量试写同一个场景五个版本写作里“多版本对比”是很有效的打磨方式。把场景描述作为输入用脚本循环调用五次把结果保存为多个 Markdown 文件。import requests import time payload { model: qwen2.5:7b, messages: [ {role: system, content: 你是短篇小说写手文字克制、画面感强。}, {role: user, content: 写一个 250 字的场景主角在旧书店发现一本书书页里夹着一张写着自己名字的旧照片。} ], temperature: 0.95 } for i in range(5): response requests.post(http://127.0.0.1:11434/v1/chat/completions, jsonpayload) text response.json()[choices][0][message][content] with open(f./outputs/draft_{i 1}.md, w, encodingutf-8) as f: f.write(text) time.sleep(1)执行后直接打开五个草稿文件对比。人工选择一个版本作为底稿继续改能明显减少“第一版怎么都下不了笔”的卡顿。6. 接口 API 与批量任务写作场景的 LLM 接口调用不需要多复杂的框架核心就是启动服务、写请求、解析返回、保存结果。难点在于批量任务多了以后怎么控制请求频率和失败重试。6.1 准备章节任务清单假设我要为一部 10 万字的网文生成初步草稿不能一次性把全文塞进去而是按“卷 - 章 - 场景”切分。推荐用 JSON 维护任务清单。{ np_task: [ { chapter_id: ch_001, title: 深夜列车, scene: 主角在一次末班地铁上发现乘客不断消失, characters: [陈默, 周岚], required_length: 1200 }, { chapter_id: ch_002, title: 废弃站台, scene: 陈默在废弃站台找到一张旧车票, characters: [陈默], required_length: 900 } ] }脚本读取任务清单逐条调用接口生成结果写入outputs目录并附带生成状态。6.2 批量脚本核心写法import json import time import requests from pathlib import Path def generate_chapter(item, output_dir): prompt ( f章节标题{item[title]}\n f场景{item[scene]}\n f出场人物{、.join(item[characters])}\n f要求写成一章约 {item[required_length]} 字的小说正文 f注意环境描写和人物动作细节结尾留悬念。 ) response requests.post( http://127.0.0.1:11434/v1/chat/completions, json{ model: qwen2.5:7b, messages: [{role: user, content: prompt}], temperature: 0.8, }, timeout300 ) content response.json()[choices][0][message][content] output_file Path(output_dir) / f{item[chapter_id]}.md output_file.write_text(content, encodingutf-8) print(f完成{item[chapter_id]}) def run_batch(task_filetask.json): tasks json.loads(Path(task_file).read_text(encodingutf-8))[np_task] for task in tasks: try: generate_chapter(task, ./outputs) except Exception as e: print(f失败{task[chapter_id]}错误{e}) time.sleep(2) if __name__ __main__: run_batch()这个脚本虽简单但已经能覆盖大部分写作批量任务。真正落地上生产前建议再加几层请求失败自动重试最多重试三次。每次请求之间增加随机延时避免触发限流。输出结果追加一个 JSONL 日志文件记录每次请求的模型、参数、耗时和结果路径。遇到连续失败时暂停任务并发送告警。6.3 把 LLM 接到自己的写作工具里如果不想在终端里操作可以把上面的服务接口接到 Obsidian、Web 应用或自建模板工具中。流行的“LLM wiki 范式”也在做类似的事把个人笔记、资料库、写作素材做成 RAG 检索库大模型在生成前先检索相关设定和文风片段再开始写作。这里的关键点是LLM 本身不必和你其他的创作工具装在同一台电脑上。只要网络能访问到服务地址写小说的工作流完全可以把“模型推理”和“素材管理”拆分到不同机器。比如一台台式机跑本地推理服务笔记本上只装编辑器和调用脚本。这也是“ComfyUI 和 LLM 是否要在同一台电脑上”这类问题的通用答案看你的网络和接口设计不一定需要同机。6.4 用 RAG 搭建个人风格库在小规模创作场景里RAG 不一定需要重型向量数据库。把一个角色的外貌、性格、说话习惯打包成固定段落在每次调用前替换进提示词就足够应付很多问题。真正需要 RAG 的时候通常是资料很多、风格样本很杂需要动态检索。轻量实现思路建一个characters/目录每个人物一个 Markdown 文件。建一个styles/目录存放自己写过的范文片段。写一个 50 行左右的 Python 脚本按关键词把相关内容拼接到提示词里。后续数据量大了再引入向量库替代目录检索。下面是简化的提示词拼接脚本from pathlib import Path def load_character(name): path Path(f./characters/{name}.md) return path.read_text(encodingutf-8) if path.exists() else def build_prompt(user_content, characters): character_block \n.join([load_character(c) for c in characters]) return ( 以下是作品中的人物设定必须严格遵守\n f{character_block}\n\n 用户内容\n f{user_content} )7. 资源占用与性能观察很多第一次跑本地 LLM 的朋友最关心的是“会不会爆显存”“会不会卡死”。其实只要会观察这些问题在动手之前就能预测。7.1 显存占用怎么看当推理服务正在运行时另开一个终端执行nvidia-smi关注Memory-Usage那一列看的是 GPU 显存占用。除此之外还要看 CPU 内存的占用因为推理框架加载模型时通常先在内存里展开再拷到显存。观察时间点分三个观察时机关注点服务启动前系统空闲显存、内存剩余模型加载后模型权重占了多少显存生成长文时KV Cache、上下文增长导致显存追加情况7.2 精度与显存的关系本地模型部署绕不开数值精度问题。常见的有 fp32、fp16、bf16 和 int8/int4 量化几种形态。fp32精度最高显存占用最大消费级显卡基本没必要。fp16半精度显存占用是 fp32 的一半很多 GPU 推理都能跑。bf16和 fp16 位数一致但指数位更多数值范围更大大模型推理时更稳。int8 / int4量化后的低精度格式显存更小牺牲少量质量换速度。如果你只有 8G 显存想稳定跑 7B 级别的中文模型选择量化版本通常会比硬跑 fp16 更实用。但具体占用多少要看你用的模型文件、上下文长度和单次生成 token 数最稳妥的做法是下载前先看模型的说明文件。7.3 影响性能的主要参数参数影响上下文长度越长显存中 KV Cache 越大长文生成更容易爆显存温度 temperature影响随机性不影响资源占用最大生成 token 数影响单次请求耗时并发请求数同时多个请求会成倍增加显存压力量化精度直接影响模型权重占用的显存批次大小批量工具里同时处理多个提示词时会增加显存7.4 降低资源占用的通用措施优先使用量化模型文件。控制单次生成长度不要一次让模型输出 8000 字而是改成 1500 字一段分段生成。关闭不用的并发任务一次只跑一个长文本请求。服务不使用时直接释放进程避免模型一直占着显存。如果端口被历史进程占用用ps aux | grep找到残留进程清掉再启动。8. LLM 写作常见问题与排查方法问题现象可能原因排查方式解决方案启动后接口请求超时模型文件很大加载缓慢查看启动日志确认是否显示 model loaded延长请求 timeout或先用小模型验证链路生成的章节人名前后不一致上下文太长模型遗忘早期设定检查提示词里是否包含完整人物设定在每章节提示词中加入“事实基线”显存不足直接退出模型参数或上下文过长nvidia-smi查看占用看是否已满换量化模型、降低上下文长度、分批生成批量任务跑到一半卡住单次请求超时或本地服务无法并发查看服务日志和运行中的进程增加请求重试减小并发数加长 timeout输出内容全是空话temperature 过低或模型指令遵循能力弱对比不同参数下的输出适当提高 temperature重写提示词加入禁止词清单风格迁移效果差参考文本没有拆出明确特征换一段特征更明确的参考文本让模型先“分析风格”再“写作”分两步走长文写到后面逻辑断裂没有给模型提供有效的大纲约束检查是否只给了场景一句话就直接扩写改成“细纲 - 分节 - 扩写”的阶梯式流程本地端口被占用之前启动的推理服务没关检查端口监听状态换端口或 kill 旧进程9. 最佳实践与合规使用9.1 工程化落地建议第一波验证先用小参数跑通模型选小一号、最大生成 token 数量设低一些确认链路没问题再放开。保留一套最小可运行配置把模型版本、提示词模板、启动脚本固化到同一目录避免“能跑但不知道怎么复现”。素材目录分开管理prompts/放提示词模板characters/放人物设定outputs/放生成结果logs/放请求日志。给每个生成文件加元信息头模型名、时间、参数、上下文版本方便回溯。--- model: qwen2.5:7b temperature: 0.85 prompt_template: v3_chapter_expand generated_at: 2025-06-01 21:30 --- 正文内容...批量任务一定要写日志。至少记录任务 ID、请求状态、耗时、输出文件路径。接口服务如果开启局域网访问必须加访问控制不要直接把11434或8000端口裸暴露到公网。9.2 创作层面的使用技巧把 LLM 当“共同创作人”而不是“代笔”。先让它给十个不喜欢的方案再从废稿里找方向比直接让它写最终稿更有用。人物设定尽量固定成结构化文本每次调用都带上而不是靠模型记忆。把文风控制拆成两层一层是“禁止词”一层是“偏好词”。禁止词控制下限偏好词控制上限。每次生成完保留至少一个成功案例作为工作流输出标准。9.3 合规和安全边界涉及真实人物形象的描写、真实事件改编需要特别谨慎必要时先获得授权。对外部 API 发送的文本要脱敏不要在故事草稿里包含真实联系方式、身份证号等敏感信息。商业平台投稿前仔细阅读平台对 AI 辅助创作的说明按平台规则披露。批量生成内容不搞色情、暴力、违法诱导这类内容既违反公序良俗也容易被服务商风控拦截。10. 总结与下一步这套 LLM 小说创作工作流最值得尝试的一点是它把“创作”从不可控的灵感和状态中部分抽离出来变成了可调用、可批量、可复现的流程。先不追求让模型写出惊艳的句子而是让它在“灵感发散、大纲拆分、人物设定、场景试写、批量对比”这些环节帮你把工作量降下来你会发现写作压力会小很多。建议你先跑通一行命令、一段接口调用、一次小批量生成先完成最小闭环。开始时最容易踩的坑有三个第一是选了过大的模型导致显存不够第二是提示词里没有加入“事实基线”导致前后矛盾第三是批量任务缺少重试和日志导致中断后无从排查。这三个坑前文都有对应的排查方式收藏起来实操时对号入座。后续想继续深入可以从这几个方向扩展给写作流程接上向量检索做一个真正属于自己的“灵感素材库”把多个模型组合起来让一个模型负责大纲、另一个负责正文、第三个负责文风润色形成多角色流水线或者把接口服务接入 Obsidian 这样的笔记工具做到在写作界面里直接调用 LLM 能力。框架不重要重要的是先把本职工作流跑通再一步步加深。
返回列表