> 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/unity-plugin-beta-overview/features/dynamic-context/troubleshooting-and-diagnostics.md).

# 故障排查与诊断

## 诊断动态上下文问题

大多数动态上下文问题都属于以下三类之一：时机不正确（调用 `Apply()` 在会话开始之前）、组件配置错误（缺少 `ConvaiCharacter` 引用或必填字段为空），或者误解了 `Reset()` 会清除什么。本页面将带你完成第一线排查清单、汇总的症状表，以及针对每个常见问题的详细指导。

## 一线排查

当上下文更新未产生预期的角色行为时，请按顺序完成这些步骤。大多数问题会在第 2 或第 3 步解决。

{% stepper %}
{% step %}
**检查 Unity Console 中的警告**

`ConvaiDynamicContextCommand` 每次都会记录一条包含完整验证消息的警告，发生于 `Execute()` 被跳过时。打开 Console（**Window > General > Console**）并查找带有以下标记的消息： `[ConvaiDynamicContextCommand]`.

如果你看到警告，请在下方的 Console Log Reference 表中找到完全相同的消息，并按照列出的修复方法处理。
{% endstep %}

{% step %}
**使用示例 UI 隔离问题**

在调试你自己的集成之前，请先使用 SDK 内置的测试 UI 来验证动态上下文系统本身是否正常工作：

**预制体路径：** `Packages/com.convai.convai-sdk-for-unity/Prefabs/SampleDynamicContextUI.prefab`

将它拖入你的场景中，分配 `ConvaiCharacter`在 Inspector 中的组件。如果 **设置状态** 按钮以发送一个已知值。如果角色通过 Sample UI 能正确响应，那么问题出在你的集成代码中——而不是动态上下文系统本身。
{% endstep %}

{% step %}
**验证角色引用是否已解析**

选择 `ConvaiDynamicContextCommand` 组件在 Inspector 中。如果 **目标** 部分显示黄色警告框，则该组件无法找到 `ConvaiCharacter`.

* **启用 Auto Resolve Character：** 确认 `ConvaiDynamicContextCommand` 是位于 `ConvaiCharacter` 位于 **同一个 GameObject**.
* **禁用 Auto Resolve Character：** 确认 **角色** 字段已分配引用。
  {% endstep %}

{% step %}
**检查角色当时是否处于会话中**

通过以下方式发送的上下文更新： `Apply()` 如果角色不在活动会话中，会被静默丢弃——Console 中不会有警告。如果你正在调用 `Apply()` 在 `Awake()`, `Start()`，或者是在会话连接之前调用，请改用 `SetState` 或 `AddEvent` 。这些方法会自动排队，并在会话开始时发送。
{% endstep %}

{% step %}
**检查反应模式**

如果上下文更新已经到达角色，但它没有立即响应，请验证 **Reaction** 设置。

* `SyncOnly` ——上下文会被静默存储。角色会在它下一次自然轮次中将其纳入回复。不会生成立即响应。这是预期行为。
* `Auto` ——服务器决定是否响应。若要保证立即响应，请使用 `ReactImmediately`.
* `ReactImmediately` ——在更新后总是触发一次立即的 LLM 轮次。
  {% endstep %}
  {% endstepper %}

## 常见问题

| 症状                                        | 可能原因                             | 修复                                                     |
| ----------------------------------------- | -------------------------------- | ------------------------------------------------------ |
| 角色完全没有引用上下文更新                             | `Apply()` 在会话开始之前被调用             | 切换为 `SetState` 或 `AddEvent` ——它们会自动排队                  |
| 角色在更新后没有立即响应                              | Reaction 模式是 `SyncOnly`          | 将 **Reaction** 到 `Auto` 或 `ReactImmediately`           |
| `OnExecutionSkipped` 触发，而不是 `OnExecuted`  | 验证失败——请查看 Console 警告             | 查看 Console Log Reference 中的确切消息及修复方法                   |
| Inspector 在该组件上显示黄色警告                     | 没有 `ConvaiCharacter` 已解析         | 启用 **自动解析** 并将两个组件放在同一个 GameObject 上，或者显式分配 **角色** 显式地 |
| `TryGetStateValue` 返回 `false` 在 `Apply()` | `Apply()` 绕过本地跟踪器                | 使用 `SetState` 如果该值需要能够通过以下方式查询： `TryGetStateValue`     |
| 两个 `上下文更新` 消息被发送，用于一次 `SetState` 调用       | 现有状态已被更新（预期行为）                   | 不是 bug——请参见“一次更新发送两条消息”                                |
| 在以下操作后角色仍然引用事实： `Reset()`                 | 初始上下文或系统提示不会被以下操作清除： `Reset()`   | 请参见“Reset 没有清除所有内容”                                    |
| 无法向同一个 GameObject 添加第二个 Command 组件        | `[DisallowMultipleComponent]` 限制 | 将额外的命令放在子 GameObject 上                                 |
| `SetStates` 列表会产生验证警告                     | 列表中有重复的状态名称或空条目                  | 删除重复项；确保每个条目都有非空名称                                     |

