You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Firebase Cloud Functions实现ChatGPT响应实时流式返回?

实现ChatGPT流式响应返回至Firebase Cloud Functions客户端

要实现实时流式返回ChatGPT的响应,你需要修改Cloud Functions代码以处理OpenAI的流式输出,并通过分块传输将内容逐步发送给客户端。以下是具体方案:

核心修改点

  • 设置流式响应头:启用分块编码,告诉客户端准备接收连续的数据流
  • 处理OpenAI流式输出:遍历SDK返回的异步迭代器(或监听数据流事件),将每个内容片段即时发送
  • 客户端适配:通过Fetch API的ReadableStream或Server-Sent Events(SSE)接收并渲染流式内容

修改后的Cloud Functions代码(基于OpenAI SDK v4)

const functions = require("firebase-functions");
const { OpenAI } = require("openai");

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY // 从环境变量读取API密钥
});

exports.chat = functions.https.onRequest(async (req, res) => {
  const { message } = req.body;

  // 配置流式响应头
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");
  res.setHeader("Access-Control-Allow-Origin", "*"); // 根据实际需求调整跨域规则

  try {
    // 调用OpenAI流式聊天接口
    const stream = await openai.chat.completions.create({
      model: "gpt-3.5-turbo",
      stream: true,
      messages: [
        { role: "system", content: "You are a helpful assistant." },
        { role: "user", content: message }
      ]
    });

    // 遍历流式响应的每个片段
    for await (const chunk of stream) {
      const content = chunk.choices[0]?.delta?.content || "";
      if (content) {
        // 以SSE格式发送内容(方便客户端解析)
        res.write(`data: ${JSON.stringify({ content })}\n\n`);
      }
    }

    // 结束响应
    res.end();
  } catch (error) {
    // 发送错误信息
    res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`);
    res.end();
  }
});

旧版OpenAI SDK(v3)兼容代码

如果你仍在使用v3版本SDK,可改用事件监听方式处理流式输出:

const functions = require("firebase-functions");
const openai = require("openai");

openai.apiKey = process.env.OPENAI_API_KEY;

exports.chat = functions.https.onRequest((req, res) => {
  const { message } = req.body;

  // 配置响应头
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");
  res.setHeader("Access-Control-Allow-Origin", "*");

  // 调用流式接口
  openai.ChatCompletion.create({
    model: "gpt-3.5-turbo",
    stream: true,
    messages: [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: message }
    ]
  })
  .on("data", (chunk) => {
    const lines = chunk.toString().split("\n").filter(line => line.trim() !== "");
    for (const line of lines) {
      const data = line.replace(/^data: /, "");
      if (data === "[DONE]") {
        res.end();
        return;
      }
      try {
        const json = JSON.parse(data);
        const content = json.choices[0]?.delta?.content || "";
        if (content) {
          res.write(`data: ${JSON.stringify({ content })}\n\n`);
        }
      } catch (err) {
        console.error("解析流式数据失败:", err);
      }
    }
  })
  .on("error", (error) => {
    res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`);
    res.end();
  })
  .on("end", () => {
    res.end();
  });
});

客户端接收示例(Fetch API)

async function sendChatMessage(userMessage) {
  const response = await fetch("/chat", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ message: userMessage })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  const outputElement = document.getElementById("chat-output");

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const text = decoder.decode(value);
    // 拆分并解析SSE格式的消息
    const messages = text.split("\n\n").filter(msg => msg.startsWith("data: "));
    
    for (const msg of messages) {
      const data = JSON.parse(msg.replace("data: ", ""));
      if (data.content) {
        // 将内容追加到聊天界面
        outputElement.textContent += data.content;
      } else if (data.error) {
        outputElement.textContent += `\n错误: ${data.error}`;
      }
    }
  }
}

注意事项

  • 函数超时设置:Firebase HTTP函数默认超时60秒,流式响应可能需要更长时间,可在Firebase控制台将函数超时调整至最大值90秒
  • 跨域配置:根据客户端域名调整Access-Control-Allow-Origin头,避免跨域错误
  • 错误处理:需处理OpenAI API调用失败、网络中断等异常情况,确保客户端能收到错误提示

内容的提问来源于stack exchange,提问作者Miguel Dey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:00:45