1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenAI Responses APIでExcelファイルを読み込み・解析する方法

Last updated at Posted at 2025-09-19

入力のフォーマットが定まっていないExcelファイルをOpenAIのResponses APIに読み込ませる必要があり、
セル指定でExcelから値を取得するのが難しかったのでExcelファイルをそのままResponses APIへ読み込ませる方法を調査した内容の備忘録です。

執筆時点のAPI仕様に基づく内容です

エラーハンドリングなど、本記事の目的外となるソースコードは省いています

私の環境では動作しましたが、環境によってはエラーが出るかもしれません

どうやった

Code Interpreterとファイルアップロード機能を使うことで実現。

Code Interpreter

ファイルアップロード機能

具体的な処理内容

① ファイルアップロード機能を利用してOpenAIのサーバーにExcelファイルをアップロードする

// curlで送信するので、解析するExcelファイルをCURLFileオブジェクトに変換
$curlFile = new CURLFile($_FILES[{対象のファイル}]['tmp_name'], $_FILES[{対象のファイル}]['type'], $_FILES[{対象のファイル}]['name']);

// OpenAIのファイルアップロードエンドポイント
$ch = curl_init('https://api.openai.com/v1/files');
curl_setopt_array($ch, [
	CURLOPT_HTTPHEADER => [
		'Authorization: Bearer ' . {OpenAIのAPIKEY},
	],
	CURLOPT_POST => true,
	CURLOPT_POSTFIELDS => [
		// 公式ドキュメントによると、アップロードされたファイルの目的を設定する項目、今回は「あらゆる用途」を意味する「user_data」を設定
		'purpose' => 'user_data',
		// アップロードするファイルオブジェクト
		'file' => $curlFile,
	],
	// お好みで
	CURLOPT_RETURNTRANSFER => true,
	// お好みで
	CURLOPT_TIMEOUT => 30,
]);

$responseBody = curl_exec($ch);

$decoded = json_decode($responseBody, true);
// OpenAIにアップロードされたファイルのIDを取得
$fileId = $decoded['id'];

リクエスト値に設定しているpurposeについて

アップロードされたファイルの目的。
以下のいずれかです。

  • assistants: アシスタントAPIで使用
  • batch: バッチAPIで使用
  • fine-tune: 微調整に使用
  • vision: ビジョンの微調整に使用する画像
  • user_data: あらゆる用途に使用できる柔軟なファイルタイプ
  • evals: 評価データセットに使用

② 手順①で取得した「OpenAIにアップロードされたファイルのID」を使用し、Responses APIにリクエストを送る

$payload = [
	// 利用したいモデル名を記載
    'model' => 'o3',
    'tools' => [
        [
            'type' => 'code_interpreter',
            'container' => [
                'type' => 'auto',
				// 手順①で取得した「OpenAIにアップロードされたファイルのID」を記載、これが読み込まれる
                'file_ids' => ['file-hghghgh'],
            ],
        ],
    ],
    'input' => [
        [
			// プロンプト入力
			// このあたりは用途に応じて調整してください
            'role' => 'user',
            'content' => [
                [
                    'type' => 'input_text',
                    'text' => '添付した読み込み、XXXの解析をしてください'
                ],
            ],
        ],
    ],
];

$ch = curl_init('https://api.openai.com/v1/responses');
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . {OpenAIのAPIKEY},
        'Content-Type: application/json',
    ],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($payload),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);

$responseBody = curl_exec($ch);

// Excelファイルを読み込んだResponses APIからのレスポンス結果を取得
$decoded = json_decode($responseBody, true);

$decodedに入っている実際の値

{
    "id": "resp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "object": "response",
    "created_at": 1758221093,
    "status": "completed",
    "background": false,
    "billing": {
        "payer": "developer"
    },
    "error": null,
    "incomplete_details": null,
    "instructions": null,
    "max_output_tokens": null,
    "max_tool_calls": null,
    "model": "o3",
    "output": [
        {
            "id": "ci_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "type": "code_interpreter_call",
            "status": "completed",
            "code": {解析に使われたPythonの内容が記載されている},
            "container_id": "cntr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx1",
            "outputs": null
        },
        {
            "id": "ci_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "type": "code_interpreter_call",
            "status": "completed",
            "code": {解析に使われたPythonの内容が記載されている},
            "container_id": "cntr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "outputs": null
        },
        {
            "id": "msg_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "type": "message",
            "status": "completed",
            "content": [
                {
                    "type": "output_text",
                    "annotations": [],
                    "logprobs": [],
                    "text": {解析結果がここに記載される}
                }
            ],
            "role": "assistant"
        }
    ],
    "parallel_tool_calls": true,
    "previous_response_id": null,
    "prompt_cache_key": null,
    "reasoning": {
        "effort": null,
        "summary": null
    },
    "safety_identifier": null,
    "service_tier": "default",
    "store": true,
    "temperature": 1.0,
    "text": {
        "format": {
            "type": "text"
        },
        "verbosity": "medium"
    },
    "tool_choice": "auto",
    "tools": [
        {
            "type": "code_interpreter",
            "container": {
                "type": "auto",
                "file_ids": [
                    "file-hghghgh"
                ]
            }
        }
    ],
    "top_logprobs": 0,
    "top_p": 1.0,
    "truncation": "disabled",
    "usage": {
        "input_tokens": 1026,
        "input_tokens_details": {
            "cached_tokens": 0
        },
        "output_tokens": 195,
        "output_tokens_details": {
            "reasoning_tokens": 0
        },
        "total_tokens": 1131
    },
    "user": null,
    "metadata": {}
}

最後に

アップロードできるファイル容量に制限があるので、
要件に合わせて、ファイルの有効期間を指定したり使用後にはファイルを削除してやるとよさそうです。

個々のファイルのサイズは最大512MB、1つの組織からアップロードされるすべてのファイルのサイズは最大1TBです。

ファイルの有効期限ポリシー。
デフォルトでは、purpose=batch、有効期限が30日後に期限切れとなるファイルは保存され、それ以外のファイルは手動で削除されるまで保存されます。

保存されたファイルの取扱

プロジェクト間でリソースを共有できますか?
プロジェクトリソース(ファイル、アシスタント、ストレージ、スレッドなど)はプロジェクト内に限定されており、プロジェクト外の管理者以外のメンバーからはアクセスできません。また、リソースをプロジェクト間で移動することもできません。

エンドポイントごとのストレージ要件と保持制御

似たような機能である「File search」じゃあ駄目なの?

File searchはExcleに対応してないから、対応している形式に変換しないとだめ...
対応しているファイル形式一覧

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?