ChatGPTに自社のREST APIを使わせる:Function Callingを使った連携実践ガイド(PHP編)

OpenAIが提供するChatGPT APIには、「Function Calling」と呼ばれる機能があります。これにより、開発者はChatGPTとの対話中に自社で定義したREST APIや処理関数を呼び出し、取得したデータを元に自然な応答を生成させることができます。 本記事では、PHPで作成したREST APIを対象に、ChatGPT APIのFunction Calling機能とどのように連携できるのかを、コード例を交えて解説します。

Function Callingとは?ChatGPTがAPIを使える仕組み

Function Callingは、ChatGPT API(GPT-4)で使用できる機能で、事前に定義された関数情報(関数名・引数・説明など)に基づき、ChatGPTが適切な関数を呼び出すよう誘導する機能です。

自然言語の入力から適切な関数名と引数を判断し、function_callという構造で返されます。 ただし、実際の関数実行は開発者側が行い、結果を再度GPTに返して自然言語で応答させる、という構造になっています。


REST APIの準備:PHPで商品データを提供するAPI

今回は以下の記事で作成したダミーのREST APIと商品データを利用します。

  • エンドポイント:/api/products
  • 機能:商品一覧の取得、またはID指定による商品詳細取得
  • データ:JSONファイルで管理

データ例:products.json

[
  { "id": 101, "name": "ハンドドリル", "price": 1980 },
  { "id": 102, "name": "インパクトドライバー", "price": 2980 },
  { "id": 103, "name": "丸ノコ", "price": 4980 },
  { "id": 104, "name": "工具セット(30点)", "price": 7980 },
  { "id": 105, "name": "電動サンダー", "price": 3980 }
]

APIの挙動

  • GET /api/products → 全商品をJSONで返す
  • GET /api/products?id=103 → IDが103の商品を1件返す

Function Calling用の関数定義

ChatGPT APIにリクエストする際、functions パラメータを使って関数の仕様をJSON Schema形式で定義します。 今回使用する関数は2つです:

$functions = [
  [
    "name" => "listProducts",
    "description" => "すべての商品を一覧表示する",
    "parameters" => [
      "type" => "object",
      "properties" => new stdClass(),
      "required" => []
    ]
  ],
  [
    "name" => "getProductById",
    "description" => "指定したIDの商品詳細を取得する",
    "parameters" => [
      "type" => "object",
      "properties" => [
        "id" => [
          "type" => "integer",
          "description" => "商品ID(例: 101)"
        ]
      ],
      "required" => ["id"]
    ]
  ]
];

実装例:JavaScriptからPHPを経由してOpenAIを呼び出す

今回の構成では、ユーザーがHTML上のフォームから入力し、JavaScriptがそれを取得してPHPに送信します。PHPはOpenAIのChatGPT APIを呼び出し、そのレスポンスに function_call が含まれていれば、指定された関数を実行します。その結果を再びChatGPTに渡して、最終的な応答を自然言語で生成し、JavaScriptを通じてHTMLに表示します。

HTML(ユーザー入力) ⇒ JavaScript ⇒ PHP ⇒ ChatGPT API(function_call ) ⇒ PHP(関数実行) ⇒ ChatGPT API(自然言語での応答生成) ⇒ PHP ⇒ JavaScript ⇒ HTML

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>商品検索チャット</title>
</head>
<body>
  <h1>商品についてChatGPTに聞いてみよう</h1>

  <input type="text" id="userInput" placeholder="例:103番の商品について教えて">
  <button id="submitBtn">送信</button>

  <div id="result" style="margin-top:1em; white-space:pre-wrap;"></div>

  <script>
    document.getElementById('submitBtn').addEventListener('click', async () => {
      const input = document.getElementById('userInput').value;
      if (!input.trim()) return;

      const res = await fetch('chat.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: input })
      });

      const data = await res.json();
      document.getElementById('result').innerText = data.reply;
    });
  </script>
</body>
</html>

chat.php

<?php
$request = json_decode(file_get_contents('php://input'), true);
$userMessage = $request['message'] ?? '';

$functions = [
  [
    "name" => "listProducts",
    "description" => "すべての商品を一覧表示する",
    "parameters" => [
      "type" => "object",
      "properties" => new stdClass(),
      "required" => []
    ]
  ],
  [
    "name" => "getProductById",
    "description" => "指定したIDの商品詳細を取得する",
    "parameters" => [
      "type" => "object",
      "properties" => [
        "id" => [
          "type" => "integer",
          "description" => "商品ID(例: 101)"
        ]
      ],
      "required" => ["id"]
    ]
  ]
];

$apiKey = 'sk-xxxxxxxxxxxxxxxx';
$endpoint = 'https://api.openai.com/v1/chat/completions';

$ch = curl_init($endpoint);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json'
  ],
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode([
    'model' => 'gpt-4',
    'messages' => [
      ['role' => 'user', 'content' => $userMessage]
    ],
    'functions' => $functions,
    'function_call' => 'auto'
  ])
]);

