Kembali ke blog
Technical Practice · Vortap 团队

通过 Vortap 实现流式聊天:SSE 实战教程

Server-Sent Events(SSE)流式输出是 LLM 应用的标配。本文手把手教你用 Vortap API 实现流式聊天。

Artikel ini saat ini hanya tersedia dalam bahasa Mandarin.

通过 Vortap 实现流式聊天:SSE 实战教程

用户对 AI 回复的等待时间很敏感。流式输出(Streaming)让模型一边生成一边推送,大幅提升用户体验。

Vortap API 完整支持 OpenAI 兼容的 SSE 流式输出。本文从前端到后端,带你实现完整的流式聊天功能。

什么是 SSE?

Server-Sent Events 是一种服务器推送协议,相比 WebSocket 更轻量,天然适合 LLM 的文本流推送场景。

优势:

  • 一行代码开启(stream=True
  • 浏览器原生支持 EventSource API
  • 断连后自动重连
  • 省资源,无需 WebSocket 长连接管理

后端实现

Python FastAPI + Vortap 流式

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from openai import OpenAI

app = FastAPI()
client = OpenAI(
    api_key="YOUR_VORTAP_KEY",
    base_url="https://api.vortap.store/v1"
)

@app.get("/chat")
async def chat(message: str):
    def generate():
        stream = client.chat.completions.create(
            model="deepseek-r1",
            messages=[{"role": "user", "content": message}],
            stream=True
        )
        for chunk in stream:
            if chunk.choices[0].delta.content:
                yield f"data: {chunk.choices[0].delta.content}\n\n"
    return StreamingResponse(generate(), media_type="text/event-stream")

Node.js + Express

const OpenAI = require('openai');
const express = require('express');
const app = express();

const client = new OpenAI({
  apiKey: process.env.VORTAP_API_KEY,
  baseURL: 'https://api.vortap.store/v1'
});

app.get('/chat', async (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const stream = await client.chat.completions.create({
    model: 'deepseek-r1',
    messages: [{role: 'user', content: req.query.message}],
    stream: true
  });

  for await (const chunk of stream) {
    const content = chunk.choices[0]?.delta?.content || '';
    if (content) {
      res.write(`data: ${content}\n\n`);
    }
  }
  res.end();
});

前端实现

浏览器原生 EventSource

const eventSource = new EventSource('/chat?message=你好');
const output = document.getElementById('output');

eventSource.onmessage = (event) => {
  output.textContent += event.data;
};

eventSource.onerror = () => {
  console.log('连接断开,会自动重连');
};

高阶技巧

1. 流式同时显示思考链

DeepSeek R1 的思维链内容可以通过 choices[0].delta.reasoning_content 获取:

for await (const chunk of stream) {
  const reasoning = chunk.choices[0]?.delta?.reasoning_content;
  const content = chunk.choices[0]?.delta?.content;
  if (reasoning) showReasoning(reasoning);
  if (content) showContent(content);
}

2. 取消流式请求

使用 AbortController:

const controller = new AbortController();

fetch('/chat?message=你好', { signal: controller.signal })
  .then(response => { /* ... */ });

// 用户停止时
controller.abort();

3. 重连与错误处理

function connectWithRetry(url, maxRetries = 3) {
  let es = new EventSource(url);

  es.onerror = () => {
    es.close();
    if (maxRetries-- > 0) {
      setTimeout(() => connectWithRetry(url, maxRetries), 1000);
    }
  };
}

性能建议

  • 使用 keep-alive 连接池减少握手开销
  • 大并发场景考虑消息队列缓冲
  • 对于低延迟场景,DeepSeek R1 和 Qwen 系列响应时间在 200-800ms(首 token)

总结

通过 Vortap API 实现流式输出只需两步:

  1. 请求时加 stream: true
  2. 解析增量返回的 delta.content

完整的流式聊天可以在 30 分钟内上线。

立即体验 → vortap.store