StoryEcho——基于大模型的沉浸式互动叙事平台初步框架搭建
框架搭建四月初我们决定初步搭建一个未接入AI Agent但能够完整实现输入与反馈的框架来方便我们后期进行功能分工前端页面优化以及AI的训练。我们计划使用SQLite数据库前端使用vue框架搭建后端使用FastAPI框架创建接口来接收前端请求、调用后端逻辑、返回数据核心的游戏逻辑使用我们一开始就决定使用的LangGraph框架搭建。我们将要求提供给了Deepseek让AI搭建了一个初步的框架。该框架的核心是LangGraph 工作流引擎先构建了游戏逻辑的状态机# story_engine.py - 状态定义 class StoryState(TypedDict): story_id: str scene_id: str messages: List[Dict[str, str]] # 对话历史 attributes: Dict[str, int] # 角色属性 inventory: List[str] # 背包物品 relationships: Dict[str, int] # NPC好感度 intent: str # 用户意图 turn_count: int # 回合计数 ending_triggered: Optional[str] # 结局标记然后创建了一个状态图该状态图中添加了三个处理节点以及节点之间两两相连的边触发节点逻辑就能在状态图中添加相关节点并与前一个剧情点连接def build_graph(self): workflow StateGraph(StoryState) # 添加节点 workflow.add_node(intent_parser, self.intent_parser) workflow.add_node(logic_referee, self.logic_referee) workflow.add_node(narrative_director, self.narrative_director) # 设置边顺序执行 workflow.add_edge(intent_parser, logic_referee) workflow.add_edge(logic_referee, narrative_director) workflow.add_edge(narrative_director, END) return workflow.compile()意图解析节点该节点是先提炼玩家输入的语句中的关键词然后将关键词传入逻辑判断节点进行分析。def intent_parser(self, state: StoryState) - StoryState: user_input state[messages][-1][content].lower() # 关键词匹配意图 intent_mapping { 攻击: attack, 打: attack, 探索: explore, 查看: explore, 使用: use, 喝: use, 说话: talk, 问: talk, } for keyword, action in intent_mapping.items(): if keyword in user_input: state[intent] action break return state逻辑判断节点接收到意图解析节点传入的关键词后进行逻辑判断并更新相关状态。def logic_referee(self, state: StoryState) - StoryState: intent state[intent] if intent attack: # 战斗判定基于力量和运气 hit_chance (attrs[strength] attrs[luck]) / 2 / 100 success random.random() hit_chance if success: damage random.randint(5, 20) attrs[hp] min(100, attrs[hp] 5) # 战胜恢复 else: attrs[hp] max(0, attrs[hp] - 10) # 失败扣血 elif intent explore: # 概率性发现物品 if random.random() 0.3: item random.choice([金币x10, 草药, 魔法水晶]) state[inventory].append(item) return state叙事导演节点根据逻辑判断出的结果生成对应的符合背景环境的剧情描述使玩家更沉浸。def narrative_director(self, state: StoryState) - StoryState: 叙事导演节点 - 生成沉浸式剧情描述 intent state.get(intent, explore) action_result state.get(last_action_result, success) attrs state.get(attributes, {}) result_desc state.get(action_result_desc, ) # 简化的叙事生成 narratives { attack_success: [ f你握紧武器眼神中闪烁着决绝的光芒。\n动作如闪电般迅捷{state.get(intent_target, 敌人)}还没反应过来你的攻击已经命中\n{result_desc}\n空气中回荡着金属碰撞的声响敌人发出痛苦的嘶吼。\n你感到肾上腺素在血管里奔涌战斗的激情让你更加专注。 ], attack_fail: [ f你试图发起攻击但脚步一个踉跄差点摔倒。\n{state.get(intent_target, 敌人)}敏锐地察觉到了你的破绽轻松躲开了你的攻击。\n{result_desc}\n它的眼中闪过一丝嘲弄你感到一阵挫败感涌上心头。 ], explore_success: [ f你屏住呼吸小心翼翼地探索着周围的环境。\n{result_desc}\n你的心跳加速这或许是命运的安排。 ], explore_fail: [ f你在周围仔细搜索但只看到普通的树木和石头。\n{result_desc}\n也许需要换个方向探索。 ], talk_success: [ f你主动与对方交谈言语诚恳而有礼。\n{result_desc}\n对方的态度明显缓和你们的关系似乎更近了一步。 ], talk_fail: [ f你尝试与对方交流但似乎没有找到合适的话题。\n{result_desc}\n气氛有些尴尬。 ], default: [ f你{state.get(intent_target, 环顾四周)}。\n{result_desc}\n迷雾森林在月光下显得神秘而宁静风吹过树叶发出沙沙的声响仿佛在诉说着古老的传说。\n你深吸一口气继续你的冒险之旅。 ] } # 选择叙事模板 key f{intent}_{action_result} if key in narratives: narrative random.choice(narratives[key]) else: narrative random.choice(narratives[default]) # 更新消息历史 state[messages].append({ role: assistant, content: full_narrative, timestamp: datetime.now().isoformat() }) state[current_description] full_narrative # 清理临时变量 if action_result_desc in state: del state[action_result_desc] return state以上是初步搭建框架的核心逻辑并且前后端是完全能连上的能进行正常的交互但是功能非常简陋还需要后期丰富并且因为并没有真正加入数据库和接入Agent所以该系统并没有能够正常游玩也不能进行丰富的对话由于结构非常简陋其中结局触发的逻辑也并不完善会在几轮对话之后自动结束该故事。后期安排所以我们下一步的安排是尝试接入deepseek的API看智能体是否能在该框架中顺利运行然后丰富部分功能包括结局触发条件结局画廊人物初始状态选择以及NPC属性栏等。