【教程】双模型架构——如何让一个AI当嫌疑人,另一个AI当参谋

05/1238 浏览开发心得
前言
在前两篇文章中,我分享了LLM接入游戏的架构设计和Prompt调优技巧。这篇要讲的是整个项目最关键的架构升级——双模型协作。
问题的起点很简单:我的审讯游戏需要给玩家提供“推荐话术”选项。最初我让一个LLM同时做两件事:扮演嫌疑人,同时生成警官视角的建议。结果它经常搞混自己是谁,推荐话术以嫌疑人的口吻输出。
如果你也在做AI对话游戏,而且需要AI同时做“角色扮演”和“出谋划策”,这篇文章会给你一个完整的解决方案。
一、单模型时代的噩梦
最初的架构
只有一个LLM,承担三个任务:
- 扮演嫌疑人马克·威尔逊,生成对话
- 生成3条警官视角的推荐话术
- 建议隐藏数值变化(恐惧、信任、防线)
它返回的JSON长这样:
{
  "npc_dialogue": "我什么都不知道...",
  "suggested_options": ["继续逼问", "换个角度", "出示证物"],
  "hidden_changes": { "fear": 10, "trust": -5 }
}
看起来没问题,但实际测试时推荐话术经常翻车。
翻车现场
玩家出示了通话记录,嫌疑人刚说完“那些电话是船长让我打的”。
然后推荐话术里出现了这样的选项:
- “我只是听命行事,不是主谋”
- “(发抖)我不知道你在说什么”
- “我需要律师”
全是嫌疑人的口吻。玩家看到选项直接懵了——我到底是谁?
这就是单模型架构的先天缺陷:让一个演员同时当导演,它一定会串台。LLM在生成嫌疑人的对话时,已经进入了“我是马克”的第一人称状态。接下来让它以警官视角生成建议,它需要立即切换身份。但上下文里全是马克的台词和情绪,它很难跳出来。
我试过各种Prompt约束——在System Prompt里写“建议必须是警官视角”,加正反面示例,甚至在服务端做正则过滤,把以“我”开头的选项自动丢弃。但都是治标不治本。同一个模型在两种身份之间反复横跳,混淆是必然的。
二、双模型架构:让专业的人做专业的事
核心思路很简单:雇两个AI,各干各的。
模型A(嫌疑人):只负责扮演马克·威尔逊。System Prompt纯角色设定,不生成任何建议,不参与数值计算。
模型B(警官参谋):只负责生成推荐话术。System Prompt是审讯策略顾问,完全从警官视角出建议。它不知道马克的内心想法,只知道马克刚才说了什么。
通信流程
玩家输入(自由文本或选择的话术)
→ 服务端做基础数值修正
→ 服务端调用模型A,传入:当前感觉 + 角色设定 + 对话历史 + 玩家输入
→ 模型A返回:嫌疑人的对话、姿态、内心独白、新情绪
→ 服务端用模型A的返回,调用模型B,传入:马克刚才的回应 + 案件背景 + 当前阶段 + 对话历史
→ 模型B返回:3条推荐话术(纯警官视角)
→ 服务端组合A和B的结果,发给客户端
关键点:模型B的输入里用的是模型A的输出文本,而不是让B去揣测A的心理。B看到的只是“嫌疑人说了什么话”,然后基于这句话给出警官接下来可以说什么。这是两个独立的工作流,互不干扰。
模型B的System Prompt(警官参谋)
你是一名资深审讯策略顾问。你正在旁观一场审讯。
嫌疑人:马克·威尔逊,黑帮财务顾问,掌握2亿赃款线索。
弱点:女儿索菲,对船长的恐惧。
你的任务:
根据嫌疑人的最新回应和当前审讯形势,为审讯警官提供3个后续话术建议。
规则:
- 所有建议必须是警官可以直接对嫌疑人说出的原话
- 建议必须具体,贴合案情和嫌疑人当前心理状态
- 绝对禁止以嫌疑人口吻(“我”)生成建议
- 第1条:直接回应当前对话的追问
- 第2条:可以推进案情的替代问法
- 第3条:保底推进话术
当前审讯状态:揭露度30%,嫌疑人情绪紧张,回合5/25。
模型B的这个设定让它完全不会混淆身份。它的上下文里没有角色扮演的内容,只有“旁观的顾问”这一个身份。它生成的话术自然全部是警官视角——因为这就是它唯一被赋予的视角。
三、实际效果对比
同一个场景,玩家出示了通话记录后。
单模型时代(模型A同时生成建议):
嫌疑人回应:“(眼神躲闪)那些电话...那是船长让我打的,我没得选。”
推荐话术:
- “我只是听命行事,不是主谋” ← 嫌疑人视角,完全错误
- “你能不能给我一个机会?” ← 还是嫌疑人视角
- “继续审问” ← 这一条碰巧对了
双模型时代(模型A扮演,模型B生成建议):
嫌疑人回应:“(眼神躲闪)那些电话...那是船长让我打的,我没得选。”
推荐话术:
- “你没得选?那为什么通话记录显示你主动拨出去过?”
- “船长让你联系阿鬼,具体让你说什么?”
- “如果你只是听命行事,那么把船长的命令原话告诉我。”
三条全是警官视角,而且紧贴马克刚说的“船长让我打”这个点,追问方向有递进感。这就是专职的差别——模型B的脑子里只有“怎么帮警官问出更多信息”,没有“我在扮演马克”的任何残留。
四、双模型架构的额外收益
收益1:嫌疑人表演质量提升
模型A卸掉了“生成建议”和“计算数值”的负担,专注度全放在角色扮演上。实测效果是对话更长、更有层次、更有身体反应描写。因为它不再需要在角色的第一人称和参谋的第三人称之间切换,整个上下文都是角色。
收益2:成本只增加约30%
模型B的输出很短(只有3条话术建议,每条不超过30字),每次调用消耗的Token远少于模型A。实测下来双模型的总成本只比单模型增加了约30%,不是翻倍。用百炼平台的免费额度完全可以覆盖。
收益3:各自独立调优
模型A的Prompt调优和模型B的Prompt调优是完全独立的。你可以给A换成角色扮演能力更强的模型(比如qwen-plus),给B换成成本更低、速度更快的模型(比如qwen-turbo),互不干扰。A的temperature可以设高(0.9)增加表演多样性,B的temperature设低(0.6)保证建议稳定可靠。
收益4:模型A出错不影响模型B
即使模型A调用失败(返回兜底文本“嫌疑人沉默不语”),模型B仍然能基于这个兜底文本生成合理的建议(“打破沉默,换个话题试试”)。而单模型架构下一个错误会导致对话和建议同时失败。
五、模型池共享:多个模型怎么分配
我在百炼平台接入了约179个有免费额度的模型。双模型架构下,所有模型共用一个模型列表和共用索引。
关键决策:不要让A和B各用一个独立的模型列表。
为什么?因为维护两套列表很麻烦:A用哪个模型、B用哪个模型、哪个模型额度用完了需要从两套列表里分别删除。而共用一个列表的话,A用第一个模型时B也用同一个,额度耗尽后自动跳到下一个,两边同步,没有任何额外维护成本。
过滤多模态模型:百炼上有部分模型是图文识别专用,纯文本请求会返回400错误。初始化时自动过滤掉这些模型,过滤后的列表A和B共用。
新模型追加:百炼不定期上架新模型,直接在model_list末尾追加模型名,重启服务端生效。不需要分配方向,不需要区分角色。
六、双模型架构成败的关键点
关键1:模型B的System Prompt必须极其严格
建议格式规则、保底分配规则(1条直接回应+1条替代问法+1条保底推进),以及大量正反面示例。绝对不能在B的Prompt里出现任何嫌疑人视角的句子,哪怕是反面示例,也要标注“以下为错误示范,绝对禁止”。
关键2:两个模型的调用顺序不能乱
必须是先A后B,不能反过来。因为B需要A的输出作为输入。如果并行调用,B就不知道马克刚才说了什么。
关键3:兜底文本要有温度
A失败时的兜底:“嫌疑人沉默不语。”
B失败时的兜底:“继续追问。”“换个角度问。”“保持沉默,观察他的反应。”
千万不能用空字符串或null,否则客户端会白屏。
关键4:A和B的对话历史管理规则不同
A需要保留最近6轮对话历史(为了角色扮演的连贯性)。
B建议只保留最近3轮对话历史(因为参谋只需要知道当前上下文,太长的历史反而干扰它)。这个差异能进一步降低B的Token消耗。
七、总结
如果你在做一个需要AI同时进行“角色扮演”和“出谋划策”的游戏,双模型架构是性价比最高的方案。不要试图用一个模型做所有事——给LLM减负,把不同性质的任务分配给专职的模型,效果会好得多。
核心经验:
1. 扮演角色的归模型A,出谋划策的归模型B,界限越清晰效果越好
2. 共用模型池,共用索引,维护成本最低
3. 两个模型的Prompt调优完全独立,可以根据各自需求选择不同模型和参数
4. 如果有精力,甚至可以再加一个Censor模型进行审核
猜你想搜
taptap 制造ai审讯游戏教程
3
1
3