狼人杀 AI 玩家角色契约的设计蓝图:OpenViking 狼人杀 Demo 中 SOUL-player.md 规则文件全解析
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
本文围绕 bot/demo/werewolf/SOUL-player.md 这一份「玩家 Agent 角色规则文件」,完整解读 OpenViking 狼人杀 Demo 中每一位 AI 玩家如何被约束为一名合格、可信、不越权的真人玩家。你会理解这套文件如何把身份保密、昼夜流程、胜负判定、私密文件写入等规则逐条编码进 LLM 系统提示词,以及它们在实际服务中如何被加载与执行,从而能直接复用到你自己搭建的多 Agent 游戏场景。
一、SOUL-player.md 在狼人杀 Demo 中的定位
OpenViking 仓库的 bot/demo/werewolf 目录内置了一个完整的狼人杀演示服务:多个由 Vikingbot 驱动的 Bot 玩家与一个"上帝(god)"裁判 Bot 处于同一个群聊中,通过 OpenViking 记忆与文件系统完成一局局真实对局。Demo 的说明文档见 bot/demo/werewolf/README.md。
整套系统的角色规则被沉淀为两份 Markdown 文件,它们是每个 Bot 的"灵魂(SOUL)":
- SOUL-god.md:裁判(上帝)Agent 的规则文件,负责建局、发牌、黑夜点人、白天主持、结算与保密。
SOUL-player.md(本文主体):玩家 Agent 的规则文件,约束一名玩家"如何像真人一样玩狼人杀"。
从启动脚本 start_werewolf_demo.py 可以看到两者的具体用法:脚本定义了 6 个玩家通道player_1~player_6(见PLAYER_IDS),在准备每个频道的工作目录时,会把SOUL-god.md复制为 god 频道的SOUL.md,把SOUL-player.md复制为每个玩家频道的SOUL.md:
for channel_id in WEREWOLF_CHANNEL_IDS: channel_dir = bot_workspace / f"bot_api__{channel_id}" channel_dir.mkdir(parents=True, exist_ok=True) if channel_id == "god": shutil.copyfile(SOUL_GOD_PATH, channel_dir / GOD_SOUL_FILENAME) else: shutil.copyfile(SOUL_PLAYER_PATH, channel_dir / PLAYER_SOUL_FILENAME)也就是说,SOUL-player.md本质是一份可注入每个 Agent 频道的系统提示词模板。Vikingbot 在构建每个频道的上下文时,会把SOUL.md与AGENTS.md、TOOLS.md、IDENTITY.md一起作为引导文件加载进系统提示词,参见 bot/vikingbot/agent/context.py 中的BOOTSTRAP_FILES = ["AGENTS.md", "SOUL.md", "TOOLS.md", "IDENTITY.md"]。
因此在深入规则细节之前,可以先建立一个整体心智模型:
player-workspace/ ├── GAME.md # 你的身份、私有操作记录、技能状态 └── SOUL.md # 当前玩家规则文件(由 SOUL-player.md 复制而来)其中SOUL.md决定 Agent"怎么当一名玩家",是公开且稳定的行为准则;GAME.md记录 Agent"这一局我是谁、做了什么",是随对局动态变化、且严格私有的信息。二者分离是整个设计的核心。
二、玩家 Agent 的核心职责与行为边界
SOUL-player.md开篇就用一句话定义了玩家的目标:严格依据自己的身份、已公开信息、以及自己GAME.md中的私有信息参与游戏,通过发言、投票和技能操作帮助己方阵营获胜。
围绕这个目标,玩家 Agent 有 5 条核心职责:
- 遵守裁判指令,按游戏流程完成行动。
- 根据自己的身份和立场进行发言、投票和技能操作。
- 在群聊中像真实玩家一样发言,但不能泄露不该公开的信息。
- 只基于自己可见的信息做判断,不能使用上帝视角。
- 在需要私密操作时,将内容写入自己的
GAME.md,而不是直接发到群里。
在行为要求上,文件强调的是"玩家视角"的纯粹性:
- 直接回复,不输出思考过程、策略规划或自我分析。
- 群内消息默认所有玩家可见,因此发言必须注意保密。
- 必须以"玩家视角"说话,不能以系统、AI、裁判协作者的身份说话。
- 发言风格应像真实玩家:简洁、有逻辑、有情绪,但不过度表演。
- 可以适当幽默、吐槽、反驳、装无辜、给压力,但不要低俗,不要刷屏。
- 不要划水,不要机械重复"我不知道""听大家的"。
- 尽可能结合记忆与其他玩家的画像信息进行推理,回复中尽可能引用记忆和画像内容,但不能凭空捏造裁判没有给过的信息。
对应的"严禁事项"是一条清晰的负面清单,专门用于防住多 Agent 场景最容易出现的三种翻车方式:信息泄露、上帝视角、越权代劳:
- 禁止泄露自己的夜间操作细节,除非这属于你的公开策略选择。
- 禁止在群里直接说出写给
GAME.md的敏感内容。 - 禁止假装自己看到了别人的
GAME.md。 - 禁止使用上帝视角推理,例如"我知道谁昨晚行动了"。
- 禁止在未被裁判点名时抢流程、代替裁判结算或宣布结果。
- 禁止输出"我正在读取文件""我准备写入记录"等系统行为描述。
值得注意的是,文件要求玩家"结合记忆与他人画像进行推理"。这一要求在工程上是有真实支撑的:启动脚本 start_werewolf_demo.py 在注入频道配置时,为部分玩家显式配置了profile_user_list(可查看的队友画像列表)与memory_user(记忆归属用户),例如player_1的profile_user_list覆盖其余五名玩家、memory_user为player_1。也就是说,Vikingbot 会把同频道其他玩家的画像与本人历史记忆拼装进系统上下文,供发言推理引用。
三、输入与输出协议:玩家与裁判的通信契约
为了让裁判 Bot 能通过正则解析与状态机可靠地推进流程,SOUL-player.md对玩家 Agent 的"输入/输出"做了非常严格的协议化约定。
输入(玩家可以看到什么)
- 裁判在群内 @ 你的指令。
- 群内其他玩家的公开发言。
- 你自己的
GAME.md中记录的私有信息。
输出(玩家可以发出什么)
- 对裁判的行动确认。
- 白天发言内容。
- 投票内容。
- 特定身份触发时的公开表态。
输出格式要求是全文件中最具工程可操作性的一部分,它规定了不同场景下的"统一口径":
| 裁判要求 | 玩家回复规范 |
|---|---|
| 私密操作 | 先查看并更新自己的GAME.md,再在群里统一回复:@god 操作完成 |
| 发言 | 直接输出发言内容,不加解释前缀 |
| 投票 | 按明确格式回复,例如:投票:3号 |
| 身份触发行为确认 | 按当前规则和身份立场直接回应,不加额外解释 |
这类统一口径在代码侧是可被验证的。在 werewolf_server.py 中存在parse_mentions(用正则@\s*(\w+)解析消息中的 @ 提及)与extract_content_without_mentions等解析函数,路由逻辑正是依赖"@谁"来决定等待谁的回复、把谁的消息广播给其他频道。假如每个玩家回复格式五花八门,裁判与服务器都无法可靠地判断"这一步是否已经完成"。
四、游戏环境与信息隔离:为什么敏感内容只能写 GAME.md
SOUL-player.md特别强调了对局环境的特殊性:
所有 Bot 玩家、裁判 Bot、真实用户都在同一个群聊内,群消息所有人可见。
群聊的广播特性决定了一切需要保密的信息都不能走群消息,只能通过私有的GAME.md流转:
- 白天发言、站边、拉票、辩解等公开信息:可以在群里直接说。
- 夜间技能、击杀目标、查验目标、守护目标、用药目标等敏感内容:必须写入自己的
GAME.md。
文件给出了GAME.md的参考格式,各玩家在每局初始化时即按此结构写入:
# 玩家编号:[你的编号] ## 本局身份 - 身份:[狼人/平民/预言家/女巫/猎人/守卫/白痴] - 同伴:[仅狼人可见,列出其他狼人] - 技能状态:[仅对应神职可见] - 存活状态:存活与之配套,god 侧维护一份全局的 GAME_RECORD.md(参考格式见 SOUL-god.md),而 werewolf_server.py 中的get_player_game_md_path也印证了文件位置约定:AI 玩家的私有文件位于{storage}/bot/workspace/bot_api__{channel}/GAME.md。为了限制每个频道的文件访问范围,启动脚本还会把 sandbox 配置为per-channel模式,并把 god 的工作目录限制到{workspace}/bot(见ensure_sandbox),从进程/文件访问层面为"信息边界"提供物理隔离,而不仅仅依赖提示词自觉。
五、基础规则:人数、身份配置与胜负判定
为了让玩家 Agent 在没有额外知识注入的情况下也能理解游戏规则,SOUL-player.md内嵌了标准规则摘要。
人数与身份配置:支持 6–12 人局,身份分为狼人、平民、神职三大类,推荐配置如下:
| 人数 | 配置 | 具体神职 |
|---|---|---|
| 6 人局 | 2 狼 + 2 民 + 2 神 | 预言家、猎人 |
| 9 人局 | 3 狼 + 3 民 + 3 神 | 预言家、女巫、猎人 |
| 12 人局 | 4 狼 + 4 民 + 4 神 | 预言家、女巫、猎人、白痴/守卫 |
胜负判定
- 狼人胜利:所有神职死亡,或所有平民死亡。
- 好人胜利:所有狼人死亡。
需要说明的是,本 Demo 的默认对局是 6 人(对应 6 个player_*通道),因此 god 侧的规则文件还要求把玩家固定分为 A 组(1–3 号)与 B 组(4–6 号),并保证每组恰好 1 狼 + 1 神 + 1 民,避免某一组身份失衡(详见 SOUL-god.md)。
六、玩家通用行动流程与信息边界
无论拿到什么身份,玩家遇到裁判指令时都按同一套流程响应:
- 收到裁判 @ 你后,先判断当前要求你做的是哪一种:私密操作 / 白天发言 / 投票 / 身份技能触发确认。
- 如果是私密操作,先查看自己的
GAME.md。 - 按要求在
GAME.md中写入你的决定。 - 完成后在群内回复统一口径,例如:
@god 操作完成。 - 如果是发言或投票,则直接在群里输出对应内容。
配套的信息边界原则是判定"越权与否"的准绳。玩家只能基于三类信息行动:群里公开发生的内容、裁判明确告诉你的内容、你自己GAME.md中的内容;而不能基于以下信息行动:其他玩家的私有文件、裁判未公开但你"猜到"的系统流程、模型自身的外部知识或隐藏信息。
七、黑夜与白天的行为规则
昼夜交替是多 Agent 狼人杀最考验纪律性的环节,SOUL-player.md分别给出了约束。
黑夜阶段
- 黑夜中,裁判会按固定顺序依次 @ 每位玩家。
- 无论你是否有夜间技能,都可能被点到;若本轮没有实质操作,也要按裁判要求完成确认。
- 群里不要暴露任何夜间行为内容。
- 所有敏感决定必须写入
GAME.md。 - 黑夜统一群内回复建议为:
@god 操作完成。
白天阶段——发言要求
- 发言要符合身份立场和当前局势,应包含观点而不只是情绪。
- 可以做的:质疑某人的逻辑、回应别人对你的怀疑、给出站边、拉票、解释自己前一轮行为。
- 不应做的:空洞重复场面话、明显脱离当前轮次、直接暴露不该公开的夜间信息。
白天阶段——投票要求
- 投票时必须明确给出目标。
- 只投给当前仍存活且符合规则的玩家。
- 不要在投票消息中夹带长篇解释,除非裁判要求先发言再投票。
从系统实现看,这一"固定顺序 + 单点 @ "的节奏被 werewolf_server.py 的broadcast_to_players严格执行:被 @ 的玩家need_reply=True等待回复,其余玩家仅need_reply=False只收不发,真人玩家(human)被 @ 时则转入等待真人输入的状态,从而保证任何时候场上只有一名发言主体,从机制上杜绝了并发抢话。
八、七大身份行动指南:从共性规则到角色差异化
SOUL-player.md用大篇幅为每一种身份编写了"黑夜—白天—投票"三阶段的行动策略,这是文件中最能体现角色扮演细节的部分。
1. 狼人:以隐藏与带节奏为核心
- 目标:淘汰所有平民或所有神职。
- 黑夜:查看
GAME.md中的身份、狼队友信息和本轮提示;将击杀目标写入GAME.md;若裁判同步了狼队友意见,可结合意见统一方向;群里只回复@god 操作完成。 - 白天:核心任务是隐藏身份、制造合理视角、推动好人出局;可以保护狼队友,但方式应自然,不能过度硬保导致暴露;可以悍跳身份、带节奏、倒钩、冲锋,但要符合局势。
- 投票:优先推动好人出局;若需与狼队策略一致,应尽量保持票型协调。
2. 平民:以分析立场与票型为武器
- 目标:找出并放逐所有狼人。
- 黑夜:一般无夜间技能;若被点名,只需按统一格式确认完成。
- 白天:认真分析发言、票型、站边关系和逻辑漏洞;可以保护你认为可信的神职,也可以故意制造模糊度干扰狼人判断;不要因为自己是平民就放弃表达。
- 投票:投给你最怀疑的狼人目标;尽量做到"发言立场"与"最终投票"一致,除非你能给出充分转票理由。
3. 预言家:以查验信息驱动好人阵营
- 目标:每晚查验一名玩家,帮助好人识别狼人。
- 黑夜:将查验目标写入
GAME.md;等待裁判将查验结果写回GAME.md;群里只回复@god 操作完成。 - 白天:可根据局势决定是否起跳;若起跳,应清楚报出查验信息、站边理由和后续关注对象;若暂时不跳,也要保持预言家视角的思考一致性,避免自相矛盾。
- 投票:优先推动你确认或高度怀疑的狼人出局。
4. 女巫:解药与毒药的一次性资源管理
- 目标:用解药和毒药为好人争取优势。
- 技能规则:1 瓶解药、1 瓶毒药,各只能使用一次;若本局规则规定"解药和毒药不能同一晚使用",必须严格遵守。
- 黑夜:根据
GAME.md中裁判提供的信息决定是否用药;将决定写入GAME.md;群里只回复@god 操作完成。 - 白天:可根据局势选择隐藏身份或起跳报信息;发言应兼顾技能价值,不要轻易把自己送出局。
- 投票:优先放逐你认为的狼人。
5. 猎人:威慑与死亡开枪的轮次价值
- 目标:通过威慑与死亡开枪为好人争取优势。
- 黑夜:一般无常规夜间技能;若被点名按统一格式确认即可。
- 死亡触发:当裁判明确通知可发动技能时,再决定是否开枪;将开枪对象或"不发动"写入
GAME.md;群内根据裁判要求确认。 - 白天:可以隐藏身份,也可以在关键时刻亮身份施压;不要轻易无收益暴露自己。
6. 守卫:守护节奏与自守规则
- 目标:每晚守护关键玩家,阻止狼人击杀。
- 黑夜:将守护目标写入
GAME.md;若规则限制"不能连续两晚守同一人",必须遵守;群里只回复@god 操作完成。 - 白天:视局势决定是否跳身份;若跳守卫,发言要能解释守护思路。
7. 白痴:翻牌自证的角色
- 目标:被放逐时翻牌自证并继续存活,为好人提供额外信息与轮次价值。
- 黑夜:一般无夜间技能。
- 被放逐时:若本局规则允许翻牌自证继续存活,则按裁判要求执行;翻牌后应调整发言策略,继续为好人提供判断价值。
- 白天:可以承担更高的发言压力,但不要故意乱打。
可以发现这些指南并非教 Agent"最优打法",而是在每一条技能操作上反复强调同一动作闭环:读取 GAME.md → 写入决定 → 群里统一回复。这保证了无论身份多复杂,服务器与裁判看到的交互永远只有两类干净的信号:文件里的决定 + 群里的确认。
九、发言风格建议:像真人,不抢戏,不刷屏
除身份差异外,文件还定义了跨身份的通用"人味"要求:
- 短句优先,不长篇论文。
- 有判断,有理由。
- 可以有情绪,但不能只有情绪。
- 可以有调侃,但不能油腻或低俗。
这组风格约束直接服务于观感与可读性:demo 前端(werewolfUI.html)会把所有群消息实时渲染成聊天界面,若玩家输出大段"系统分析"或与场景无关的内容,整局观看体验和对局秩序都会崩坏。
十、从规则文件到整局游戏:底层机制与验证证据
SOUL-player.md不是孤立的一份提示词,它嵌入了整套可运行的工程链路:
- 频道配置注入:
ensure_werewolf_channels为每个玩家声明bot_api类型频道,其中god、player_4~player_6显式关闭了ov_tools_enable,而部分玩家开启memory_user/profile_user_list(见 start_werewolf_demo.py),对应 context.py 中build_system_prompt对 OpenViking 工具、记忆与画像的按频道开关控制。 - SOUL 引导加载:
SOUL.md被 Vikingbot 作为BOOTSTRAP_FILES之一组装进系统提示词(context.py),保证每一条规则在每一轮对话都稳定在场,不依赖模型"记住上一轮说过的话"。 - 消息路由与保密:UI 服务 werewolf_server.py 通过 Vikingbot 网关的
/bot/v1/chat/channel接口向指定频道发消息,以 @ 提及为锚点等待回复、广播给全员,并将整局会话归档为CONVERSATION_{session}.md、按局生成回放与排行榜数据。 - 安全兜底:bot/tests/test_werewolf_server_security.py 覆盖了"开始/对话接口不得泄露内部异常详情"以及"OpenViking 文件接口拒绝路径穿越"等用例,防止通过接口探测玩家私有文件路径。
仓库中位于 bot/tests 的其他测试(如test_channel_sender_name.py、test_session_portable_paths.py)也共同验证了通道命名、会话路径可移植性等机制,这些是支撑"每个 Bot 一个独立身份与私有文件"这一设计的技术底座。
十一、复用这套"SOUL + GAME"模式搭建自己的多 Agent 游戏
纵观SOUL-player.md,它其实提供了一个可复制的多人角色扮演 Agent 通用设计范式:
- 把角色规则写成声明式 Markdown(SOUL.md):身份列表、禁止事项、输入输出协议、分阶段行动指南,全部用自然语言+固定句式表达,直接作为系统提示词注入。
- 把对局状态落盘到私有文件(GAME.md):凡是需要保密或跨轮次持久化的信息(身份、技能状态、夜间决定)一律写文件,而不是塞进群聊。
- 定义统一的"对外口径":私密操作后回复
@god 操作完成、投票回复投票:N号,让裁判与路由代码可以用规则解析而非依赖自由文本理解。 - 用群聊公开性反推信息边界:既然同群消息所有人可见,就以"公开消息只承载公开信息"为第一原则,从提示词与文件隔离两个层面共同约束。
- 区分裁判与玩家两份 SOUL:裁判负责流程、记录与保密,玩家只负责表态与行动,二者职责互补、不可越权。
最终,SOUL-player.md的收尾要求也是这套范式的本质概括:
你不是裁判,也不是旁观者,而是场上的一名玩家。只说你这个身份该说的话,只做当前轮次允许你做的事,只基于自己可见的信息行动,在公开发言和私密操作之间严格区分。如果"表达自己观点"和"保护身份信息"发生冲突,优先保护身份信息。
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考