For the complete documentation index, see llms.txt. This page is also available as Markdown.

会话生命周期

了解 ConvaiCharacter 会话如何在状态之间转换、会话 ID 存储在哪里,以及如何配置重连和恢复对话行为。

每个 ConvaiCharacter 场景中的都与 Convai 保持一个独立会话。该会话会跟踪角色是否已连接、当前状态是什么,以及——在启用持久化时——你上次连接时处于哪段对话。理解会话如何创建、持久化和恢复,可以让你在训练模拟、交互式体验和游戏中构建可靠、可恢复的角色交互。


会话状态机

每个角色会话会经历以下状态。

状态
含义

未连接

0

没有活动会话。初始状态,以及正常断开后的最终状态。

连接中

1

连接尝试进行中。从未连接过渡到已连接。

Connected

2

会话处于活动状态。音频流和对话都在运行。

重新连接中

3

连接已丢失。SDK 正在尝试自动重新建立连接。

正在断开连接

4

正在进行优雅关闭。从已连接过渡到未连接。

错误

5

不可恢复的错误。需要人工干预才能重新连接。

你会通过以下方式接收状态转换: SessionStateChangedRelayData 事件,通过 ConvaiSessionEventRelay。参见 事件系统 来了解如何订阅。


按角色的会话

每个 ConvaiCharacter 都有自己独立的会话。会话不会在角色之间共享。在多角色场景中,每个角色都会独立连接和断开——会话 ID 绑定到 Inspector 中设置的角色 ID 字符串(而不是场景名或对象名),重连策略按角色生效,并且某个角色上的会话错误不会影响其他角色。

ConvaiSessionData 是持久化会话存储,它将每个角色映射到其当前会话标识。它会在启动时自动从磁盘加载,并在每次更改时写入到 {Application.persistentDataPath}/Convai/sessions.json ——会话 ID 无需任何额外设置即可在应用重启后保留。

方法
描述

GetSessionId(characterId)

返回该角色当前的会话 ID,或者 null (如果不存在)。

StoreSessionId(characterId, sessionId)

为该角色存储一个会话 ID,并立即保存到磁盘。

ClearSessionId(characterId)

移除某个角色的会话 ID 并保存。

ClearAllSessionIds()

移除所有已存储的会话 ID 并保存。

GetAllSessionIds()

返回所有当前角色→sessionId 映射的只读快照。

ConvaiSessionData 是一个单例。数据存储在 {Application.persistentDataPath}/Convai/sessions.json ,并在应用重启后持续保留。如果你需要从头开始,请显式调用 ClearAllSessionIds()


会话持久化

当会话 ID 被持久化后,SDK 可以在下一次连接时恢复之前的对话——角色会记住先前交互的上下文。

哪些会持久化,哪些会重置

重连时
行为

会话 ID

通过以下方式持久化: ConvaiSessionData ——支持恢复

对话历史

由 Convai 管理;当会话 ID 有效时会恢复

进行中的音频

重置——任何流中的音频都会被丢弃

活动轮次状态

重置——该轮次会重新干净开始

模块状态(例如情绪)

重置——模块会在重连时重新初始化

默认持久化栈

SDK 通过以下方式提供可插拔的持久化层: ISessionPersistence ,适用于需要自定义后端存储的项目(加密存储、云存档、数据库)。默认栈如下:

会话 ID 以如下格式的键存储: convai.session.<characterId>.

替换持久化存储

实现 IKeyValueStore 即可使用任何后端存储——数据库、加密存储、云存档系统。 PlayerPrefsKeyValueStore 会在内部将所有读写调度到 Unity 主线程;如果你的后端存储有线程限制,也请采用同样的线程安全模式。

通过以下方式注册: ConvaiRuntimeBuilder:


重连策略

ReconnectPolicy 控制当连接意外断开时 SDK 的行为。

字段
类型
默认值
描述

RoomRejoinTtlSeconds

double

60

SDK 在断开后可以重新加入现有房间的时间窗口(秒)。超过该窗口后,会创建一个新房间。

