Я хочу передать ответ Openai gpt-3.5 и отобразить его в фрейме tkinter. Приведенный ниже код работает нормально, но проблема в том, что каждый фрагмент потоковой передачи отображается в новой строке. Я хочу правильно объединить эти потоковые фрагменты и отобразить их в чате как полное предложение. Я не знаю, как это сделать правильно. Может ли кто-нибудь помочь? Ниже мой код:
import tkinter as tk
from tkinter import ttk
from datetime import datetime
import openai
import json
import requests
history = []
# Create a function to use 5 turbo to answer a question based on the prompt
def get_answer_from_chatgpt(prompt, history):
openai.api_key = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
print("Trying")
messages = [
{"role": "system", "content": "You are a helpful assistant."}
]
for sender, message in history:
messages.append({"role": sender, "content": message})
try:
stream = openai.chat.completions.create(
model = "gpt-3.5-turbo",
messages=messages,
stream=True,
)
for chunk in stream:
#answer = chunk.message.content.strip()
if chunk.choices[0].delta.content is not None:
chunk = chunk.choices[0].delta.content
append_to_chat_log("Gpt-3.5-turbo", chunk)
#answer = response.choices[0].message.content.strip()
history.append(("assistant", chunk))
print(chunk)
print("Streamig complete")
except Exception as e:
print(e)
return "Sorry, an error occurred while processing your request."
# Create a function to use OpenAI to answer a question based on the search results
def append_to_chat_log(sender, message):
chat_log.config(state=tk.NORMAL)
chat_log.insert(tk.END, f"{sender}:\n\n", ("sender",))
chat_log.insert(tk.END, f"{message}\n\n\n")
chat_log.tag_config("sender", font=('Arial', 12, 'bold'))
chat_log.config(state=tk.DISABLED)
chat_log.see(tk.END)
def send_message(event=None):
global history
message = message_entry.get(1.0, "end-1c")
message = message.strip()
message_entry.delete(1.0, tk.END)
message_entry.update()
if not message:
pass
else:
append_to_chat_log("User", message)
history.append(("user", message))
if len(history) >4:
history = history[-4:]
print(message)
response = get_answer_from_chatgpt(message, history)
append_to_chat_log("Gpt", response)
history.append(("assistant", response))
root = tk.Tk()
root.title("Chat")
# Maximize the window
root.attributes('-zoomed', True)
chat_frame = tk.Frame(root)
chat_frame.pack(expand=True, fill=tk.BOTH)
chat_log = tk.Text(chat_frame, state='disabled', wrap='word', width=70, height=30, font=('Arial', 12), highlightthickness=0, borderwidth=0)
chat_log.pack(side=tk.LEFT, padx=(500,0), pady=10)
message_entry = tk.Text(root, padx=17, insertbackground='white', width=70, height=1, spacing1=20, spacing3=20, font=('Open Sans', 14))
message_entry.pack(side=tk.LEFT, padx=(500, 0), pady=(0, 70)) # Adjust pady to move it slightly above the bottom
message_entry.insert(1.0, "Ask me anything...")
message_entry.mark_set("insert", "%d.%d" % (0,0))
message_entry.bind("<Return>", send_message)
root.mainloop()
@acw1668 acw1668 Если я это сделаю, мне придется дождаться завершения потока. Прежде чем оно отобразится в журнале чата, пройдет небольшая задержка. Я хочу отображать по мере поступления.
Тогда вам нужно переписать append_to_chat_log()
, чтобы делать то, что вы хотите.
@ acw1668 Как мне это сделать?
Если вы хотите, чтобы все фрагменты записывались как отдельные предложения, вам нужно изменить append_to_chat_log()
, чтобы не вставлять символы новой строки после вставки фрагмента:
def append_to_chat_log(sender=None, message=None):
chat_log.config(state = "normal")
if sender:
chat_log.insert("end", f"{sender}:\n", "sender")
if message:
chat_log.insert("end", message)
chat_log.config(state = "disabled")
chat_log.see("end")
chat_log.update()
Затем измените get_answer_from_chatgpt()
, чтобы учесть изменения:
def get_answer_from_chatgpt(prompt, history):
...
try:
...
# log the sender only
append_to_chat_log("Gpt-3.5-turbo")
for chunk in stream:
# log the chunk only
append_to_chat_log(message=chunk)
# if you want, append newlines after inserting all the chunks
append_to_chat_log(message = "\n\n\n")
print("Streaming complete")
except:
...
Обратите внимание, что вам также необходимо изменить send_message()
, чтобы учесть изменение append_to_chat_log()
.
Также после создания chat_log.tag_config("sender", font=("Arial", 12, "bold"))
нужно вызвать chat_log
.
Теперь фрагменты корректно передаются в журнал чата, но каждый фрагмент по-прежнему находится на новой строке. Может ли это быть из-за этой строки? chat_log.insert("end", message)
@ noocoder777 Вы должны предоставить образцы данных фрагментов. chat_log.insert("end", message)
не будет вставлять новую строку, если внутри данных фрагмента нет новой строки.
Но по какой-то причине он вставляет новую строку. Дело в том, что внутри данных патрона также нет новой строки.
У меня нет такой проблемы с данными моего примера фрагмента.
Ты был прав. У меня была опечатка в коде. Теперь он работает идеально! Спасибо за это.
Почему бы вам не объединить все фрагменты с помощью цикла for, а затем вызвать
append_to_chat_log()
после цикла for?