> 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/qing-xu.md).

# 情绪

### 连接时启用

```ts
const client = useConvaiClient({
  apiKey: '...',
  characterId: '...',
  enableEmotion: true,
});
```

当 `enableEmotion` 为 `true`，SDK 会发送 `emotion_config` 到服务器。如果没有它，就不会发送任何 `bot-emotion` 帧，并且 `emotionChange` 从不触发。

***

### 订阅 `emotionChange`

```ts
client.on('emotionChange', (emotion) => {
  if (emotion === null) {
    // 对话重置 — 清除任何情绪 UI
    return;
  }
  console.log(emotion.emotion); // 例如：“Trust”、“Grief”、“Joy”
  console.log(emotion.scale);   // 整数强度：1（低）→ 3（高）
});
```

事件触发时：

* 每次角色轮次后触发，带有检测到的情绪和强度
* 在 `null` 当对话被重置时（例如 `resetSession()`)

***

### React

```tsx
import { useConvaiClient, ConvaiWidget } from '@convai/web-sdk';
import { useEffect, useState } from 'react';

export default function App() {
  const client = useConvaiClient({
    apiKey: '...',
    characterId: '...',
    enableEmotion: true,
  });

  const [emotion, setEmotion] = useState<{ emotion: string; scale?: number } | null>(null);

  useEffect(() => {
    return client.on('emotionChange', setEmotion);
  }, [client]);

  return (
    <>
      {emotion && (
        <div style={{ position: 'fixed', top: 20, right: 20 }}>
          {emotion.emotion} ({emotion.scale})
        </div>
      )}
      <ConvaiWidget convaiClient={client} />
    </>
  );
}
```

`client.on(...)` 返回一个取消订阅函数 — 将其从 `useEffect` 中返回会自动清理。

#### 通过 `state.emotion`

情绪也可在响应式状态对象上同步获取——如果你已经从 state 渲染，则无需额外订阅：

```tsx
// 每当 stateChange 触发时，emotion 都会更新 — 无需 useEffect
<div>{client.state.emotion?.emotion}</div>
```

***

### 原生 JS

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

const client = new ConvaiClient({
  apiKey: '...',
  characterId: '...',
  enableEmotion: true,
});

const emotionEl = document.querySelector('#emotion');

const unsubEmotion = client.on('emotionChange', (emotion) => {
  if (emotionEl) {
    emotionEl.textContent = emotion ? `${emotion.emotion} (${emotion.scale})` : '';
  }
});

createConvaiWidget(document.body, { convaiClient: client as any });

// 清理时
// unsubEmotion();
```

***

### 微调检测

通过以下方式控制情绪检测的激进程度： `emotionConfig`:

支持两种提供方： `"llm"` 使用语言模型从回复文本中推断情绪； `"nrclex"` 使用 NRC 情绪词典，这是一种按词级别查找的词典，速度更快但上下文感知较弱。

```ts
// LLM 提供方（默认）— 无需额外选项
useConvaiClient({
  apiKey: '...',
  characterId: '...',
  enableEmotion: true,
  emotionConfig: { provider: 'llm' },
});

// NRCLex 提供方 — 支持强度阈值
useConvaiClient({
  apiKey: '...',
  characterId: '...',
  enableEmotion: true,
  emotionConfig: {
    provider: 'nrclex',
    min_word_threshold: 3,        // 跳过短于此长度的轮次
    low_intensity_threshold: 0.33,  // 分数低于此值 → 级别 1
    high_intensity_threshold: 0.66, // 分数高于此值 → 级别 3；介于两者之间 → 级别 2
  },
});
```

#### `"llm"` 配置

| 字段    | 类型      | 说明                |
| ----- | ------- | ----------------- |
| `提供方` | `"llm"` | 使用 LLM 从回复上下文推断情绪 |

#### `"nrclex"` 配置

| 字段                         | 类型         | 默认值    | 说明                 |
| -------------------------- | ---------- | ------ | ------------------ |
| `提供方`                      | `"nrclex"` | —      | 词级别的 NRC 情绪词典查找    |
| `min_word_threshold`       | `数字`       | `3`    | 跳过少于此词数的轮次的检测      |
| `low_intensity_threshold`  | `数字`       | `0.33` | 级别 1 和级别 2 之间的分数边界 |
| `high_intensity_threshold` | `数字`       | `0.66` | 级别 2 和级别 3 之间的分数边界 |

***

### API 参考

#### `enableEmotion` （连接选项）

| 字段              | 类型    | 默认值     | 说明                                        |
| --------------- | ----- | ------- | ----------------------------------------- |
| `enableEmotion` | `布尔值` | `false` | 启用情绪检测。必须 `true` 用于 `emotionChange` 才会触发。 |

#### `emotionChange` 事件

```ts
client.on('emotionChange', (emotion: { emotion: string; scale?: number } | null) => { ... });
```

| 字段        | 类型       | 说明                                     |
| --------- | -------- | -------------------------------------- |
| `emotion` | `string` | 情绪标签（例如 `"Trust"`, `"Grief"`, `"Joy"`) |
| `scale`   | `数字`     | 强度： `1` = 低， `2` = 中， `3` = 高          |

触发 `null` 在对话重置时。

#### `state.emotion`

```ts
client.state.emotion // { emotion: string; scale?: number } | null
```

与最后一个 `emotionChange` 有效载荷相同。可在 React 钩子中通过以下方式实现响应式： `stateChange`.


---

# 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/web-plugins/convai-web-sdk/qing-xu.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.
