剧情生成 Agent¶
项目背景与目标¶
游戏剧情是叙事类游戏的核心体验,传统剧情由编剧手工撰写,分支有限、成本高、玩家选择自由度低。理想中的"千人千面"剧情需要海量内容支撑,纯人工难以实现。AI 剧情生成 Agent 通过世界观建模、角色关系管理、分支剧情动态生成,实现玩家驱动的涌现式叙事,让每个玩家都有独特故事体验。
本项目目标是构建一个游戏剧情自动生成 Agent,支持世界观设定、角色关系演化、分支剧情生成、剧情连贯性维护。
需求分析¶
核心能力: 1. 世界观管理:设定世界规则、势力、地理、历史 2. 角色关系:维护角色间关系网络与动态演化 3. 剧情生成:基于玩家选择生成合理分支剧情 4. 连贯性维护:前后剧情逻辑一致,无矛盾 5. 节奏控制:把握剧情张弛节奏,避免平淡或过载 6. 主题深化:围绕核心主题推进,避免发散
生成类型:主线推进、支线任务、随机事件、角色对话、结局分支。
技术选型说明¶
| 模块 | 技术方案 | 选型理由 |
|---|---|---|
| Agent 框架 | LangGraph | 剧情生成流程 |
| LLM | GPT-4o / Claude | 长文本创意生成 |
| 世界观存储 | 知识图谱 Neo4j | 复杂关系建模 |
| 记忆系统 | 向量数据库 | 剧情历史检索 |
| 一致性检查 | 规则 + LLM 校验 | 防止剧情矛盾 |
| 剧情模板 | 叙事结构库 | 经典叙事框架 |
| 后端 | FastAPI | 与游戏引擎集成 |
| 数据库 | PostgreSQL | 剧情存档 |
架构设计¶
flowchart TD
PLAYER[玩家选择] --> AGENT[剧情 Agent]
AGENT --> WORLD[世界观模块]
WORLD --> KG[(世界观图谱)]
AGENT --> CHAR[角色关系]
CHAR --> REL[(关系网络)]
AGENT --> GEN[剧情生成]
GEN --> TPL[(叙事模板)]
GEN --> LLM[LLM 创意生成]
GEN --> CONSIST[一致性检查]
CONSIST --> HIST[(剧情历史)]
CONSIST --> RULE[(世界规则)]
AGENT --> PACE[节奏控制]
AGENT --> OUT[剧情输出]
OUT --> GAME[游戏引擎]
OUT --> SAVE[剧情存档]
关键模块实现思路¶
模块1:世界观建模¶
世界观是剧情生成的约束框架。用知识图谱建模:世界规则(魔法体系、科技水平、社会制度)、势力关系(联盟/敌对/中立)、地理结构(城市、区域、地标)、历史事件时间线。剧情生成必须遵循世界规则,避免设定崩坏。
WORLD_RULES = {
"magic_system": "需消耗灵石,低阶修士每日限额",
"technology": "蒸汽朋克,无电力",
"social": "三大势力:帝国、反抗军、商会联盟",
"geography": {"capital": "铁穹城", "rebel_base": "雾隐谷"}
}
世界规则作为硬约束注入生成提示,LLM 不得违背。
模块2:角色关系网络¶
角色关系是剧情推动的核心。维护角色关系图谱:节点为角色,边为关系(亲属/敌友/师徒/暗恋)。关系动态演化:玩家行为触发关系变化(帮助 A 得罪 B),衍生新剧情线索。
def update_relations(graph, event):
if event.type == "player_help_A":
graph.add_edge("player", "A", relation="ally", strength=+20)
if graph.has_edge("A", "B", relation="enemy"):
graph.add_edge("player", "B", relation="hostile", strength=-10)
# 衍生剧情:B 对玩家设陷阱
关系网络变化触发剧情钩子,形成"蝴蝶效应"式叙事。
模块3:分支剧情生成¶
剧情生成采用"模板 + LLM"结合。叙事模板提供结构骨架(如三幕剧:起因-发展-高潮-解决),LLM 在骨架上填充具体内容。生成时检索相关历史剧情与角色关系,确保连贯。
def generate_plot(player_choice, context):
template = select_template(player_choice.type) # 选择叙事结构
prompt = f"""基于以下生成剧情:
世界设定:{context.world}
角色关系:{context.relations}
历史剧情:{retrieve_history(context, top_k=5)}
玩家选择:{player_choice}
叙事模板:{template.structure}
要求:遵循世界规则,与历史连贯,推进主题"""
plot = llm.generate(prompt)
return consistency_check(plot, context)
模块4:连贯性检查¶
连贯性是最大挑战。LLM 可能生成与前文矛盾的剧情(如已死角色复活、已获得道具再次出现)。双重校验: - 规则校验:硬性规则(角色状态、物品归属、时间线)自动比对 - LLM 校验:用另一个 LLM 检查逻辑矛盾
def consistency_check(new_plot, history):
# 规则校验
for char in new_plot.characters:
if char in history.dead_chars and new_plot.has_char_alive(char):
return {"pass": False, "issue": f"{char}已死亡不能复活"}
# LLM 逻辑校验
issues = llm_verify(new_plot, history)
return {"pass": len(issues) == 0, "issues": issues}
校验失败则重新生成或调整,确保剧情可信。
模块5:节奏与主题控制¶
剧情不能无限发散,需有节奏感与主题聚焦。节奏控制基于叙事张力曲线:张弛有度,避免连续高潮疲劳或长期平淡。主题控制锚定核心主题(如"复仇与救赎"),每次生成评估是否推进主题,偏离则拉回。
def assess_pacing(plot_sequence):
tensions = [p.tension for p in plot_sequence]
if all(t > 0.8 for t in tensions[-3:]):
return "需要舒缓段落" # 连续高潮
if all(t < 0.3 for t in tensions[-3:]):
return "需要冲突升级" # 过于平淡
return "节奏良好"
核心流程详解¶
剧情生成流程: 1. 玩家做出选择 → Agent 接收 2. 加载:世界观 + 角色关系 + 历史剧情 3. 选择叙事模板 → LLM 生成剧情草案 4. 连贯性检查 → 通过则采用,否则调整 5. 节奏与主题评估 → 必要时重新生成 6. 输出剧情内容 → 游戏引擎呈现 7. 更新角色关系与剧情历史 → 存档
支线生成流程: 1. 触发条件(玩家进入区域、与 NPC 互动) 2. 检索相关角色与地点 → 生成支线任务 3. 支线与主线关联(人物交叉、主题呼应) 4. 难度与玩家进度匹配 5. 输出任务描述与目标
部署与优化建议¶
- 模型分级:主线用强模型保证质量,支线用轻量模型控制成本
- 预生成缓存:常见选择分支预生成剧情,降低实时延迟
- 玩家画像:记录玩家偏好(战斗/解谜/对话),剧情倾向调整
- 人工审校:关键剧情节点人工审核,保证质量
- 版本管理:剧情存档版本化,支持回溯与多周目
- 反馈循环:玩家跳过/停留数据反馈优化生成策略
常见问题与解决方案¶
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 剧情矛盾 | LLM 记忆有限 | 历史检索 + 规则校验 |
| 设定崩坏 | 世界规则未约束 | 硬约束注入 + 校验 |
| 剧情平淡 | 缺乏冲突 | 叙事模板 + 张力控制 |
| 角色扁平 | 角色塑造不足 | 角色档案 + 动机深化 |
扩展方向¶
- 多结局系统:选择累积影响最终结局
- 玩家共创:玩家贡献剧情片段,社区投票入库
- 跨周目记忆:NPC 记得上周目玩家行为
- 动态难度:剧情难度随玩家能力调整