娱乐场景里,桌游是个很妙的方向:规则是确定性的,但玩法是开放性的。这正好是大模型和传统程序各干擅长的活——规则交给代码,扮演交给模型。这篇是一套可以直接落地的开源方案(我按自己搭 POC 的过程整理,组件都可替换)。
场景拆解:AI 桌游主持要干四件事
- 规则仲裁:玩家行动合不合法、结算对不对——必须确定性,错了玩家会掀桌。
- 剧情推进:开放式剧情、事件生成——需要生成能力。
- NPC 扮演:有性格的角色,会记仇、会合作——需要角色一致性。
- 语音与呈现:主持用「说」的,比「弹文字」有代入感一个量级。
核心设计原则:能写代码判定的,绝不让模型判定。 模型只负责开放部分,这是这个项目成败的分水岭。
分层架构(POC 版)
玩家端(Web/App)
│ WebSocket / REST
规则引擎(Python:状态机 + 规则代码) ← 仲裁、结算、胜负,纯代码
│ 合法的动作/事件(结构化 JSON)
编排层(LangGraph 或手写状态机) ← 回合流、剧情分支
├─ 剧情/事件生成 → LLM(开源模型自托管)
├─ NPC 决策 → LLM + 角色卡(Redis 缓存人设)
└─ 主持人播报 → LLM 生成台词 → 开源 TTS
护栏层:内容过滤 / 越狱检测 / 成本帽
开源选型表(都经过实际部署验证)
| 层 | 开源组件 | 备注 |
|---|---|---|
| 后端框架 | FastAPI + WebSocket | 回合制天然适合事件驱动 |
| 规则引擎 | 自己写(状态机 + 规则代码) | 别用 LLM 仲裁,理由见上 |
| 编排 | LangGraph 或手写状态机 | 简单场景先手写,别急着上框架 |
| 模型推理 | vLLM + Qwen 等开源模型 | 部署细节见私有化部署篇 |
| 角色/记忆 | Redis + 向量库(pgvector 起步) | 角色卡短记忆热缓存,长记忆向量化 |
| TTS 语音 | CosyVoice / Fish Speech / GPT-SoVITS | 中文主持腔,先跑通再谈音色 |
| 实时语音链路 | LiveKit(开源 WebRTC) | 比自拼 WebRTC 省一半工作量 |
关键设计点(踩过的坑)
- 结构化协议:规则引擎和 LLM 之间只传结构化的 JSON 动作,不让模型自由发挥流程。模型「出牌」用 JSON Schema 约束,解析失败算玩家操作无效,不阻塞游戏。
- 规则边界写死:把「不可变规则」(胜负、结算)做成代码单测覆盖;模型只输出「剧情描述」「NPC 台词」这类不改变游戏状态的内容。
- 状态一致性:游戏状态由规则引擎唯一持有,模型不持有状态——防止模型「记忆错乱」导致剧情与结算打架。
- 成本控制:每回合模型调用控制在 1–3 次(播报 + 事件),台词结果做缓存(同事件不重复生成);完整策略见AI 成本控制教程。
- 防越狱:主持人是「规则的话事人」,玩家会想办法让它放水——角色提示词要做对抗测试,护栏层放内容过滤(开源 moderation 模型自托管即可)。
落地顺序
- 先做文字版单机:规则引擎 + 剧情生成,验证「代码仲裁 + 模型演绎」的配合。
- 再加 NPC 与记忆(角色卡 + 短记忆),验证一致性。
- 最后加语音与多人房间——这时候才碰 LiveKit 和 TTS,别一开始就全栈开工。
落地清单
- 规则引擎纯代码实现并有单测(仲裁不出错)
- LLM 只输出结构化、不改状态的开放内容
- 每回合模型调用预算与缓存策略定好
- 角色一致性:短记忆热缓存 + 长记忆向量检索
- 越狱用例跑过一轮对抗测试
- 文字版验证通过再碰语音
同类场景的姊妹篇:虚拟陪伴类应用的技术方案 | 通用分层见 AI 应用参考蓝图