> 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/sync-behavior-and-timing.md).

# 同步行为和时序

每个已跟踪的动态上下文操作都会产生一条或两条 RTVI `上下文更新` 发送给 Convai 的消息。本页记录了每种场景下的准确消息序列、会话开始前的排队行为，以及 SDK 在会话开始时如何刷新待处理上下文。

### 标准上下文格式

在描述同步场景之前，先了解 SDK 发送的内容会很有帮助。标准上下文是一个由所有已跟踪状态和事件组装而成、以换行符分隔的字符串：

```
{StateName} 是 {Value}
{AnotherState} 是 {Value}
事件文本第一行
事件文本第二行
```

状态首先出现，顺序与它们 **首次设置** ——而不是最近一次更新的顺序。更新某个状态的值不会改变其在输出中的位置。事件按时间顺序（调用顺序）排列。

**示例——状态插入顺序会在更新中保持不变：**

```csharp
context.SetState("Station", "Bay 3");       // position 1
context.SetState("HazardLevel", "High");    // position 2
context.AddEvent("Operator bypassed interlock");
context.SetState("Station", "Bay 7");       // updates value; position stays at 1
```

四次调用后的标准输出：

```
Station 是 Bay 7
HazardLevel 是 High
操作员绕过了联锁装置
```

### 活动会话期间的同步场景

#### 添加新状态

**SDK 调用：** `SetState("Station", "Bay 3")` — `Station` 从未设置过。

**发送的消息：** 一条 Append。

```
模式：  Append
text:  "Station 是 Bay 3"
```

服务器会将这一行追加到其现有上下文视图中。

#### 更新现有状态

**SDK 调用：** `SetState("Station", "Bay 7")` — `Station` 先前为 `"Bay 3"`.

**发送的消息：** 连续两条消息。

**消息 1——Replace（包含更新后值的完整标准上下文）：**

```
模式：  Replace
text:  "Station 是 Bay 7\nHazardLevel 是 High\n操作员绕过了联锁装置"
```

**消息 2——Append（用于自然对话引用的增量）：**

```
模式：  Append
text:  "Station 从 Bay 3 更改为 Bay 7"
```

Replace 让角色获得当前状态的权威完整视图。Append 让它能够以自然的方式在对话中提及这一变化： *“我看到你已经从 Bay 3 移动到了 Bay 7。”*

{% hint style="info" %}
一条调用对应两条消息 `SetState` 对现有状态的一次调用是预期行为。如果你在调试时监控网络流量，请预期每次对现有状态的修改都会出现这种模式。
{% endhint %}

#### 移除状态

**SDK 调用：** `RemoveState("Station")`.

**发送的消息：** 一条 Replace，包含移除该状态后的标准上下文。

```
模式：  Replace
text:  "HazardLevel 是 High\n操作员绕过了联锁装置"
```

#### 使用以下方式进行批量更新： `SetStates`

**SDK 调用：** `SetStates({ "Station": "Bay 7", "HazardLevel": "Extreme" })` — `Station` 已存在（`"Bay 3"`), `HazardLevel` 是新的。

由于至少有一个现有状态被修改，因此会发送两条消息：

**消息 1——Replace（完整标准上下文，所有值均已更新）：**

```
模式：  Replace
text:  "Station 是 Bay 7\nHazardLevel 是 Extreme\n..."
```

**消息 2——Append（汇总所有更改）：**

```
模式：  Append
text:  "Station 从 Bay 3 更改为 Bay 7\nHazardLevel 是 Extreme"
```

**仅包含全新状态：** 如果……中的每个状态 `SetStates` 是新的（之前都不存在），则只发送一条 Append——不发送 Replace。Append 包含所有新状态行，并以换行符连接。

#### 添加事件

**SDK 调用：** `AddEvent("Operator bypassed interlock")`.

**发送的消息：** 一条 Append。

```
模式：  Append
text:  "操作员绕过了联锁装置"
```

事件绝不会触发 Replace。服务器会将事件文本追加到其上下文视图中。

#### 重置所有上下文

**SDK 调用：** `Reset()`.

**发送的消息：** 一条 Reset 模式消息。

```
模式：  Reset
text:  null
```

服务器会清空其动态上下文视图。本地跟踪器也会被清空——所有状态和事件都会被移除。

### 会话前排队

所有受跟踪的方法—— `SetState`, `SetStates`, `AddEvent`, `RemoveState`, `Reset` ——当没有活动会话时自动排队。

当会话连接后，SDK 会以以下两种方式之一刷新待处理队列：

* **待同步项（已排队的状态或事件）：** 一条 Replace 消息，包含连接时刻的完整标准上下文。所有增量更改都会折叠为一个权威快照——它们不会作为单独的 Append 和 Replace 消息重新播放。
* **待处理的重置（离线时调用了 Reset）：** 一条 Reset 消息。如果重置和后续更改都在待处理队列中，则重置优先，并会清空队列。

**示例——这三个调用会在连接前安全排队： `ConnectAsync`:**

```csharp
void Start()
{
    // 可在 ConnectAsync 之前安全调用——这三个调用都会排队并在连接时刷新
    _character.DynamicContext.SetState("Facility", "Offshore Platform Alpha");
    _character.DynamicContext.SetState("Scenario", "Fire Drill");
    _character.DynamicContext.AddEvent("Session initialized");
}
```

角色会在连接时收到一条 Replace：

```
Facility 是 Offshore Platform Alpha
Scenario 是 Fire Drill
会话已初始化
```

### `Apply()` 异常

`Apply()` 完全绕过跟踪器，并且不会 **不是** 在会话前排队。

* 如果角色处于 **不是** 处于活动会话中：该更新会被丢弃，并通过 Convai 日志器发出警告。启用 Convai 调试日志即可在 Unity Console 中看到它。不会构建队列——该更新会丢失。
* 如果角色 **为** 处于活动会话中：该消息会直接发送到传输层，使用 `ConvaiContextUpdateMode` 你指定的。
* 本地状态跟踪器不会更新。 `TryGetStateValue` 返回 `false` 适用于通过……发送的键 `Apply()`.

{% hint style="danger" %}
不要使用 `Apply()` 用于必须在会话开始前传递的上下文。请改用 `SetState`, `AddEvent`，或其他已跟踪的方法——它们会自动排队并在连接时刷新。
{% endhint %}

### 下一步

{% 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/531d80b1af7cb4aba63c4979e0a4c0f8e029bc95" %}
[动态上下文故障排查](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/troubleshoot-dynamic-context.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:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/sync-behavior-and-timing.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.