$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);

$call = $data['choices'][0]['message']['function_call'] ?? null;
$reply = '回答できませんでした。';
$func = null;

if ($call) {
  $func = $call['name'];
  $args = json_decode($call['arguments'], true);

  if ($func === 'listProducts') {
    $reply = file_get_contents('https://yourdomain.com/api/products');
  } elseif ($func === 'getProductById' && isset($args['id'])) {
    $reply = file_get_contents('https://yourdomain.com/api/products?id=' . urlencode($args['id']));
  }
}

if ($func && $reply !== '回答できませんでした。') {
  $second = curl_init($endpoint);
  curl_setopt_array($second, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
      'Authorization: Bearer ' . $apiKey,
      'Content-Type: application/json'
    ],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode([
      'model' => 'gpt-4',
      'messages' => [
        ['role' => 'user', 'content' => $userMessage],
        ['role' => 'function', 'name' => $func, 'content' => $reply]
      ]
    ])
  ]);

  $secondRes = curl_exec($second);
  curl_close($second);
  $secondData = json_decode($secondRes, true);
  $reply = $secondData['choices'][0]['message']['content'] ?? '返答が取得できませんでした。';
}

header('Content-Type: application/json');
echo json_encode(['reply' => $reply]);

実際のやりとり例:商品一覧と詳細の返答例

商品一覧取得

■ 処理の流れ

  • ユーザー:「商品一覧を見せて」
  • Chat GPTが listProducts を選択
  • PHPが自社のREST API(/api/products)を実行し、結果をChat GPTに渡す
  • Chat GPTが自然言語で応答する

■ 実行結果

商品詳細取得

■ 処理の流れ

  • ユーザー:「103番の商品について教えて」
  • Chat GPTが getProductById を選択し、引数 {"id": 103} を返す
  • PHPが自社のREST API(/api/products?id=103)を実行し、結果をChat GPTに渡す
  • Chat GPTが自然言語で応答する

■ 実行結果


注意点と補足

  • スキーマ定義の厳密さに注意functions パラメータの parameters は JSON Schema 準拠で正しく書く必要があります。特に type, properties, required の記述ミスがあると、ChatGPT APIがエラーを返します。
  • APIの戻り値とトークン制限:OpenAI APIは1レスポンスあたりのトークン数に上限があります。REST APIから返されるデータが多すぎると、レスポンスの一部が切り捨てられる可能性があります。
  • function_callがない場合もある:ユーザーの入力が想定された関数と一致しない場合、ChatGPTは関数呼び出しを提案せず、そのままテキストを返すことがあります。この場合に備えて通常応答の処理も検討しておきましょう。
  • OpenAI APIのエラーハンドリング:通信エラーや認証エラー、モデル指定の誤りなど、OpenAI APIからのエラーに備えて適切な例外処理・ログ出力を入れておくことが重要です。
  • セキュリティとAPIキー管理:APIキーはコード内にベタ書きせず、.env や設定ファイルなどで安全に管理してください。誤って公開リポジトリなどに含めないよう注意が必要です。
  • POST APIや認証付きAPIとの連携も可能:今回のサンプルではGET形式のREST APIを使用しましたが、Function Callingの仕組みはPOSTリクエストやトークン付きAPIにも応用可能です。

まとめ:自社データとChatGPT連携はここまでできる

Function Calling機能により、ChatGPTはただの会話AIから“実用的な情報インターフェース”へと進化しました。 自社で構築したREST APIなどと連携することで、商品の問い合わせやFAQの自動応答、カスタマーサポート、社内情報の検索インターフェースなど、さまざまな業務やサービスに活用できる可能性があります。

今後、OpenAIのAPIやChatGPTの機能がさらに拡張されていくことを考えると、今回紹介したようなシンプルな連携方法を早い段階で実装しておくことは、AI活用の土台づくりとして非常に有効です。 ChatGPT APIを活用しながら、自社の強みやデータを活かした“自分(自社)だけのAI体験”を構築していきましょう。

Contact

ウェブサイトの制作や運用に関わる
お悩みやご相談
お気軽にお問い合わせ下さい

ウェブサイトと一口に言っても、企業サイトやECサイト、ブログ、SNSなど、その“カタチ”は目的に応じてさまざまであり、構築方法や使用する技術も大きく異なります。株式会社コナックスでは、お客様のご要望やブランドの個性を丁寧に汲み取り、最適なウェブサイトの“カタチ”をご提案いたします。

デザイン、ユーザビリティ、SEO対策はもちろん、コンテンツ制作やマーケティング戦略に至るまで、あらゆるフェーズでお客様のビジネスに寄り添い、成果につながるウェブサイトづくりをサポートいたします。私たちは、ウェブサイトの公開をゴールではなくスタートと捉え、お客様のビジネスの成功に向けて共に伴走してまいります。