AI Dungeon 与 NovelAI
本页拆解 AI Dungeon 与 NovelAI——最早的 LLM 应用类型之一:AI 文字冒险游戏和 AI 小说生成。从 GPT-2/3 时代的开创性探索到如今本地化部署和角色扮演生态(SillyTavern、KoboldAI 等),理解 LLM + 上下文管理 + 世界设定记忆的系统工程。
这些产品是什么
Section titled “这些产品是什么”- AI Dungeon(2019)——Nick Walton 开发的 AI 文字冒险游戏,是最早消费级 LLM 应用之一。最初基于 GPT-2,后转向 GPT-3。玩家用自然语言输入动作,AI 生成叙事响应,创造无限可能的互动故事。2023 年后因 Latitude(母公司)战略调整逐渐减少维护,但它开创的”LLM + 上下文管理 + 世界设定”范式深刻影响了后续整个 AI 角色扮演生态。
- NovelAI(2021)——Anlatan 推出的商业化 AI 写作与故事生成平台。最初基于 GPT-Neo/GPT-J,现已发展出自研模型系列:Kayra(基于 LLaMA 2 微调,约 13B 参数)、Erato(2024 年发布,基于 Mistral/Llama 3 架构,性能大幅提升),支持小说写作、图片生成(基于 Stable Diffusion)、世界设定管理。
2024-2025 生态演变
Section titled “2024-2025 生态演变”AI Dungeon/NovelAI 开创的”LLM 角色扮演 + 世界设定”范式,在 2023-2025 年催生了一个繁荣的本地 LLM 角色扮演生态:
- SillyTavern 成为事实上的前端标准——开源、支持几乎所有后端、社区贡献了海量角色卡和世界设定。详见 SillyTavern。
- 本地 LLM 质量飞跃:Llama 3 (2024)、Llama 3.1/3.2/3.3 (2024-2025)、Qwen 2.5/3 (2024-2025)、Mistral 系列、DeepSeek V3/R1 (2024-2025) 等开源模型的质量已接近甚至达到 GPT-4 级别,使得完全本地化的 AI 角色扮演成为现实。
- 专用微调模型:社区在上述基础模型上用大量角色扮演/创意写作语料微调,产生如 Stheno、Euryale、Magnoliae 等专用模型,在创意写作和角色扮演方面超越通用模型。
- GGUF 量化生态成熟:llama.cpp 的 GGUF 格式 + 4-bit/5-bit/6-bit/8-bit 量化方案,让 70B 参数模型也能在双 24GB 消费级 GPU 上流畅运行。
这类产品的本质是 LLM + 持久化上下文管理:
- 普通聊天:对话历史即上下文,聊完即弃
- 文字冒险/小说生成:需要维护一个不断增长的”世界状态”——角色、地点、事件、物品——并在每次生成时把相关信息注入 LLM 上下文
核心挑战:LLM 的上下文窗口是有限的,但故事可以是无限的。如何用有限窗口承载无限故事?
2024-2025 年的一个重大变化是上下文窗口大幅扩展:Llama 3.1 支持 128K tokens,Qwen 2.5 支持至 1M tokens,Gemini 1.5 Pro 支持 2M tokens。这极大地缓解了”窗口不够”的问题,但并未消除——因为故事越长,注意力稀释(attention dilution)和”中间遗忘”(lost in the middle)问题依然存在。
技术架构拆解
Section titled “技术架构拆解”AI Dungeon / NovelAI 技术架构
Section titled “AI Dungeon / NovelAI 技术架构”上下文窗口的”预算分配”
Section titled “上下文窗口的”预算分配””LLM 上下文窗口是稀缺资源,需要在不同信息之间分配”预算”。以下是 8K 窗口时代的经典分配比例(128K+ 窗口下比例可放宽):
💡 在 128K tokens 的现代窗口中,对话历史可占据 60-70%(约 80K tokens),世界设定可用 10-15%(约 15K tokens),生成预算保留 2-4K tokens。即使如此,超过 50K tokens 后注意力质量会逐渐下降。
关键技术点详解
Section titled “关键技术点详解”1. 持久上下文管理
Section titled “1. 持久上下文管理”普通聊天 API 是无状态的——每次请求都要重新发送完整对话历史。AI Dungeon/NovelAI 的创新在于维护一个持久化的故事状态,每次请求时智能组装上下文。核心技术是 World Info(世界信息) 系统——类似手动版的 RAG。
2. 世界设定记忆(World Info / Lorebook)
Section titled “2. 世界设定记忆(World Info / Lorebook)”这是 AI 小说/文字冒险产品的核心创新。World Info 是一个键值对触发的知识库:
- 作者预先定义世界设定条目(如”埃尔多拉多” → 城市描述)
- 每次生成时,系统扫描最近几轮对话的关键词
- 匹配到的条目被注入 LLM 上下文
这本质上是一种基于关键词的检索增强生成(RAG),比向量 RAG 更可控、更适合小说场景(作者精确控制什么信息何时出现)。向量化的 World Info 进一步增强了模糊匹配能力。
SillyTavern 的 World Info 系统在此基础上增加了更多高级功能:
- 递归扫描(Recursive Scanning):一个条目被注入后,它的内容中的关键词会触发更多条目——形成链式世界展开。
- 常驻条目(Constant Entries):某些核心设定始终注入(如主角的外貌、核心世界观),无需关键词触发。
- 选择性条目(Selective Entries):支持 AND/OR/NOT 逻辑组合的复杂触发条件。
- 位置控制(Position):每个条目可以精确控制注入位置——放在系统提示之后、角色卡之前/之后、对话历史的不同深度——以影响 LLM 的注意力分配。
详见 RAG 检索增强生成。
3. 令牌优化与超长处理
Section titled “3. 令牌优化与超长处理”当故事越来越长,对话历史超出上下文窗口时,需要裁剪/压缩策略:
- 滑动窗口(Sliding Window):只保留最近 N 轮对话,丢弃更早的。最简单但容易导致”角色失忆”。
- 摘要压缩(Summarization):用 LLM 将旧对话总结成一段摘要,放在上下文开头。SillyTavern 的 “Summary” 扩展自动执行此流程。
- 重要事件标记:标记关键情节点,裁剪时优先保留。
- 分层记忆:近期对话保留原文,中期用摘要,远期只保留 World Info 条目。
- 向量数据库检索(Vector Storage + RAG):将完整对话存入向量数据库,每次生成前检索最相关的历史片段注入。这是 2024-2025 年的高级方案。
# SillyTavern 风格的分层上下文管理(简化版伪代码)class ContextManager: def __init__(self, max_tokens=8192): self.max_tokens = max_tokens self.recent_messages = [] # 近期对话原文 self.summary = "" # 中期摘要 self.world_info = {} # 世界设定(关键词触发) self.vector_store = None # 向量数据库(远期检索) self.important_events = [] # 标记的关键事件
def build_prompt(self, user_input): budget = self.max_tokens sections = []
# 预算分配 system_budget = int(budget * 0.05) wi_budget = int(budget * 0.20) history_budget = int(budget * 0.60) input_budget = int(budget * 0.10) generation_budget = budget - system_budget - wi_budget - history_budget - input_budget
# 1. 系统提示 sections.append(("system", self.system_prompt, system_budget)) # 2. 世界设定(关键词触发 + 常驻) triggered = self.scan_world_info(user_input) sections.append(("world_info", triggered, wi_budget)) # 3. 摘要(中期记忆) if self.summary: sections.append(("summary", self.summary, 500)) # 4. 近期对话(滑动窗口) recent = self.fit_recent(history_budget) sections.append(("history", recent, history_budget)) # 5. 用户输入 sections.append(("input", user_input, input_budget))
return self.assemble(sections)LLM 上下文长度和分词原理见 Tokenizer 分词器详解。
4. 多角色生成
Section titled “4. 多角色生成”小说/文字冒险场景通常有多个 NPC 角色。生成策略:
- 单模型多角色:一个 LLM 在 prompt 中被告知要扮演多个角色,根据上下文切换人格。这是目前最主流的方案——现代 LLM(如 Llama 3.1 70B)能可靠地在多个角色间切换。
- 角色卡驱动:每个角色有独立的性格描述、对话风格、关系网络,在生成时动态注入。SillyTavern 的 “Group Chat” 模式让多个角色卡轮流响应。
- 多模型协作(较少见):不同角色用不同微调模型,对话由路由器分配。随着本地推理性能提升,这种方案在 2025 年变得更具可行性。
5. 自部署开源模型(Kayra / Erato / LLaMA / DeepSeek)
Section titled “5. 自部署开源模型(Kayra / Erato / LLaMA / DeepSeek)”NovelAI 的模型演进代表了 AI 写作领域的技术路线:
| 模型 | 发布时间 | 基础架构 | 参数量 | 特点 |
|---|---|---|---|---|
| Calliope | 2021 | GPT-Neo 2.7B | 2.7B | 初代,基于 EleutherAI |
| Sigurd | 2022 | GPT-J 6B | 6B | 质量飞跃 |
| Euterpe | 2022 | GPT-NeoX 20B | 20B | 更长上下文 |
| Kayra | 2023 | LLaMA 2 | 13B | 切换 LLaMA 架构 |
| Erato | 2024 | Mistral/Llama 3 | ~20B | 当前最强,创意写作大幅提升 |
自部署关键技术:
- LoRA 微调:在大量高质量小说语料上微调,保留通用能力的同时增强创意写作。社区微调模型(Stheno、Euryale 等)也广泛使用 LoRA。详见 LLM 微调技术。
- 本地推理:用户可以下载模型在本地 GPU 推理,无需联网,数据隐私有保障。详见 LLM 推理优化。
- 量化部署:4-bit/5-bit/8-bit 量化让大模型在消费级 GPU 上运行。GGUF 格式是本地部署的事实标准。详见 小模型与端侧部署。
本地 LLM 角色扮演生态(2024-2025)
Section titled “本地 LLM 角色扮演生态(2024-2025)”AI Dungeon 和 NovelAI 开创的技术范式,在 2024-2025 年催生了一个庞大且成熟的本地化角色扮演生态:
关键工具对比(2025 年)
Section titled “关键工具对比(2025 年)”| 工具 | 定位 | 优势 | 适合人群 |
|---|---|---|---|
| SillyTavern | 角色扮演前端之王 | 最丰富的功能(角色卡、World Info、Group Chat、扩展插件)、活跃社区 | 角色扮演/互动小说爱好者 |
| KoboldAI / KoboldCpp | 文字冒险引擎 | AI Dungeon 精神继承者、专注故事生成、内置 World Info | 文字冒险/小说写作者 |
| Ollama | 极简 LLM 部署 | 一行命令装好模型、REST API、跨平台 | 想快速试用本地 LLM 的用户 |
| text-generation-webui (oobabooga) | 通用 LLM 前端 | 支持所有模型格式、灵活的 prompt 模板 | 技术用户/研究者 |
| Faraday.dev | 桌面角色扮演 | 无需配置的桌面应用、内置模型下载 | 非技术用户 |
| Backyard.ai | 商业角色扮演平台 | 跨设备同步、角色市场、本地推理选项 | 想要”开箱即用”的用户 |
角色卡格式生态
Section titled “角色卡格式生态”角色卡是角色扮演的核心配置文件,定义角色的名字、性格、对话风格、开场白、场景设定等。2024-2025 年形成了两种主流格式:
- V2 (TavernAI 格式):JSON 结构,字段包括
name、description、personality、scenario、first_mes、mes_example等。几乎所有前端都支持。 - V3 (SillyTavern 扩展格式):2024 年提出,增加了
creator_notes、character_book(内置 World Info)、extensions、tags等字段,支持更丰富的角色元数据。
角色卡以 PNG 图片(嵌入 JSON 元数据)或纯 JSON 文件形式在社区中分享——Chub.ai、JanitorAI、CharacterHub 等平台汇聚了大量社区创作的角色卡。
用 OpenAI API 模拟文字冒险的核心循环
Section titled “用 OpenAI API 模拟文字冒险的核心循环”from openai import OpenAI
client = OpenAI()
# 世界设定(简化版 World Info)world_info = "埃尔多拉多是一座漂浮在云端的水晶之城,居民掌握古老的风之魔法。"
# 故事上下文(持久化维护)story = [ {"role": "system", "content": f"你是文字冒险游戏的叙事 AI。世界设定:{world_info}"}, {"role": "assistant", "content": "你来到埃尔多拉多城门前。水晶塔在阳光下闪烁,守卫审视着你。"},]
# 核心循环:接收用户动作 → 生成叙事 → 追加到上下文while True: action = input("\n> 你的行动:") if action == "quit": break story.append({"role": "user", "content": action}) resp = client.chat.completions.create( model="gpt-4o-mini", messages=story, max_tokens=200, temperature=0.8, # 高温度增加叙事创意 ) reply = resp.choices[0].message.content story.append({"role": "assistant", "content": reply}) print(f"\n{reply}") # 注意:实际产品需做令牌裁剪,防止 story 超出窗口用关键词触发 World Info 注入
Section titled “用关键词触发 World Info 注入”# World Info 条目(关键词 → 描述)world_info_entries = { "埃尔多拉多|水晶之城": "埃尔多拉多:漂浮云端的水晶城,风之魔法之都。", "守卫|士兵": "守卫身穿水晶铠甲,手持风暴之矛,效忠风之王。",}
def inject_world_info(recent_text, system_prompt): """扫描最近文本,注入匹配的世界设定""" injected = system_prompt for keywords, desc in world_info_entries.items(): for kw in keywords.split("|"): if kw in recent_text: injected += f"\n[{desc}]" break return injected
# 每次生成前调用,把相关设定动态注入 prompt用本地 LLM 构建角色扮演(Ollama + Python)
Section titled “用本地 LLM 构建角色扮演(Ollama + Python)”import requests
# Ollama 默认运行在 localhost:11434# 先用命令行拉取模型: ollama pull llama3.1:8b
OLLAMA_URL = "http://localhost:11434/api/chat"
# 角色卡(简化版)character_card = { "name": "艾莉娅", "description": "一位来自精灵森林的游侠,性格冷淡但内心善良,擅长弓术和风系魔法。", "personality": "冷淡、警惕、但一旦信任某人便极尽忠诚", "scenario": "你在森林深处遇到了正在巡逻的艾莉娅",}
system_prompt = f"""你扮演的角色:{character_card['name']}角色描述:{character_card['description']}性格特征:{character_card['personality']}场景设定:{character_card['scenario']}请始终以角色身份回应,不要跳出角色。"""
messages = [ {"role": "system", "content": system_prompt}, {"role": "assistant", "content": "(艾莉娅警惕地拉弓指向你)你是谁?为何出现在精灵领地?"},]
# 交互循环while True: user_input = input("\n你: ") if user_input == "quit": break messages.append({"role": "user", "content": user_input})
resp = requests.post(OLLAMA_URL, json={ "model": "llama3.1:8b", "messages": messages, "stream": False, "options": {"temperature": 0.8, "num_predict": 200}, })
reply = resp.json()["message"]["content"] messages.append({"role": "assistant", "content": reply}) print(f"\n艾莉娅: {reply}")
# 简单的滑动窗口裁剪:保留 system + 最近 20 条消息 if len(messages) > 22: messages = [messages[0]] + messages[-20:]💡 以上是原理演示。生产环境中推荐直接使用 SillyTavern——它已经实现了完整的 World Info 系统、上下文管理、多角色支持、扩展插件等功能。
- 温度参数很关键:创意写作用 0.7-0.9(高随机性),功能对话用 0.3-0.5(稳定性优先)。角色扮演推荐 0.7-0.85。
- World Info 要精简:每个条目控制在 100-200 tokens,注入太多会占用对话预算。关键词触发要设”扫描深度”(只扫描最近 2-3 轮)。
- 令牌裁剪要保留故事连贯性:不能简单截断,会导致角色失忆/剧情断裂。优先用摘要压缩旧内容。
- 本地部署优先 GGUF 量化格式:llama.cpp 的 GGUF 格式在消费级 GPU 上推理最快。对于角色扮演,推荐 Q4_K_M 或 Q5_K_M 量化(质量与速度的最佳平衡)。详见 小模型与端侧部署。
- 模型选择策略(2025):
- 消费级 GPU(8-12GB VRAM):Llama 3.1 8B、Qwen 2.5 7B/14B(Q4 量化)
- 中端 GPU(24GB VRAM):Llama 3.3 70B(Q2/Q3 量化)、Qwen 2.5 32B(Q4/Q5)
- 双卡或更好:Llama 3.1/3.3 70B(Q4+ 量化)——创意写作质量极佳
- 创意写作专用微调:Stheno V3 / Euryale 系列(基于 Llama 微调)
- 内容安全:NovelAI 等平台需要内容过滤机制,自部署则完全由用户控制。详见 AI 安全与护栏。
- 长上下文的”中间遗忘”:即使有 128K 窗口,LLM 对位于上下文中间的信息也会注意力下降。重要设定放在上下文开头或结尾。
典型应用场景
Section titled “典型应用场景”- 互动小说/文字冒险游戏:AI Dungeon 模式,玩家自由输入,AI 生成无限叙事。
- AI 辅助小说创作:NovelAI 模式,作者写框架,AI 续写细节、扩写场景。
- 角色扮演聊天:设定角色卡,与 AI 角色进行深度对话(详见 SillyTavern)。
- DnD 跑团辅助:AI 担任 DM(地下城主),管理世界设定和 NPC。
- 教育叙事:历史模拟、语言学习中的沉浸式对话场景。
- 游戏 NPC 增强:2024-2025 年,越来越多游戏(如 Nvidia ACE、Inworld AI)将 LLM 驱动的 NPC 对话集成到 3D 游戏中,让 NPC 具备自然语言交互能力。
OpenAI API vs 自部署开源模型(2025)
Section titled “OpenAI API vs 自部署开源模型(2025)”| 维度 | 云端 API(OpenAI / Claude / Gemini) | 自部署(Llama 3.3 / Qwen / DeepSeek) |
|---|---|---|
| 成本 | 按 token 计费,重度使用成本高 | 一次性 GPU 成本,长期便宜 |
| 质量 | GPT-4o / Claude 3.5 级别,最优 | 接近 GPT-4 级别(差距持续缩小) |
| 隐私 | 数据发送到云端 | 完全本地,数据不出设备 |
| 延迟 | 网络延迟 200-500ms | 本地推理可低至 30-50ms |
| 内容限制 | 有严格内容策略 | 无限制,完全自控 |
| 可定制性 | 无法微调 | 支持 LoRA / 全量微调 |
| 上下文窗口 | 最高 2M(Gemini) | 128K-1M(模型决定) |
| 部署门槛 | 零(注册即用) | 需 GPU + 技术知识 |
💡 2025 年的关键变化:开源模型(Llama 3.3 70B、DeepSeek V3、Qwen 2.5)的创意写作能力已非常接近 GPT-4o。对于角色扮演和小说创作,本地部署从”勉强可用”升级为”体验优秀”。很多社区用户甚至认为,经过创意写作微调的开源模型(如 Stheno)在角色扮演场景下超越 GPT-4o。
典型类库与工具
Section titled “典型类库与工具”| 工具 | 语言 | 说明 |
|---|---|---|
| SillyTavern | JavaScript/Node.js | 角色扮演前端之王,支持几乎所有 LLM 后端,World Info 系统、扩展生态 |
| KoboldAI / KoboldCpp | Python/C++ | 开源本地 LLM 文字冒险引擎,AI Dungeon 精神继承者 |
| llama.cpp | C++ | 高效本地 LLM 推理框架,GGUF 量化格式,CPU/GPU 混合推理 |
| Ollama | Go | 一键部署开源 LLM 的工具,极简 REST API,跨平台 |
| text-generation-webui | Python | 开源 LLM Web UI,支持角色卡和预设(oobabooga 开发) |
| ExLlamaV2 | Python/CUDA | GPU 加速的量化推理引擎,EXL2 格式,速度极快 |
| NovelAI API | 多语言 | NovelAI 官方 API,访问 Kayra/Erato 等模型 |
| Chub.ai | Web | 角色卡分享社区,海量社区创作角色和世界设定 |
| 术语 | 英文 | 解释 |
|---|---|---|
| 世界信息 | World Info / Lorebook | 基于关键词触发的世界设定知识库 |
| 上下文窗口 | Context Window | LLM 单次能处理的最大 token 数 |
| 令牌裁剪 | Token Truncation | 上下文超长时截断/压缩旧内容 |
| 角色卡 | Character Card | 定义角色人设、性格、对话风格的配置文件 |
| 滑动窗口 | Sliding Window | 只保留最近 N 轮对话的上下文策略 |
| LoRA | Low-Rank Adaptation | 轻量微调方法,适配特定写作风格 |
| GGUF | GPT-Generated Unified Format | llama.cpp 的量化模型格式,本地部署标准 |
| ExL2 | ExLlamaV2 Quantization | ExLlamaV2 的量化格式,GPU 推理优化 |
| 递归扫描 | Recursive Scanning | World Info 条目内容触发更多条目的链式展开机制 |
| 角色卡 V2/V3 | Character Card V2/V3 | 社区标准角色卡格式,V3 支持内置 World Info 和扩展字段 |