OpenAI Responses APIのWeb検索と状態

こちらをDatabricksでウォークスルーします。

https://cookbook.openai.com/examples/responses_api/responses_example

翻訳版のノートブックはこちらです。

https://github.com/taka-yayoi/openai_responses_api/blob/main/responses_example.ipynb

# Responses API とは

Responses API は、当社(OpenAI)の API を使用する際のシンプルさと表現力を向上させることに焦点を当てた新しい API です。これは、複数のツール、複数のターン、および複数のモダリティに対応するように設計されています。現在の API は、主にテキストの入出力（chat completions）を目的として設計されているため、これらの機能が追加されているか、単純な操作を実行するために多くのブートストラップが必要です（assistants API）。

ここでは、Responses API が提供するいくつかの新機能を紹介し、最後にそれらをまとめます。
`responses` は、現在の API セットに関する多くのユーザーの痛点を解決します。Completions API を使用している間、次のような要望がありました：

- 単一の API 呼び出しで簡単にマルチターンのモデル対話を実行する機能
- 当社のホストツール（ファイル検索、ウェブ検索、コードインタープリター）へのアクセス
- モデルに送信されるコンテキストの詳細な制御

モデルが長時間の推論および思考能力を発展させ始めると、ユーザーは非同期対応で状態を保持するプリミティブを求めるようになります。応答 API はこれを解決します。

```py
%pip install -U mlflow openai
%restart_python
```

