見出し画像

【図解】Realtime APIにおけるFunction Callingの仕組み

OpenAIのRealtime APIには、Function Callingという機能が組み込まれています。

Chat GPTの高度な音声対話モード(Advanced Voice Mode)では、ユーザーが質問をしたらAIモデルが直接回答をします。それに対してRealtime APIでは、Function Callingの機能を使って開発者が作成した関数を呼び出し、APIを通じて外部の知識を利用したり、画面を更新したり、正確な計算をしたりした上で、AIモデルに会話を引き継ぐため、会話体験を拡張することができます。

例えば、天気予報や株価のAPIを利用して正確に答えるとか、カレンダーに予定を追加したり、商品の在庫数を調べて答えたり、日付を正確に計算して返したりといった使い方があります。

ユーザー体験を考える上で、Function Callingがどのような手順で呼び出され、後続の処理にどのように続くのか、理解しておく必要があります。

Function Callingの基本的な流れ

会話セッションの開始から応答までの基本的な流れを図解しました。拡大してご覧ください。

1. 関数ツールの登録

まず、あらかじめAIモデルが呼び出せる関数を定義しておきます。そして、活用できる関数をAIに対して登録し教えておきます。関数は複数登録することができます。

会話を開始するタイミングのセッション単位(session.update)と、一つ一つの応答をするレスポンス単位(response.create)で関数を登録できます。

会話全体で関数を活用したい場合はセッション単位で登録しておき、特定の会話のパターンでのみ関数を使う場合はレスポンス単位で上書きをします。

関数を登録する際には、以下のような情報を用意します。

  • name: 関数名

  • description: 関数の役割を説明するテキスト(モデルがどんなときに呼べばいいかを理解しやすいように書く)

  • parameters: 関数を呼び出す際に渡す引数の型を定義。ここでは、星占いで利用する星座として、12の星座名からいずれかを選択して、文字列として返すことを指示しています。

{
  "type": "session.update",
  "session": {
    "tools": [
      {
        "type": "function",
        "name": "generate_horoscope",
        "description": "今日の運勢をユーザーの星座にもとづいて占います",
        "parameters": {
          "type": "object",
          "properties": {
            "sign": {
              "type": "string",
              "description": "星占いで利用する星座",
              "enum": [
                "牡羊座","牡牛座","双子座",
                "蟹座","獅子座","乙女座",
                "天秤座","蠍座","射手座",
                "山羊座","水瓶座","魚座"
              ]
            }
          },
          "required": ["sign"]
        }
      }
    ],
    "tool_choice": "auto"
  }
}

2. ユーザー入力とモデルの判断

ユーザーからの問いかけがあると、モデルはその内容を解析し、「関数を呼び出す必要があるかどうか」を決定します。Realtime APIではユーザーが発話を終了し無音状態になると判断を開始します。

たとえば「星占いしてほしい、私の星座は双子座です。」といった内容を認識し、正座に基づいて占い結果を出力する関数の呼び出しが必要と判断します。

「カレンダーで今日の予定を調べて。」と問いかけられたら、別に登録しておいた、カレンダーAPIを叩く関数を呼び出します。「ちょっと悩みを相談したくて。」などと問いかけられた場合には、関数を呼び出さずにAIモデルがすぐに直接回答を生成します。

3. モデルが関数呼び出しを提案

モデルは関数呼び出しを行おうとすると、レスポンスの一部として「関数呼び出しアイテム」を生成します。ここでは、AIはユーザーに対する回答を生成しません。ただ、関数を呼び出すことを提案するだけで、そこで会話が止まります。

AIモデルはそれまでの会話の文脈から、ユーザーの星座が何かを特定し、星占いの関数と、その関数に渡す引数として「双子座」と指定します。

サーバーから送信されるサーバーイベント(例: response.done)において、以下のような内容を受け取ることができます。

