誰もこれをやっていなかったなんて信じられない OpenAIのWebSocket移行がもたらすAPI革命

OpenAI・サムアルトマン
この記事は約19分で読めます。

OpenAIがAPIアーキテクチャに大きな変革をもたらした。従来のRESTベースのServer-Sent Events方式から、WebSocketへの移行である。この変更により、帯域幅が90%以上削減され、処理速度が20〜30%向上するという驚異的な成果が得られている。その背景には、AIモデルとエージェントの動作原理に関する深い理解が必要だ。従来のシステムでは、ツール呼び出しのたびに全コンテキスト履歴をAPIに再送信する必要があり、膨大なデータ転送が発生していた。WebSocketの導入により、ステートフルな接続が維持され、新しいデータのみを送信すればよくなった。この技術的変革は、単なるプロトコル変更ではなく、AIエージェントの実行効率を根本から改善する画期的な進歩である。

I can't believe nobody's done this before...
OpenAI moving the responses api from http to websockets such a huge win...Thank you Blacksmith for sponsoring! Check the...

OpenAIのWebSocket移行という大きな変革

よく聞かれるんですよ。もしアルゴリズムを気にせずに動画を作れるとしたら、どんな動画を作りたいかって。正直なところ、私が作りたい動画のほとんどは、そのトピックが好きだからという理由もあるんですけど、リーチも考えてるんです。でもこれは、正直爆死すると思ってます。

じゃあなぜやるのかって? それは、このトピックが本当に重要だからです。これは大きな変化で、私が掘り下げるのが大好きなマニアックで奇妙な詳細がたくさん含まれているんです。うまくいけばいいんですけどね。

OpenAIがAPIに大きな変更を加えました。もう誰もがやっているようなREST呼び出しだけでやるのではなく、WebSocketに移行しているんです。これは見た目以上に大規模な変革です。帯域幅が90%以上削減され、速度が20〜30%向上するという話なんです。Server-Sent EventsからWebSocketに移行するだけで、そんなことが可能なんて信じられないでしょう? まあ、そうですよね。

AIモデルがどう動作するか知らない人には、信じられないかもしれませんが、この動画はネットワーク技術と、AIモデル、特にエージェントが実際にどのように仕事をするかという奇妙な特性の両方についての深掘りになります。

AIモデルとサーバーの関係を理解する

ターミナルやエディタで実行しているものと、そこに出力を生成している実際のサーバーとの関係をまだ理解していないなら、これはとても役立つ動画になるでしょう。そして、すでに理解しているなら、これはさらに役立つでしょうし、同僚に送るのに良いリソースになると思います。同僚の方々は間違いなくこういうことを理解していないでしょうから。

どれだけ多くの開発者がコンテキストの仕組みやリクエストのやり取り、その他諸々を全く理解していないかには、定期的に驚かされます。この動画で皆さんがもっと理解できるようになることを願っています。

でもその前に、もう一つ理解していただきたいことがあります。今日のスポンサーがどれだけ素晴らしいかということです。

スポンサー紹介:Blacksmith

デプロイ準備ができている変更があるのに、CIのビルド待ちでブロックされたことが何回ありますか? やっと終わったと思ったら、修正しなければならないランダムなエラーが出て、小さな変更を出すだけなのに、また何時間も待たされる。それは使っているCIツールがダメだからです。

今日のスポンサーであるBlacksmithを使っていない限りはね。彼らはCIを驚くほど速くしてくれます。私のシンプルなTypeScriptコードベースでさえ、ビルド時間が半分になることが多いんです。3分以上かかっていたものが、私が取り組んでいる多くのプロジェクトで1分未満になります。そして、もしDockerを使っているなら、40倍速いDockerビルドは本当にありがたいです。

