Cách sửa lỗi 'RuntimeError: This event loop is already running' với AsyncOpenAI trong Jupyter

intermediate🧠 AI Tools2026-06-24| Jupyter Notebook, JupyterLab, VS Code Jupyter Extension, IPython 7.0+, Python 3.7+, OpenAI Python SDK v1.0+

Error Message

RuntimeError: This event loop is already running. Passing coroutines is forbidden when an event loop is already running.
#openai#asyncio#jupyter#python#async#nest-asyncio

Vấn đềBạn đang chuyển sang sử dụng Python bất đồng bộ (asynchronous) để tăng tốc các lệnh gọi OpenAI API. Tuy nhiên, thay vì kết quả nhanh hơn, bạn lại gặp một loạt thông báo lỗi màu đỏ. Điều này thường xảy ra ngay khi bạn chuyển từ client OpenAI() tiêu chuẩn sang AsyncOpenAI() và cố gắng thực thi mã bằng asyncio.run().

Notebook của bạn có khả năng sẽ kích hoạt lỗi cụ thể này:

RuntimeError: This event loop is already running. Passing coroutines is forbidden when an event loop is already running.

Tại sao lỗi này xảy ra trong JupyterĐiều này xảy ra vì Jupyter Notebook chạy trên một kernel IPython. Kernel này vốn đã bận chạy một vòng lặp sự kiện (event loop) asyncio để giữ cho giao diện luôn phản hồi. Vì thư viện tiêu chuẩn của Python không cho phép các vòng lặp lồng nhau, việc gọi asyncio.run() bên trong một notebook sẽ gây ra xung đột trực tiếp. Nó cố gắng bắt đầu một vòng lặp mới trong khi một vòng lặp khác đang hoạt động.

Client AsyncOpenAI của OpenAI phụ thuộc vào các vòng lặp này để thực hiện các yêu cầu không chặn (non-blocking). Khi phát hiện hai vòng lặp đang tranh giành quyền kiểm soát, nó sẽ tự đóng để ngăn chặn hư hỏng dữ liệu.

Cách khắc phục nhanh: nest-asyncioGói nest-asyncio là một tiện ích nhỏ giúp cấu hình lại vòng lặp hiện có. Nó cho phép bạn chạy asyncio.run() ngay cả khi một vòng lặp đã hoạt động. Đây là lựa chọn tốt nhất nếu bạn muốn giữ mã của mình tương thích với các script Python tiêu chuẩn.

Bước 1: Cài đặt thư việnChạy lệnh này trong một ô (cell) của notebook để cài đặt thư viện dung lượng 1MB này:

%pip install nest-asyncio

Bước 2: Áp dụng bản váThêm hai dòng này vào đầu notebook của bạn. Việc này chỉ cần thực hiện một lần cho mỗi phiên làm việc.

import nest_asyncio
nest_asyncio.apply()

Bước 3: Chạy mã AsyncOpenAI của bạnGiờ đây, các hàm async của bạn sẽ chạy mà không bị lỗi. Dưới đây là một ví dụ hoàn chỉnh:

import asyncio
from openai import AsyncOpenAI
import nest_asyncio

nest_asyncio.apply()
client = AsyncOpenAI(api_key="thay_api_key_cua_ban_tai_day")

async def fetch_completion():
    response = await client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": "Xin chào!"}]
    )
    print(response.choices[0].message.content)

asyncio.run(fetch_completion())

Cách khắc phục hiện đại: Top-Level AwaitNếu bạn muốn mã nguồn gọn sạch hơn, hãy bỏ qua thư viện bổ sung. Các môi trường Jupyter hiện đại (IPython 7.0 trở lên) hỗ trợ "top-level await" ngay lập tức. Điều này có nghĩa là bạn có thể await các hàm trực tiếp trong một cell mà không cần sử dụng asyncio.run().

Cách tiếp cận này giúp giảm bớt các đoạn mã rườm rà (boilerplate) và thường được coi là phương pháp tốt nhất cho các môi trường tương tác. Dưới đây là phiên bản tinh gọn:

from openai import AsyncOpenAI

client = AsyncOpenAI(api_key="thay_api_key_cua_ban_tai_day")

# Không cần asyncio.run() ở đây
response = await client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Kể cho tôi một câu chuyện đùa."}]
)

print(response.choices[0].message.content)

Để xác minh cách khắc phụcKiểm tra cách khắc phục bằng cách chạy ba yêu cầu cùng lúc. Điều này chứng minh môi trường của bạn xử lý đồng thời (concurrency) chính xác. Nếu mã bên dưới in ra ba phản hồi cùng lúc, thiết lập của bạn đã hoàn hảo:

async def test_concurrent():
    tasks = [
        client.chat.completions.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": f"Đếm đến {i}"}])
        for i in range(1, 4)
    ]
    responses = await asyncio.gather(*tasks)
    for res in responses:
        print(res.choices[0].message.content)

await test_concurrent()

Mẹo khắc phục sự cố- Khởi động lại Kernel: Nếu lỗi vẫn còn sau khi áp dụng bản vá, hãy vào Kernel -> Restart. Thao tác này sẽ xóa mọi xung đột vòng lặp còn sót lại.- Người dùng VS Code: Đảm bảo kernel bạn chọn ở góc trên bên phải khớp với môi trường mà bạn đã cài đặt nest-asyncio.- Vị trí đặt Client: Hãy định nghĩa client = AsyncOpenAI() một lần ở đầu notebook. Việc khởi tạo nó bên trong một vòng lặp có thể dẫn đến các cảnh báo về kết nối chưa được đóng.

Related Error Notes