問題の発生OpenAI APIの呼び出しを高速化するために、Pythonの非同期処理(async)に移行しようとしているかもしれません。しかし、期待した結果の代わりに、大量の赤いエラーテキストが表示されることがあります。これは通常、標準の OpenAI() クライアントから AsyncOpenAI() に切り替え、asyncio.run() を使ってコードを実行しようとした瞬間に発生します。
ノートブックでは、おそらく次の特定のエラーがトリガーされます:
RuntimeError: This event loop is already running. Passing coroutines is forbidden when an event loop is already running.
Jupyterでこれが発生する理由このエラーは、Jupyter NotebookがIPythonカーネル上で動作しているために発生します。このカーネルは、インターフェースの応答性を維持するために、すでに asyncio イベントループを実行しています。Pythonの標準ライブラリではループのネスト(入れ子)が許可されていないため、ノートブック内で asyncio.run() を呼び出すと、すでにアクティブなループと競合してしまいます。
OpenAIの AsyncOpenAI クライアントは、非ブロッキングリクエストのためにこれらのループに依存しています。制御を争う2つのループを検知すると、データの破損を防ぐために停止します。
手軽な解決策:nest-asyncionest-asyncio パッケージは、既存のループを再構成する小さなユーティリティです。これを使用すると、ループがすでにアクティブな状態でも asyncio.run() を実行できるようになります。コードを標準的なPythonスクリプトと互換性を持たせたい場合に最適な選択肢です。
ステップ1:パッケージのインストールノートブックのセルで次のコマンドを実行し、1MB程度のライブラリをインストールします:
%pip install nest-asyncio
ステップ2:パッチの適用ノートブックの冒頭に次の2行を追加します。これはセッションごとに1回だけ実行する必要があります。
import nest_asyncio
nest_asyncio.apply()
ステップ3:AsyncOpenAIコードの実行これで、非同期関数がクラッシュせずに動作するようになります。完全な例を以下に示します:
import asyncio
from openai import AsyncOpenAI
import nest_asyncio
nest_asyncio.apply()
client = AsyncOpenAI(api_key="ここにAPIキーを入力")
async def fetch_completion():
response = await client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "こんにちは!"}]
)
print(response.choices[0].message.content)
asyncio.run(fetch_completion())
モダンな解決策:トップレベルAwaitよりクリーンなコードベースを好む場合は、追加のライブラリをスキップできます。最近のJupyter環境(IPython 7.0以降)は、標準で「トップレベルawait」をサポートしています。つまり、asyncio.run() を使わずに、セル内で直接関数を await できるということです。
このアプローチはボイラープレート(定型文)を減らし、対話型環境においては一般的にベストプラクティスとされています。簡略化されたバージョンは以下の通りです: from openai import AsyncOpenAI
client = AsyncOpenAI(api_key="ここにAPIキーを入力")

