Skip to content

PlotChoiceGenerator 选择生成器

字数
1203 字
阅读时间
5 分钟

AI 驱动的剧情分支选择生成器,每轮调用 LLM 生成 3 个不同级别的选择项。

基本用法

python
from nbot.plot import PlotChoiceGenerator

generator = PlotChoiceGenerator()
choices = await generator.generate(
    response_text=ai_reply,
    turn_context={"mood": "happy", "relationship": "好感度75"},
    session_context={"recent_topics": ["天气", "动漫"], "current_arc": "校园日常"},
    recent_history=[{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}],
    session_id="sess_abc",
)
# 返回: [{"level": "normal", "text": "...", "intent": "..."}, ...]

参数

参数类型说明
response_textstrAI 角色的回复文本
turn_contextdict当前轮次上下文(mood, relationship 等)
session_contextdict会话级别上下文(recent_topics, current_arc)
recent_historylist[dict]最近几轮对话 [{role, content}, ...],用于避免重复
session_idstr会话 ID,用于 token 统计

选择生成规则

三个级别

级别推进力度说明
normal小步顺势推进,带出新细节或下一步动作
important中步主动开辟新话题、转移场景或推进关系
turning_point大步时间跳跃、突发事件、新人物或重大决定

核心铁律

每个选择必须引入「上一轮还不存在的新东西」,从以下至少一类取材:

  • 新的行动目标或动作
  • 尚未聊过的新话题
  • 场景或地点转移
  • 时间推移或跳跃
  • 新出场人物或关系进展
  • 突发外部事件

严禁「原地打转」的写法:复述角色刚说过的话、反复追问同一件事、停留在同一场景情绪中纠缠。

文本要求

  • 必须使用第一人称或直接动作("我拉起你往门外走")
  • 禁止元指令句式("告诉她……""问她是否……")
  • 禁止第三人称描述("她/他/角色/玩家")
  • 建议 8-24 字

文本规范化(_normalize_choice_text)

自动将 AI 生成的元指令转换为第一人称可发送消息:

AI 输出转换后
"告诉她你想去看电影""我想告诉你,想去看电影"
"问她是否愿意一起去""我想问你,是否愿意一起去"
"向她表达你的感受""我想对你说,我的感受"
"握住她的手""我握住你的手"

转换规则:

  1. 前缀替换("告诉她" → "我想告诉你,")
  2. 代词替换("她的" → "你的","她" → "你")
  3. 动作前缀补 "我"("握住" → "我握住")

错误回退

AI 无响应或解析失败时,回退到默认选择:

python
_DEFAULT_CHOICES = [
    {"level": "normal", "text": "我拉起你,说走,带你去个地方。", "intent": "顺势推进"},
    {"level": "important", "text": "对了,我一直想跟你聊聊另一件事。", "intent": "主动开辟新话题"},
    {"level": "turning_point", "text": "几天后,我带着一个没人知道的消息回来找你。", "intent": "时间跳跃+突发事件"},
]

AI 调用

使用 ai_client.chat_completion() 发送请求,system prompt 包含完整的分支设计指令。token 用量通过 token_stats 模块记录(purpose: PURPOSE_PLOT)。

风格选择(v3.0.6+)

会话可通过 plot_choice_style 字段指定本次剧情选项的整体语气与取向。

预设风格

key名称说明
default默认不追加任何风格要求,沿用基础 system prompt
sweet甜蜜暧昧三个选择都带心动、亲近或试探,让关系更靠近一步
suspense悬疑紧张三个选择都带不安、悬念或压迫感,引入疑点与潜在危机
daily日常轻松三个选择自然、生活化、带点小趣味,不必强行制造大冲突
dramatic戏剧转折三个选择都倾向于制造强烈情节起伏,用意外、抉择、冲突推动剧情

自定义风格

除预设外,前端允许输入任意自定义风格描述(如"偏幽默吐槽""偏诗意抒情"),原样追加到 system prompt 的"本次剧情风格要求"段落中。

风格注入逻辑

风格要求由 _build_system_prompt(style) 在基础 system prompt 末尾追加:

text
【本次剧情风格要求】
<style 原文>
注意:风格只影响三个选择的语气与取向,上文"必须推进剧情"的铁律与文本写法要求仍然全部适用。

会话字段传递路径

text
Web 前端 (plotChoiceStyle)
  → socket_events  → req.metadata.plot_choice_style
  → ai_pipeline    → ctx.metadata.plot_choice_style
  → PlotChoiceGenerator.generate(style=...)
  → 持久化层 plot_choice_style 字段

AI 调用

使用 ai_client.chat_completion() 发送请求,system prompt 包含完整的分支设计指令。token 用量通过 token_stats 模块记录(purpose: PURPOSE_PLOT)。

页面历史