> 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/how-dynamic-context-works.md).

# 动态上下文的工作方式

Dynamic Context 让角色能够实时、结构化地了解场景中正在发生什么。它不再只依赖在 Convai 仪表板上配置的静态系统提示，而是可以引用受训者当前所在位置、已收集的设备，或刚刚触发的警报——因为这些信息是在事件发生时直接注入到会话中的。本页解释其底层模型：原语是什么，SDK 如何将它们组装成规范化的上下文字符串，以及为什么在对话开始前更新会安全排队。

### 状态和事件

Dynamic Context 建立在两种原语类型之上。

**状态** 是持久化的、带名称的键值对。每个状态都有名称和值。当你设置一个状态时，该名称之前的任何值都会被替换。状态适合表示会随时间变化、但在任一时刻只有一个当前值的事实：操作员当前所在工位、某区域的危险等级，或某个检查项是否已完成。

**事件** 是按时间顺序记录的一次性发生事项。与状态不同，事件会按顺序累积，且永远不会被替换或去重。每次调用 `AddEvent` 都会向角色的上下文追加一行新内容。事件适合表示会话中发生过、且角色应当能够按顺序引用的事情："受训者绕过了手动锁定程序"、"7 号工位触发了化学警报"。

这两种原语会同时馈入角色的感知。状态提供当前条件的稳定、可查询快照；事件提供已发生事项的时间顺序记录。

### 规范化上下文格式

当 SDK 向 Convai 发送更新时，它会基于所有已跟踪的状态和事件组装出一个规范化上下文字符串：

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

状态最先出现，按它们被 **首次设置** 的顺序排列——更新某个状态的值不会改变它的位置。所有状态之后，事件按调用顺序排列。

状态之所以在更新后仍保留插入顺序，是为了给角色提供一个稳定、可预测的世界视图。如果 `工位` 是最先设置的内容，无论其值改变了多少次，它始终会在角色上下文中排在第一位。这让模型更容易始终如一地解释上下文。

**示例：**

```csharp
context.SetState("Station", "Bay 3");       // 位置 1
context.SetState("HazardLevel", "High");    // 位置 2
context.AddEvent("Operator bypassed interlock");
context.SetState("Station", "Bay 7");       // 更新值；位置保持为 1
```

所有四次调用后的规范化上下文：

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

你只需提供名称、值和事件文本。SDK 会自动组装并传递规范化字符串。

### 两种入口

Dynamic Context 有两个入口，它们写入同一个底层跟踪器，并产生相同的网络行为。

**检查器 — `ConvaiDynamicContextCommand`**

添加此 `MonoBehaviour` 到 NPC 的 GameObject 上，并在检查器中配置命令类型、字段和响应模式。调用 `Execute()` 从 `UnityEvent`、触发器碰撞体、时间线标记或 UI 按钮中调用。无需编写脚本。一个组件封装一个命令；对于每个 NPC 的多个命令，请将每个命令放在一个子 GameObject 上。

当以下情况时使用此入口：

* 上下文变化与已触发的场景事件 `UnityEvent` 回调
* 非程序员需要配置或修改上下文触发器
* 你想在不编写胶水代码的情况下快速原型验证

**脚本 — `IConvaiDynamicContext`**

访问 `character.DynamicContext` 以获取 `IConvaiDynamicContext` 接口，并直接从 C# 调用方法。这使你能够完全控制时机、批量处理和响应模式。

```csharp
IConvaiDynamicContext context = _character.DynamicContext;
context.SetState("Station", "Bay 7");
context.AddEvent("Operator bypassed interlock");
```

当以下情况时使用此入口：

* 上下文更新取决于运行时逻辑或无法用静态 Inspector 字段表示的数据
* 多个状态必须以原子方式更改（使用 `SetStates`)
* 你需要读回状态值（`TryGetStateValue`)
* 更新源是外部系统，例如状态机或分析流水线

### 对话前排队

在会话开始前所做的更新，会由所有已跟踪的方法自动排队—— `SetState`, `SetStates`, `AddEvent`, `RemoveState`，和 `Reset`。当会话连接时，SDK 会发送一条 Replace 消息，其中包含当时的完整规范化上下文。

这意味着你可以自由地从 `Awake` 或 `Start` 中设置初始上下文，而无需担心时机。SDK 会负责传递。

```csharp
void Start()
{
    // 安全——当 ConnectAsync 触发时，所有三项都会排队，并作为一次 Replace 一并刷新
    _character.DynamicContext.SetState("Facility", "Offshore Platform Alpha");
    _character.DynamicContext.SetState("Scenario", "Fire Drill");
    _character.DynamicContext.AddEvent("Session initialized");
}
```

之所以会折叠为一次 Replace，而不是逐条重放单独消息，是出于效率：角色接收到的是一个权威快照，而不是一串可能乱序到达、或造成冗余 LLM 回合的增量更新流。

{% hint style="warning" %}
`Apply()` 是唯一的例外：它不会排队。如果在对话开始前调用，更新会被丢弃。请在对话前上下文中使用 `SetState`, `AddEvent`，或其他已跟踪的方法。详情请参见 [动态上下文脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/dynamic-context-scripting-api.md) 。
{% endhint %}

### 何时使用哪种命令类型

| 目标                   | 使用                           |
| -------------------- | ---------------------------- |
| 跟踪一个当前条件             | `SetState`                   |
| 跟踪多个在同一时刻变化的条件       | `SetStates` （一次规范化重建，一次网络往返） |
| 记录某事已经发生             | `AddEvent`                   |
| 移除一个不再适用的条件          | `RemoveState`                |
| 清除所有运行时上下文（用于新的场景阶段） | `Reset`                      |
| 发送外部构造的上下文文本         | `Apply()` ——高级用法；不会排队        |

### 下一步

{% content-ref url="/pages/aad74412c9dc416577acffb5b0f1b8be3c9ad61d" %}
[动态上下文快速入门](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/dynamic-context-quick-start.md)
{% endcontent-ref %}

{% content-ref url="/pages/fe2e3da29009b41a36bf622ae1efd7921e09aab7" %}
[命令组件参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/dynamic-context/command-component-reference.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:

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