すべてのDockerレイヤーが同じコンピュータのNVMeドライブにキャッシュされるので、キャッシング、ダウンロード、そしてDockerのビルドプロセス全体がずっと速くなるんです。サイトには本当に良い例があって、Android GitHubアクションなんかは、公式のGitHub CIで9分かかっていたのが、1行の変更で今は3分になり、コストは4分の1になっています。

私たちはpingでのすべてのCIにBlacksmithを使っていて、チームは夢中です。新しいリポジトリが現れてCIを追加し始めるたびに、Blacksmithを追加し忘れたことに気づきます。1行のコード変更をして、突然ビルドが1分未満になるんです。素晴らしいですよ。そしてご覧のとおり、私たちの大きなプロジェクトでさえ、ビルドは一貫して50秒くらいです。

可観測性がどれだけ優れているか詳しく説明したいところですが、そうすると何時間も話し続けてしまいます。GitHubが数十年で公開したものより遥かに優れています。本当にすごいです。実際にアクションをデバッグできるようにしたいなら、Blacksmithに移行する必要があります。アクションのコストを半分にしたいなら、Blacksmithを使うべきです。

CIをずっと速くしたいなら、Blacksmithを使うべきです。Dockerビルドをずっと速くしたいなら、Blacksmithを使うべきです。一般的に言って、soy.link/blacksmithでチェックしてみるべきです。

WebSocket移行に興奮する理由

さて、なぜ私はこのWebSocketへの移行にこんなに興奮しているのか? まず明確にしたいのは、T3チャットではまだこれを使っていないということです。正直なところ、T3チャットのユースケースでは、これはあまり意味がないんです。でも、これが驚くほど意味を持つ場所が他にあります。

まず、コンテキスト管理とAIモデルへのリクエストがどう機能するかを理解しましょう。上部にシステムプロンプトがあります。次にユーザーメッセージがあります。

伝統的なものでやってみましょう。例えば、アプリケーションのSEOを改善したい。このアプリのSEOを良くする方法について徹底的な計画を書きましょう、みたいな。典型的な標準的なユーザーメッセージです。そして、エージェントからのレスポンスを赤で表すことにしましょう。

エージェントは言います。まず、このコードベースをよりよく理解しましょう。ユーザーがプロンプトを作成します。エージェントはコードベースをより理解する必要があると判断します。では何をするか? ツールを呼び出します。lsか何か、特定のディレクトリ内のすべてをリストアップするようなものです。

そのツール呼び出しは何をするか? 面白いことに、重要なコードはおそらくsource/にあるだろうと言います。だから、次はそれをスキャンしましょう。わかりますよね。

そして、そういうことがたくさん起こった後、最終的な答えに到達します。あなたのSEOは改善されました。Dを編集しました。わかりますよね。私たちは皆エージェントを使って構築したことがあります。これを見たことがあります。これがその瞬間のあなたのコンテキストです。

コンテキストの蓄積とリクエストの仕組み

そして明らかに、物事が進むにつれて、コンテキストは構築されます。上部にシステムプロンプトがあり、次にユーザーメッセージ、そしてエージェントメッセージがあります。

エージェントメッセージはツール呼び出しで終わります。ツール呼び出しが実行され、結果を得て、エージェントが応答し、次のツール呼び出しのセットを行い、そして最終的に実際の結果を得ます。わかりますよね。

では、フォローアップメッセージを送りたい場合はどうなるか? 例えば、最後にこう言うとします。いい感じだけど、説明を変更したい、みたいな。

このフォローアップメッセージを送ったとき、OpenAI APIにどんなリクエストが送られるか? その中には何が含まれているか?

しばらくやっていればわかりますよね。そしてチャットを見れば、わかります。全部です。すべてです。すべてです。

そう、皆さんわかりましたね。フォローアップリクエストは、新しいメッセージを送るだけではないんです。全体を送っているんです。

でも、それが痛点でさえないんです。それが全部だったら、そんなに大したことじゃないでしょう。すべてのテキストをユーザーメッセージごとに1回送るだけなら問題ないでしょう。でも、それがそれよりもはるかに多く送られていると言ったらどうでしょう?