{
  "type": "response.done",
  "response": {
    "id": "resp_xxxx",
    "output": [
      {
        "object": "realtime.item",
        "type": "function_call",
        "name": "generate_horoscope",
        "call_id": "call_sHlR7iaFwQ2YQOqm",
        "arguments": "{\"sign\":\"双子座\"}"
      }
    ]
  }
}

• type: "function_call" になっているアイテムが、「モデルが関数を呼び出そうとしている」という合図。
• name は呼び出す関数名。
• arguments はJSON文字列で、関数呼び出しに必要な引数が入っています。
• call_id は、あとで関数の出力をモデルに渡す際に必要となる識別子です。

4. 実際の関数実行と出力

クライアント側(あるいはサーバーサイドの実装)で、モデルが指定した関数 (name) と引数 (arguments) をもとに実際にコードを実行します。実行した結果をconversation.item.createを使って会話履歴に挿入します。

たとえば、generate_horoscope 関数をPythonで実装している場合、以下のような流れになります。
1. 受け取った call_id と arguments をパースし、sign = "双子座" を取得。
2. generate_horoscope(sign="双子座") を実行し、占いの結果の文字列を得る。
3. その結果をJSON文字列にして、次のようにRealtime APIへ返す。

{
  "type": "conversation.item.create",
  "item": {
    "type": "function_call_output",
    "call_id": "call_sHlR7iaFwQ2YQOqm",
    "output": "{\"horoscope\": \"新しい人間関係に恵まれる\"}"
  }
}

• item.type は function_call_output と指定
• call_id はモデルが発行したIDと同じもの
• output は関数の実行結果を表すJSON文字列(内容は自由)

5. モデルが結果を反映して最終応答

最後に、関数結果が会話アイテムとして追加されたため、モデルが再度応答を生成できます。
response.create を再度呼び出すなどして、AIモデルに「関数呼び出し結果を踏まえてユーザーに占いの結果を伝えてください。」と指示すると、モデルは「双子座のあなたの今日の運勢は…」といった形で最終メッセージを生成し、会話を続けます。

もしアウトプットを会話全体に残したくない場合や、複数同時に呼び出したい場合は、response.conversation = "none" のように「デフォルト以外の会話スレッド」を使うこともできます。

Function Calling導入のメリット

1. 自然言語でのAPI呼び出し: ユーザーの要望を明示的なボタン操作やコマンド入力なしで、自然言語を通じて実行できる。
2. スケーラブルな拡張: 関数を追加登録するだけで、AIアシスタントの機能を容易に拡張可能。
3. 柔軟なデータ取得・計算: モデルが苦手とする複雑な計算や、外部サービスからのデータ取得を関数に任せ、モデル側は指示や応答の自然さにフォーカスできる。

まとめ

Function Callingを使うと、モデルと外部機能の連携が非常にスムーズになります。モデルが提案する形で引数が受け取れるため、ユーザーの入力をもとに「どの関数を呼ぶか」「どんなパラメータが必要か」という推論を自然言語ベースで行えます。

特に、音声インタフェースやチャットボットで「外部サービスとやり取りして結果を反映する」というシナリオが多い場合、Realtime APIとFunction Callingの組み合わせは強力なソリューションとなるでしょう。

今後の論点として、Function Callingを使うとき、例えばWEBのクローリングや重たい処理を行うには、関数の実行完了に時間がかかる場合があります。そうした場合にどのようにユーザーを待たせるかや、画面の操作とどのように連携させるかなど、ユーザー体験の課題がたくさん出てくることでしょう。

また、実際にFunction Callingを使うには、どんな関数をどのように定義するかを設計しなければいけません。単純な天気API連携から複雑な業務ロジック連携まで、多種多様なユースケースが考えられます。

引き続き研究を進めながらベストプラクティスが生まれたら記事にしていきます。

ぜひモデルとの対話を活用し、ユーザーが求めるタスクをダイナミックに実行するアプリケーションを作ってみてください。


公式ドキュメント
https://openai.com/index/introducing-the-realtime-api/

いいなと思ったら応援しよう!