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

如何避免调用ChatGPT API时阻塞Discord Bot其余代码执行?

解决Discord Bot调用ChatGPT API时的代码阻塞问题

问题原因

你的DM_response虽然声明为async函数,但内部调用的openai.ChatCompletion.create()是同步阻塞式的API。它会占用整个事件循环直到API返回结果,导致Bot无法处理其他消息、心跳等任务,出现全局暂停的情况。而你测试的asyncio.sleep()是真正的异步非阻塞操作,不会占用事件循环,所以Bot能正常运行。

解决方案

有两种可靠的方式解决这个问题,优先推荐官方异步客户端方案:


方案1:使用OpenAI官方异步客户端

这是官方支持的异步调用方式,性能最优,无需额外线程开销。

  1. 确保安装最新版OpenAI库:
pip install --upgrade openai
  1. 修改responses.py中的DM_response函数:
import openai
from openai import AsyncOpenAI

# 初始化异步客户端,建议通过环境变量管理API密钥,不要硬编码
client = AsyncOpenAI(api_key="MY OPENAI KEY")

async def DM_response(messages: str, message, username, user_id):
    if len(message.attachments) > 0:
        await message.author.send(await read_error_codes('manual_responses.txt', 1))
        return
    else:
        # 使用异步API调用
        completion = await client.chat.completions.create(
            model="gpt-3.5-turbo", 
            max_tokens=150,
            temperature=0.1,
            messages = [
                {"role": "system", "content": "You are a helpful assistant"},
                {"role": "user", "content": messages}
            ]
        )
        DMresponse = completion.choices[0].message.content
        DMresponse = DMresponse.replace('\n', '')
        return DMresponse

方案2:用线程池封装同步API调用

如果无法升级OpenAI库,可将同步调用放到线程池中执行,让事件循环继续处理其他任务。

修改responses.py中的DM_response函数:

import asyncio
import openai

async def DM_response(messages: str, message, username, user_id):
    openai.api_key = "MY OPENAI KEY"
    if len(message.attachments) > 0:
        await message.author.send(await read_error_codes('manual_responses.txt', 1))
        return
    else:
        # 定义同步调用函数
        def get_gpt_completion():
            return openai.ChatCompletion.create(
                model="gpt-3.5-turbo", 
                max_tokens=150,
                temperature=0.1,
                messages = [
                    {"role": "system", "content": "You are a helpful assistant"},
                    {"role": "user", "content": messages}
                ]
            )
        
        # 把同步任务放到线程池执行,不阻塞事件循环
        completion = await asyncio.to_thread(get_gpt_completion)
        DMresponse = completion['choices'][0]['message']['content']
        DMresponse = DMresponse.replace('\n', '')
        return DMresponse

额外建议

  • 不要将API密钥硬编码在代码中,建议使用环境变量(如os.getenv("OPENAI_API_KEY"))或配置文件管理,避免密钥泄露。
  • 可以添加超时处理,防止API响应过久导致任务挂起:比如用asyncio.wait_for()包装异步调用,设置合理的超时时间。

内容的提问来源于stack exchange,提问作者Giorgi Samukashvili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:42:20