有没有办法直接在本机反应中逐字传输chatgpt api的响应(使用javascript)

Iba*_*man 8 javascript react-native expo openai-api chatgpt-api

我想直接在 React Native (expo) 中使用 Chat GPT Turbo api 与逐字流这里是没有流的工作示例

  fetch(`https://api.openai.com/v1/chat/completions`, {
  body: JSON.stringify({
    model: 'gpt-3.5-turbo',
    messages: [{ role: 'user', content: 'hello' }],
    temperature: 0.3,
    max_tokens: 2000,
  }),
  method: 'POST',
  headers: {
    'content-type': 'application/json',
    Authorization: 'Bearer ' + API_KEY,
  },
}).then((response) => {
  console.log(response); //If you want to check the full response
  if (response.ok) {
    response.json().then((json) => {
      console.log(json); //If you want to check the response as JSON
      console.log(json.choices[0].message.content); //HERE'S THE CHATBOT'S RESPONSE
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

我可以改变什么来逐字流数据

Nic*_*nié 4

OpenAI API 依靠 SSE(服务器端事件)将响应流式传输回给您。如果您在 API 请求中传递参数,您将收到由 OpenAI 计算的数据块。这会产生模仿某人打字的实时响应的错觉。

最难弄清楚的部分可能是如何将前端与后端连接起来。每次后端收到一个新块时,您都希望将其显示在前端中。

我在Replit上创建了一个简单的 NextJs 项目来演示这一点。现场演示

你需要安装better-sse 包

npm install better-sse

服务器端 在 API 路由文件中

import {createSession} from "better-sse";

const session = await createSession(req, res);
      if (!session.isConnected) throw new Error('Not connected');

const { data } = await openai.createCompletion({
  model: 'text-davinci-003',
  n: 1,
  max_tokens: 2048,
  temperature: 0.3,
  stream: true,
  prompt: `CHANGE TO YOUR OWN PROMPTS`
}, {
  timeout: 1000 * 60 * 2,
  responseType: 'stream'
});

//what to do when receiving data from the API
data.on('data', text => {
  const lines = text.toString().split('\n').filter(line => line.trim() !== '');
  for (const line of lines) {
    const message = line.replace(/^data: /, '');
    if (message === '[DONE]') { //OpenAI sends [DONE] to say it's over
      session.push('DONE', 'error');
      return;
    }
    try {
      const { choices } = JSON.parse(message);
      session.push({text:choices[0].text});
    } catch (err) {
      console.log(err);
    }
  }
});

//connection is close
data.on('close', () => { 
  console.log("close")
  res.end();
});

data.on('error', (err) => {
  console.error(err);
});
Run Code Online (Sandbox Code Playgroud)

现在您可以在前端调用此 API 路由

let [result, setResult] = useState("");

//create the sse connection
const sse = new EventSource(`/api/completion?prompt=${inputPrompt}`);

//listen to incoming messages
sse.addEventListener("message", ({ data }) => {
  let msgObj = JSON.parse(data)
  setResult((r) => r + msgObj.text)
});
Run Code Online (Sandbox Code Playgroud)

希望这是有道理的,并帮助其他有类似问题的人。