ツール呼び出しのたびに全履歴を送信する問題

ユーザーメッセージを送ったときにここで送られ、最初のツール呼び出しが完了したときにここで、2番目のツール呼び出しが完了したときにここで、そして新しいプロンプトを送ったときに再び送られると言ったらどうでしょう。

すべてのツール呼び出しが全履歴を送り返しているんです。考えてみれば理にかなっています。ここにエージェント呼び出しがあります。まず、コードベースをよりよく理解しましょう、と言ってツール呼び出しを出力します。

エージェントは単なる自動補完です。単語を生成しているだけです。何が起こっているかわかりません。自分がどんなシステムなのかわかりません。どのくらい時間がかかるかわかりません。

ツール呼び出しが起こると一時停止が発生すると思っている人がいるようですが、それは起こっていることではありません。ツール呼び出しは生成が終了したことを意味します。AIはツール呼び出しが起こっているときに実行されていません。AIは事実上一時停止しています。死んでいます。殺されています。オフです。

そして、ツール呼び出しが完了すると、ここから上のすべてがAIに送り返され、それを実行しているサービスへのAPI呼び出しを通じて送り返されます。そして今、それを使って生成を続けるための新しい履歴があります。

誰かが、これはツール呼び出しが機能したかを確認するためかと尋ねましたが、違います。ツール呼び出しからの情報を持つためです。ツール呼び出しは物をリストアップすることでした。ls呼び出しです。だから今出力があるんですが、その出力を得るまで何もできません。だから止まるだけです。

モデルのステートレスな性質

だから、ツール呼び出しが起こるたびに、モデルはツール呼び出しの結果が何かを知る必要があります。だから、ツール呼び出しが完了すると、すべてが必要なのですべてを送り返します。モデルが目を覚ますたびに、脳には何も残っていないグラウンドホッグ・デイのようなものです。ステートレスです。何も起こっていません。

だから、すべての状態を毎回送り返さなければなりません。長いエージェント実行中のネットワークトラフィックを見ると、これらのツール呼び出しのそれぞれが全履歴をAnthropicのAPIに、OpenAIのAPIに、その他何にでも送り返しています。そして、利用可能なGPUが、そのすべてのコンテキストを取り込んで、次のレスポンスのためにロードします。

そして、皆さんが考えていることはもうわかっています。それがキャッシングの目的じゃないのかって?

キャッシュは、モデルが行わなければならない計算を減らすためのものです。それによってずっと安くなり、最初のトークンを取得するのも速くなりますが、送信するデータ量は変わりません。なぜなら、そのキャッシュのキーは履歴のハッシュだからです。

だから、この部分がすべてキャッシュされている場合でも、AIに「そのキャッシュから引き出してこれを追加して」と伝えているわけではありません。全履歴を渡して、それがハッシュ化され、ああ、この時点までの履歴がキャッシュされていると言うんです。新しい部分はここです。だから、その新しいものまでの状態をロードします。

それから、新しいものを追加します。それから、応答を始めます。それがキャッシュの機能です。キャッシュは送信するデータ量を変えません。キャッシュはデータを処理するのにかかる時間を変えるだけです。事実上、そのためのハッシュです。

だから、キャッシュは単なる計算削減手法です。送信しなければならないトラフィックを全く変えていません。これは非常に非常に明確にしておきたいです。

これがコンパクションかと誰かが尋ねましたが、違います。コンパクションは非常に異なります。コンパクションはこれ以上異なることはできません。コンパクションは全履歴を取って要約することで、もうすべてのトークンが必要なくなるようにします。でもコンパクションはキャッシュを壊します。キャッシュを助けません。コンパクションはより短い履歴を持ちたいのでキャッシュを放棄することを選択しているんです。

膨大なデータ転送の非効率性