## 角色没有引用上下文更新

当角色看起来完全不知道你发送的某个状态或事件时，请按顺序检查以下内容。

**验证所使用的方法。** `Apply()` 如果角色不在活动会话中，则会成为静默无操作。不会记录警告。请将初始化代码中的 `Apply()` 调用替换为 `SetState` 或 `AddEvent`，后者会自动排队，并在会话打开时刷新。

**验证 Execute() 没有被跳过。** 将 `ConvaiDynamicContextCommand` **On Execution Skipped** 事件连接到一个临时的 `Debug.Log` 调用，在开发期间使用。如果它被触发，Console 会显示导致跳过的确切验证消息。

**验证更新模式。** 如果反应模式是 `SyncOnly`，角色已经接收到更新，但不会立即生成响应——它会在下一次自然轮次中引用新状态。如果需要立即确认，请切换到 `Auto` 或 `ReactImmediately` 。

## Apply() 没有效果

`Apply()` 具有两种不同于其他所有 `IConvaiDynamicContext` 方法的行为：

* **没有会话前队列。** 如果角色在 `Apply()` 被调用时不在活动会话中，该更新会立即被丢弃——没有警告，也不会排队。请使用 `SetState`, `AddEvent`，或者如果调用可能发生在会话开始之前，则使用其他带跟踪的方法。
* **不更新跟踪器。** `Apply()` 会直接发送到传输层，而不会触及本地状态跟踪器。随后对 `TryGetStateValue` 的调用，针对通过以下方式发送的键： `Apply()` 返回 `false`。如果该值需要能够通过以下方式读取： `TryGetStateValue`，请使用 `SetState` 代替。

{% hint style="warning" %}
`Apply()` 是一个高级逃生口，供会构造自己上下文文本的外部系统使用。对于所有标准上下文管理，优先使用带跟踪的方法—— `SetState`, `SetStates`, `AddEvent`, `RemoveState`，以及 `Reset` ——这些方法会自动排队，并保持本地跟踪器一致。
{% endhint %}

## Reset 没有清除所有内容

`Reset()` 仅作用于 **运行时动态上下文层**。有两类角色知识来源不在其作用范围内：

**初始动态信息文本。** 以下内容的内容： `InitialDynamicInfoText` on `ConvaiCharacter` 会在连接时作为会话请求的一部分发送一次。 `Reset()` 不会重新发送它，并且在不结束并重新启动会话的情况下，任何动态上下文操作都无法清除它。

**系统提示。** 内置在 Convai 仪表板中角色系统提示里的事实，不属于动态上下文层。运行时没有任何 SDK 调用会影响它们。

**会话内 LLM 记忆。** 角色的语言模型会在同一会话内的各轮之间保留对话上下文。 `Reset()` 会清除动态上下文跟踪器并向后端发送 Reset 消息，但不会清除模型在当前会话内的对话记忆。

## 一次更新发送两条消息

当你调用 `SetState` 作用于一个已存在且值不同的状态时，会按顺序发送两条 `上下文更新` RTVI 消息：

1. A **Replace** 消息，携带完整的规范上下文，并将更新后的值放入其中。
2. 一条 **Append** 消息，携带人类可读的增量： `“名称已从 OldValue 更改为 NewValue”`.

这是有意设计且不可配置的。Replace 为角色提供权威的完整图景；Append 为它在对话中引用这一变化提供自然方式。如果你在调试时监控网络流量，那么对于每一次现有状态修改，都应预期看到这种模式。

完整的序列图请参见“同步行为与时序——场景 2”。

## 无法向同一个 GameObject 添加多个 Command 组件

`ConvaiDynamicContextCommand` 被标记为 `[DisallowMultipleComponent]`。Unity 会阻止向同一个 GameObject 添加第二个实例。

