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

排查动态上下文问题

修复 Convai Unity SDK 中常见的动态上下文问题,包括更新丢失、响应延迟,以及重置行为未清除所有内容。

Relay 和 tracker 流程中的大多数 Dynamic Context 问题都来自三类之一:在角色进入对话之前发起的调用、产生意外响应的反应模式,或者一个 ConvaiDynamicContextRelay 无法解析一个 ConvaiCharacter。请按下面的一线排查清单逐步检查——大多数问题会在前两三步内解决。

第一线调查

1

检查 Unity 控制台中的警告

Dynamic Context 警告由 ConvaiCharacter ——前缀带有角色名称——以及由 ConvaiDynamicContextRelay。打开控制台(窗口 → 常规 → 控制台)并查找提到 动态上下文 或 分配一个 ConvaiCharacter.

如果你看到警告,请在下面的 控制台日志参考 表中找到准确消息并按列出的修复方法操作。

2

使用示例调试中心隔离问题

在调试你自己的集成之前,先确认 Dynamic Context 本身正常工作。导入 口型同步示例 从 Package Manager 导入并打开其场景——示例包含一个 示例调试中心 ,并传入一个 上下文 抽屉,用于将状态、事件和注意对象更新发送到场景的 ConvaiCharacter 而无需自行连接 UI。

如果角色通过调试中心能正确响应,问题就在你自己的中继或脚本设置中——而不是 Dynamic Context 本身。

3

验证角色引用已解析

选择 ConvaiDynamicContextRelay 组件在 Inspector 中。

  • 启用 Auto Resolve Character: 确认 ConvaiDynamicContextRelay 和 ConvaiCharacter 位于 同一个 GameObject 上.

  • 禁用 Auto Resolve Character: 确认 Character 字段已分配引用。

如果两者都无法解析角色,则每次调用都会触发 On Skipped 并记录 分配一个 ConvaiCharacter 或启用 Auto Resolve Character。

4

检查角色当时是否处于对话中

跟踪调用—— SetState, SetStates, AddEvent, RemoveState, Reset, SetCurrentAttentionObject,以及 ClearCurrentAttentionObject ——会立即在本地暂存,甚至在对话开始之前也是如此。一旦角色就绪,已暂存的批次会自动送达 Convai,因此在 Awake() 或 Start() 中发起的调用无需额外处理。

Apply() 是例外:它不会暂存。在角色不处于对话中时发起的调用会被丢弃,Convai 会记录 无法应用原始动态上下文更新:不在对话中.

5

检查批处理窗口和反应模式

在跟踪的更改被暂存后,SDK 会等待 ConvaiCharacter.DynamicContextBatchDelaySeconds ——默认 0.5 秒——再发送,因此多次快速更改会合并为一次更新。调用 Flush() 在 IConvaiDynamicContext,或者启用 立即刷新 中继上的该选项,以便无需等待即可发送已暂存的更改。

如果角色在你预期 静默 抑制回复时却作出了响应,那么同一批处理窗口中暂存的另一项更改很可能请求了更强的反应—— MustRespond 优先于 自动,它的优先级高于 静默,整个批次都会采用它。

常见问题

症状
可能原因
修复方法
验证

角色从不引用通过 SetState

新值与该状态的当前值相同—— SetState 在没有变化时是空操作

确认值确实发生了变化;使用 TryGetStateValue 首先

TryGetStateValue 在使用一个真正不同的值调用后会返回新值

在 Awake() 或 Start() 中发起的调用似乎没有效果

预期行为——跟踪调用会在本地暂存,并在角色就绪后自动刷新

跟踪方法无需任何操作;避免 Apply() 在对话开始之前使用,因为它不会暂存

对话开始后不久,状态或事件会出现在角色的回复中

ConvaiDynamicContextRelay 触发 On Skipped 而不是 On Queued

没有 ConvaiCharacter 已解决—— Auto Resolve Character 处于禁用状态且没有 Character 已分配,或者中继位于错误的 GameObject 上

启用 Auto Resolve Character 并将中继放在 NPC 的 GameObject 上,或者分配 Character 明确地

On Queued 触发,且控制台未显示 分配一个 ConvaiCharacter 警告

On Queued 触发,但角色从未引用该更新

空的状态名称或一个 null 值在发送后未通过验证—— On Queued 这只能确认已发送,而不能确认该值被接受

检查控制台中的验证警告;参见 控制台日志参考

更新会出现在角色的上下文中,且不会记录验证警告

角色在更新后没有立即响应

该调用请求的反应被解析为 静默

使用 自动 或 MustRespond ——在中继的 响应模式 字段中,或者作为 反应 脚本调用中的参数

角色会在下一回合中引用该更新(自动/静默)或立即响应(MustRespond)

AddEvent 通过中继发送的内容不会使用其脚本默认值 自动

中继始终传递其自身的 响应模式 字段,并在每次调用时显式指定,从而覆盖该方法的脚本默认值

将中继的 响应模式 字段设置为 自动 或 MustRespond 如果该事件应触发回复

角色的反应与中继配置的 响应模式,而不是 AddEvent的脚本默认值一致

尽管调用使用了 静默

同一批处理窗口中暂存的另一调用请求了 自动 或 MustRespond ——批次中最强的反应会覆盖整个批次

若需要彼此独立反应的调用之间间隔超过批处理窗口,请分开调用,或者调用 Flush() 其间

批次会以你预期的反应发送

Apply() 似乎没有效果

Apply() 会绕过本地跟踪器且不会暂存;在活动对话之外发起的调用会被丢弃并给出警告

使用 SetState, AddEvent,或者其他跟踪方法——它们会自动暂存

