tRPC 流 API 响应从 OpenAI 到 React 客户端

问题描述 投票:0回答:1

我目前正在研究一种将

openai-node
包实施到我的 Next.js 应用程序中的方法。由于 OpenAI 补全的生成时间较长,我想使用流式传输(包内通常不支持流式传输,请参阅here)。但是我有一个完美的解决方法,在下面的代码中:

const response = await openai.createChatCompletion({
  messages: [
    {
      role: 'user',
      content: 'hello there!'
    }
  ],
  model: 'gpt-3.5-turbo',
  temperature: 0.85,
  stream: true
}, { responseType: 'stream' })

let activeRole = '';

response.data.on('data', (data: Buffer) => {

  const lines = data.toString().split('\n').filter(line => line.trim() !== '');
  lines.forEach(( line, idx, arr ) => {

    const message = line.replace(/^data: /, '');
    if(message === '[DONE]') return

    const parsed:OpenAIStreamChunk = JSON.parse(message);
    if(parsed.choices[0].finish_reason == 'stop') return

    activeRole = parsed.choices[0].delta.role ?? activeRole

    const chunk = {
      role: activeRole,
      content: parsed.choices[0].delta.content ?? 'EMPTY'
    }

    console.log(chunk)
  })

});

现在,我想使用上面的代码将这个流从我的 API 路由传输到我的前端(流在那里被解析)。我在我的应用程序中使用了

tRPC
,到目前为止已经创建了这个:

// Backend code:

import { Readable } from 'stream';
import { initOpenAI } from 'lib/ai';

export const analysisRouter = router({

  generate: authenticatedProcedure
    .input(z.object({
    }))
    .mutation( async ({ ctx, input }) => {

      const stream = new Readable({ objectMode: true})
      const openai = initOpenAI()

      const result = await openai.createChatCompletion({
        messages: [
          {
            role: 'user',
            content: 'hello there!'
          }
        ],
        model: 'gpt-3.5-turbo',
        temperature: 0.85,
        stream: true
      }, { responseType: 'stream' })

      let activeRole = '';

      result.data.on('data', (data: Buffer) => {

        const lines = data.toString().split('\n').filter(line => line.trim() !== '');
        for(const line of lines) {

          const message = line.replace(/^data: /, '');
          if(message === '[DONE]') return

          const parsed:OpenAIStreamChunk = JSON.parse(message);
          if(parsed.choices[0].finish_reason == 'stop') return

          activeRole = parsed.choices[0].delta.role ?? activeRole

          if(parsed.choices[0].delta.content) {
            stream.push({
              role: activeRole,
              content: parsed.choices[0].delta.content
            })
          }
        }
      });

      return stream
    })
})


// Front-end code, that reads the stream (this is in React)

useEffect(() => {
  (async () => {

    const stream = await trpc.analysis.generate.mutate({ type: 'lesson'})
    stream.on('data', (data) => { console.log(data) })
    
  })()
}, [])

除了上面的以下代码不能正常工作。客户端流上的事件为空,

stream.on
未被识别为有效函数。我知道这个 tRPC 代码在技术上不是流,但有人能指出我显而易见的地方吗?我需要更改什么以支持通过 tRPC 进行流式传输?这甚至是一个选择吗?

提前致谢。

typescript next.js stream openai-api trpc.io
1个回答
0
投票

截至 4 月 13 日,tRPC 仅支持 json。

我昨天在聊天中向核心团队成员问了这个问题。

有关于该主题的讨论,但不清楚 tRPC 是否支持流式传输。

© www.soinside.com 2019 - 2024. All rights reserved.