とにかく、問題が多少見えてきたと思います。問題は、モデルがこのデータを取得するのが難しすぎるということではありません。非常に単純に、ツール呼び出しが起こるたびに、このすべてを送信することです。毎回増大するデータ量を送るのは、単純に良くないです。本当に非効率的です。本当に高価です。

大量の帯域幅を使用します。並列でたくさんのエージェントを実行することが必要以上に高価になるということです。OpenAIのAPIがこれらの巨大なテキストペイロードとルーティングとすべてのことを処理できる必要があるということです。

これらすべてを送る代わりに、新しいもの、つまりツール呼び出しだけを送ればいいとしたら、もっと簡単じゃないですか? それはクールじゃないですか?

でも、それは物事をより複雑にします。なぜなら、事実上OpenAIのインフラがそれを本当に許可していないからです。OpenAIにはたくさんのGPUがありますが、GPUにアクセスしているわけではありません。このリクエストを直接GPUに送っているわけではありません。明らかに、そうでなければすべてを完全に異なる方法でフォーマットしなければならないからです。意味がありません。

そして、そのGPUには特定のキャッシュがないかもしれません。だから、事実上これらすべてのリクエストはオーケストレーションレイヤー、つまりAPIを通過する必要があります。

OpenAIのインフラストラクチャ

OpenAIのGPUの前には、このAPIがあります。そしてもちろん、1つのGPUではなく、何千ものGPUがあり、多くの異なる場所に数万のGPUがあります。

だから、リクエストはAPIに送られます。リクエストがAPIに送られると、チェックが行われます。以前にここにいたときのキャッシュ値があるかどうかチェックします。これをルーティングできるオープンなGPUがあるかどうか。このユーザーにこのことをする権限があるかどうか。そして、ここで結論づけたものをGPUにルーティングします。それがうまくいけば、それらのトークンで応答します。

そして、それらのトークンがあなたに送り返され、それがエージェントレスポンスになります。

でも、APIがここで見えるほど単純ではないことも覚えておいてください。これもたくさんの別々のAPIボックスで、すべてがランダムな利用可能なGPUを探してそこにルーティングします。だから、最初のリクエストは最初のAPIボックスに行くかもしれません。2番目のリクエストは4番目のAPIボックスに行くかもしれませんし、これは完全に異なるGPUに行くかもしれません。

問題が見えますか? たとえサーバーがこの状態を維持しようとしても、正しいものが正しいコンテキストを持っていることを確認するのは面倒です。そして、キャッシングレイヤーは完全に別の第3のレイヤーで、これらすべてを管理しなければならないと確信しています。

だから、リクエストを送ると、OpenAIが実行する比較的ダムなサーバーに送られます。そのサーバーはたくさんあって、どのキャッシュがトークンのキャッシュ値を持っているかをチェックしに行かなければならず、その状態をGPUにロードし、プロンプトをGPUにロードし、トークンを生成し、そして応答します。

そして、これを理解してください。時には10トークンしかない生成のために、これらすべてを行わなければならないんです。

このAPIレイヤーは履歴を持っていないので、以前に何を送ったか知りません。なぜなら、すべての追加リクエストは別の場所にルーティングされるからです。全体を再送信しなければなりません。そうしないと失われてしまうからです。

ステートフルな接続の必要性

IDを付けてずっと保持し、常にすべてをキャッシュしようとすることもできますが、どのくらいの期間保持する必要があるかわからないでしょう。それをグローバルにスケールさせるレイテンシの問題は、実行可能ではありません。全く実行可能ではありません。そのためのアーキテクチャは、すべてのAPIが接続する外部データストアで、すべてのリクエストをキャッシュする必要があります。

実行可能ではありません。そのデータ量には全く実行可能ではありません。そして、半分の時間はそれが重要でさえないものには。

そして覚えておいてください。時にはこれらの応答が本当に短いことがあります。間違ったディレクトリを試していますみたいな。これは本当のことです。エージェントは応答するかもしれません。エージェントは送られた10万トークンを取り込むかもしれません。

