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

# 动态上下文

## 简介

Convai 角色有两层上下文：

* **角色层级** — 背景故事、性格和行为规则。在 Convai 仪表板中配置，且会在所有会话中保留。
* **会话层级** — 仅与当前交互相关的信息：玩家是谁、刚刚发生了什么、当前游戏状态。

动态上下文是 Convai Unity SDK 的运行时功能，可让你的游戏在对话进行中向 Convai AI 角色推送临时的、会话专属的信息。不同于在 Convai 仪表板中配置的角色固定背景故事，动态上下文是在运行时注入的，且是临时的——它只在当前会话期间存在。

用它来弥合你的游戏世界与 AI 之间的差距：告诉角色刚刚发生了什么、玩家是谁、他们携带了什么、他们在哪里，或任何其他应该影响角色回复但又不想硬编码到提示中的信息。

***

## 工作原理

当你调用 `UpdateDynamicContext`，SDK 会序列化一个 `context-update` 消息，并通过当前会话的数据通道将其发送到 Convai 后端。后端接收该更新，并在处理下一条用户发言之前，将新信息整合进角色的活动上下文窗口。

流程如下：

```
你的游戏代码
      │
      ▼
IConvaiRoomConnectionService.UpdateDynamicContext(text, mode, runLlm)
      │
      ▼
已序列化的上下文更新消息通过会话数据通道发送
      │
      ▼
Convai 后端 → LLM 上下文窗口
```

这是一个 **一次性发送、仅出站** 操作。上下文更新本身不会有直接响应——其效果会体现在角色下一次的口头回复中。

***

## 关键概念

在编写任何代码之前，先了解这三个参数，它们控制着每一次 `UpdateDynamicContext` 调用设置。

### `text`

你希望角色知晓的内容。这是一个普通字符串——可以是一句话、一个结构化段落，或者按你喜欢的任何方式格式化的键值数据。

```
"玩家的名字是 Aria。她现在是 12 级，当前正在进行任务 'Lost in the Fog'。"
```

`text` 为 **必填** 关于 `append` 和 `replace` 模式。当使用 `reset` mode 时，它会被忽略。

***

### `mode`

控制新文本如何应用到角色现有的临时上下文中。

| 模式        | 行为                                                   | 何时使用                        |
| --------- | ---------------------------------------------------- | --------------------------- |
| `append`  | 添加 `text` 到任何现有临时上下文中。之前的条目会保留。                      | 渐进式信息——随着会话展开逐步添加事实。        |
| `replace` | 丢弃当前所有临时上下文，并将其完全替换为新的 `text`.                       | 一个干净的状态切换——进入新场景、开启新章节。     |
| `reset`   | 清除所有运行时临时上下文。 `text` 会被忽略。初始动态信息不受影响——它会在整个会话期间保持固定。 | 在保留会话级固定上下文的同时重置已累积的运行时上下文。 |

**默认：** `"append"`

***

### `runLlm`

在上下文更新后是否触发一次 LLM 推理。

| 值       | 行为                          |
| ------- | --------------------------- |
| `auto`  | 服务器会根据其内部流水线状态决定。推荐用于大多数场景。 |
| `true`  | 在上下文更新后始终立即触发 LLM 回复。       |
| `false` | 静默更新上下文——不会触发 LLM 回复。       |

**默认：** `"auto"`

使用 `"false"` 当你批量进行多个上下文更新，并且只希望 LLM 在最后一次之后才回复时使用。使用 `"true"` 当上下文更新本身就应该促使角色做出反应时使用。

***

#### `mode`

控制新文本如何应用到角色现有的临时上下文中。

| 模式        | 行为                                                               | 何时使用                        |
| --------- | ---------------------------------------------------------------- | --------------------------- |
| `append`  | 添加 `text` 到任何现有临时上下文中。之前的条目会保留。                                  | 渐进式信息——随着会话展开逐步添加事实。        |
| `replace` | 丢弃当前所有临时上下文，并将其完全替换为新的 `text`.                                   | 一个干净的状态切换——进入新场景、开启新章节。     |
| `reset`   | 清除所有 **运行时** 临时上下文。 `text` 会被忽略。 **初始动态信息不受影响** ——它会在整个会话期间保持固定。 | 在保留会话级固定上下文的同时重置已累积的运行时上下文。 |

默认： `"append"`

***

## 初始动态信息

`UpdateDynamicContext` 并不是向角色提供会话级上下文的唯一方式。该 `ConvaiCharacter` 组件还提供了第二层，其在整个会话期间保持固定： **初始动态信息**.

这是在 Unity Inspector 中对以下项进行配置的： `ConvaiCharacter` 组件中的 **SESSION** 部分：

1. 启用 **将初始动态信息保留在上下文中** ——此开关控制下方文本是否会包含在连接请求中，并由服务器在整个会话中固定。
2. 启用后， **动态信息（连接请求）** 字段会出现。请在 **初始动态信息文本**.

<figure><img src="/files/40743013a48b0023d1519e537a81289d4dcbe73c" alt=""><figcaption></figcaption></figure>

