PythonとOpenAI APIで実践！MCP開発入門 【第4回】コードでAIと初対話！PythonからOpenAI APIへシンプルなリクエストを送信、JSONレスポンスを体験

# はじめに：理論から実践へ！AIとのファーストコンタクト、その瞬間

皆さん、こんにちは！AI開発の冒険、第4回です。前回（第3回）では、OpenAI APIを利用するための「通行証」であるAPIキーを取得し、それを環境変数と **.envファイル** 、そして **.gitignore** を駆使して、プロフェッショナルかつ安全に管理する鉄壁のテクニックを学びました。これで、私たちはAIの強力な能力を安全に呼び出す準備が整いました。

今回は、まさにその瞬間、理論が実践へと変わるエキサイティングなステップです！ 私たちが書いたPythonのコードから、実際にOpenAIのAIモデル（今回は広く使われている **gpt-3.5-turbo** を例にします）に対して、シンプルな「お願い（リクエスト）」を送信し、AIからの「お返事（レスポンス）」を受け取り、その中身を覗いてみます。この一連の流れを通じて、APIコールの基本的な仕組み、HTTPリクエストの概念、そしてAIとのコミュニケーションで標準的に使われるデータ形式であるJSONについて、具体的な体験と共に理解を深めていきましょう。

（2025年5月19日、ここ東京からお送りするこの記事が、あなたのAI開発者として記念すべき「AIとの初対話」の成功体験に繋がることを願っています！）

# APIコールの解剖学：あなたのコードとAIサーバー間の「デジタルな会話」

Pythonの数行のコードでAIと対話できるのは、まるで魔法のようですが、その裏側では明確な技術的ステップに基づいた「デジタルな会話」が行われています。openaiライブラリが多くの複雑さを隠蔽してくれていますが、何が起きているのか概要を掴んでおくことは非常に重要です。

クライアント（あなたのPythonスクリプト）とサーバー（OpenAIのAI基盤）:
あなたのPythonスクリプトが「クライアント」となり、OpenAIが運用する強力なAIモデルが乗った「サーバー」に対して、お願いごとをします。

# リクエスト (Request) - あなたのPythonスクリプトが送るもの:

1. APIエンドポイントURL (API Endpoint URL): AIの特定の機能（例：「チャットで応答を生成して」）を呼び出すための、インターネット上の正確な「住所」です。例えば、チャット機能なら https://api.openai.com/v1/chat/completions のようなURLになります。
1. HTTPメソッド (HTTP Method): リクエストの種類を示します。データを送信して処理を依頼する場合は、主に **POST** メソッドが使われます。
ヘッダー (Headers): リクエストに関する重要な「付帯情報」です。代表的なものに以下があります。
1. Authorization: あなたのAPIキーをここに乗せて送信し、「私は正当な利用者です」と認証を受けます。通常、Bearer sk-xxxxxxxx のような形式になります。
1. Content-Type: リクエスト本体（ボディ）のデータ形式を指定します。通常、application/json が使われます。 (注: openaiライブラリを使うと、これらのヘッダーの多くは自動的に適切に設定されます。)
1. ボディ (Body / Payload): AIに伝えたい具体的な内容、つまり **プロンプト（指示や質問）、利用するAIモデル名、その他オプションパラメータ（応答の最大長など）** を、JSON (JavaScript Object Notation) 形式で記述して格納します。
1. レスポンス (Response) - OpenAIサーバーが返してくるもの: ステータスコード (Status Code): リクエストが成功したか、失敗したかを示す3桁の数字。200 OK なら成功。401 Unauthorized ならAPIキーが無効、403 Forbidden ならアクセス権限なし、429 Too Many Requests ならリクエストが多すぎる（レートリミット超過）、500 Internal Server Error ならサーバー側で問題発生、などがあります。（エラー処理の詳細は後の回で！）
1. ヘッダー (Headers): レスポンスに関する追加情報（例：コンテンツの形式、日付など）。
1. ボディ (Body / Payload): リクエストが成功した場合、ここにAIが生成したテキストやその他の情報が、やはりJSON形式で格納されて返ってきます。
この一連の「リクエスト→処理→レスポンス」という流れが、APIコールの基本です。

