用 AI 写古风小说:世界观设定、角色塑造、风格一致性的三难问题
一、个性化深度引言
去年尝试用 AI 辅助写古风小说。第一版生成出来:主角在唐朝用手机 App 点外卖。这算 Bug 还是算创意?模型没有时代意识,它只会根据概率拼接——而“手机”和“吃饭”在语料中的共现概率极高。
古风创作有三个特殊挑战:世界观必须自洽(不能出现时代错位)、角色必须一致(同一个人不能上一章腹黑下一章天真)、语言必须纯正(不能冒出“好的亲”这种现代口语)。见证奇迹的时刻,是我们发现这三者不是独立问题而是一个耦合问题——世界观约束角色,角色约束语言。
二、个性化原理剖析
三难问题的耦合关系
解决方案:三层约束注入
第一层:世界观注入(System Prompt 级)
将世界观设定作为系统级约束,永久生效。包括时代背景、技术上限、语言规范。
第二层:角色注入(User Prompt 级)
在每次生成前,注入当前出场角色的人物档案。包括性格、目标、当前状态。
第三层:风格注入(Few-shot 级)
提供 3-5 个同风格的段落示例,让模型学习具体的语言节奏。
一致性校验机制
生成完成后,运行三层校验:
三、个性化代码实践
from typing import List, Dict, Optional
from dataclasses import dataclass, field
import re
@dataclass
class WorldSetting:
"""世界观设定"""
dynasty: str # 朝代
tech_level: str # 科技水平
forbidden_terms: List[str] # 禁止词汇
allowed_greetings: List[str] # 允许的称谓
@dataclass
class CharacterProfile:
"""角色档案"""
name: str
title: str # 称号/身份
personality: str # 性格描述
speech_style: str # 说话风格
motivation: str # 核心动机
forbidden_actions: List[str] # 不允许的行为
class AncientStyleWriter:
"""古风小说辅助写作工具"""
# 设计原因:时代违禁词库——古风写作中最基础的过滤层
MODERN_TERMS = {
"唐朝": ["手机", "电脑", "WiFi", "App", "地铁", "飞机",
"电话", "网络", "微信", "外卖", "快递", "共享"],
"宋代": ["手机", "电脑", "WiFi", "App", "地铁", "飞机",
"电话", "网络", "微信", "外卖", "快递", "共享"],
# 通用古代禁止词
"通用": ["OK", "好的亲", "宝子", "集美", "栓Q"],
}
def __init__(
self,
world: WorldSetting,
characters: Dict[str, CharacterProfile],
):
self.world = world
self.characters = characters
def build_system_prompt(self) -> str:
"""构建世界观 System Prompt"""
# 设计原因:三层约束分离注入——系统级、角色级、风格级
forbidden = self.MODERN_TERMS.get(
self.world.dynasty, self.MODERN_TERMS["通用"]
)
prompt = f"""# 世界观设定
– 故事发生在 {self.world.dynasty},科技水平:{self.world.tech_level}
– 人物称谓使用古语,避免任何近现代词汇
– 禁止使用以下词汇:{', '.join(forbidden)}
# 语言风格
– 使用古风书面语,偶尔使用文言句式
– 对话允许口语化,但不能出现网络用语
– 描写重视意象和氛围,多用五感描写"""
return prompt
def build_character_prompt(
self, character_id: str
) -> str:
"""构建角色 User Prompt"""
# 设计原因:每次只注入当前场景出场角色,避免上下文过长
char = self.characters.get(character_id)
if not char:
return ""
return f"""# 当前主角:{char.name}
– 身份:{char.title}
– 性格:{char.personality}
– 说话风格:{char.speech_style}
– 动机:{char.motivation}
– 行为限制:{', '.join(char.forbidden_actions)}"""
def check_era_consistency(self, text: str) -> Dict:
"""时代一致性检查"""
# 设计原因:生成后必须校验,不能假设 Prompt 能完美约束模型
issues = []
forbidden = self.MODERN_TERMS.get(
self.world.dynasty, self.MODERN_TERMS["通用"]
)
for term in forbidden:
if term in text:
# 找到违禁词所在的句子
for sentence in text.split("。"):
if term in sentence:
issues.append({
"term": term,
"context": sentence.strip() + "。",
"severity": "high" if term not in ["OK", "好的亲"] else "medium",
})
return {
"passed": len(issues) == 0,
"issues": issues,
"score": 1.0 – len(issues) * 0.1,
}
def check_character_consistency(
self, text: str, character_id: str
) -> Dict:
"""角色一致性检查"""
# 设计原因:用关键词匹配检测角色行为是否越界
char = self.characters.get(character_id)
if not char:
return {"passed": True, "issues": [], "score": 1.0}
issues = []
for action in char.forbidden_actions:
if action in text:
issues.append({
"character": char.name,
"forbidden": action,
"severity": "medium",
})
return {
"passed": len(issues) == 0,
"issues": issues,
"score": 1.0 – len(issues) * 0.15,
}
def check_style_consistency(
self, paragraphs: List[str]
) -> Dict:
"""段落间风格一致性检查"""
# 设计原因:相邻段落风格突变会影响阅读体验
if len(paragraphs) < 2:
return {"passed": True, "score": 1.0}
# 计算相邻段的句长差异
issues = []
for i in range(len(paragraphs) – 1):
len_a = len(paragraphs[i].replace(" ", ""))
len_b = len(paragraphs[i + 1].replace(" ", ""))
# 设计原因:相邻段长度比超过 3 倍视为风格突变
ratio = max(len_a, len_b) / max(min(len_a, len_b), 1)
if ratio > 3:
issues.append({
"para": i + 1,
"ratio": ratio,
"severity": "low",
})
return {
"passed": len(issues) == 0,
"issues": issues,
"score": 1.0 – len(issues) * 0.05,
}
# 使用示例
world = WorldSetting(
dynasty="唐朝",
tech_level="冷兵器时代,无电力",
forbidden_terms=[],
allowed_greetings=["公子", "娘子", "陛下", "大人"],
)
characters = {
"li_mo": CharacterProfile(
name="李墨",
title="剑客/前朝遗孤",
personality="冷峻寡言,但内心重情义",
speech_style="话极少,每句不超过15字,不用敬语",
motivation="为家族复仇",
forbidden_actions=["哭泣", "示弱", "长篇大论", "开玩笑"],
),
}
writer = AncientStyleWriter(world, characters)
system_prompt = writer.build_system_prompt()
character_prompt = writer.build_character_prompt("li_mo")
print("=== System Prompt ===")
print(system_prompt[:200])
print("\\n=== Character Prompt ===")
print(character_prompt[:200])
# 一致性校验示例
test_text = "李墨掏出手机看了看时间,心想该出发了。这位剑客哭了。"
era_result = writer.check_era_consistency(test_text)
char_result = writer.check_character_consistency(test_text, "li_mo")
style_result = writer.check_style_consistency(test_text.split("\\n\\n"))
print(f"\\n时代一致性: {'通过' if era_result['passed'] else '未通过'}")
if era_result["issues"]:
for issue in era_result["issues"]:
print(f" 违禁词「{issue['term']}」:{issue['context']}")
print(f"角色一致性: {'通过' if char_result['passed'] else '未通过'}")
if char_result["issues"]:
for issue in char_result["issues"]:
print(f" {issue['character']} 执行了禁止行为「{issue['forbidden']}」")
四、个性化边界权衡
| 无约束自由生成 | 极高 | 极低 | 高(出现现代词) | 随意但混乱 |
| 仅 System Prompt | 高 | 中低 | 中 | 较自然 |
| System + 角色 Prompt | 中 | 中高 | 中低 | 有一定方向感 |
| 三层约束 + 生成后校验 | 中低 | 高 | 低 | 像填表格,缺乏惊喜 |
| 人工自由写作 | 极高 | 依赖作者 | 低(知识正确) | 最佳 |
关键权衡:
五、总结
AI 辅助古风小说创作的三大难题——世界观设定、角色塑造、风格一致性——是具有强耦合关系的系统性问题。世界观约束角色的行为边界和语言选择,角色的性格决定其表达方式,语言的连贯性反哺风格统一。技术上,建议采用“三层注入 + 生成后校验”的策略:System Prompt 注入世界观,User Prompt 注入角色档案,Few-shot 注入风格示例;生成后在时代一致性、角色一致性和风格一致性三个维度进行校验。工程上,违禁词库是最基础也最有效的一致性保障手段,但深层错误需要配合知识图谱进行检测。最终,AI 的角色是辅助工具而非替代者——它可以帮你避免低级错误,但无法替你判断哪句话更好。