不同于 `UpdateDynamicContext`初始动态信息

**关键区别：** `reset` mode 中的 `UpdateDynamicContext` 不会 **上的初始动态信息文本** 清除初始动态信息。它只会重置运行时临时层。固定的初始文本在整个会话期间始终保持有效，不受你发送的任何上下文更新影响。

#### 各自何时使用

|                  | 初始动态信息                             | 运行时动态上下文                   |
| ---------------- | ---------------------------------- | -------------------------- |
| **通过以下方式设置：**    | Unity Inspector（`ConvaiCharacter`) | 代码（`UpdateDynamicContext`) |
| **发送时间**         | 在房间连接时，且在会话开始之前                    | 在活跃会话期间的任何时候               |
| **可变**           | 否——在整个会话中固定                        | 是——可随时追加、替换或重置             |
| **清除方式 `reset`** | 否                                  | 是                          |
| **用于**           | 稳定的会话配置：角色职责、场景规则、固定指令             | 变化中的游戏状态、玩家数据、事件、情绪        |

{% hint style="info" %}
对于在会话期间绝不应更改的上下文——角色指令、场景设置、固定规则——请使用初始动态信息。对于 `UpdateDynamicContext` 会随着会话推进而变化的所有内容，请使用。
{% endhint %}

***

## 访问 API

动态上下文通过以下方式公开： `IConvaiRoomConnectionService`，通过以下方式获取： `ConvaiManager`。根据谁负责连接生命周期，存在两种不同模式。

### 模式 A——自包含

当组件负责自身初始化时使用。通常用于会话开始场景，此时一旦连接就绪就必须立即发送上下文。

```csharp
using System.Collections;
using Convai.Runtime.Components;
using Convai.Runtime.Room;
using UnityEngine;

public class ExampleSelfContained : MonoBehaviour
{
    private IConvaiRoomConnectionService _connectionService;

    private IEnumerator Start()
    {
        // 轮询，直到 ConvaiManager 和房间服务可用。
        // 在正常情况下，一两帧内即可解析完成。
        while (true)
        {
            ConvaiManager manager = ConvaiManager.ActiveManager;
            if (manager != null && manager.TryGetRoomConnectionService(out _connectionService))
                break;
            yield return null;
        }

        // 服务引用已可用，但房间可能尚未连接。
        // 先检查 IsConnected：如果此组件在会话
        // 已建立之后才初始化，那么 Connected 事件将永远不会触发。
        if (_connectionService.IsConnected)
            OnReady();
        else
            _connectionService.Connected += OnConnected;
    }

    private void OnConnected()
    {
        _connectionService.Connected -= OnConnected;
        OnReady();
    }

    private void OnReady()
    {
        bool sent = _connectionService.UpdateDynamicContext("...", mode: "replace", runLlm: "false");
        if (!sent)
            Debug.LogWarning("[Example] UpdateDynamicContext returned false.");
    }

    private void OnDestroy()
    {
        // 如果此对象在连接前被销毁，防止留下悬挂订阅。
        if (_connectionService != null)
            _connectionService.Connected -= OnConnected;
    }
}
```

***

### 模式 B——注入

当会话协调器或上层系统负责提供已连接的服务时使用。组件在调用其公共方法时，默认该服务有效。

```csharp
using Convai.Runtime.Room;
using UnityEngine;

public class ExampleInjected : MonoBehaviour
{
    private IConvaiRoomConnectionService _connectionService;

    /// <summary>
    /// 使用一个活动的房间连接服务初始化此组件。
    /// 必须由会话所有者在 Convai 会话建立后调用。
    /// </summary>
    public void Initialize(IConvaiRoomConnectionService connectionService)
    {
        _connectionService = connectionService;
    }

    public void DoSomething()
    {
        // ?. 用于防止尚未调用 Initialize。
        bool sent = _connectionService?.UpdateDynamicContext("...", mode: "append", runLlm: "false") ?? false;
        if (!sent)
            Debug.LogWarning("[Example] UpdateDynamicContext returned false.");
    }
}
```

{% hint style="info" %}
`UpdateDynamicContext` 返回 `false` 如果会话未连接。务必检查返回值。
{% endhint %}

***

## API 参考

```csharp
bool UpdateDynamicContext(string text, string mode = "append", string runLlm = "auto");
```

| 参数       | 类型    | 必需      | 默认值        | 描述                                           |
| -------- | ----- | ------- | ---------- | -------------------------------------------- |
| `text`   | `字符串` | 是（除非重置） | —          | 要注入的上下文文本。                                   |
| `mode`   | `字符串` | 否       | `"append"` | 如何应用文本： `"append"`, `"replace"`，或 `"reset"`. |
| `runLlm` | `字符串` | 否       | `"auto"`   | 是否触发 LLM 回复： `"true"`, `"false"`, `"auto"`.  |

**返回：** `true` 如果消息已发送到传输层； `false` 如果会话未连接。

***

#### `mode`

控制新文本如何应用到角色现有的临时上下文中。

