> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kontext.so/llms.txt
> Use this file to discover all available pages before exploring further.

# 会话生命周期

> Kontext 会话如何创建、喂入消息、监听事件并关闭。

**Session（会话）** 表示一次聊天对话。它是 SDK 的核心组织单元——承载对话上下文、广告缓存、活跃的网络请求以及事件流。每一次 Kontext 接入都遵循相同的会话生命周期，即使各 SDK 的 API 形态略有不同。

## 一次对话对应一个会话

会话绑定到**一个用户的一次对话**。当用户开始新对话时，使用新的 `conversationId` 创建一个新会话。不要在多个对话之间复用同一个会话。

| 场景               | 应该怎么做                                      |
| ---------------- | ------------------------------------------ |
| 用户在同一对话中又发了一条消息  | 复用现有会话——直接调用 `addMessage`。                 |
| 用户开始新对话          | 关闭当前会话，并用新的 `conversationId` 创建一个新会话。      |
| 用户退出登录 / 另一个用户登录 | 关闭当前会话，并用新的 `userId` 创建一个新会话。              |
| 应用被后台并恢复，对话仍是同一个 | 如果会话仍在则继续复用；如果不在，则创建新会话，SDK 会基于现有消息重新填充缓存。 |

## 四个阶段

无论用哪个 SDK，每个会话都会走过相同的四个阶段。

### 1. 创建

创建会话时需要传入描述这次对话的 ID 与选项：

* `publisherToken` —— onboarding 时发放，用于标识你的账号。
* `userId` —— 该用户的稳定标识，跨对话保持不变。
* `conversationId` —— 当前对话的唯一标识。
* 可选项：`character`、`regulatory`、`variantId`，以及事件和调试回调。

各 SDK 的完整字段列表见 [SDK 页面](/overview)。每个 ID 的含义见 [ID 与 token](/concepts/ids-and-tokens)。

创建时，SDK 会在后台调用 `POST /init`。响应中携带服务端控制的开关：会话是否 `enabled`、`preloadTimeout`，以及两个遥测开关（`reportErrors`、`reportDebug`）。这些值在会话生命周期内保持不变——若需要刷新，请重建会话。

### 2. 喂消息

对话进行时，应用为每条新消息调用一次 `addMessage`。**用户消息和助手消息都需要传入**——SDK 使用完整的对话上下文（而不仅是最后一条消息）来寻找上下文相关的广告。

每次 `addMessage` 都会触发一次防抖后的 `POST /preload`。SDK 会把返回的广告与助手消息 id 配对，并为每条 message 触发 `filled` 或 `no-fill` 事件。

每条消息需要包含哪些字段、为什么 ID 要稳定，详见 [消息](/concepts/messages)。

### 3. 监听事件

会话也是 SDK 向你的应用反馈的通道。事件统一从同一个流中发出：

* **预加载期事件** —— 在 `/preload` 返回时按 `messageId` 触发 `filled` 或 `no-fill`。
* **渲染期事件** —— 当挂载的广告组件在展示广告时，触发 `viewed`、`clicked`、`error`，以及（适用时）视频和奖励事件。

订阅方式因 SDK 而异：闭包回调、Combine publisher、Kotlin `Flow`、React 事件 prop 等等。完整事件列表与含义见 [广告生命周期事件](/concepts/events)。

### 4. 关闭

对话结束时，请关闭会话。关闭会：

* 取消所有进行中的 `/preload`、`/error`、`/debug` 请求。
* 释放广告缓存。
* 停止事件流。

命令式 SDK（Swift、Kotlin、JS）通过显式调用 `destroy()` 关闭。声明式 SDK（React、React Native、Vue、Flutter）会在 `AdsProvider` 卸载时自动关闭会话，无需你额外调用。

忘记关闭命令式会话会泄漏资源，但并不致命——为同一用户下一次创建会话仍能正常工作。

## 可变 vs 不可变选项

创建时传入的大多数选项是**不可变的**——若要修改，请关闭当前会话并重建一个。少数选项在运行时**可变**；常见的包括 regulatory 对象（CMP 弹窗后 consent 字符串会变化），以及部分 SDK 的 character。可变面被刻意控制得很小，以保持广告缓存与对话上下文的一致性。

你所用平台上哪些选项可变、以及如何更新，请参考对应的 SDK 页面。

## 下一步

<CardGroup cols={2}>
  <Card title="ID 与 token" icon="key" href="/concepts/ids-and-tokens">
    会话上每个 ID 的含义与生成方。
  </Card>

  <Card title="消息" icon="message" href="/concepts/messages">
    `addMessage` 接收什么字段，以及稳定 ID 的重要性。
  </Card>

  <Card title="广告生命周期事件" icon="bell" href="/concepts/events">
    会话发出的所有事件及其含义。
  </Card>
</CardGroup>
