1. OpenAI Assistants APIの紹介

1.1 Assistants APIの定義と目的

Assistants APIは、開発者が自分自身のアプリケーション内で人工知能アシスタントを構築できるようにします。カスタムコマンドを定義し、モデルを選択することで、アシスタントはユーザーのクエリに対応するためにモデル、ツール、知識を使用できます。現時点では、Assistants APIはCode Interpreter、Retrieval、Function Callingという3種類のツールをサポートしています。

1.2 Assistants APIの応用

Assistants APIは、対話型AIサポートが必要なさまざまなシナリオに適しています。たとえば:

  • カスタマーサポート: 一般的な質問に自動的に回答して人間のカスタマーサービスの負荷を軽減します。
  • オンライン教育: 生徒の質問に答えてカスタマイズされた学習支援を提供します。
  • データ解析: ユーザーがアップロードしたデータファイルを解析し、レポートを生成しチャートを視覚化します。
  • 個別推薦: ユーザーの過去のやり取りに基づいて個別の提案とサービスを提供します。

1.3 Assistantsのコア概念

Assistants APIの中心オブジェクトには、Assistant、Thread、およびMessageが含まれます。これらのオブジェクトとそれらの機能について詳細に紹介します。

Assistant

AssistantオブジェクトはOpenAIモデルに基づいて構築されており、AIアシスタントのツールを呼び出すことができます。Assistantの指示をカスタマイズして、その性格と機能を調整することができます。たとえば、「データアナリスト」という名前のAssistantを作成し、「code_interpreter」ツールを使用してデータを解析し、チャートを生成するAssistantを作成できます。

Thread

Threadオブジェクトは、ユーザーとAssistantの会話セッションを表します。ユーザーごとにThreadを作成し、ユーザーがAssistantとやり取りする際にメッセージを追加することができます。Threadオブジェクトは、効果的にメッセージ履歴を保存し、必要に応じてモデルのコンテキスト長の制限に準拠するためにメッセージを切り詰めます。

Message

Messageオブジェクトは、ユーザーまたはAssistantによって作成されることができます。Messageにはテキスト、画像、その他のファイルが含まれる可能性があります。MessageはThread上のリストとして保存されます。APIの実際の使用では、開発者はユーザーメッセージをThreadに追加し、必要に応じてAssistantの応答をトリガーできます。

Run

Runオブジェクトは、Assistantリクエストの実行を表し、Thread内のメッセージ内容に基づいてAssistantを呼び出します。Assistantは構成とThreadのメッセージを利用して、モデルとツールを呼び出してタスクを実行します。実行の一環として、AssistantはThreadにメッセージを追加します。

2. Assistants APIの開発プロセス

2.1 あなたのAssistantを作成する

Assistantを作成するには、指示、モデル名、ツール構成を含むリクエストをAPIに送信する必要があります。以下は、個人用の数学の家庭教師Assistantを作成する簡単な例です:

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "あなたは個人の数学の家庭教師です。コードを書いて実行して数学の質問に答えます。",
    "name": "Math Tutor",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4"
  }'

APIパラメータ:

  • instructions - Assistantに対して何をするかを示すシステムの指示。
  • name - Assistantの名前。
  • tools - Assistantが使用できるツールを定義します。各Assistantには最大128個のツールを持つことができます。現在のツールタイプはcode_interpreter、retrieval、またはfunctionです。
  • model - Assistantはどのモデルを使用するか?

Assistantを作成した後、Assistant IDが返されます。

2.2 セッションThreadを作成する

Threadは会話を表し、会話を開始するユーザーごとにセッションThreadを作成することをお勧めします。Threadを作成するには、以下のようにします:

curl https://api.openai.com/v1/threads \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d ''

Threadを作成した後、Thread IDが返されます。

2.3 メッセージをスレッドに追加する

