Coze API 中的流式响应(Streaming)实现及协议,以及错误处理

在 Coze API 中,流式响应(Streaming Response)是 LLM 交互的一个关键特性,能够让模型生成的内容逐步返回给前端,而不是等整个响应完成后再一次性返回。这样可以提高用户体验,使得 AI 回复更加自然、即时。

 协议

Coze API 采用 HTTP 长连接(Long Polling)Server-Sent Events (SSE)WebSocket 来实现流式响应。其中,主流实现方式是 SSE,它基于 HTTP/1.1chunked transfer encoding(分块传输编码),允许服务器逐步推送数据到客户端。

SSE(Server-Sent Events)工作原理

SSE是一种在网页开发中使用的、基于HTTP长连接技术,允许服务器向客户端浏览器实时推送更新。客户端通过创建一个EventSource对象并指向服务器上的一个URL来发起请求,这个请求保持打开状态,服务器可以在这个单一的TCP连接上不断发送新的数据块。这些数据块被称为“事件”,每个事件包含类型(可选)、数据和一些元数据(如事件ID,重新连接时间间隔等)。服务器端以简单的文本格式(通常为UTF-8编码的纯文本)发送数据。

SSE 是基于 HTTP 的单向服务器推送技术,主要特点:

  • 服务器可以持续向客户端发送数据,而客户端不需要轮询。

  • 数据是通过 文本流(text/event-stream) 逐步发送的,前端可以实时监听并解析流数据。

  • 适用于消息推送、实时聊天等场景。

 SSE响应格式

event: message
data: {"content": "Hello"}
 
event: message
data: {"content": " how can I help you?"}

event: done
data: [DONE]

其中:

  • event: message 表示服务器发送的新数据块。

  • data: {"content": "Hello"} 是具体的消息内容。

  • event: done 代表流式响应结束。

在前端,我们可以解析这些 data 数据并逐步渲染到对话框中,实现类似 逐行打印 的效果。

在项目中怎么利用cozeAPI建立sse长连接

1.使用CozeAPI类初始化一个API客户端实例,同时传入必要的参数,比如token,基地址等等

2.调用实例方法apiClient.chat.stream发起流式请求,同时传入请求体参数,得到stream对象

3.利用 for await...of 循环来迭代 stream 对象,从而逐步处理服务端推送的数据

4.根据不同的事件类型(如 conversation.message.deltaconversation.message.completed 等),对数据进行不同的处理,比如拼接消息内容、更新状态、存储结果等。

底层技术和原理:

在浏览器环境中,apiClient.chat.stream 方法内部大概率使用了 EventSource 对象来建立 SSE(Server - Sent Events)连接。这种连接方式允许服务端向客户端实时推送数据。服务端需要设置特定的响应头,像 Content - Type: text/event - streamCache - Control: no - cacheConnection: keep - alive,以此来表明这是一个 SSE 连接。客户端则借助监听 EventSourcemessage 事件来接收服务端推送的数据。

结合VUE3实现

// 初始化 Coze API 客户端
const apiClient = new CozeAPI({
  token: '',
  baseURL: 'https://api.coze.cn',
  allowPersonalAccessTokenInBrowser: true, // 强制启用
})

async function fetchChatStream() {
try {
    // 发起流式请求
    const stream = await apiClient.chat.stream({
      bot_id: '',
      user_id: 'tay',
      conversation_id: conversation_id.value,
      additional_messages: [
        {
          content: textarea.value,
          content_type: 'text',
          role: 'user',
          type: 'question',
        },
      ],
      auto_save_history: true,
    })
    // 先占位,逐步填充内容
    // let botResponse = { role: 'assistant', content: '' }
    // messages.value.push(botResponse)
    // 监听流式数据
    for await (const chunk of stream) {
      if (chunk.event === 'conversation.message.delta' && chunk.data?.content) {
        messages.value += chunk.data.content // 逐步拼接
      } else if (chunk.event === 'conversation.message.completed') {
        if (chunk.data.type === 'answer') {
          isStreaming.value = false // 结束流状态
          messages.value = ''
          content_list.value = content_list.value.concat(chunk.data) // 将结果添加到 content_list 数组中
        } else if (chunk.data.type === 'follow_up') {
          follow_up_list.value = follow_up_list.value.concat(chunk.data) // 筛选 type 为 'verbose' 的对象
        }
      } else if (chunk.event === 'conversation.chat.completed') {
        break // 结束
      }
    }
  } catch (error) {
    console.error('流式请求失败', error)
  }
}

SSE 连接管理 

LLM 对话框组件 采用了 SSE(Server-Sent Events) 进行流式消息传输。
但在生产环境中,可能会遇到 服务器限流、网络波动、响应超时 等问题,导致流式对话体验不稳定,例如:

  • 启动 SSE 请求

    • 调用fetchChatStream()进行对话流式请求

    • 设置 timeoutTimer 监测 10s 内是否有数据返回

    • 收到数据时,重置 timeoutTimer,防止误触发超时

  • 处理超时

    • 10s 内未收到数据,主动断开 SSE 连接并触发 handleReconnect()

  • SSE 连接意外断开

    • 进入 catch 语句,调用 handleReconnect() 进行重连

  • 自动重连

    • 指数退避 + Jitter 控制重试间隔,避免服务器压力过大

    • 最大重试 5 次,如果失败,提示用户

  • 服务器限流

    • 如果 error.response.status === 429,系统自动等待后重试

### COZE 流式传输 SDK 使用指南 #### 安装 对于希望集成流式数据处理能力的应用程序,安装 COZE 流式传输 SDK 是第一步。此过程可以通过 Python 的包管理工具 `pip` 来完成: ```bash pip install --upgrade coze_stream_sdk ``` 该命令会下载最新版本的 COZE 流式传输 SDK 并将其安装到当前环境中[^1]。 #### 配置 成功安装后,需配置环境变量或在代码中设置必要的认证信息以便访问服务。通常这涉及到获取 API 密钥,并按照官方文档指示进行相应配置。具体步骤可参见 COZE 官方文档中的API 认证”章节[^2]。 #### 使用方法概述 COZE 流式传输 SDK 提供了一系列用于发送和接收实时消息的功能函数。为了更好地理解这些特性,在开始之前应该熟悉以下几个核心概念: - **连接建立**: 初始化客户端实例并与服务器建立安全连接。 - **事件监听器注册**: 注册回调函数来响应特定类型的事件。 - **消息发布/订阅模式**: 实现一对一或多播的消息传递机制。 下面是一个简单的例子展示了如何利用 COZE 流式传输 SDK 发送一条消息: ```python from coze_stream import StreamClient, Message client = StreamClient(api_key='your_api_key_here') message = Message(content="Hello World!") response = client.send_message(message) print(f"Message sent successfully! Response: {response}") ``` 这段代码创建了一个新的 `StreamClient` 对象,并通过它向指定端点发送了一条包含 "Hello World!" 字符串的消息[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值