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

OpenAI流式响应在Node.js Firebase函数中无法分块返回问题排查

问题:Firebase函数中OpenAI流式响应无法分块返回

我在基于Express搭建的Firebase函数中编写了Node.js POST接口,用于调用OpenAI的text-davinci-003模型实现流式响应。目前接口能运行,但通过Postman或curl调用时,无法按预期分块返回响应,要等整个completion调用完成后才返回最终结果。

接口代码如下:

exports.complete = async (req, res, next) => {
    const {prompt} = req.body
    res.writeHead(200, {
      'Content-Type': 'text/plain',
      'Transfer-Encoding': 'chunked'
    })
    const result = await openai.createCompletion(
    {
      model: 'text-davinci-003',
      prompt: prompt,
      temperature: 0.6,
      max_tokens: 700,
      stream: true
    },
    { responseType: 'stream' }
  )

  result.data.on('data', data => {
    const lines = data
      .toString()
      .split('\n')
      .filter(line => line.trim() !== '')
    for (const line of lines) {
      const message = line.replace(/^data: /, '')
      if (message === '[DONE]') {
          res.end()
      }
      try {
        const parsed = JSON.parse(message)
        res.write(parsed.choices[0].text)
      } catch (error) {
        // console.error('Could not JSON parse stream message', message, error)
      }
    }
  })
}

附curl请求示例:

curl --location 'http://localhost:5001/testapp-7aca9/us-central1/api/completion/complete' \
--header 'Content-Type: application/json' \
--data '{
    "message": "Say two random lines"
}'

解决方案

1. 修正请求参数不匹配问题

你的curl请求中传递的是message字段,但接口代码里取的是prompt,这会导致模型接收到的prompt为undefined,直接影响生成逻辑。把curl请求的"message"改为"prompt":

curl --location 'http://localhost:5001/testapp-7aca9/us-central1/api/completion/complete' \
--header 'Content-Type: application/json' \
--data '{
    "prompt": "Say two random lines"
}'

2. 解决Firebase的响应缓冲问题

Firebase Functions默认会缓冲响应,直到函数执行完毕才发送给客户端,这是流式响应不生效的核心原因。需要调整响应处理逻辑:

  • 在每次调用res.write()后,添加res.flush()强制刷新响应缓冲区,确保chunk能即时发送到客户端;
  • 补充必要的响应头,比如Cache-Control: no-cache和Connection: keep-alive,避免客户端或中间层缓存响应。

修改后的代码片段:

try {
  const parsed = JSON.parse(message)
  res.write(parsed.choices[0].text)
  res.flush() // 新增:强制刷新缓冲区
} catch (error) {
  // console.error('Could not JSON parse stream message', message, error)
}

3. 升级OpenAI SDK以获得原生流式支持

你使用的旧版SDK需要手动处理流数据,而OpenAI Node SDK v4+已经原生支持流式响应,代码更简洁且兼容性更好。升级SDK后,可改用如下方式实现:

const OpenAI = require('openai');
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

exports.complete = async (req, res) => {
  const { prompt } = req.body;
  // 设置流式响应所需的响应头
  res.setHeader('Content-Type', 'text/plain');
  res.setHeader('Transfer-Encoding', 'chunked');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  try {
    const stream = await openai.completions.create({
      model: 'text-davinci-003',
      prompt: prompt,
      temperature: 0.6,
      max_tokens: 700,
      stream: true,
    });

    // 用for-await-of遍历流,自动处理chunk
    for await (const chunk of stream) {
      const text = chunk.choices[0]?.text || '';
      if (text) {
        res.write(text);
        res.flush();
      }
    }
  } catch (err) {
    res.status(500).write(`Error: ${err.message}`);
  } finally {
    res.end();
  }
};

4. 确认Firebase函数的运行环境配置

确保你的Firebase Functions使用的是支持流式响应的运行环境,避免使用免费层的限制(免费层可能对长连接或流式响应有约束),可以在firebase.json中配置函数的运行参数:

{
  "functions": {
    "runtime": "nodejs18",
    "maxInstances": 10,
    "memory": "512MB"
  }
}

内容的提问来源于stack exchange,提问作者Aousaf Rashid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:33:21