| 模式        | 行为                                                               | 何时使用                        |
| --------- | ---------------------------------------------------------------- | --------------------------- |
| `append`  | 添加 `text` 到任何现有临时上下文中。之前的条目会保留。                                  | 渐进式信息——随着会话展开逐步添加事实。        |
| `replace` | 丢弃当前所有临时上下文，并将其完全替换为新的 `text`.                                   | 一个干净的状态切换——进入新场景、开启新章节。     |
| `reset`   | 清除所有 **运行时** 临时上下文。 `text` 会被忽略。 **初始动态信息不受影响** ——它会在整个会话期间保持固定。 | 在保留会话级固定上下文的同时重置已累积的运行时上下文。 |

**默认：** `"append"`

***

## 动态上下文与相关功能

<table><thead><tr><th>功能</th><th width="216.407470703125">方法</th><th width="127.9259033203125">范围</th><th width="107.370361328125">跨会话保留</th><th>用途</th></tr></thead><tbody><tr><td><strong>动态上下文</strong></td><td><code>UpdateDynamicContext</code></td><td>临时（运行时）</td><td>否</td><td>运行时事实：玩家状态、游戏事件、情境感知。</td></tr><tr><td><strong>初始动态信息</strong></td><td><code>ConvaiCharacter</code> 检查器</td><td>临时（会话开始时固定）</td><td>否</td><td>固定会话指令：场景规则、角色职责、稳定设置。不受 <code>reset</code>.</td></tr><tr><td><strong>动态信息</strong></td><td><code>SendDynamicInfo</code></td><td>每条消息</td><td>否</td><td>附加到特定用户发言上的内联上下文。</td></tr><tr><td><strong>模板键</strong></td><td><code>UpdateTemplateKeys</code></td><td>会话</td><td>否</td><td>解析命名占位符（<code>{PlayerName}</code>）在叙事设计文本中的值。</td></tr><tr><td><strong>场景元数据</strong></td><td><code>UpdateSceneMetadata</code></td><td>会话</td><td>否</td><td>供后端上下文锚定流程使用的场景结构化数据。</td></tr><tr><td><strong>仪表板背景故事</strong></td><td>Convai 控制台</td><td>永久</td><td>是</td><td>角色性格、世界观设定、固定行为规则。</td></tr></tbody></table>

***

## 常见陷阱

* **在会话连接前调用** `UpdateDynamicContext` 返回 `false` 并静默丢弃更新。请使用协程或订阅 `IConvaiRoomConnectionService.Connected` 以将上下文注入延迟到会话上线后。
* **使用 `append` 无限期地** 每个 `append` 会扩展上下文窗口。在长会话中，这会降低回复连贯性并增加延迟。请使用 `replace` 定期使用，或者采用 `DynamicContextManager` 模式。
* **发送 `text` 与 `reset` mode** `text` 在以下情况下会被忽略： `mode` 为 `"reset"`后，在聊天机器人组件上执行。 `null` 显式使用，以使意图更清晰。
* **期待同步效果** 动态上下文在端到端上是异步的。在下一次 LLM 推理之前，角色不会知道这次更新。不要设计假定会立即生效的逻辑。
* **过度使用 `runLlm: "true"`** 每次更新都强制立即回复会产生对话噪音。只在确实需要角色反应的时刻使用它。

***

## 快速参考

```csharp
// 将新信息追加到现有的临时上下文中（默认）
connectionService.UpdateDynamicContext("玩家刚刚进入地牢。");

// 用新内容替换所有临时上下文
connectionService.UpdateDynamicContext("玩家现在进入第二幕。", mode: "replace");

// 清除所有临时上下文
connectionService.UpdateDynamicContext(null, mode: "reset");

// 静默累积（无 LLM 回复）
connectionService.UpdateDynamicContext("玩家捡到了金钥匙。", runLlm: "false");

// 更新并触发角色立即回复
connectionService.UpdateDynamicContext("村庄着火了！", runLlm: "true");

// 注入情绪状态
connectionService.UpdateDynamicContext("请急促地说话。威胁正在逼近。", mode: "replace", runLlm: "false");
```

***

## 结论

动态上下文是你的游戏或应用的实时状态与 AI 角色对其理解之间的桥梁。角色的永久配置——性格、背景故事、行为规则——会稳定保留在 Convai 仪表板中。所有属于这个会话、这个用户以及这个时刻的内容都会通过 `UpdateDynamicContext`.

该 API 的设计刻意保持简洁：一个方法，三个参数。真正的巧思在于你如何使用它——无论是在会话开始时个性化对话、在会话中途对阈值变化做出反应、静默累积事件直到它们值得评论，还是在整个训练会话中跟踪能力缺口。

需要牢记的几个原则：

* **静默更新是默认姿态。** 使用 `runLlm: "false"` 用于状态同步。将 `runLlm: "true"` 留给真正值得角色回应的时刻。
* **将上下文窗口视为一种资源。** 无界的 `append` 会随着时间推移降低质量。请在 `replace` 自然边界处使用——如场景切换、模块变更、会话重置。
* **你的应用拥有状态。角色接收状态。** 动态上下文就是清晰地实现这种分离的机制。


---

# 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/dynamic-context.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.
