You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:46:04