我目前正在研究如何将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的流?这是一个选项吗?
先谢谢你了。
1条答案
按热度按时间pobjuy321#
截至4月13日,tRPC仅支持json。
我昨天在一次聊天中向一位核心团队成员提出了这个问题。
关于这个主题有a discussion,但目前还不清楚tRPC是否支持流。