React与OpenAI流式传输结果在更新和显示响应时出现重复值

我正在尝试从OpenAI的流式响应中获取响应,并在聊天界面中向用户显示响应。然而,虽然响应的每个块本身是正确的,但我的状态最终会出现重复的词语… 问题出在哪里?

这是我的代码以及显示UI和控制台输出的截图:

useEffect(() => {  const doCompletion = async () => {    if (!newMessage) return;          try {      await handleCompletion(messages);      setNewMessage(false);    } catch (err) {      console.log("无法与模型服务通信: ", err)    }  }  doCompletion();}, [newMessage]);const handleNewMessage = async (formData: FormData) => {  const message = formData.get("message") as string;  addMessage({id: uuidv4(), data: {role: "user", content: message}});  setNewMessage(true);}const handleCompletion = async (messages: Message[]) => {  const formattedMessages = messages.map((message: Message)=> message.data)  const stream = await openai.chat.completions.create({    messages: formattedMessages,    model: "deepseek-chat",    stream: true  });      for await (const chunk of stream) {    const content = chunk.choices[0]?.delta?.content;    console.log("内容: ", content)          setMessages((prev) => {      let tmpMessages = [...prev];      const lastMessageIndex = tmpMessages.length-1;      if (tmpMessages[lastMessageIndex].data.role !== "assistant") {        tmpMessages.push({id: chunk.id, data: {role: "assistant", content: ""}});        return tmpMessages;      }      const prevContent = tmpMessages[lastMessageIndex].data.content;      console.log("之前的内容: ", prevContent)            const newContent = prevContent! + content!;      console.log("新的内容: ", newContent)              tmpMessages[lastMessageIndex].data.content = newContent;      return tmpMessages;    });  }}

输入图片说明


回答:

让我们尝试修复它!

你的问题是在React中流式传输OpenAI响应时,快速的块更新可能会导致状态过时,从而在显示的聊天中出现重复的词语。

我的建议是使用useRef来存储来自OpenAI流的最新累积内容。这样可以确保状态更新基于最新的数据。

import React, { useState, useEffect, useRef } from 'react';const YourComponent = () => {  const [messages, setMessages] = useState([]);  const assistantContentRef = useRef('');  const handleCompletion = async (messages) => {    // 设置OpenAI流    assistantContentRef.current = ''; // 重置ref    for await (const chunk of stream) {      const content = chunk.choices[0]?.delta?.content;      if(content){        assistantContentRef.current += content;        setMessages((prev) => {          // 使用assistantContentRef.current更新消息          let tmpMessages = [...prev];          const lastMessageIndex = tmpMessages.length - 1;          if (tmpMessages[lastMessageIndex]?.data.role !== 'assistant') {            tmpMessages.push({              id: chunk.id,              data: { role: 'assistant', content: assistantContentRef.current },            });          } else {            tmpMessages[lastMessageIndex].data.content = assistantContentRef.current;          }          return tmpMessages;        });      }    }  };  // 你的其他代码 };export default YourComponent;

这种方法可以保证你的React状态始终反映最新的AI响应,防止重复出现。:)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注