# ステップ1：Pythonスクリプトの準備 - AIとの対話窓口を作る

まず、第3回で作成した.envファイルがあるプロジェクトフォルダ内に、新しいPythonファイルを作成しましょう。ファイル名は first_ai_dialogue.py とします。
```
# Python
# first_ai_dialogue.py

import os
from dotenv import load_dotenv
from openai import OpenAI # openaiライブラリをインポート

# .envファイルから環境変数を読み込む (APIキーのため)
if load_dotenv():
    print(".envファイルを読み込み、環境変数を設定しました。")
else:
    print("警告: .envファイルが見つからないか、読み込めませんでした。APIキーが設定されません。")
    # ここで処理を中断するか、ユーザーにエラーを伝えるのが親切
    exit() # APIキーがないと進めないので終了

# OpenAIクライアントの初期化
# APIキーは環境変数 "OPENAI_API_KEY" から自動的に読み込まれる
# もし.env以外の方法でキーを設定している場合は、 api_key="YOUR_KEY" のように直接指定も可能だが非推奨
try:
    client = OpenAI()
    print("OpenAIクライアントの初期化に成功しました。")
except Exception as e:
    print(f"OpenAIクライアントの初期化中にエラーが発生しました: {e}")
    exit()
```
このコードは、まず必要なライブラリをインポートし、.envファイルからAPIキーを環境変数として読み込みます（OpenAI()クライアントはデフォルトでOPENAI_API_KEYという環境変数を探します）。そして、OpenAI APIと通信するための「クライアントオブジェクト」を初期化しています。

# ステップ2：シンプルなリクエストの作成 - AIへの最初の「問いかけ」

今回は、OpenAIのチャットモデルの gpt-4o-mini を使って、簡単な問いかけをしてみましょう。「猫に関する短いジョークを一句教えて」とお願いしてみます。

first_ai_dialogue.py に続けて、以下のコードを追加します。
```
# Python
# (上記の準備コードの続き)

# AIへの指示内容（プロンプト）
user_prompt = "猫に関する一行で終わる短いジョークを一つ教えてください。"
print(f"\nAIへのプロンプト: 「{user_prompt}」")

# APIに送信するリクエストのパラメータを設定
# 今回はシンプルなチャット形式のリクエストを作成
try:
    print("OpenAI APIにリクエストを送信します...")
    completion = client.chat.completions.create(
        model="gpt-4o-mini",  # 利用するAIモデルの指定
        messages=[
            {"role": "system", "content": "あなたはユーモアのセンスがあるアシスタントです。"}, # AIの役割や振る舞いを指示 (省略可能)
            {"role": "user", "content": user_prompt} # ユーザーからの実際の指示
        ],
        max_tokens=50,         # AIが生成する応答の最大長（トークン数）を制限
        temperature=0.7        # 応答の「創造性」や「ランダム性」の度合い (0に近いほど決定的、1に近いほど多様)
    )
    print("APIからのレスポンスを受信しました。")
except Exception as e:
    print(f"OpenAI APIへのリクエスト中にエラーが発生しました: {e}")
    exit()

# ここまででAPIコールとレスポンス受信が完了
```
ここでは、client.chat.completions.create() メソッドを使ってAIにリクエストを送っています。

1. model: 使用するAIモデルを指定します。gpt-3.5-turbo は非常に高機能かつ比較的安価で、多くのタスクに適しています。
1. messages: AIとの対話内容をリスト形式で指定します。
role: "system": AIの基本的な役割や性格付け、指示の前提条件などを伝えるために使います。
1. role: "user": 私たちユーザーからの具体的な質問や指示をここに記述します。
1. max_tokens: AIが生成するテキストの最大長をトークン数で指定します。これはコスト管理と応答の簡潔さのために重要です。（トークンについては料金体系の回で詳述します）。
1. temperature: 値が低い（例:0.2）ほどAIの応答は決定的で一貫性が高くなり、高い（例:0.9）ほど多様で創造的（時に予測不能）になります。0.7あたりがバランスの取れた値とされます。