更新会出现在角色的下一次回复中

TryGetStateValue 返回 false 在……之后 Apply()

Apply() 从不更新本地跟踪器

使用 SetState 如果该值必须可通过 TryGetStateValue

TryGetStateValue 返回 true 在切换到后 SetState

角色在之后仍然引用初始场景事实 Reset()

默认值 Reset() 只会清除运行时跟踪器——初始动态信息文本、系统提示事实以及会话内 LLM 记忆都不会被触及

调用 Reset(removeStatic: true) 以便同时请求 Convai 移除此会话的静态初始上下文

角色不再引用仅存在于静态初始上下文中的事实

无法添加第二个 ConvaiDynamicContextRelay 到同一个 GameObject

[DisallowMultipleComponent] 限制

将额外的中继放在子 GameObject 上,禁用 Auto Resolve Character,并分配 Character 明确地

每个中继都会在其分配的角色上独立运行

Apply() 丢弃了我的更新

Apply() 是唯一不会暂存的 Dynamic Context 入口点。与 SetState, AddEvent,与其他跟踪方法不同,在角色不处于活动对话时发起的调用会立即丢弃——Convai 会记录 无法应用原始动态上下文更新:不在对话中 并且不会将该更新排队以便在对话开始后送达。

Apply() 还会完全绕过本地跟踪器:通过 Apply() 发送的值不会更新可被 TryGetStateValue 读取的状态。参见 Apply 脚本 API 参考文档中的完整验证警告列表。

Reset() 会保留事实

调用 Reset() 不带参数会只清除运行时 Dynamic Context 跟踪器——即所有已跟踪的状态和事件。它不会触及角色知识的另外三个来源:

  • Initial Dynamic Info Text,在连接时通过 ConvaiCharacter.

  • 系统提示事实 在 Convai 仪表板上配置。

  • 会话内 LLM 记忆 由模型在多轮对话中保留。

调用 Reset(removeStatic: true) 以便同时请求 Convai 移除该角色在当前会话中的静态初始动态上下文。系统提示事实和会话内记忆仍然不受影响——没有任何运行时调用可以清除这两者中的任意一个。参见 连接时的静态上下文 了解静态初始上下文的配置方式。

角色没有响应

以下决策树涵盖了看起来没有效果的上下文更新的完整排查范围。

控制台日志参考

在进行 Dynamic Context 操作时,以下消息会出现在 Unity 控制台中。

消息
来源
含义
修复方法
验证

分配一个 ConvaiCharacter 或启用 Auto Resolve Character。

ConvaiDynamicContextRelay

没有 ConvaiCharacter 已为此次调用解析。

启用 Auto Resolve Character 并将中继放在角色的 GameObject 上,或者分配 Character 明确地。

警告不再出现,并且 On Queued 触发而不是 On Skipped.

动态上下文状态名称不能为空

ConvaiCharacter.DynamicContext — SetState, SetStates, RemoveState

状态名称为空或仅包含空白字符。

请传入非空且不全为空白的状态名称。

该调用不再记录警告,状态会出现在角色的上下文中。

动态上下文状态 '{name}' 不能使用 null 值

ConvaiCharacter.DynamicContext — SetState, SetStates

传入给 {name} 为 null。允许空字符串; null 但不允许 null。

请传入空字符串而不是 null,或者提供实际值。

该调用不再记录警告,并且 {name} 会更新为预期值。

无法设置空的动态上下文状态

ConvaiCharacter.DynamicContext — SetStates

传递给 SetStates 为 null 的字典为空或没有条目。

请传入至少包含一个名称/值对的字典。

该调用不再记录警告,传入的每个状态都会出现在角色的上下文中。

动态上下文事件文本不能为空

ConvaiCharacter.DynamicContext — AddEvent

事件文本为空或仅包含空白字符。

请传入非空事件文本。

该调用不再记录警告,事件行会出现在角色的上下文中。

动态上下文注意对象不能为空

ConvaiCharacter.DynamicContext — SetCurrentAttentionObject

注意对象参数是 null.

将一个 string 对象名称或一个 ConvaiActionObjectDefinition 引用,或者调用 ClearCurrentAttentionObject 替代。

该调用不再记录警告,角色会引用预期对象。

无法应用原始动态上下文更新:不在对话中

ConvaiCharacter.DynamicContext — Apply

当 Apply 被调用时,角色并不处于活动对话中。

使用 SetState, AddEvent,或者用于可能在对话开始前发生的更新的其他跟踪方法。

跟踪方法调用会成功,并在对话就绪后让更新到达角色。

{purpose} 的连接尚未就绪

ConvaiCharacter.DynamicContext ——内部发送路径

传输层存在,但当一个已暂存的批次、一个 Reset,或一个 Apply 调用尝试发送时,连接尚未就绪。 {purpose} 说明正在发送的内容,例如 动态上下文批次.

确认角色已完全连接(IsInConversation)之后再依赖立即送达;待连接稳定后重试。

该消息不再出现,批次、重置或 Apply 调用会在下一次尝试时到达 Convai。

场景元数据未发送(已在 SDK 4.3.0 中修复)

SDK 4.3.0 修复了一个问题:待处理的场景元数据可能无法到达 Convai——CHANGELOG 将其记录为“修复了待处理的场景元数据未被刷新”。如果你的项目使用的是 SDK 4.3.0 或更高版本,这不是当前症状。如果场景元数据仍然看起来没有到达角色,请在将其视为新问题之前先确认 SDK 包版本。

下一步

中继组件参考动态上下文脚本 API同步行为与时序

最后更新于

这有帮助吗?