我試圖將OpenAI流式響應的響應進行流式傳輸,并在聊天界面中向用戶顯示響應。然而,雖然每個響應塊本身都是正確的,但我的狀態最終還是出現了重復的單詞。。。我哪里做錯了?
以下是我的代碼以及顯示UI和控制臺輸出的屏幕截圖:
useEffect(() => {
const doCompletion = async () => {
if (!newMessage) return;
try {
await handleCompletion(messages);
setNewMessage(false);
} catch (err) {
console.log("unable to communicate with model service: ", 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: ", 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: ", prevContent)
const newContent = prevContent! + content!;
console.log("newContent: ", newContent)
tmpMessages[lastMessageIndex].data.content = newContent;
return tmpMessages;
});
}
}
讓我們試著修復它!
你的問題是,當在React中流式傳輸OpenAI響應時,快速的塊更新可能會導致過時狀態,導致顯示的聊天中出現重復的單詞。
我的建議是使用
useRef
來存儲OpenAI流中的最新累積內容。這確保了狀態更新基于最新數據。這種方法保證您的React狀態始終反映最新的AI響應,防止重復。:)