> 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).

# 排查动态上下文问题

中继和跟踪器流程中的大多数动态上下文问题都来自三类之一：在角色进入对话之前发起的调用、产生了意外回复的反应模式，或者一个 `ConvaiDynamicContextRelay` 无法解析的 `ConvaiCharacter`. 请按照下面的一线排查清单逐步处理——大多数问题会在前两三步内解决。

### 一线排查

{% stepper %}
{% step %}

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

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

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

{% step %}

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

在调试你自己的集成之前，请先确认动态上下文本身正常工作。导入 **LipSync 示例** ，在 Package Manager 中打开其场景——该示例包含一个 **示例调试中心** ，其中包含一个 **Context** 抽屉，可将状态、事件和注意对象更新发送到场景中的 `ConvaiCharacter` ，无需自行搭建 UI。

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

{% step %}

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

选择 `ConvaiDynamicContextRelay` Inspector 中的组件。

* **已启用自动解析角色：** 确认 `ConvaiDynamicContextRelay` 和 `ConvaiCharacter` 位于 **同一个 GameObject 上**.
* **已禁用自动解析角色：** 确认该 **角色** 字段已分配引用。

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

{% step %}

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

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

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

{% step %}

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

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

如果你本以为角色会 `Silent` 抑制回复，但同一批处理窗口中暂存的另一项更改很可能请求了更强的反应—— `MustRespond` 高于 `Auto`——它的优先级高于 `Silent`，整个批次都以它为准。
{% endstep %}
{% endstepper %}

### 常见问题

| 症状                                                              | 可能原因                                                                          | 修复                                                                              | 验证                                                    |
| --------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------- |
| 角色从未引用通过以下方式发送的状态 `SetState`                                    | 新值与该状态的当前值相同—— `SetState` 当没有变化时不会产生任何操作                                      | 确认值确实发生了变化；先用 `TryGetStateValue` 先                                              | `TryGetStateValue` 在传入一个确实不同的值后会返回新值                  |
| 在 `Awake()` 或 `Start()` 中发起的调用似乎没有效果                            | 预期行为——已跟踪调用会在本地暂存，并在角色就绪后自动刷新                                                 | 跟踪方法无需任何操作；避免在 `Apply()` 对话开始前使用它，因为它不会暂存                                       | 该状态或事件会在对话开始后不久出现在角色的回复中                              |
| `ConvaiDynamicContextRelay` 触发 **On Skipped** 而不是 **On Queued** | 未 `ConvaiCharacter` 已解决—— **自动解析角色** 已禁用且没有 **角色** 已分配，或者中继位于错误的 GameObject 上 | 启用 **自动解析角色** 并将中继放在 NPC 的 GameObject 上，或者分配 **角色** 明确地                         | **On Queued** 触发，但控制台没有显示任何 `分配一个 ConvaiCharacter` 警告 |
| **On Queued** 触发了，但角色从未引用该更新                                    | 空的状态名称或一个 `null` 值在发送后未通过验证—— **On Queued** 这只表示已发送成功，并不表示该值已被接受              | 检查控制台中的验证警告；参见 [控制台日志参考](#console-log-reference)                                | 该更新出现在角色上下文中，且未记录验证警告                                 |
| 更新后角色没有立即响应                                                     | 该调用请求的反应被解析为 `Silent`                                                         | 使用 `Auto` 或 `MustRespond` ——在中继的 **Reaction Mode** 字段中，或者作为 `reaction` 脚本调用中的参数 | 角色会在下一轮中引用该更新（`Auto`/`Silent`）`MustRespond`)          |
| `AddEvent` 通过中继发送的内容不会使用其脚本默认值 `Auto`                           | 中继始终会显式传递其自身的 **Reaction Mode** 字段，覆盖该方法的脚本默认值                                | 将中继的 **Reaction Mode** 字段设为 `Auto` 或 `MustRespond` 如果该事件应触发回复                   | 角色反应与中继配置的 **Reaction Mode**，而不是 `AddEvent`的脚本默认值一致   |
| 即使调用使用了 `Silent`                                                | 同一批处理窗口中暂存的另一项调用请求了 `Auto` 或 `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 上，禁用 **自动解析角色**，并分配 **角色** 明确地                             | 每个中继都会独立运行于其分配的角色                                     |

### `Apply()` 丢弃了我的更新

`Apply()` 是唯一一个不会暂存的动态上下文入口点。与 `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()` 不带参数调用时，只会清除运行时动态上下文跟踪器——所有已跟踪的状态和事件。它不会影响角色知识的另外三个来源：

* **初始动态信息文本**，在连接建立时通过 `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单独验证发送是否成功]
```

### 控制台日志参考

在执行动态上下文操作期间，Unity 控制台会出现以下消息。

| 消息                                 | 来源                                                                        | 含义                                                                              | 修复                                                                                           | 验证                                          |
| ---------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `请分配一个 ConvaiCharacter 或启用自动解析角色。` | `ConvaiDynamicContextRelay`                                               | 未 `ConvaiCharacter` 已为此次调用解析。                                                   | 启用 **自动解析角色** 并将中继放在角色的 GameObject 上，或者分配 **角色** 明确地。                                        | 警告不再出现，并且 `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` ——内部发送路径                                 | 传输层存在，但在暂存批次、 `重置`或 `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" %}
[Relay 组件参考](/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.