特定のスレッドにメッセージを追加できます。これにはテキストを含めることができ、任意でユーザがアップロード可能なファイルを含めることもできます。例:

curl https://api.openai.com/v1/threads/{thread_id}/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
      "role": "user",
      "content": "この方程式 `3x + 11 = 14` を解く必要があります。助けてくれますか?"
    }'

APIパラメータ:

  • thread_id - 会話スレッドIDを表し、スレッドを作成する際に取得できます。

APIリクエストボディは通常、ユーザの質問を表すユーザメッセージであり、会話モデルのメッセージ構造に類似しています。

2.4 アシスタントを実行してレスポンスを生成する

ユーザのメッセージに応答するためには、Runを作成する必要があります。これにより、アシスタントはスレッドを読み取り、ツールを使用するか(有効になっている場合)、または単純にモデルを使用してクエリに最適な回答をするかを決定できます。

注:この時点まででは、アシスタントはユーザの質問にはまだ応答していません。Run APIを呼び出すと、AIアシスタントがユーザの質問に応答します。

curl https://api.openai.com/v1/threads/{thread_id}/runs \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "assistant_id": "assistant_id",
    "instructions": "ユーザをジェーン・ドウとして扱ってください。ユーザはプレミアムアカウントです。"
  }'

APIパラメータ:

  • thread_id - 会話スレッドIDを表し、スレッドを作成する際に取得できます。
  • assistant_id - アシスタントIDを表し、アシスタントを作成する際に取得できます。
  • instructions - アシスタントの指示で、アシスタントを作成する際に設定された指示を上書きできます。

成功したAPIリクエストはRun IDを返します。

2.5 アシスタントの実行状態を確認する

アシスタントでタスク(Run)を開始した後、タスクの実行は非同期です。これは、Runの状態を定期的にチェックして、完了したかどうかを確認する必要があることを意味します。Runの状態を確認するには、CURLを使用してHTTPリクエストを行うことができます。以下はこのプロセスの具体的な紹介です。

CURLリクエストの例:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

APIパラメータの説明:

  • https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123: これはAPIのリクエストURLで、thread_abc123 はスレッド(Thread)の一意の識別子であり、run_abc123 はRunの一意の識別子です。

レスポンスボディの例:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "completed",
  "created_at": 1699073585,
  ...
}

APIレスポンスパラメータの説明:

  • id: Runの一意の識別子。
  • object: 返されたオブジェクトの種類を示し、ここでは thread.run です。
  • status: Runの状態で、queuedin_progresscompletedrequires_actionfailed などの可能な値があります。
  • created_at: Runが作成されたタイムスタンプ。

2.6 アシスタントの応答結果を取得する

アシスタントのRunが完了した後、スレッド(Thread)に追加されたメッセージをチェックすることで、アシスタントの応答結果を読み取ることができます。以下は、CURLを使用してリクエストを行う方法と、APIパラメータの詳細な説明です。

ヒント:アシスタントとの会話と同様に、アシスタントがユーザのクエリの処理を終えると、アシスタントは会話スレッド(Thread)にメッセージを追加します。したがって、会話スレッド(Thread)の最新メッセージを問い合わせるだけで、アシスタントの応答を取得できます。

CURLリクエストの例:

curl https://api.openai.com/v1/threads/thread_abc123/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

API パラメータの説明:

  • https://api.openai.com/v1/threads/thread_abc123/messages: このAPIのリクエストURLです。ここで thread_abc123 はスレッド(Thread)のユニークな識別子です。
  • 以前にランのステータスを確認するために使用されたリクエストヘッダーと同じものを含み、認証情報やAPIバージョン情報を含みます。

アシスタントの応答結果の例:

この例では、ユーザーがアシスタントに数学の質問をし、アシスタントがそれを処理した後にスレッドに応答メッセージを追加しました。

