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

# 动态上下文的工作原理

了解动态上下文如何跟踪运行时状态、批处理事件、选择响应行为并为 Convai 组装载荷。

动态上下文是 Convai 角色了解在会话开始时不可用——或尚未发生——的运行时信息的方式。你从 Blueprint 推送更新；插件在本地存储这些更新，将快速变化批处理起来，并把组装好的负载发送给 Convai。

{% embed url="<https://www.youtube.com/watch?v=MPbr3b6r9bo>" %}
在 Unreal Engine 中逐步讲解动态上下文
{% endembed %}

可以把动态上下文看作两个通道：

| 通道    | 它所代表的内容   | Blueprint 节点           | 示例              |
| ----- | --------- | ---------------------- | --------------- |
| State | 可被替换的当前事实 | `设置上下文状态` / `设置上下文状态集` | `Health` 是 `80` |
| 事件    | 会话中的一次性时刻 | `添加上下文事件`              | `4 区触发警报`       |

### 状态属性和事件

一个 **状态属性** 是一个有名称的键值对，表示一个当前的、可替换的事实—— `Health` 是 `80`, `区域` 是 `市场区`, `任务激活` 是 `true`. `设置上下文状态` 和 `设置上下文状态集` 立即写入本地跟踪器。刷新时，插件会发送一条 `替换`-模式 `上下文更新` 其文本为规范上下文，下一行可选地跟随 delta 行。

一条 **事件** 是一个自由格式的按时间顺序排列的字符串—— `玩家捡起了红钥匙`, `4 区触发警报`. `添加上下文事件` 将文本暂存到待处理批次中。刷新时，该事件会提交到跟踪器的时间顺序事件列表，并包含在规范上下文中。常规上下文事件不会复制到单独的 delta 行。

| 通道   | 可替换       | 典型用途           |
| ---- | --------- | -------------- |
| 状态属性 | 是——仅保留最新值 | 当前生命值、区域、装备配置  |
| 事件   | 否——仅追加    | 警报、里程碑、一次性叙事节点 |

### 角色接收的内容

刷新时，插件会将所有活动状态和事件组装成一个按换行分隔的上下文字符串：

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

状态会首先出现，按插入顺序排列。更新值不会移动其位置。事件按时间顺序排列在后。

```
// Blueprint 伪代码——当状态更新时，插入顺序会被保留
Set Context State  Name="区域"   Value="市场区"   ShouldRespond=Never
Set Context State  Name="生命值" Value="80"                ShouldRespond=Never
Add Context Event  Text="玩家捡起了红钥匙"     ShouldRespond=Auto
Set Context State  Name="区域"   Value="码头"             ShouldRespond=Never
```

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

```
区域 is 码头
生命值 is 80
玩家捡起了红钥匙
```

你提供名称、值和事件文本。插件会在刷新时组装并传递规范字符串。

### 防抖批处理

对……的调用 `设置上下文状态`, `设置上下文状态集`，以及 `添加上下文事件` 会安排一次防抖刷新，而不是立即发送。 `移除上下文状态` 仅当键存在于本地跟踪器中时，才会安排防抖刷新。

短时间内的快速更新会合并为一次发送。以下两个属性会影响 `UConvaiChatbotComponent` 时机：

| 属性                         | 详情面板标签                        | 默认    | 含义                                       |
| -------------------------- | ----------------------------- | ----- | ---------------------------------------- |
| `ContextDebounceWindow`    | `Context Debounce Window (秒)` | `0.5` | 在最近一次暂存更新之后，等待这么多秒再刷新。窗口内的每次新更新都会重置计时器。  |
| `ContextMaxDebounceWindow` | `Max Debounce Window (秒)`     | `3.0` | 从突发中的第一次更新开始算起的总延迟硬上限。可防止连续不断的更新无限期推迟刷新。 |

防抖计时器在突发中的第一次更新到达时启动。后续更新会将计时器重置为 `ContextDebounceWindow` 距最近一次调用，但绝不超过 `ContextMaxDebounceWindow` 从突发开始算起。计时器触发时，所有暂存的更改会合并为一个单一的 `上下文更新` 消息。

这两个属性都标记为 `高级显示` 位于 `Convai > DynamicContext` Details 面板中的

### 角色何时可能响应

每个暂存的状态或事件都携带自己的 `ShouldRespond` 值。批次将它们合并为一个聚合等级： `始终` > `自动` > `从不`。刷新会发送一条单一的 `上下文更新` ，并将该聚合值作为 `run_llm`.

聚合等级控制是否会发出状态 delta 行：

* **聚合 `从不`** ——不发送 delta 行。新的状态键会立即进入规范上下文，以便 Convai 保留它们。
* **聚合 `自动` 或 `始终`** ——delta 行会附加在规范块之后（由一个换行符分隔）。批次中的全新状态键在此次刷新中不会包含在规范内容里，只会以 delta 行出现；它们会在下一次刷新时进入规范内容。