以下でMLflow Traceを有効化していますが、執筆時点ではResponses APIは[サポートされていません](https://www.mlflow.org/docs/latest/tracing/integrations/openai#supported-apis)でした。

```py
import mlflow
mlflow.openai.autolog()
```

# 基本
設計上、表面的には、Responses API は Completions API と非常に似ています。

```py
from openai import OpenAI
import os

client = OpenAI(api_key=dbutils.secrets.get("demo-token-takaaki.yayoi", "openai_api_key"))
```

```py
response = client.responses.create(
    model="gpt-4o-mini",
    input="ジョークを教えてください",
)
```

```py
print(response.output[0].content[0].text)
```

```
もちろん！こちらのジョークはいかがでしょうか？

**質問:** カメはどうしてあんなに遅いの？

**答え:** だって、みんなに「カメの進化」って言われてるから！ 

笑っていただけたら嬉しいです！他にジョークをお求めですか？
```

Responses API の主な機能の一つは、ステートフルであることです。つまり、会話の状態を自分で管理する必要はなく、API がそれを処理してくれます。例えば、いつでも応答を取得でき、その中には完全な会話履歴が含まれます。

```py
fetched_response = client.responses.retrieve(
response_id=response.id)

print(fetched_response.output[0].content[0].text)
```
```
もちろん！こちらのジョークはいかがでしょうか？

**質問:** カメはどうしてあんなに遅いの？

**答え:** だって、みんなに「カメの進化」って言われてるから！ 

笑っていただけたら嬉しいです！他にジョークをお求めですか？
```

前の応答を参照して会話を続けることができます。

```py
response_two = client.responses.create(
    model="gpt-4o-mini",
    input="別のを教えてください。",
    previous_response_id=response.id
)
```
```py
print(response_two.output[0].content[0].text)
```
```
もちろん！こちらはいかがでしょう？

「お医者さん、私の背中が痛いんです。」

「どの辺が痛いですか？」

「右の肩甲骨のあたりです。」

「それなら、右の肩甲骨を使わないようにしてみてください。」

「それだと、何もできなくなっちゃいますよ！」

「そうですね、でも痛みは和らぐかもしれません！」 

（使わない方が良いという皮肉な逆説的なジョークです。）
```

もちろん、自分でコンテキストを管理することもできます。しかし、OpenAIがコンテキストを管理してくれる利点の一つは、任意の時点で応答を分岐させ、その時点から会話を続けることができることです。

```py
response_two_forked = client.responses.create(
    model="gpt-4o-mini",
    input="そのジョークは好きではありませんでした。別のジョークを教えてください。そして、2つのジョークの違いを教えてください。",
    previous_response_id=response_two.id # フォークして2番目のレスポンスから続ける
)

output_text = response_two_forked.output[0].content[0].text
print(output_text)
```

```
分かりました！別のジョークをどうぞ：

「今日は何か特別なことがあったんだ。」

「何があったの？」

「仕事に遅れて行ったら、上司がすごく怒ってた。」

「それで？」

「いや、特に何もなかった。ただ、遅刻しただけ。」

このジョークは、期待される特別な出来事が何もなく、ただの遅刻であったことがオチになっています。

### 2つのジョークの違い

1. **内容の方向性**:
   - 最初のジョークはダブルミーニングを用いた言葉遊びでした。
   - 新しいジョークは、シンプルな状況の皮肉を使ったものです。

2. **ユーモアのスタイル**:
   - 最初のジョークは言葉の意味をひねったもので、予想外の返事に笑いを求めています。
   - 新しいジョークは日常的な状況を描写し、それが期待外れであることにユーモアがあります。

どうぞ気に入っていただけたら嬉しいです！
```

# ホストされたツール

Responses APIのもう一つの利点は、`file_search`や`web_search`のようなホストツールのサポートを追加することです。ツールを手動で呼び出す代わりに、ツールを渡すだけでAPIがどのツールを使用するかを決定し、使用します。

以下は、`web_search`ツールを使用してウェブ検索結果を応答に組み込む例です。ChatGPTがウェブを検索できることはすでにご存知かもしれません。同様の体験を構築することができます！ウェブ検索ツールは、ChatGPTのウェブ検索を支えるOpenAIインデックスを使用しており、チャットアプリケーション向けに最適化されています。

```py
response = client.responses.create(
    model="gpt-4o",  # あるいは他のサポートされているモデル
    input="最新のAIニュースは何ですか？",
    tools=[
        {
            "type": "web_search"
        }
    ]
)
```

元のコードですと文字列が適切に表示されなかったので、[こちら](https://stackoverflow.com/questions/18337407/saving-utf-8-texts-with-json-dumps-as-utf-8-not-as-a-u-escape-sequence)を参考に`ensure_ascii=False`を追加しています。

```py
import json
print(json.dumps(response.output, default=lambda o: o.__dict__, indent=2, ensure_ascii=False))
```
```
[
  {
    "id": "ws_67e270b4c3ec8191812d522f775f98a9083790869728bdde",
    "status": "completed",
    "type": "web_search_call"
  },
  {
    "id": "msg_67e270b89fd88191a9aa9cadd71ac0b3083790869728bdde",
    "content": [
      {
        "annotations": [
          {
            "end_index": 322,
            "start_index": 215,
            "title": "AIニュース",
            "type": "url_citation",
            "url": "https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai"
          },
          {
            "end_index": 579,
            "start_index": 472,
            "title": "AIニュース",
            "type": "url_citation",
            "url": "https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai"
          },
          {
            "end_index": 834,
            "start_index": 727,
            "title": "AIニュース",
            "type": "url_citation",
            "url": "https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai"
          },
          {
            "end_index": 1122,
            "start_index": 1015,
            "title": "AIニュース",
            "type": "url_citation",
            "url": "https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai"
          },
          {
            "end_index": 1413,
            "start_index": 1306,
            "title": "AIニュース",
            "type": "url_citation",
            "url": "https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai"
          }
        ],
        "text": "最新のAI関連ニュースをお伝えします。\n\n**1. Anthropic、AIモデル「Claude 3.5 Sonnet」と「Claude 3.5 Haiku」を発表**\n\n2024年10月22日、AnthropicはAIモデル「Claude 3.5 Sonnet」と「Claude 3.5 Haiku」を発表しました。これらのモデルは、前バージョンよりも高度な機能を備え、より自然な対話や複雑なタスクの処理が可能となっています。 ([chatopenai.jp](https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai))\n\n**2. OpenAI、ChatGPTの新機能「Canvas」を導入**\n\n2024年10月3日、OpenAIはChatGPTに新しいインターフェース「Canvas」を導入しました。これにより、ユーザーは従来のチャットボックスに加え、より直感的で視覚的な方法でAIと対話できるようになりました。 ([chatopenai.jp](https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai))\n\n**3. OpenAI、ChatGPTの高度な音声モードをウェブに拡大**\n\n2024年11月19日、OpenAIはChatGPTの高度な音声モードをウェブ版にも拡大しました。これにより、ユーザーはテキスト入力だけでなく、音声を通じてAIと対話することが可能となり、利便性が向上しています。 ([chatopenai.jp](https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai))\n\n**4. OpenAI、ChatGPTのプレミアムプラン「ChatGPT Pro」を発表**\n\n2024年12月5日、OpenAIはChatGPTの新しいプレミアムサブスクリプションプラン「ChatGPT Pro」を発表しました。このプランでは、高度な機能を備えた複雑なタスクの処理が可能となり、プロフェッショナルユーザー向けのサービスが強化されています。 ([chatopenai.jp](https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai))\n\n**5. OpenAI、ChatGPTと電話やWhatsAppでのやりとりを可能に**\n\n2024年12月18日、OpenAIは「12 Days of Ship-mas」の10日目を記念して、ユーザーがChatGPTと電話やWhatsAppでやりとりできる新機能を発表しました。これにより、より多様なコミュニケーション手段でAIと対話することが可能となりました。 ([chatopenai.jp](https://chatopenai.jp/category/ai%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/?utm_source=openai))\n\nこれらのニュースは、AI技術の進化とその応用範囲の拡大を示しています。今後もAIの発展に注目が集まることでしょう。 ",
        "type": "output_text"
      }
    ],
    "role": "assistant",
    "status": "completed",
    "type": "message"
  }
]
```

# マルチモーダル、ツール拡張会話

Responses APIは、テキスト、画像、音声のモダリティをネイティブにサポートしています。
すべてを結びつけることで、Responses APIを通じて1回のAPI呼び出しで完全なマルチモーダル、ツール拡張インタラクションを構築できます。

```py
import base64

from IPython.display import Image, display

# 提供されたURLから画像を表示
url = "https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Cat_August_2010-4.jpg/2880px-Cat_August_2010-4.jpg"

display(Image(url=url, width=400))

response_multimodal = client.responses.create(
    model="gpt-4o",
    input=[
        {
            "role": "user",
            "content": [
                {"type": "input_text", "text": 
                 "画像に関連するキーワードを考え、それらのキーワードを使って検索ツールで関連ニュースを検索し、"
                 "結果を要約し、出典を引用してください。"},
                {"type": "input_image", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Cat_August_2010-4.jpg/2880px-Cat_August_2010-4.jpg"}
            ]
        }
    ],
    tools=[
        {"type": "web_search"}
    ]
)
```

![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Cat_August_2010-4.jpg/2880px-Cat_August_2010-4.jpg)

```py
import json
print(json.dumps(response_multimodal.__dict__, default=lambda o: o.__dict__, indent=4, ensure_ascii=False))
```
```
{
    "id": "resp_67e326c173c88191bafdb4c2639d9afe05953ee1d40340a1",
    "created_at": 1742939841.0,
    "error": null,
    "incomplete_details": null,
    "instructions": null,
    "metadata": {},
    "model": "gpt-4o-2024-08-06",
    "object": "response",
    "output": [
        {
            "id": "msg_67e326c440888191b57031c98a69ec4005953ee1d40340a1",
            "content": [
                {
                    "annotations": [],
                    "text": "画像に関連するキーワードとして、「猫」「キジトラ」「階段」「リラックス」が考えられます。\n\nこれらのキーワードを基に関連ニュースを検索します。",
                    "type": "output_text"
                }
            ],
            "role": "assistant",
            "status": "completed",
            "type": "message"
        },
        {
            "id": "ws_67e326c7cbd08191988876f13617466505953ee1d40340a1",
            "status": "completed",
            "type": "web_search_call"
        },
        {
            "id": "msg_67e326cb021c819189a7cffbdf53163705953ee1d40340a1",
            "content": [
                {
                    "annotations": [
                        {
                            "end_index": 251,
                            "start_index": 172,
                            "title": "MIX　キジトラに関する記事一覧｜ねこのきもちWEB MAGAZINE",
                            "type": "url_citation",
                            "url": "https://cat.benesse.ne.jp/tags/?id=911&utm_source=openai"
                        },
                        {
                            "end_index": 442,
                            "start_index": 367,
                            "title": "一仕事終えたキジトラ猫さんが帰宅してくつろいでいると… 茶トラ猫さんがねぎらいにやって来た♪ | TRILL〖トリル〗",
                            "type": "url_citation",
                            "url": "https://trilltrill.jp/articles/3564320?utm_source=openai"
                        },
                        {
                            "end_index": 696,
                            "start_index": 595,
                            "title": "猫「両立したいんです……」　まったり中の猫2匹、本能にあらがえない様子が「これは笑うw」「かわいい～！」〖ポーランド〗（1/2 ページ） - ねとらぼ",
                            "type": "url_citation",
                            "url": "https://nlab.itmedia.co.jp/nl/articles/2311/29/news019.html?utm_source=openai"
                        },
                        {
                            "end_index": 931,
                            "start_index": 830,
                            "title": "お昼寝中の2匹の猫、ぎゅ～っと抱き合って……　寒い時期ならではの光景がたまらなくかわいい〖米〗（1/3 ページ） - ねとらぼ",
                            "type": "url_citation",
                            "url": "https://nlab.itmedia.co.jp/nl/articles/2311/24/news131.html?utm_source=openai"
                        },
                        {
                            "end_index": 1116,
                            "start_index": 1050,
                            "title": "おやすみの「チュー」ではなく「カプっ」。キジトラちゃんが寝る前にしたご挨拶に…キュン(〃∇〃)♡ | PECO（ペコ）",
                            "type": "url_citation",
                            "url": "https://peco-japan.com/79137?utm_source=openai"
                        }
                    ],
                    "text": "以下のキーワード「猫」「キジトラ」「リラックス」を用いて関連ニュースを検索し、結果を要約しました。\n\n1. **甘えん坊なキジトラ猫のリキちゃん**  \n   キジトラ猫のリキちゃんは、パパさんがテーブルに肘をかけていると、腕枕を求めてやってきます。どんなクッションよりも気持ちよさそうに、うっとりとした表情を見せる姿が可愛らしいと話題です。 ([cat.benesse.ne.jp](https://cat.benesse.ne.jp/tags/?id=911&utm_source=openai))\n\n2. **キジトラ猫と茶トラ猫の心温まる交流**  \n   日課のパトロールを終えたキジトラ猫が帰宅し、くつろいでいると、友達の茶トラ猫が近づいてきて、ねぎらいの様子を見せました。2匹の仲睦まじい姿に多くの人が癒されています。 ([trilltrill.jp](https://trilltrill.jp/articles/3564320?utm_source=openai))\n\n3. **まったり中の猫2匹、本能にあらがえない様子**  \n   ポーランドで撮影された動画では、キジトラ猫と黒猫が寄り添ってまったりしている最中、外の鳥に対してクラッキング（狩猟本能からくる動作）をする様子が捉えられています。寝たいけれど狩りたいという本能にあらがえない姿が微笑ましいと評判です。 ([nlab.itmedia.co.jp](https://nlab.itmedia.co.jp/nl/articles/2311/29/news019.html?utm_source=openai))\n\n4. **お昼寝中の2匹の猫、ぎゅ～っと抱き合う姿が話題**  \n   アメリカで撮影された動画では、バスケットの中で寄り添って眠るグレーの猫とキジトラ猫の姿が公開されました。寒い時期ならではの光景で、2匹がぎゅっと抱き合っている様子が多くの人々を癒しています。 ([nlab.itmedia.co.jp](https://nlab.itmedia.co.jp/nl/articles/2311/24/news131.html?utm_source=openai))\n\n5. **キジトラ猫のおやすみ前の可愛らしい挨拶**  \n   体をくっつけ合う仲良しな黒猫とキジトラ猫の兄弟。眠気がピークに達したキジトラ猫が、おやすみの挨拶として黒猫に「カプっ」と甘噛みする様子が可愛らしいと注目を集めています。 ([peco-japan.com](https://peco-japan.com/79137?utm_source=openai))\n\nこれらの記事は、キジトラ猫のリラックスした様子や愛らしい行動を紹介しており、多くの猫好きの心を和ませています。 ",
                    "type": "output_text"
                }
            ],
            "role": "assistant",
            "status": "completed",
            "type": "message"
        }
    ],
    "parallel_tool_calls": true,
    "temperature": 1.0,
    "tool_choice": "auto",
    "tools": [
        {
            "type": "web_search_preview",
            "search_context_size": "medium",
            "user_location": {
                "type": "approximate",
                "city": null,
                "country": "US",
                "region": null,
                "timezone": null
            }
        }
    ],
    "top_p": 1.0,
    "max_output_tokens": null,
    "previous_response_id": null,
    "reasoning": {
        "effort": null,
        "generate_summary": null
    },
    "status": "completed",
    "text": {
        "format": {
            "type": "text"
        }
    },
    "truncation": "disabled",
    "usage": {
        "input_tokens": 3394,
        "input_tokens_details": {
            "cached_tokens": 1408
        },
        "output_tokens": 793,
        "output_tokens_details": {
            "reasoning_tokens": 0
        },
        "total_tokens": 4187
    },
    "user": null,
    "_request_id": "req_bd6bb94f8ad95ee7a8df373a2e40f0e8"
}
```

上記の例では、`web_search`ツールを使用して、Chat Completions APIを使用する場合に必要な複数回の往復ではなく、1回のAPI呼び出しで画像に関連するニュースをウェブ検索することができました。

Responses APIを使用すると、🔥 1回のAPI呼び出しで以下を処理できます：

✅ マルチモーダル入力を使用して画像を分析。

✅ `web_search`ホストツールを介してウェブ検索を実行。

✅ 結果を要約。

対照的に、Chat Completions APIを使用する場合は、各ステップごとにAPIへの往復が必要です：

1️⃣ 画像をアップロードして分析を取得 → 1回のリクエスト

2️⃣ 情報を抽出し、外部ウェブ検索を呼び出す → 手動ステップ + ツール実行

3️⃣ ツールの結果を再送信して要約 → もう1回のリクエスト

以下の図で、視覚的な比較を確認してください！

![Responses vs Completions](https://raw.githubusercontent.com/openai/openai-cookbook/main/images/comparisons.png)

Responses APIを試してみて、コードを簡素化し、複雑なマルチモーダル、ツール拡張インタラクションを構築するのがどれだけ簡単になるかを体験してください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)