> 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/api-can-kao/core-api-reference/live-apis-beta/metrics.md).

# 指标

本页解释了通过 WebRTC 数据通道发送给客户端的指标。

***

### 1. 在 Connect API 请求中启用指标

要在 WebRTC 数据通道上接收指标，请在 `debug` 为 `true` 调用 connect API 时设置。

HTTP 请求：

```http
POST https://live.convai.com/connect
X-Api-Key: <X-Api-Key>
Content-Type: application/json
```

请求体：

```json
{
  "character_id": "<your character_id>",
  "debug": true
}
```

***

### 2. 在客户端接收指标

指标会作为 RTVI 消息通过 WebRTC 数据通道发送。

使用以下条件过滤传入消息：

* `label === "rtvi-ai"`
* `type === "metrics"`

***

### 3. 指标消息结构

#### A：TTFB 消息

```json
{
  "label": "rtvi-ai",
  "type": "metrics",
  "data": {
    "ttfb": [
      {
        "processor": "<PROCESSOR_INSTANCE>",
        "model": "<MODEL_NAME>",
        "value": "<TTFB_SECONDS>"
      }
    ]
  }
}
```

#### B：处理消息

```json
{
  "label": "rtvi-ai",
  "type": "metrics",
  "data": {
    "processing": [
      {
        "processor": "<PROCESSOR_INSTANCE>",
        "model": "<MODEL_NAME>",
        "value": "<PROCESSING_SECONDS>"
      }
    ]
  }
}
```

#### C：自定义（NeuroSync）消息

```json
{
  "label": "rtvi-ai",
  "type": "metrics",
  "data": {
    "custom": [
      {
        "processor": "<PROCESSOR_INSTANCE>",
        "model": "<MODEL_NAME>",
        "metric": "<CUSTOM_METRIC_NAME>",
        "value": "<CUSTOM_METRIC_VALUE>",
        "type": "NeuroSyncMetricsData"
      },
      {
        "processor": "<PROCESSOR_INSTANCE>",
        "model": "<MODEL_NAME>",
        "metric": "<CUSTOM_METRIC_NAME>",
        "value": "<CUSTOM_METRIC_VALUE>",
        "type": "NeuroSyncMetricsData"
      }
    ]
  }
}
```

说明：

* `data` 在一条消息中只包含一个键（`ttfb` 或 `processing` 或 `custom`）。
* 在单个响应轮次中，你会收到多条指标消息。

***

### 4. 指标类型及含义

| 指标桶          | 位置                  | 含义                                | 单位 |
| ------------ | ------------------- | --------------------------------- | -- |
| `ttfb`       | `data.ttfb[]`       | 从处理器接收第一条输入到该处理器输出第一条结果之间的时间。     | 秒  |
| `processing` | `data.processing[]` | 该处理器在所发出的 span/turn 窗口内的总有效处理时间。  | 秒  |
| `custom`     | `data.custom[]`     | 自定义处理器指标（当前为 NeuroSync 质量/吞吐量信号）。 | 数值 |

条目字段：

* `processor` （字符串）：阶段实例标识符
* `model` （字符串，可选）：可用时的模型标识符
* `值` （数值）：指标值（或文档示例中的占位值）
* `metric` （字符串，仅自定义）：指标键，例如 `neurosync.output_fps`
* `类型` （字符串，仅自定义）：当前 `NeuroSyncMetricsData`

当前发出的 NeuroSync 自定义指标：

* `neurosync.output_fps`
* `neurosync.blendshapes_received`
* `neurosync.blendshapes_sent`
* `neurosync.frames_dropped`

***

### 5. 查看指标的示例代码

```javascript
import { Room, RoomEvent } from "livekit-client";

const CORE_SERVICE_BASE_URL = "https://live.convai.com";
const API_KEY = "<X-Api-Key>";
const CHARACTER_ID = "<your character_id>";

async function startVoiceSessionAndWatchMetrics() {
  // 1) 使用启用 debug 的状态调用 /connect
  const connectResp = await fetch(`${CORE_SERVICE_BASE_URL}/connect`, {
    method: "POST",
    headers: {
      "x-api-key": API_KEY,
      "content-type": "application/json",
    },
    body: JSON.stringify({
      character_id: CHARACTER_ID,
      debug: true,
    }),
  });

  if (!connectResp.ok) {
    throw new Error(`/connect failed: ${connectResp.status}`);
  }

  const connectData = await connectResp.json();
  const { room_url, token, session_id } = connectData;

  // 2) 使用 room_url + token 加入 WebRTC 房间
  const room = new Room();

  room.on(RoomEvent.Connected, () => {
    console.log("已连接到房间");
  });

  room.on(RoomEvent.DataReceived, (payload) => {
    // LiveKit 数据负载是字节 -> 解码 -> 解析 JSON
    let msg;
    try {
      const text = new TextDecoder().decode(payload);
      msg = JSON.parse(text);
    } catch {
      return;
    }

    // 3) 仅过滤 RTVI 指标消息
    if (msg?.label !== "rtvi-ai") return;
    if (msg?.type !== "metrics") return;

    const ttfb = msg?.data?.ttfb ?? [];
    const processing = msg?.data?.processing ?? [];
    const custom = msg?.data?.custom ?? [];

    console.log("RTVI 指标", { ttfb, processing, custom });
  });

  room.on(RoomEvent.Disconnected, () => {
    console.log("已从房间断开连接");
  });

  await room.connect(room_url, token);

  // 返回对象，以便调用方稍后断开连接/清理
  return { room, session_id };
}

// 示例用法：
startVoiceSessionAndWatchMetrics().catch(console.error);
```

***

### 6. 使用说明

这些指标在实时对话期间提供即时的每轮上下文，可作为实用的故障排查信号。当响应感觉缓慢或质量下降时，载荷有助于识别哪个阶段对延迟贡献最大（STT、LLM、TTS 或 NeuroSync）。


---

# 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/api-can-kao/core-api-reference/live-apis-beta/metrics.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.