User: この方程式 `3x + 11 = 14` を解きたいのですが、手伝ってもらえますか?
Assistant: もちろん、Jane Doeさん。方程式 `(3x + 11 = 14)` を解くには、`(x)` を方程式の片側に単独で置く必要があります。`(x)` の値を計算してあげましょう。
Assistant: 方程式 `(3x + 11 = 14)` の解は `(x = 1)` です。

アシスタントからの応答結果を得た後、ユーザーがアシスタントの提供するサービスをよりよく理解し、活用できるように示すことができます。

3. ツール: OpenAIによって提供される組み込みツール

3.1 コードインタプリターツール

コードインタプリターツールを使用すると、アシスタントAPIがPythonコードをサンドボックス実行環境で書いて実行できます。このツールはさまざまなデータやファイル形式を処理し、データやグラフィカルイメージを含むファイルを生成できます。コードインタプリターは、アシスタントが複雑なコーディングや数学の問題を解決するためにコードを反復的に実行できるようにします。アシスタントが書いたコードが実行に失敗した場合、コードを別の方法で試みて成功するまで反復的に実行できます。

コードインタプリターの有効化

コードインタプリターを有効にするには、Assistantオブジェクトを作成する際に tools パラメータで code_interpreter を渡します:

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "あなたは個人の数学の家庭教師です。数学の質問に答えるためにコードを書いて実行してください。",
    "tools": [
      { "type": "code_interpreter" }
    ],
    "model": "gpt-4-turbo-preview"
  }'

その後、モデルはユーザーのリクエストの性質に基づいてランタイムでコードインタプリターを起動するかどうかを決定します。この動作をアシスタントの instructions (例: "この問題を解くためにコードを書いてください") を通じて促進できます。

ファイルの処理にコードインタプリターを使用する

コードインタプリターを使用すると、ファイルからデータを解析できます。これは、アシスタントに大量のデータを提供したり、ユーザーが自分のファイルを分析するためにアップロードすることを許可したりする場合に便利です。コードインタプリターにアップロードされたファイルは検索索引には含まれません。検索索引にファイルを含めたい場合の詳細については、以下の検索ツールのセクションを参照してください。

アシスタントレベルで渡されたファイルは、このアシスタントに関連付けられたすべてのランによってアクセスできます:

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/mydata.csv"

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "あなたは個人の数学の家庭教師です。数学の質問に答えるためにコードを書いて実行してください。",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4-turbo-preview",
    "file_ids": ["file_123abc456"]
  }'

コードインタプリターによる画像およびファイルの読み込み

コードインタプリターは、APIでファイル出力することもできます。たとえば、画像チャート、CSV、PDFファイルの生成が挙げられます。生成されるファイルには、画像ファイルとデータファイル(例: アシスタントによって生成されたデータが含まれるCSVファイル)の2種類があります。

コードインタプリターが画像を生成した場合、これをアシスタントメッセージのfile_idフィールドで見つけてダウンロードすることができます:

{
    "id": "msg_abc123",
    "object": "thread.message",
    "created_at": 1698964262,
    "thread_id": "thread_abc123",
    "role": "assistant",
    "content": [
    {
      "type": "image_file",
      "image_file": {
        "file_id": "file-abc123"
      }
    }
  ]
  // ...
}

3.2 検索ツール

検索ツールは、アシスタントの機能を強化し、モデル外部からの知識(例: 独自の製品情報やユーザー提供のドキュメント)を追加します。ファイルがアップロードされ、アシスタントに渡されると、OpenAIは自動的にドキュメントをスライスし、インデックス化し、埋め込みを保存し、ベクトル検索を実装して関連コンテンツを取得し、ユーザーのクエリに回答します。

検索の有効化

アシスタントのtoolsパラメータで検索を有効にするには、retrievalを渡します:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "お客様サポートチャットボットです。ナレッジベースを使用して、お客様のクエリに効果的に応答してください。",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
  }'

検索のためのファイルアップロード