ResumePolicy

ResumePolicy

ResumeIfPossible

控制 SDK 是否尝试通过以下方式恢复之前的对话: character_session_id.

MaxReconnectAttempts

int

3

在会话进入以下状态之前允许的自动重连最大次数: 错误 状态的聊天机器人。

SpawnAgentOnRejoin

bool

true

重新加入现有房间时是否重新生成 AI 代理。

StartWaitTimeoutMs

int

5000

连接 Start() 阶段在被视为失败之前的超时时间(毫秒)。

AutoMicStartDelaySeconds

float

0.5

连接后等待多长时间再启动麦克风(秒)。可防止在会话完全就绪前捕获音频。

ResumePolicy 选项

行为

AlwaysFresh

始终开启全新对话。角色不会记住上一个会话。

ResumeIfPossible

尝试恢复之前的对话。如果会话已过期或恢复失败,则回退到全新会话。

AlwaysResume

始终恢复。如果恢复失败,连接就会失败——不会回退到全新会话。

预设策略

预设
描述

ReconnectPolicy.Default

60 秒 TTL, ResumeIfPossible,3 次尝试,麦克风延迟 0.5 秒

ReconnectPolicy.AlwaysCreateNew

不尝试重新加入。始终创建新房间和全新会话。


使用示例

示例 1:医疗训练模拟——网络中断后恢复

学习者正在评估中途时网络中断。连接恢复后,患者角色会恢复同一段对话——不会丢失上下文。

预期结果: SDK 会在 2 分钟窗口内自动重试最多 5 次。如果 Convai 端的会话仍然有效,对话会从中断处继续。如果会话已过期,角色会开启一段全新对话,而不是卡住。


示例 2:企业入职自助终端——始终全新的对话

每位接近终端的新员工都应从头开始,并且不记得之前的用户。 AlwaysFreshAlwaysCreateNew 确保每次都从干净状态开始。

为了确保在下一次会话开始前移除前一位用户的数据:

预期结果: 每位新用户都会开始一段完全全新的对话。角色不会记住之前的交互,这对于共享自助终端部署是正确的。


示例 3:在训练模拟中处理错误状态

当所有重连尝试都用尽后,会话会进入 错误 状态。应将其呈现给培训主持人,并允许手动重试,而不是静默卡住。

预期结果: 当会话进入 错误 状态时,错误面板会出现。培训主持人点击“重试”,即可在不重启模拟的情况下尝试新的连接。


故障排查

症状
可能原因
修复

会话在断开后一直停留于 错误 状态

AlwaysResume 无法在后端恢复已过期的会话

切换为 ResumeIfPossible;调用 ClearSessionId(characterId) 以移除陈旧的会话 ID,然后重新连接

尽管 ResumeIfPossible

之前的 ClearAllSessionIds() 调用清空了会话文件,或者运行之间角色 ID 发生了变化

请验证 characterId 字符串在各次运行之间保持稳定;检查 {persistentDataPath}/Convai/sessions.json

会话一直卡在 连接中 状态,永远不变

StartWaitTimeoutMs 未针对慢速网络配置;或防火墙阻止了传输

增加 StartWaitTimeoutMsReconnectPolicy;验证对 Convai 端点的网络访问

重连循环始终失败;会话最终进入 错误

MaxReconnectAttempts 已耗尽

订阅 ConvaiSessionEventRelay.OnSessionStateChanged 并将错误展示给用户;在用户确认后手动调用重连

两个角色共享了同一个会话 ID

Inspector 中的角色 ID 字符串相同

为每个角色分配唯一的角色 ID ConvaiCharacter 在场景中


下一步

现在你已经了解角色会话如何创建、状态转换如何工作、会话 ID 如何在重启间持久化,以及如何配置重连行为。接下来阅读轮次切换模式,了解 SDK 如何检测语音输入,然后阅读事件系统,学习如何在场景脚本中订阅会话和角色事件。

轮流发言模式事件系统

最后更新于

这有帮助吗?