文字通り2メガバイトのテキストを送られて、それから8語で応答するかもしれません。それは毎日私たちに起こっている本当のことです。わずか数トークンを生成するために、非常に多くのデータを処理しているんです。それはとても無駄です。

そして、このレイヤーでできることで、これほどスケールされた状態を保ちながら、外部に状態を永続化するものは基本的にありません。だから、どれにヒットしても問題ありません。

でも、解決策があります。すべてのリクエストが同じボックスにヒットすることを保証できたらどうでしょう? ツール呼び出し2がツール呼び出し1と同じボックスに行くことを確認できたらどうでしょう?

これらすべてのフォローアップ、このセッション中に起こっているこれらすべてのことが同じボックスにヒットすることを確認できたらどうでしょう? そうすれば、これらすべてをストレージからロードする必要はありません。

何がキャッシュされているかチェックする必要はありません。すでにわかっています。すべてのコンテキストを送る必要さえありません。新しいメッセージや新しいツール呼び出しを送るだけでいいんです。あまり多くのものを送る必要はありません。

でも、それはステートフルでなければなりません。以前のOpenAIのAPIの動作方法は事実上ステートレスでした。

これらのボックスは何も知りませんでした。データを調べに行かなければなりませんでした。キャッシュエンティティがあるかどうかデータベースをチェックしに行かなければなりませんでした。あなたがそのことをする許可があるかどうかOサーバーをチェックしに行かなければなりませんでした。そして、すべてのツール呼び出しはすべてを二重チェックしなければなりませんでした。すべてのリクエストがすべてをチェックしなければなりませんでした。

でも、最初のリクエストがすべてをカバーしていたら、2番目のリクエストは本当にそのすべてが必要でしょうか? 最初のリクエストの後に、あなたが誰で、何をしていて、どのキャッシュにヒットできるかを知っていたらどうでしょう?

WebSocketが解決策である理由

これが今日WebSocketについて話している理由です。ここでのWebSocketの価値は、それがより良いプロトコルだからではありません。WebSocketが天からの贈り物だから魔法のように速いわけではありません。非常にシンプルです。

WebSocketは同じボックスにヒットすることを保証できるんです。生成全体を通してそのAPIサーバーへの接続を維持しているので、その状態を失うことを心配する必要はありません。

認証を再チェックすることを心配する必要はありません。何がキャッシュされているかどうかを知ることを心配する必要はありません。WebSocketはここではプロトコルというよりも、保証です。

保証は、この生成が実行されている間、これまでに何をしたかを追跡できる同じサーバーボックスにヒットし続けることができるということです。

認証を再チェックする必要はありません。コンテキスト全体を再送信する必要はありません。新しいものだけを送ればいいんです。そうすれば、すぐにGPUに接続し、すべてをそこに送り、応答を始められます。

これは送信するデータ量を減らします。これは処理しなければならないデータ量を減らします。これは行わなければならないチェックの数、触れなければならないキャッシュの量、ツール呼び出しがあなたのマシンで完了してからAPIが何が起こっているかを認識するまでに発生しなければならないことの数を減らします。

それは素晴らしいです。そして、こういうことが起こるのにこれほど時間がかかったのは信じられません。そして、OpenAIがこれをやった人たちであることに本当に本当に感謝しています。なぜなら、これらのことに対するOpenAIの実装が標準になる傾向があるからです。

Open Responsesという新しい標準

OpenAIの標準はほぼすべての人にクローンされているだけでなく、実際に完全にオープンソース化されました。

Open ResponsesはOpenAI Responses APIにインスパイアされた標準です。共有されたリクエスト・レスポンスモデル、ストリーミングセマンティクス、ツール呼び出しパターンを結びつけます。だから、クライアントとプロバイダーは一貫した形式で構造化された入力と出力を交換できます。