コードインタプリターと同様に、ファイルをアシスタントレベルまたは個々のメッセージレベルでアップロードすることができます。

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/knowledge.pdf"

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "お客様サポートチャットボットです。ナレッジベースを使用して、お客様のクエリに効果的に応答してください。",
    "name": "数学の先生",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
    "file_ids": ["file_123abc456"]
  }'

3.3 関数呼び出しツール

チャット補完APIと同様に、Assistants APIは関数の呼び出しをサポートしています。関数呼び出しを使用すると、アシスタントに関数を説明し、その関数とそのパラメータをインテリジェントに返すことができます。関数呼び出しが実行されると、Assistants APIは実行を一時停止し、関数呼び出しの結果を提供して実行を続行できます。

関数の定義

アシスタントを作成する際、アシスタントが呼び出す一連の関数を定義できます。これらの関数は、アシスタントオブジェクトを作成する際に明示的に指定する必要があります。各関数には一意の名前、説明、およびパラメータ仕様が必要です。

以下のコードは、アシスタントを作成する際に、curlコマンドを使用して2つの関数を定義する方法を示しています。

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "天気予報ボットです。提供された関数を使用して質問に答えます。",
    "tools": [{
      "type": "function",
      "function": {
        "name": "getCurrentWeather",
        "description": "特定の場所の天候を取得します",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "都市と州、例: サンフランシスコ、CA"},
            "unit": {"type": "string", "enum": ["c", "f"]}
          },
          "required": ["location"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "getNickname",
        "description": "都市のニックネームを取得します",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "都市と州、例: サンフランシスコ、CA"}
          },
          "required": ["location"]
        }
      }
    }],
    "model": "gpt-4-turbo-preview"
  }'

アシスタントによって呼び出された関数の読み取り

ユーザーがアシスタントにメッセージを送信し、そのメッセージの内容が関数呼び出しをトリガーすると、この関数呼び出しの情報を読み取る必要があります。このプロセス中、アシスタントはrequires_actionステータスの実行を生成します。この時点で、Runオブジェクトを取得して関数呼び出しの詳細情報を取得できます。

以下は、Runオブジェクトを取得して関数呼び出しの情報を取得する方法を示した例です。

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "requires_action",
  "required_action": {
    "type": "submit_tool_outputs",
    "submit_tool_outputs": {
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "getCurrentWeather",
            "arguments": "{\"location\":\"サンフランシスコ\"}"
          }
        },
        {
          "id": "call_abc456",
          "type": "function",
          "function": {
            "name": "getNickname",
            "arguments": "{\"location\":\"ロサンゼルス\"}"
          }
        }
      ]
    }
  },
  ...
}

tool_callsパラメータには関数呼び出しの情報が含まれており、ローカルプログラムで対応する関数を呼び出す必要があります。

関数出力の提出

関数呼び出しをローカルで実行し、結果を取得した後は、これらの結果を Assistantsアシスタントに提出して、アシスタントがユーザーのリクエストを継続処理できるようにする必要があります。関数の出力を提出する際は、出力が元の関数呼び出しと関連付けられていることを確認する必要があります。

以下は、関数の出力結果を提出する方法の例コードです。

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_123/submit_tool_outputs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "tool_outputs": [
      {
        "tool_call_id": "call_abc123",
        "output": "{\"temperature\": \"22\", \"unit\": \"セ氏\"}"
      }, 
      {
        "tool_call_id": "call_abc456",
        "output": "{\"nickname\": \"LA\"}"
      }
    ]
  }'

パラメータの説明:

  • thread_abc123 は会話スレッドのIDを表します
  • run_123 はRunオブジェクトのIDを表します
  • tool_call_id は特定の関数呼び出しのIDを表し、これは前のtool_callsパラメータから取得されます。

すべての関数出力を正常に提出すると、Runオブジェクトのステータスが再度更新され、アシスタントは処理を継続して最終的な応答をユーザーに返します。