> 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/web-plugins/convai-web-sdk/dynamic-context.md).

# 在运行时更新角色上下文

向角色提供关于场景、会话以及它正在交谈对象的实时信息，并控制每次更新是否会促使它回应。

在应用发生变化时让角色保持知情：在连接时传入初始上下文，然后在会话期间无需重新连接即可发送更新。当角色在对话时需要了解场景状态、进度或发生变化的文件时，请使用此页面。这里的每个方法都存在于 `ConvaiClient` 以及返回值上 `useConvaiClient`.

### 先决条件

* 已安装 Convai Web SDK，并且有一个可连接的客户端。参见 [Web SDK 快速入门](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/quickstart.md).
* 对于模板键，请使用已启用叙事设计的角色。参见 [叙事设计指南](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/narrative-design-guide.md).

### 在连接时传递上下文

设置 `dynamicInfo` 到初始情况的文本描述。

```ts
import { ConvaiClient } from '@convai/web-sdk/core';

const client = new ConvaiClient({
  apiKey: 'YOUR_API_KEY',
  characterId: 'YOUR_CHARACTER_ID',
  dynamicInfo: '学员：Aria。模块：化学品泄漏响应。进度：5步中的第2步。',
});
```

`keepInContext` 控制该文本的保留方式。使用 `true`时，它在整个连接期间都表现为静态提示，并且在重新连接后必须再次发送。使用 `false`时（默认），它可以在会话期间更新和重置。 `keepInContext` 仅在与 `dynamicInfo`.

### 在会话期间更新上下文

`updateContext(options)` 会更改角色的临时运行时上下文。

```ts
// 在不回复的情况下添加到现有上下文
client.updateContext({ text: '学员关闭了阀门。', mode: 'append', run_llm: 'false' });

// 替换上下文，并让 Convai 决定是否回应
client.updateContext({ text: '5步中的第3步：控制泄漏。', mode: 'replace', run_llm: 'auto' });

// 清除上下文
client.updateContext({ mode: 'reset' });
```

| 选项                         | 值                                      | 默认值        | 效果                                                                                                                                              |
| -------------------------- | -------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `文本`                       | `string`                               | 无          | 要应用的上下文。除非 `模式` 是 `'reset'` 或仅 `current_attention_object` 发生变化。                                                                                 |
| `模式`                       | `'append'`, `'replace'`, `'reset'`     | `'append'` | 向临时上下文添加、替换或清除内容。                                                                                                                               |
| `run_llm`                  | `'true'`, `'false'`, `'auto'`          | `'auto'`   | `'true'` 总是触发回应并停止本地口型同步播放。 `'false'` 绝不会触发回应。 `'auto'` 让 Convai 自行决定，而不会停止播放。                                                                  |
| `respond_mode`             | `'must_respond'`, `'auto'`, `'silent'` | 无          | 可替代 `run_llm`。当两者都设置时， `run_llm` 将优先生效。                                                                                                         |
| `current_attention_object` | `string`                               | 无          | 角色当前关注的对象。必须与以下内容中的名称匹配： `actionConfig.objects`；空字符串会将其清除。参见 [处理角色动作](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/actions.md). |

当 `文本` 在模式之外缺失 `'reset'` 模式，并且未提供注意对象时，不会发送任何内容，控制台会记录 `[ConvaiClient] updateContext：除非 mode 为 'reset'，否则需要 text 或 current_attention_object`。除了 `uploadFile`之外，本页上的每个方法在会话未连接时都不会执行任何操作。

### 发送快速动态信息更新

`updateDynamicInfo(text)` 发送一条 `update-dynamic-info` 消息，将该文本作为会话的动态信息传递。这与 `updateContext`不同，它只接受字符串，并且没有模式或回应控制。空文本或仅包含空白的文本会被忽略。

```ts
client.updateDynamicInfo('学员健康状况：30%。');
```

使用 `updateContext` 当你需要在 append、replace 和 reset 之间做选择，或控制回应时使用。

### 读取上下文 token 配额

Convai 会确认每个 `context-update` 并传入 `serverResponse` 事件。其 `extras` 可以包含 token 数量。

```ts
client.on('serverResponse', (response) => {
  if (response.event_type !== 'context-update') return;
  if (response.status === 'error') {
    console.error('上下文更新被拒绝：', response.message);
    return;
  }
  const { token_count, remaining_tokens, max_tokens } = response.extras ?? {};
  console.log(`上下文 token：已使用 ${token_count}，剩余 ${remaining_tokens} / ${max_tokens}`);
});
```

`extras` 也可以携带 `static_token_count`, `runtime_token_count`, `static_max_tokens`, `runtime_max_tokens`，以及 `content`，即更新后保留的完整运行时上下文。

### 使用模板键个性化叙事设计

叙事设计部分的目标和 speak 标签可以包含单大括号占位符，例如 `{player_name}`。在评估该部分时，模板键会替换它们，因此一个叙事图可服务于多个会话。键区分大小写，且没有对应键的占位符会解析为空字符串。

