使用Node.js和Express.js打开OpenAI完成流。

7

我正在尝试构建一个 ChatGPT 网站的克隆版本,现在我需要制作流式完成效果,以逐字显示结果。 我的服务器是一个使用 Express.js 框架的 TypeScript Node.js 应用程序。

这是路由:

import express, { Request, Response } from 'express';
import cors from 'cors';
import { Configuration, OpenAIAPI } from 'openai';

// ...

app.post('/api/admin/testStream', async (req: Request, res: Response) => {
    const { password } = req.body;

    try {
        if (password !== process.env.ADMIN_PASSWORD) {
            res.send({ message: 'Incorrect password' });
            return;
        }
        const completion = await openai.createCompletion({
            model: 'text-davinci-003',
            prompt: 'Say this is a test',
            stream: true,
        }, { responseType: 'stream' });

        completion.data.on('data', (chunk: any) => {
            console.log(chunk.toString());
        });

        res.send({ message: 'Stream started' });
    } catch (err) {
        console.log(err);
        res.send(err);
    }
});

// ...

现在,它给我一个错误,说

属性“on”在类型“CreateCompletionResponse”上不存在。ts(2339)

即使我设置了{ responseType: 'stream' }

我该如何解决这个问题并将响应逐块发送到前端?(我正在使用Socket.IO。)


你可能需要使用completion.on('data', ...);代替completion.data.on('data', ...); - uzluisf
@uzluisf已经尝试过了,它也不起作用(同样的错误)。 - Alexxino
你说得对。我看了一下这个包的NPM页面,上面写着“流式完成(stream=true)目前还没有本地支持,但如果需要,可以使用解决方法。”你试过了吗?虽然它似乎与你已经拥有的东西非常相似?解决方法链接:https://github.com/openai/openai-node/issues/18#issuecomment-1369996933 - uzluisf
很高兴你已经解决了它 :)! - uzluisf
1个回答

16

终于在 @uzluisf 的帮助下解决了!这是我所做的:

import express, { Request, Response } from 'express';
import cors from 'cors';
import { Configuration, OpenAIAPI } from 'openai';
import http, { IncomingMessage } from 'http';

// ...

app.post('/api/admin/testStream', async (req: Request, res: Response) => {
    const { password } = req.body;

    try {
        if (password !== process.env.ADMIN_PASSWORD) {
            res.send({ message: 'Incorrect password' });
            return;
        }

        const completion = await openai.createChatCompletion({
            model: 'gpt-3.5-turbo',
            messages: [{ role: 'user', content: 'When was America founded?' }],
            stream: true,
        }, { responseType: 'stream' });

        const stream = completion.data as unknown as IncomingMessage;

        stream.on('data', (chunk: Buffer) => {
            const payloads = chunk.toString().split("\n\n");
            for (const payload of payloads) {
                if (payload.includes('[DONE]')) return;
                if (payload.startsWith("data:")) {
                    const data = JSON.parse(payload.replace("data: ", ""));
                    try {
                        const chunk: undefined | string = data.choices[0].delta?.content;
                        if (chunk) {
                            console.log(chunk);
                        }
                    } catch (error) {
                        console.log(`Error with JSON.parse and ${payload}.\n${error}`);
                    }
                }
            }
        });

        stream.on('end', () => {
            setTimeout(() => {
                console.log('\nStream done');
                res.send({ message: 'Stream done' });
            }, 10);
        });

        stream.on('error', (err: Error) => {
            console.log(err);
            res.send(err);
        });
    } catch (err) {
        console.log(err);
        res.send(err);
    }
});

// ...

欲知详情,请访问https://github.com/openai/openai-node/issues/18

同时成功通过Socket.IO事件发送消息块!


顺便说一下,如果有人想要查看这个应用的更多内容,可以查看以下链接:


你的客户端代码是什么样子的? - texas697
2
@texas697 你可以在这里找到整个代码库:https://github.com/alessandrofoglia07/LeafGPT-FE 前端;https://github.com/alessandrofoglia07/LeafGPT-BE 后端; - Alexxino
谢谢你的回复,也感谢你提供示例代码的链接! - Kitson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接