# ステップ3：APIからのレスポンスを体験 - JSON形式の「お返事」

上記のコードで completion 変数に格納されたものが、OpenAIサーバーからのレスポンスです。まずは、このレスポンス全体がどのような形をしているのか、そのまま表示してみましょう。

first_ai_dialogue.py に続けて、以下のコードを追加します。
```
# Python
# (上記のAPIコールコードの続き)

# レスポンスオブジェクト全体を表示してみる（デバッグや学習目的）
print("\n--- RAW API Response (生のレスポンス全体) ---")
print(completion)
print("--- End of RAW API Response ---")

# レスポンスは通常、JSON形式のデータがPythonオブジェクトに変換されたもの
# (厳密にはPydanticモデルのオブジェクトですが、辞書のようにアクセスできます)
```
この completion オブジェクトの中身は、JSON (JavaScript Object Notation) というデータ形式に基づいています。JSONは、キー: 値 のペアで構成され、人間にも機械にも読みやすい軽量なデータフォーマットで、API間のデータ交換に広く用いられています。openaiライブラリがこのJSONデータを扱いやすいPythonオブジェクトに変換してくれています。

# ステップ4：JSONレスポンスの解析 - AIの「答え」を取り出す

レスポンス全体を眺めると、様々な情報が含まれていることが分かります。AIが生成した実際のメッセージ（ジョーク）は、その中の特定の場所に格納されています。チャットモデルの場合、通常は以下のようにアクセスできます。

first_ai_dialogue.py に続けて、以下のコードを追加します。
```
# Python
# (上記のRAWレスポンス表示コードの続き)

# AIが生成したメッセージ内容を取り出す
try:
    ai_message_content = completion.choices[0].message.content
    print("\nAIからのジョーク:")
    print(ai_message_content)
except (IndexError, AttributeError, TypeError) as e:
    print(f"\nAIのメッセージ取得中にエラーが発生しました: {e}")
    print("レスポンスの構造が予期したものと異なる可能性があります。RAWレスポンスを確認してください。")

# API利用状況（トークン数など）も確認できる
try:
    usage_info = completion.usage
    print("\n--- API利用状況 (トークン数など) ---")
    print(f"プロンプトトークン数: {usage_info.prompt_tokens}")
    print(f"生成されたトークン数: {usage_info.completion_tokens}")
    print(f"合計トークン数: {usage_info.total_tokens}")
    print("--- End of API利用状況 ---")
except AttributeError:
    print("\nAPI利用状況の取得に失敗しました。レスポンスに'usage'属性が含まれていない可能性があります。")
```

1. completion.choices: AIが生成した応答の候補がリスト形式で入っています。通常、1つの応答を要求するので、choices[0]で最初の（そして唯一の）候補にアクセスします。
1. .message: その候補の中のメッセージオブジェクト。
1. .content: メッセージの実際のテキスト内容。
1. completion.usage: このAPIコールで消費されたトークン数（入力プロンプトのトークン数、AIが生成した応答のトークン数、合計トークン数）が格納されています。これはAPIの利用料金に直結する重要な情報です（詳細は後の回で）。

# 完成コードと実行：AIとの記念すべき初対話！