在连接时用以下内容预置键： `会将动态信息作为该连接的固定提示保留。`:

```ts
const client = new ConvaiClient({
  apiKey: 'YOUR_API_KEY',
  characterId: 'YOUR_CHARACTER_ID',
  narrativeTemplateKeys: {
    player_name: 'Aria',
    location: 'Engineering Deck',
  },
});
```

在会话期间通过以下方式更改它们： `updateTemplateKeys`，然后再触发使用这些键进入该部分的触发器：

```ts
client.updateTemplateKeys({ player_name: 'Aria', location: 'Medical Bay' });
client.sendTriggerMessage('NextObjective');
```

`updateTemplateKeys` 会替换整个映射，而不是合并到其中，因此请包含图表仍然需要的每个键。空映射不会发送。当角色未启用叙事设计时，Convai 会确认 `update-template-keys` 消息，并在 `serverResponse` 上返回错误 `叙事设计服务不可用`.

### 控制角色何时回应

`respondModes` 在连接时设置每种输入类型是否会让角色回应。 `respondModeUpdate` 会在会话期间更改其中之一。

```ts
const client = new ConvaiClient({
  apiKey: 'YOUR_API_KEY',
  characterId: 'YOUR_CHARACTER_ID',
  respondModes: { contextUpdate: 'silent', sceneMetadata: 'auto' },
});

// 之后：
const updateId = client.respondModeUpdate({ modality: 'context_update', mode: 'auto' });
```

| `respondModes` 字段 | `respondModeUpdate` 模态 | 允许的模式                                  |
| ----------------- | ---------------------- | -------------------------------------- |
| `文本`              | `'text'`               | `'must_respond'`                       |
| `音频`              | `'audio'`              | `'must_respond'`                       |
| `视觉`              | `'vision'`             | `'must_respond'`, `'auto'`, `'silent'` |
| `contextUpdate`   | `'context_update'`     | `'must_respond'`, `'auto'`, `'silent'` |
| `触发器`             | `'trigger'`            | `'must_respond'`, `'auto'`, `'silent'` |
| `sceneMetadata`   | `'scene_metadata'`     | `'must_respond'`, `'auto'`, `'silent'` |

`respondModeUpdate` 会返回其发送的更新 ID，或者 `null` 当会话未连接时返回。请传入你自己的 `updateId` 以进行选择。

### 描述场景

`updateSceneMetadata(items, options?)` 向角色说明可见或附近有什么。它仅用于描述：不会更改 `actionConfig`，因此通过这种方式发送的项目永远不会成为动作目标。

```ts
client.updateSceneMetadata(
  [
    { name: 'smoke', description: '储藏室里飘出淡淡的烟雾。' },
    { name: 'alarm', description: '火警正在响。' },
  ],
  { respondMode: 'must_respond' },
);
```

`respondMode` 是可选的。 `'must_respond'` 会让角色回应，并停止新回合的本地口型同步播放。

### 向角色发送文件

`uploadFile(file, options?)` 在会话期间向角色发送文件。它仅适用于默认的 LiveKit 传输。

```ts
const input = document.querySelector<HTMLInputElement>('#file-input');

input?.addEventListener('change', async () => {
  const file = input.files?.[0];
  if (!file) return;
  try {
    await client.uploadFile(file, {
      onProgress: (percent) => console.log(`${percent}% uploaded`),
    });
  } catch (error) {
    console.error('上传失败：', error);
  }
});
```

| 选项           | 默认值             | 效果                     |
| ------------ | --------------- | ---------------------- |
| `topic`      | `'file-upload'` | 上传的路由 topic。           |
| `onProgress` | 无               | 调用时会传入 0 到 100 的整数百分比。 |

支持的格式为 JPEG、PNG、GIF 和 WebP，最大 10 MB。文件以原始二进制形式发送。上传完成时 Promise 会解析，无法发送时会拒绝，因此请将调用包裹在 `尝试`/`捕获`.

### 验证一次更新

发送 `client.updateContext({ text: '警报已经停止。', run_llm: 'false' })`，然后询问角色它对警报了解什么。

{% hint style="success" %}
一个 `serverResponse` 带有 `event_type` `'context-update'` 并且 `status` `'success'` 事件到达时，角色的回答会反映新的上下文。
{% endhint %}

### 后续步骤

{% content-ref url="/pages/503cd2436973022c29d385f47025d13de33f428c" %}
[处理角色动作](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/actions.md)
{% endcontent-ref %}

{% content-ref url="/pages/4f33318cc644cad5dc970e09e48c72b8b29329f6" %}
[使用长期记忆](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/long-term-memory.md)
{% endcontent-ref %}

{% content-ref url="/pages/1ef8009eea712d4c41fd7a2a07e473a277395698" %}
[处理错误和断开连接](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/error-handling.md)
{% endcontent-ref %}

{% content-ref url="/pages/8c6e3631e7e7da5b3c9acf5a0019d7737dc79e19" %}
[Web SDK 事件参考](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/event-reference.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/web-plugins/convai-web-sdk/dynamic-context.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.