将每个额外的命令放在 NPC 的一个 **子 GameObject** 上。在每个命令的 **目标** 部分中，禁用 **自动解析角色** ，并显式分配 NPC 的 `ConvaiCharacter` ——自动解析只会搜索同一个 GameObject。

## 角色没有响应——决策树

```mermaid
flowchart TD
    A[角色未响应上下文更新] --> B{哪个入口点？}
    B -- ConvaiDynamicContextCommand --> C{OnExecuted 是否触发？}
    C -- 否 --> D[检查 Console 中的\n验证警告\n参见 Console Log Reference]
    C -- 是 --> E{反应模式？}
    B -- IConvaiDynamicContext 脚本 --> F{哪个方法？}
    F -- Apply --> G{在活动会话中？}
    G -- 否 --> H[Apply 静默无操作\n请使用 SetState 或 AddEvent]
    G -- 是 --> E
    F -- SetState / AddEvent / 等 --> E
    E -- SyncOnly --> I[预期行为——不会立即响应\n切换到 Auto 或 ReactImmediately]
    E -- Auto 或 ReactImmediately --> J{更新是否到达后端？}
    J -- 是 --> K[检查角色系统提示\n和仪表板配置]
    J -- 不确定 --> L[使用 Sample UI prefab\n来隔离验证传递]
```

## 控制台日志参考

以下消息会在动态上下文操作期间出现在 Unity Console 中。使用此表来识别每条消息的原因和修复方法。

| 消息                                                                                                   | 来源             | 含义                                                     | 修复                                                     |
| ---------------------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------ | ------------------------------------------------------ |
| `[ConvaiDynamicContextCommand] 在此 GameObject 上未找到 ConvaiCharacter。请分配一个，或禁用 Auto Resolve Character。` | `Execute()` 验证 | **自动解析** 已开启，但没有 `ConvaiCharacter` 位于同一个 GameObject 上。 | 将命令移动到 NPC 的 GameObject 上，或禁用 **自动解析** 并分配 **角色** 显式地。 |
| `[ConvaiDynamicContextCommand] 请分配一个 ConvaiCharacter，或启用 Auto Resolve Character。`                    | `Execute()` 验证 | **自动解析** 已关闭，且 **角色** 未被分配。                            | 分配该 `ConvaiCharacter` 引用，或启用 **自动解析**.                 |
| `[ConvaiDynamicContextCommand] Set State 需要一个非空的状态名称。`                                               | `Execute()` 验证 | **状态名称** 字段为空。                                         | 输入一个非空的状态名称。                                           |
| `[ConvaiDynamicContextCommand] Set States 至少需要一个状态条目。`                                               | `Execute()` 验证 | **State Entries** 列表为空。                                | 至少添加一个 Name/Value 条目。                                  |
| `[ConvaiDynamicContextCommand] 每个状态条目都需要一个非空名称。`                                                     | `Execute()` 验证 | 一个或多个 **State Entries** 具有空白名称。                        | 填写所有条目名称。                                              |
| `[ConvaiDynamicContextCommand] 状态条目包含重复名称“{name}”。`                                                  | `Execute()` 验证 | 中的两个条目 **State Entries** 共享同一个状态名称。                    | 删除或重命名重复项。                                             |
| `[ConvaiDynamicContextCommand] Add Event 需要非空事件文本。`                                                  | `Execute()` 验证 | **Event Text** 字段为空。                                   | 输入事件文本。                                                |
| `[ConvaiDynamicContextCommand] Remove State 需要一个非空状态名称。`                                             | `Execute()` 验证 | **状态名称** 字段为空。                                         | 输入要移除的状态名称。                                            |
| `[ConvaiDynamicContextCommand] Raw Update 需要文本，除非模式为 Reset。`                                         | `Execute()` 验证 | **Raw Text** 为空，且 **Raw Mode** 不是 `Reset`.             | 输入文本，或将 **Raw Mode** 到 `Reset`.                        |

## 接下来是什么

* 同步行为与时序——控制更新何时以及如何传输的精确规则。
* 脚本 API 参考—— `Apply()` 及所有带跟踪方法的方法签名、参数语义和排队行为。

## 结论

Unity Console 验证警告、Sample UI prefab，以及上方的决策树，涵盖了动态上下文的完整故障排查范围。先从 Console 开始以获得即时诊断，使用 Sample UI 来隔离问题究竟出在你的集成还是 SDK 本身，并使用常见问题表来解决最常见的配置错误。


---

# 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:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/unity-plugin-beta-overview/features/dynamic-context/troubleshooting-and-diagnostics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