按键 `ShouldRespond` 在单个调用中仍会计入聚合等级，但当 aggregate 不是时，首次出现延迟会应用于批次中的每个新状态键 `从不`.

### 立即刷新

每个变更函数都提供一个 `高级` 参数 `bFlushImmediately`。当 `true`，插件会调用 `FlushDynamicContext()` 在当前帧中，从而绕过防抖计时器。仅在聊天机器人已连接后、用于时间关键更新时才应使用。高频使用可能会在已连接且存在暂存工作的情况下，每次调用都发送一条 `上下文更新` 。

`重置动态上下文` 不提供 `bFlushImmediately`。当角色已连接时，它会立即调用刷新路径；当离线时，它会将重置排队，等待下一次连接后的刷新。

### 会话前排队

在 `IsChatbotConnected()` 返回 `true` 之前进行的默认防抖调用会累积在 `PendingContextBatch`. `TickDynamicContext()` 在断开连接时会提前返回，因此不会发送消息。会话连接后，下一次达到防抖截止时间的 tick 会调用 `FlushDynamicContext()` 并将待处理批次作为一个 `替换`-模式快照。不要在连接前将其用于必须送达的数据，因为它会绕过断开连接时的 tick 保护。 `bFlushImmediately = true` 连接前将其用于必须送达的数据，因为它会绕过断开连接时的 tick 保护。

你可以从 `BeginPlay` 填充初始状态，而无需延迟执行或连接保护：

```
// Blueprint 伪代码——可在 BeginPlay 中、Start Session 之前安全调用
Event BeginPlay
  → Set Context State  Name="设施"  Value="海上平台 Alpha"  ShouldRespond=Never
  → Set Context State  Name="场景"  Value="消防演练"               ShouldRespond=Never
  → Add Context Event  Text="会话已初始化"                         ShouldRespond=Never
```

### 重置顺序

`重置动态上下文` 标记 `bPendingReset` 在待处理批次上。当已连接时，它会立即刷新；当断开连接时，它会将重置安排到下一次连接后的刷新。它不会 **包含** 预先清空跟踪器或丢弃暂存更新。刷新时：

1. 暂存的状态、事件和可选注意力会作为一个 `替换` `上下文更新`.
2. 如果有排队的环境元数据，则会被处理掉。那些在 `重置动态上下文` 被调用时已存在的排队叙事触发器已被该重置请求清除；在待处理的离线 `重置` 之后排队的触发器仍可在 `重置`.
3. 一个 `重置` `上下文更新` 最后触发（`模式：重置`, `run_llm: "false"`时，不会发送 `text` 为空的 `重置` 负载），然后本地跟踪器被清空。

如果你调用 `重置动态上下文` 并在同一个离线窗口中暂存新的更新，则首次连接后的刷新会先传递暂存内容，然后 `重置` 清除远程和本地上下文。如果你打算从空的动态层开始，请让重置刷新完成后再暂存新数据。

### 批次内事件去重

在同一防抖窗口内，多次暂存的相同事件字符串会去重——该次刷新只保留第一次出现。同一突发中的不同事件字符串会按时间顺序全部保留。

### 动态环境信息是单独的通道

`DynamicEnvironmentInfo` 是一个 `FString` 属性，位于 `UConvaiChatbotComponent`。更改它会调用 `update-dynamic-info` 使用 `dynamic_info.text` 当会话代理存在时，并且该值也会在参与者连接时发送。它不受 `FConvaiDynamicContextTracker` 跟踪，也不会经过防抖批次。参见 [连接时的静态上下文](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/dynamic-context/static-context-at-connection-time.md).

### 何时使用哪个函数

| 目标           | 使用                                                      |
| ------------ | ------------------------------------------------------- |
| 跟踪一个当前条件     | `设置上下文状态`                                               |
| 跟踪多个会同时变化的条件 | `设置上下文状态集`                                              |
| 记录某事已发生      | `添加上下文事件`                                               |
| 移除不再适用的条件    | `移除上下文状态`                                               |
| 清除所有运行时上下文   | `重置动态上下文`                                               |
| 发送外部构造的上下文文本 | `更新上下文` ——绕过跟踪器                                         |
| 推送会话级自由格式备注  | `DynamicEnvironmentInfo` ——单独的 `update-dynamic-info` 通道 |

### 下一步

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

{% content-ref url="/pages/602e67296ec3ed2b843879adb48efa844ab06ec3" %}
[动态上下文快速开始](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/dynamic-context/dynamic-context-quick-start.md)
{% endcontent-ref %}

{% content-ref url="/pages/a80705d8480f2f63dc8b84ea2e437c9dac45b7c5" %}
[动态上下文 Blueprint 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/dynamic-context/dynamic-context-blueprint-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/b420c88b0fe545f2bdf932b279270d9c5974103c" %}
[排查动态上下文问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/dynamic-context/how-dynamic-context-works.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
