基于ChatGPT API与Gradio构建异步流式聊天机器人的报错解决
解决Gradio结合ChatGPT API异步流式输出的ValueError问题
你遇到的ValueError是因为定义的chat_with_gpt是异步生成器(带yield的async def函数),而Gradio调用异步函数时,期望的是普通异步协程,无法直接处理异步生成器类型的返回值。虽然print能正常迭代异步生成器输出内容,但Gradio的流式输出逻辑需要函数内部逐步返回增量内容。
解决方案
调整异步函数的逻辑,累积流式返回的内容并逐步yield,同时处理空的返回块,再配合Gradio的stream=True参数实现实时输出:
完整代码示例(基于ChatInterface)
import gradio as gr from openai import AsyncOpenAI # 初始化异步OpenAI客户端 client = AsyncOpenAI(api_key="你的API密钥") async def chat_with_gpt(prompt, history): # 调用ChatGPT API流式接口 stream = await client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], stream=True, ) response_content = "" async for chunk in stream: # 提取当前块的内容,跳过空内容的块 chunk_content = chunk.choices[0].delta.content if chunk_content: response_content += chunk_content # 每次yield累积的内容,Gradio会实时更新界面 yield response_content # 创建Gradio界面并启用流式输出 with gr.Blocks() as demo: # ChatInterface自带聊天历史管理,stream=True开启流式更新 gr.ChatInterface(chat_with_gpt, stream=True) demo.launch()
关键说明
- 保留
history参数:ChatInterface要求聊天处理函数接收prompt和history两个参数,即使暂时不需要历史记录也得保留。 - 过滤空内容块:流式返回中部分chunk的
delta.content为空,直接yield会导致界面异常,必须过滤掉。 - 累积内容再yield:Gradio的流式输出需要每次返回完整的累积结果,而非单个字符/片段,这样界面会实时追加更新内容。
- 启用
stream=True:在ChatInterface或对应的输出组件中开启该参数,Gradio才会处理逐步返回的内容并实时更新界面。
基础组件实现方式(Textbox+Button)
如果不需要聊天历史管理,用基础组件也可以实现:
import gradio as gr from openai import AsyncOpenAI client = AsyncOpenAI(api_key="你的API密钥") async def stream_response(prompt): stream = await client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], stream=True, ) response = "" async for chunk in stream: content = chunk.choices[0].delta.content if content: response += content yield response with gr.Blocks() as demo: input_box = gr.Textbox(label="输入问题") output_box = gr.Textbox(label="流式回复", stream=True) input_box.submit(stream_response, inputs=input_box, outputs=output_box) demo.launch()
内容的提问来源于stack exchange,提问作者daehui
相关产品推荐
相关产品推荐