AnthropicからGeminiまで、あらゆるもののAPIを呼び出すためにこの形式を使用できます。そして今、それはオープン標準です。そして残念ながら、いいえ、標準にはまだWebSocketの部分が実装されていません。これは非常に非常に近いうちに実装されると予想しています。

ええ、これすべてに関わっている人たちに本当に感謝しています。これが実装された方法、それが行われた場所は、これが単なる標準番号72にならず、代わりにこれらのエージェントツールが使用できる新しいデフォルトになる可能性を大幅に高めます。

チャットアプリでの利用について

そして、非常に非常に明確にするために、極めて明確にするために、ここでの利点はチャットアプリのユースケースではそれほど大きくありません。なぜなら、すぐにフォローアップしない場合、その接続を維持する価値がないからです。

だから、ここでの2番目のユーザーメッセージはおそらく同じWebSocketを通過しないでしょうし、おそらく同じAPIボックスにヒットしないでしょう。そしてそれで問題ありません。

ユーザーメッセージごとに1回すべてのコンテキストをリロードするのは完全に妥当です。ツール呼び出しごとにそれを行うのは、時には1つのユーザーメッセージが数百のツール呼び出しを生み出す可能性があるので、それははるかに受け入れがたいです。

そして、結果が気になるなら、これがOpenAIが言わなければならなかったことです。そして、これを早期にテストする幸運に恵まれた者として、ここで共有しているものよりもさらにクレイジーかもしれないと確認できます。

WebSocketはResponses APIへの永続的な接続を維持し、すべてのターンでコンテキスト全体を送るラウンドトリップの代わりに、新しい入力のみを送ることができます。インタラクション全体でインメモリ状態を維持することで、繰り返しの作業を回避し、20以上のツール呼び出しを持つエージェント実行を20〜40%高速化します。そして、彼らの小さなデモビデオでこれがどのように見えるかわかります。

この変革の意義

これがどれほど大規模かわかりますか? この分野で重要なことはたくさんあって、それはモデルがどれだけ速くトークンを生成できるかだけではないんです。

ある意味では私たちが早期にいると言うとき、これが私たちが話していることです。一方で、これはとてもクールです。ええ、今は物事を状態に保ち、パフォーマンスを大幅に改善する方法があります。

他方で、この種のことが生成されるたびに全コンテキストを送ることに単純に満足していたなんて、どれほど早期なんでしょう。なぜなら、既存のAPIと標準にツール呼び出しをホチキスで留めただけだったからです。ここには非常に多くの機会があります。これが皆さんを構築することに興奮させることを願っています。

スタック全体にわたって有用な改善を行う余地が非常に多くあります。特定の方法で行っている非常に多くのことが、それが始まった方法だからというだけです。まだ依存している非常に多くのツールが、単に慣れているものだからです。

ネットワークの方法から、リクエストの送信方法、Gitでコードを保存する方法まで、スタックのすべてが今すぐ変更の対象です。これは本当に楽しいです。

ディープな技術計画と思考とプロセスがAIの結果として死んでいると考えている人たちに言いたいのは、間違っているということです。これまで以上に重要です。今、すべてを第一原理から再考できるんです。そして、それは楽しいです。本当に楽しいです。

OpenAIがここで行っている変更について教えてくれたとき、とても興奮しました。少し早めに使わせてもらえて本当に幸運でした。そして、これをマニアックであろうとも、この動画が爆死すると予想していようとも、皆さんとこれをすべて共有できることに本当に感謝しています。うまくいくことを本当に願っています。なぜなら、このことは新しいモデルが何であれということよりもずっとクールだからです。

私は個人的に、Codex SparkよりもSonnet 4.6よりも、基本的に最近出てきたオープンウェイトモデルのどれよりも、この小さなAPI変更についてずっと興奮しています。ええ。

一緒にマニアックになってくれてありがとうございます。私と同じくらい楽しんでいただけることを願っています。次回まで、ピース、ナーズたち。

コメント

タイトルとURLをコピーしました