ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

LLM赋能小说创作:从工程分层到RAG与精度调优的实践指南

LLM赋能小说创作:从工程分层到RAG与精度调优的实践指南 “LLMs Set My Fiction Free”——这个标题如果直译就是“大模型让我的小说创作获得了自由”。过去一年里这个判断经常出现在科幻作者、网文写手和同人创作者的讨论中不再是“我写不出来让 AI 帮我写”而是“我想写的太多整理和实现不过来现在终于可以放手去写”。很多开发者看到这句话第一反应是“这不就是 AI 代写吗”。但我更想把视角拉回工程一侧LLM 在小说创作中真正释放的不是“生成能力”而是“批量验证和快速迭代能力”。换句话说它改变的并不是“有没有灵感”而是“从灵感到正文之间的那条又长又容易放弃的路径”。这篇文章不是一篇文学创作心得而是一篇面向开发者和创作者的技术实践文章。我会从“LLM 的能力边界”切入讲清楚它为什么能释放创作自由度然后给出一套可以跑通的最小工作流包含提示词设计、API 调用示例、本地部署方案、RAG 资料库雏形以及我在工程接入中最常踩的坑。读完你可以用一套可落地的技术方案把 LLM 接进自己的小说创作流程知道哪些环节适合交给模型哪些环节必须由人控制遇到生成效果差、上下文断裂、设定冲突时知道该从哪一层去排查。1. 这篇文章真正要解决的问题先说结论LLM 对小说创作最重要的贡献是把创作过程中的“体力活系数”降了下来。写一部小说尤其是长篇真正消耗人的往往不是“没想到”而是世界观设定散落在几十个文档里写到第五章时忘了第二章埋的伏笔人物动机在写作过程中发生漂移读者觉得角色“崩了”时间线、能力体系、人物关系越来越多手动维护开始出现矛盾需要反复回到前文补细节导致写作节奏被打断有了灵感但缺乏足够的内容结构去承接只能在脑子里反复“空转”。这些问题的共同点是它们不是“创造性”问题而是“信息组织和上下文一致性”问题。而这两点恰好是 LLM 作为工程工具最擅长处理的。但这不代表 LLM 能独立写好一本小说。如果你让模型“自由发挥”一万字它大概率会给你一篇结构完整、语言流畅、但逻辑松散的中庸之作。真正的用法是让人负责决策让模型负责扩展、改写、校验和检索。当模型把“填充细节”这类工作接走之后创作者才有精力把时间花在“选择哪条剧情线”“这个角色到底是谁”这类高价值的判断上。所以这篇文章要帮读者解决的核心问题不是“怎么写小说”而是“怎么搭一套以 LLM 为执行层、以创作者为决策层的工程化写作系统”。2. 为什么“自由”来自能力分层而不是模型单点输出我在技术社区里看到过不少失败的 AI 写作尝试几乎都有一个共同点把 LLM 当成了“一个人”要求它从零到一完成整本小说。这种做法必然遇到三个问题上下文窗口有限模型很快就会遗忘前文的设定生成结果与既有设定冲突的概率随文本长度递增创作者失去了对作品的“手感”写出来的内容不像自己的风格。真正可行的模式是把创作过程拆层。2.1 决策层创作者需要拍板的内容包括故事基调、人物弧光、关键情节点、叙事视角、哪些细节要保留、哪些冲突要激化。这一层的能力边界是审美和世界观模型不擅长做“选择”因为选择需要价值判断。2.2 执行层LLM负责把决策转化成文本。例如给出一句话的故事梗概让模型扩写出一章给出人物性格列表让模型生成符合该性格的对话给出前文摘要让模型续写下一段。模型不需要“知道”整个宇宙只需要在当前任务里执行到位。2.3 记忆层RAG 与设定库这是最容易忽略、也最关键的一层。长篇创作和短篇不同你不可能把前文的几十万字都塞进提示词。需要把设定、人物档案、时间线、风格样本拆成结构化文档用检索的方式按需取用。这样既节省 token又保证生成时的上下文在可控范围内。2.4 校验层二次模型调用或规则过滤写完一章可以用另一个 prompt 让模型检查时间线是否一致、人物称呼是否统一、是否有前后矛盾。这一步相当于自动化的“编辑审稿”。把流程拆开之后你会得到一个新的自由不再依赖某一次生成的质量。任何一次输出不满意都可以单独重跑一个步骤而不是推倒重来。3. 创作场景中的模型选型与基础环境既然要工程化第一步是选模型和跑通环境。创作者通常有两种路线各有取舍。3.1 云端 API 路线适合大多数用户不需要高端显卡按量付费模型能力持续更新。在长文创作场景重点是选择“长上下文能力好、中文指令理解强、支持结构化输出”的模型。常见的云端方案包括 OpenAI 系列、Claude 系列、DeepSeek、通义千问、智谱 GLM 等。各家模型能力差异很大而且容易变化这里不写死版本和参数你需要以官方最新文档为准。但选型时有一个通用标准先用一个小型任务集做对比而不是看跑分。3.2 本地部署路线适合对隐私敏感、有创作数据保密需求、或者需要长期离线写作的用户。本地部署首选 Ollama 这类工具它可以方便地拉取并运行开源模型。在小说创作场景模型的精度格式直接影响到观感。这就涉及到热搜词里反复出现的 fp16、fp32、bf16 问题我在第 6 章展开。这里先给出结论追求生成质量优先选 fp16 或 bf16 的模型显存不够时再考虑 4-bit 量化但要接受一定的文本流畅度下降。3.3 一次最小的环境准备本地部署的最小环境以目前常见的消费级配置为例# 安装 OllamamacOS / Linux 用户 curl -fsSL https://ollama.com/install.sh | sh # Windows 用户去官网下载安装包即可之后在命令行使用 ollama 服务 # 拉取一个适合中文创作的开源模型这里以 qwen 系列为例具体 tag 以官方为准 ollama pull qwen2.5:14b # 启动一个常驻服务 ollama serve启动之后可以用一个最小的 HTTP 请求验证服务是否正常curl http://localhost:11434/api/generate -d { model: qwen2.5:14b, prompt: 用一句话描述一个发生在雨夜古城的悬疑开场。, stream: false }如果返回中包含response字段说明本地推理链路已经跑通。云端 API 路线的环境准备更简单关键是申请并配置 API Key。注意Key 属于敏感凭证不要硬编码在代码里更不要提交到公开仓库。生产环境建议用环境变量或密钥管理服务。4. 最小可用的创作工作流从灵感到章节现在进入核心部分。我带你把创作过程拆成一个最小闭环。这套流程不需要开发复杂系统用脚本或甚至纯提示词就能跑起来。4.1 生成故事设定草案假设你只有一个模糊的灵感“一个失去记忆的调香师在一座永远下雨的城市里寻找自己的过去。”先让模型把这个灵感展开成结构化设定。关键点是要求模型输出 JSON而不是散文。结构化数据后面可以被程序解析也能直接入库。请把以下灵感扩展为小说设定草案并输出 JSON 格式 { 故事梗概: , 核心冲突: , 世界观关键词: [], 主要人物: [ {姓名: , 身份: , 动机: , 秘密: } ] } 灵感一个失去记忆的调香师在一座永远下雨的城市里寻找自己的过去。 要求人物动机要有内在逻辑世界观关键词控制在 5 个以内。这里有一个容易踩坑的地方很多模型对“输出 JSON”理解不稳定偶尔会在 JSON 前后加说明文字。更稳妥的方案是在 API 调用层面把response_format设为json_objectOpenAI 系兼容接口、或在提示词里加“只输出 JSON不要任何解释”。后面代码示例我会给出一种通用处理方式。4.2 建立人物档案模型生成的设定草稿只是一个起点。你需要手工筛选、修改形成真正属于你的人物档案。这一步不能省因为模型生成的动机往往偏“逻辑正确”但不够“有血有肉”。修好之后把人物档案保存为一个 Markdown 文件。比如# 人物档案陆明远 - 身份失去记忆的调香师27 岁 - 外在特点左手中指有旧伤疤常年带着一只旧怀表 - 性格底色谨慎、疏离、但在气味面前会失控 - 核心动机找回自己的过去 - 核心秘密他的记忆不是丢失而是被一家香水公司清洗过 - 说话习惯句子短很少用形容词 - 禁忌拒绝谈起玫瑰花这个文件后续既是创作时的参考也是 RAG 检索库里的核心条目。4.3 生成章节大纲有了人物档案你可以让模型生成章节大纲。和大纲相比模型的优点是可以快速提供多种剧情走向帮助你打破思维定式。请基于以下内容生成第一章的三种不同写法大纲。 人物档案 {把上面的人物档案粘贴进来} 故事梗概 {粘贴你的故事梗概} 要求 1. 三种写法分别侧重悬疑氛围、人物内心、事件推进 2. 每种写法给出本场目标、冲突点、结尾钩子 3. 控制输出在 600 字以内注意大纲是模型输出中少数可以“放心让 AI 自由发挥”的环节。因为大纲不直接进入正文即使跑偏损失也很小。但正因如此它更适合用来做“脑暴”而不是替代你决策。4.4 章节扩写把大纲变成正文这是最需要控制的一步。很多创作者在这里犯同样的错误直接把大纲丢给模型说“写出来”。问题在于缺少约束的正文会“泛化”。模型会写出一段文笔优美、但完全不像你风格的内容。更有效的方式是给模型一个“锚点”开头一句话、结尾一句话、必须保留的三个情节点、以及你希望的语气风格。例如请根据以下结构扩写第一章正文。 【已有背景】 下雨的城市调香师陆明远在一家倒闭的香水店里发现了一瓶没有标签的香水。 【开场句】 雨滴砸在玻璃橱窗上城市像一块被泡发的旧海绵。 【结尾句】 他打开香水瓶闻到了一股不该在这个时代出现的味道十六年前母亲厨房里的桂花香。 【本场情节点】 1. 陆明远进入香水店躲雨 2. 他发现香水瓶上没有标签但瓶身有一道熟悉的划痕 3. 店主出现言辞闪烁似乎认识他 4. 他偷偷拿走香水瓶离开店铺 【写作要求】 - 第三人称限知视角跟随陆明远的所见所感 - 段落短句为主氛围偏冷峻 - 不要解释人物心理通过动作和感官描写暗示情绪 - 输出 1200 字左右这个 prompt 的意义在于你做了所有关键决策模型只负责文字执行。这样生成的结果即使不满意你也可以定位到具体问题——是情节不够刺激还是风格不对而不是笼统地觉得“AI 写得不行”。4.5 运行与验证关于如何运行我用一个通用 Python 示例来演示。这里不再限定具体厂商思路是用 OpenAI 兼容接口通过base_url切换云端或本地服务。这样代码可以复用。# 文件路径scripts/generate_chapter.py import os import json from openai import OpenAI # 方式一云端 API通过环境变量读取 Key client OpenAI( api_keyos.getenv(LLM_API_KEY), base_urlos.getenv(LLM_BASE_URL), # 例如云端服务的地址 ) # 方式二本地 Ollama 服务默认监听 11434 # client OpenAI( # api_keyollama, # base_urlhttp://localhost:11434/v1, # ) def generate_chapter(prompt: str, model: str qwen2.5:14b) - str: try: resp client.chat.completions.create( modelmodel, messages[ {role: system, content: 你是一位擅长文学创作的编辑善于在框架内写出高质量的小说正文。}, {role: user, content: prompt}, ], temperature0.8, ) return resp.choices[0].message.content except Exception as e: # 生产环境应记录日志并做重试这里先抛出方便定位 raise RuntimeError(fLLM 调用失败: {e}) def load_prompt_from_file(file_path: str) - str: with open(file_path, r, encodingutf-8) as f: return f.read() if __name__ __main__: prompt load_prompt_from_file(prompts/chapter_01.txt) result generate_chapter(prompt) print(result) # 保存结果保留原始输出方便对比和回滚 with open(outputs/chapter_01_draft.md, w, encodingutf-8) as f: f.write(result)这个脚本有几个值得留意的设计用环境变量管理 Key避免硬编码。用文件读取 prompt方便版本管理。输出到outputs/目录且不覆盖原文件。每一次生成的草稿都保留这对后续对比模型效果很重要。运行命令export LLM_API_KEYyour_key export LLM_BASE_URLhttps://your-api-endpoint python scripts/generate_chapter.py如果你的模型在本地把LLM_BASE_URL改成http://localhost:11434/v1并把 API Key 填成ollama即可。验证生成效果我建议按四步走是否完整有没有漏掉某个情节点的展开。是否一致人物性格、称呼、服化道细节是否和档案一致。是否可读抛开文学性不谈句子是否通顺、节奏是否正常。是否符合预期这是最主观的一步也是必须由创作者判断的一步。如果前两步不过关通常不是模型不行而是你的提示词里信息不够。把人物档案和更多背景粘进去效果立刻不同。5. 用 RAG 构建“设定检索库”当你开始写长篇小说很快就会面临一个尴尬问题提示词放不下全部设定。假设你有 50 个人物档案、20 个地点、30 年时间线这些加起来的字数可能超过 3 万。每次写一章之前都要手动把相关内容挑选出来这个成本会压垮创作热情。这时候就需要一个非常精简的 RAG检索增强生成流程。核心思路是把设定文档切成小块存入向量数据库生成正文前先用向量检索找出与当前章节最相关的设定拼进提示词。这里我给一个最小可用的简化实现足够跑通概念。生产环境可以考虑用更完整的框架但原理都一样。# 文件路径scripts/build_rag_index.py # 这是一个概念演示版本生产环境请使用正式向量库并处理更多细节 import os import json from pathlib import Path # 这里用轻量级方式模拟向量检索按关键词打分 # 生产环境建议使用开源的向量数据库并接入真正的 embedding 模型 SETTING_DIR Path(settings) # 存放设定文档的目录 INDEX_FILE Path(setting_index.json) def build_keyword_index(): index [] for md_file in SETTING_DIR.glob(*.md): content md_file.read_text(encodingutf-8) # 提取文件标题和首行作为检索入口 lines content.splitlines() title lines[0].lstrip(# ).strip() if lines else md_file.stem # 简单切分按段落拆块 chunks [] current_chunk [] for line in lines[1:]: if line.strip() : if current_chunk: chunks.append( .join(current_chunk)) current_chunk [] else: current_chunk.append(line.strip()) if current_chunk: chunks.append( .join(current_chunk)) for chunk in chunks: if len(chunk) 30: continue index.append({ title: title, file: md_file.name, content: chunk, keywords: set(chunk[:80].split()) # 简化关键词提取 }) return index def retrieve(query: str, index: list, top_k: int 3): # 简化打分query 中的字词在块中出现的次数越多权重越高 query_terms set(query.replace(, ).replace(。, ).split()) scored [] for item in index: overlap len(query_terms item[keywords]) scored.append((overlap, item)) scored.sort(keylambda x: x[0], reverseTrue) return [item for score, item in scored[:top_k] if score 0] if __name__ __main__: index build_keyword_index() print(f索引构建完成共 {len(index)} 个文本块) query 陆明远 桂花香 香水店 下雨 results retrieve(query, index) for r in results: print(---) print(f来源: {r[file]} | 标题: {r[title]}) print(r[content][:200])这段代码故意没有引入真实的向量库原因是为了让你先理解流程。真正上生产时你需要用 embedding 模型把文本转成向量而不是关键词打分使用专门的向量数据库或者至少在内存里维护向量索引在做正文生成前先用当前章节的情节点作为 query检索出相关设定再拼进 prompt。这个“检索 → 拼装 → 生成 → 校验”的循环是长篇创作工作流的基本单位。比起把全书塞进上下文这要省 token 得多而且效果更稳定。6. 模型精度fp16、fp32、bf16 对小说创作意味着什么写小说最怕什么最怕文本“崩字”。一段话中出现奇怪的重复、逻辑跳跃、用词失衡即使概率只有 5%长篇里也会频繁遇到。而模型精度恰恰会影响这种“长尾错误”的概率。这里把三个概念讲清楚。6.1 fp3232 位浮点模型训练和推理最常见的表示方式之一。精度最高但显存占用也最大。一个 70B 级别的模型用 fp32 推理普通消费级显卡基本带不动。6.2 fp1616 位浮点半精度显存占用比 fp32 少一半推理速度更快。在生成文本时fp16 通常是本地部署的质量优先选择。但它的数值范围有限对特别大或特别小的数值不敏感可能导致训练时出现精度问题。好在推理阶段尤其对创作类文本fp16 的损失肉眼几乎不可见。6.3 bf16bfloat16同样是 16 位但保留了 fp32 的指数范围舍弃了更多尾数精度。它的优势是训练稳定性更好不容易溢出。在生成任务中bf16 的质量通常和 fp16 非常接近。很多新硬件的推理框架默认用 bf16。精度格式显存占用数值范围文本生成稳定性适用场景fp32高大参考基准小模型、对精度极度敏感的场景fp16中较小好通用本地推理创作文本够用bf16中较大很好新硬件推理训练与生成通用对于写小说这个场景我的建议是如果你的硬件支持 bf16优先用 bf16否则 fp16 也完全够。只有在显存实在不足时才考虑 4-bit 量化但要在质量与资源之间做取舍。你可以在 Ollama 中通过模型的 tag 或环境变量切换精度具体参数以你的硬件驱动和模型仓库说明为准。这里不写死命令因为不同平台差异较大重点是你需要知道当生成结果出现莫名其妙的逻辑断裂时除了检查 prompt还应该考虑精度设置是否过低。7. 创作场景的版本管理与回滚写小说和写代码有一个共通点版本管理很重要。而且在这个场景里版本管理不只是“保存旧稿”而是“保存每一次决策”。我的建议是建立如下目录结构project/ ├── prompts/ # 所有可复用的提示词按版本保存 │ ├── chapter_01_v1.txt │ ├── chapter_01_v2.txt │ └── compare_prompt.py # 对比不同 prompt 生成的正文 ├── setting_docs/ # 人物档案、世界观、时间线 │ ├── characters/ │ ├── world/ │ └── timeline/ ├── outputs/ # 模型生成结果按章/版本保存 │ ├── chapter_01_draft_v1.md │ └── chapter_01_draft_v2.md ├── scripts/ # 调用脚本、RAG 索引、校验脚本 │ └── generate_chapter.py └── git_repo/ # 或者直接在项目根目录用 git这样做的原因很明显你经常需要回到“上一版 prompt”重新生成。如果 prompt 和输出散落在对话记录里回顾成本会非常高。一个实用技巧在输出文件的头部加一行注释记录本次生成使用的模型、温度参数、prompt 文件路径。这样可以快速复盘什么条件下效果最好。!-- 元信息: modelqwen2.5:14b, temp0.8, promptprompts/chapter_01_v2.txt, date2025-01-10 --正文开始……这种“元信息优先”的思想是从数据工程和实验追踪里借鉴来的。它不增加多少工作量却能避免很多“咦上次那版是怎么写出来的”的迷茫。8. 常见问题与排查思路在接入 LLM 创作流程时你会遇到几类固定问题。提前知道原因排查会快很多。问题现象可能原因排查方式解决方案模型生成的设定前后矛盾提示词中设定信息不足或上下文被截断检查 prompt 中是否包含人物档案和世界观摘要增加 RAG 检索或把关键设定写入 prompt生成正文“文笔很好但不像你的风格”缺少风格示例模型在模仿通用文学腔在 prompt 中加入你自己的 2-3 个句子作为风格参考维护一个风格样本文件随 prompt 一起提交同一段提示词多次生成结果差异过大温度参数设置过高检查 temperature 参数创作草稿可用 0.7-0.9设定整理建议降到 0.3 以下模型输出 JSON 格式不稳定提示词没有明确约束或模型版本不支持强制 JSON开启 response_format 或后处理去掉多余内容用正则提取 JSON 块失败时重试一次本地推理速度慢模型过大、精度过高、显存不足查看 ollama ps 或 nvidia-smi 监控资源换更小模型或使用量化版本长文生成到一半开始重复语句上下文过长导致注意力分散检查输出文本长度与模型窗口控制单次生成篇幅按章节生成而不是整本生成特别提醒一个创作场景特有的问题不要用默认的“对话式”思维去写提示词。模型在对话中会逐渐“讨好”你给出的回复越来越趋于平均。你需要的是“任务式”prompt目标明确、边界清晰、输出格式固定。9. 最佳实践与安全边界最后一部分我想把工程上的建议和创作伦理结合着说。9.1 把模型当“执行编辑器”而不是“共同作者”在创作层面建议你始终保留标题、关键情节、人物弧光和最终润色的决策权。这不仅是风格问题也是版权和创作完整性问题的底线。AI 生成的内容可以作为草稿和素材但最终的文学判断必须由人完成。9.2 做好合规与授权这里有两层意思。第一你使用的 API 和模型必须符合服务商的条款。第二如果你计划发布作品尤其是商业发布建议明确标注哪些部分使用了 AI 辅助创作。不同平台对 AI 辅助内容的政策不同发布前先了解目标平台的规定。涉及他人作品、受版权保护的资料时不要随意喂给模型并要求模仿生成这是法律风险较高的操作。9.3 设定文档要保持单一事实源不要让同一份人物信息既出现在角色档案里又散落在章节注释里。正确做法是角色档案是唯一权威来源章节内不同可以临时调整但最终要同步回档案。这样RAG 检索时拿到的永远是修正后的信息而不是某次草稿里的旧设定。9.4 做好输出安全与隐私如果你的作品尚未公开注意不要把未公开的大纲、章节、人物设定上传到不受信任的第三方模型平台。敏感内容请选择本地部署方案或者与签署了保密协议的云服务商合作。对外调用 API 时日志里不要记录完整 prompt 和输出只记录任务编号、耗时、成功失败状态。9.5 建立“人审”环节一次完整的模型输出至少需要经过一遍人工审阅。你可以把审阅拆成两遍第一遍看情节和人物第二遍看语言和风格。模型很少能一次写出完全不用改的文本但能把“从零开始”变成“改稿”这个改动本身就是效率的巨大提升。10. 总结从一次最小闭环开始回到标题“LLMs Set My Fiction Free”。如果把它理解成“AI 帮我写小说”方向就偏了。真正的“自由”来自把繁琐的扩展、检索、校验工作交给模型让创作者把精力集中在最擅长的判断和决策上。你可以从一个小项目起步不需要搭建完整的系统选一个好用的云端 API 或本地模型跑通一次生成本文链路写一个固定格式的 prompt保存为文件把自己的风格样本放进去生成一章 500 字左右的测试文本手工改到满意记录下“哪些提示词改动效果最明显”。等这个小闭环稳定之后再逐步加入人物档案、RAG 检索、版本管理、结果校验。这样你不会被复杂度吓退也能在看到真实效果后更清楚自己到底需要哪一层能力。技术只是工具故事还是你的。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表