これで、first_ai_dialogue.py の全コードが完成です。VSCodeのターミナル（仮想環境(mcp_env)が有効になっていること）で、以下を実行してみましょう。
```
# Bash

python first_ai_dialogue.py
```
すべてがうまくいけば、ターミナルにAPIキーの読み込み成功メッセージ、プロンプトの内容、そしてAIが生成した猫のジョーク、最後にAPI利用状況（トークン数）が表示されるはずです！
```
# 実行結果のイメージ
.envファイルを読み込み、環境変数を設定しました。
OpenAIクライアントの初期化に成功しました。

AIへのプロンプト: 「猫に関する一行で終わる短いジョークを一つ教えてください。」
OpenAI APIにリクエストを送信します...
APIからのレスポンスを受信しました。

--- RAW API Response (生のレスポンス全体) ---
ChatCompletion(id='chatcmpl-xxxxxxxxxxxxxxxxxxxxxxxxx', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='なぜ猫はポーカーが下手なの？いつもチート（cheetah）するから！', role='assistant', function_call=None, tool_calls=None))], created=1716092446, model='gpt-3.5-turbo-0125', object='chat.completion', system_fingerprint=None, usage=CompletionUsage(completion_tokens=27, prompt_tokens=32, total_tokens=59))
--- End of RAW API Response ---

AIからのジョーク:
猫は「ニャー」というけれど、実は「おやつちょうだい！」と叫んでいるんだよ！

--- API利用状況 (トークン数など) ---
プロンプトトークン数: 49
生成されたトークン数: 31
合計トークン数: 80
--- End of API利用状況 ---
（ジョークの内容やトークン数は実行ごとに変わることがあります）
```

# よくある初回トラブルと対処法（ミニTIPS）

1. 「APIキーが見つかりません」エラー: .envファイルの名前や中身（OPENAI_API_KEY="sk-..."の形式）、load_dotenv()の呼び出し位置を確認。
1. openaiライブラリ関連エラー: pip install openai が仮想環境で正しく実行されたか確認。
1. インターネット接続エラー: PCがインターネットに接続されているか確認。
1. OpenAIサーバー側の問題（稀）: OpenAIのステータスページ（status.openai.com）を確認。
1. 以下のエラーの場合は、請求情報が正しく設定されていないか、期限切れの可能性があります。OpenAIのAPI referencen画面で Billing を確認してください。
```
OpenAI APIへのリクエスト中にエラーが発生しました: Error code: 429 - {'error': {'message': 'You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs: https://platform.openai.com/docs/guides/error-codes/api-errors.', 'type': 'insufficient_quota', 'param': None, 'code': 'insufficient_quota'}}
```

# おわりに：AIとのコミュニケーション、その扉は開かれた！

おめでとうございます！ あなたは今、Pythonコードを通じてOpenAIの強力なAIと、記念すべき最初の「対話」を成功させました。
この一連のプロセスで、

- APIエンドポイントという「AIの窓口」
- HTTP POSTリクエストという「お願いの仕方」（openaiライブラリが大部分を自動化）
- JSON形式のペイロードという「情報の形」（リクエストとレスポンスの両方）
- APIキーによる認証という「通行証の提示」
- 同期的なAPIコール（プログラムが応答を待つ仕組み） 
という、API連携の基本要素を実践的に体験しました。

これは、あなたが今後、より複雑で高度なAIアプリケーションを構築していく上での、最も重要な基礎となります。AIが返してきたJSONレスポンスの構造を理解し、必要な情報（今回はAIのメッセージとトークン使用量）を正確に取り出せたことは、大きな一歩です。

この「AIとコードで対話できた！」という感動を胸に、次回からは、AIの能力をさらに引き出すための「プロンプトエンジニアリング」の世界へと足を踏み入れていきます。

## 次回予告
AIとの最初のコンタクトは成功しました！でも、AIはもっと賢く、もっと私たちの意図を汲み取ってくれるはずです。その鍵を握るのが「プロンプト」の質。
次回、第5回「AIを操る「呪文」？ プロンプトエンジニアリングの基礎と効果的な指示の黄金律（ゼロ/ワン/フューショットの概念も）」では、AIから最高のパフォーマンスを引き出すための「指示術」、プロンプトエンジニアリングの基本原則とテクニックを、ユーザー様提供のPDF資料の要素も交えながら解説します。AIとの対話が、もっと楽しく、もっと生産的になりますよ！