> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/troubleshoot-dynamic-context.md).

# 排查动态上下文故障

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

### 第一线调查

{% stepper %}
{% step %}

#### 检查 Unity 控制台中的警告

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

如果你看到警告，请在下面的 [控制台日志参考](#console-log-reference) 表中找到准确消息并按列出的修复方法操作。
{% endstep %}

{% step %}

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

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

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

{% step %}

#### 验证角色引用已解析

选择 `ConvaiDynamicContextRelay` 组件在 Inspector 中。

* **启用 Auto Resolve Character：** 确认 `ConvaiDynamicContextRelay` 和 `ConvaiCharacter` 位于 **同一个 GameObject 上**.
* **禁用 Auto Resolve Character：** 确认 **Character** 字段已分配引用。

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

{% step %}

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

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

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

{% step %}

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

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

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

### 常见问题

| 症状                                                              | 可能原因                                                                                                     | 修复方法                                                                           | 验证                                                 |
| --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------- |
| 角色从不引用通过 `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** 这只能确认已发送，而不能确认该值被接受                                          | 检查控制台中的验证警告；参见 [控制台日志参考](#console-log-reference)                               | 更新会出现在角色的上下文中，且不会记录验证警告                            |
| 角色在更新后没有立即响应                                                    | 该调用请求的反应被解析为 `静默`                                                                                        | 使用 `自动` 或 `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 会记录 `无法应用原始动态上下文更新：不在对话中` 并且不会将该更新排队以便在对话开始后送达。

{% hint style="warning" %}
使用 `Apply()` 仅适用于高级场景，例如在外部构造上下文文本，或将上下文更新与动作配置补丁合并。对于任何可能在对话开始前运行的内容，请使用 `SetState`, `AddEvent`，或其他跟踪方法——它们会自动暂存。
{% endhint %}

`Apply()` 还会完全绕过本地跟踪器：通过 `Apply()` 发送的值不会更新可被 `TryGetStateValue` 读取的状态。参见 [`Apply`](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/dynamic-context-scripting-api.md#apply) 脚本 API 参考文档中的完整验证警告列表。

### `Reset()` 会保留事实

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

* **Initial Dynamic Info Text**，在连接时通过 `ConvaiCharacter`.
* **系统提示事实** 在 Convai 仪表板上配置。
* **会话内 LLM 记忆** 由模型在多轮对话中保留。

调用 `Reset(removeStatic: true)` 以便同时请求 Convai 移除该角色在当前会话中的静态初始动态上下文。系统提示事实和会话内记忆仍然不受影响——没有任何运行时调用可以清除这两者中的任意一个。参见 [连接时的静态上下文](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/static-context-at-connection-time.md) 了解静态初始上下文的配置方式。

### 角色没有响应

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

```mermaid
flowchart TD
    A[角色没有响应上下文更新] --> B{哪个入口点？}
    B -- ConvaiDynamicContextRelay --> C{On Queued 是否触发？}
    C -- 否，On Skipped 触发 --> D[检查控制台中的\nAssign a ConvaiCharacter 警告]
    C -- 是 --> E{哪个方法？}
    B -- IConvaiDynamicContext 脚本 --> E
    E -- Apply --> F{是否处于活动对话中？}
    F -- 否 --> G[已丢弃并带有警告\n改用 SetState 或 AddEvent]
    F -- 是 --> H{此批次的反应模式？}
    E -- SetState / AddEvent / 等 --> H
    H -- Silent --> I[预期：不会立即响应\n检查同一批次中是否有更强的反应]
    H -- Auto 或 MustRespond --> J{更新是否到达 Convai？}
    J -- 是 --> K[检查角色系统提示\n和仪表板配置]
    J -- 不确定 --> L[使用示例调试中心\n单独验证送达情况]
```

### 控制台日志参考

在进行 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 中修复）

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

### 下一步

{% content-ref url="/pages/743bcc7de155496cbbf02a52a5577aee99f28aab" %}
[中继组件参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/relay-component-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/5c3f9bcc544ac6f441fe54139ac1c670eeb5c958" %}
[动态上下文脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/dynamic-context-scripting-api.md)
{% endcontent-ref %}

{% content-ref url="/pages/bb1aef3496a2be08987c770aa7b8072e7d8c5cd6" %}
[同步行为和时序](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/sync-behavior-and-timing.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/troubleshoot-dynamic-context.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
