HN 日本語サマリー

← 一覧へ戻る
AI・機械学習

Meta Museをストレステストし、そのエージェント制御プレーンがタイムアウトし始めたまで

I stress-tested Meta Muse until its agent control plane started timing out (blog.cygankiewicz.com)

4 pointsby mpkc1 コメント

要約

本記事は、MetaのAIエージェント「Muse」の負荷テストに関する調査です。筆者は、多数のサブエージェントを同時に起動する「バースト」テストを実行し、PostgreSQLのロックタイムアウトによるエージェント生成の失敗率が、起動試行回数の増加とともに急激に上昇することを発見しました。この現象は、Museのサブエージェント生成パスにおける競合を示唆していますが、具体的な原因特定には至っていません。

全文翻訳

Meta Museのエージェント制御プレーンがタイムアウトするまで負荷テストを行った

Meta Museに一度に120個のサブエージェントを生成させました。それぞれに同じ、意図的に退屈なジョブを与えました。それは、シェルで sleep 30 を実行し、1行だけ送信するというものです。

33個のエージェントが作成されました。残りの87件の生成試行は失敗しました。最終的な回答を得ることはできませんでした。

Meta Museは、2026年9月8日にリリースされたMetaのパーソナルAIエージェントです。質問に答えるだけでなく、ユーザーの代わりにタスクを実行するように設計されています。独自のブラウザを持ち、アプリが閉じられた後も作業を継続でき、専用のMuse Secure VMで実行されます。インターフェースはGrok Botに似ており、会話を通じて制御される人格化されたエージェントですが、これはインターフェースレベルのアナロジーであり、アーキテクチャの共有を前提とするものではありません。この記事では、その下のレイヤーに潜り、サブエージェントのファンアウト、PostgreSQLに保存される状態、および負荷下での生成パスの狭い部分を調べます。ここでは、永続的な状態とは、UIの一時的な状態ではなく、データベースに保存されたレコードを意味します。

私はこれらのテストを自身のMuseセッションで実行しました。セッションに公開されているインターフェースのみを使用しました。具体的には、subagent.spawn、割り当てられた環境でのシェル、および保存された診断データとトレースデータへの制限された読み取り専用インターフェースです。他のユーザー、テナント、または私に割り当てられた環境外のデータにアクセスしようとはしませんでしたし、アクセス制御をバイパスすることもありませんでした。これはMeta公認のセキュリティ評価として提示するものではなく、アクセス権のみではすべての負荷実験が個別に承認された証拠にはなりません。これは、私のセッションに付与されたアクセス権の観点からのブラックボックス/リバースエンジニアリングのレポートです。

公開後の更新:2026年9月13日。 アクセス範囲を明確にし、Rohan Adwankarの分析からの独立したアーキテクチャコンテキストを追加し、STAGGERED-80をバーストスタイルの実行から分離し、ケイデンスとトポロジーをより良く分離するための2つの提案制御を説明しました。実験データ、公開されたCSV、および図は変更されていません。

データベースは、33個すべてのアージェントをcompletedとしてマークしました。そのうち32個については、ワークロードが完了したことを独立して確認できました。残りの1つのエージェントについては、保存されたトレースだけではワークロードの完了を確認するには不十分でした。親レコードはまだrunningと表示されており、インターフェースは最終的にErrorを表示しました。

ランタイムがPostgreSQLに書き込んだレコード(エージェントレジストリ、ランタイム生成レコード、ワーカーごとの進捗テーブル、コンテキストアイテムストア)から実行を再構築しました。この記事のために負荷テストを再実行することはありませんでした。1つの詳細は、セッション中に構築されたテーブルにのみ残っています。PROBE-40セクションでそれを特定します。

Museが外部からどのように見えたか

ユーザーの視点からは、これは通常のチャットセッションでした。ペルソナテキストはプレーンで、ツールリストはそうではありませんでした。

セッションが呼び出せるツールの中には、subagent.spawn、subagent.close、subagent.resume、およびPostgreSQLデータベースへの読み取り専用インターフェースがありました。そのデータベースは付随的なものではありませんでした。ランタイム自身のブックキーピングを保持していました。agent.agents、agent.subagent_spawns、agent.subagent_progress_tool_eventsのようなテーブルは、どのエージェントが存在し、誰がそれを生成し、どのツールを実行し、いつ完了したかを記録していました。

インターフェースは1つの会話を示しましたが、データベースレコードはそれを裏で支えるエージェントを明らかにしました。ランタイムの生成レコードには、失敗した呼び出しの行はありませんでした。試行と結果の個別の台帳を保持していたため、失敗した生成試行の数を数えることができました。

私が読んだすべてのアージェント行(ルート、コーディネーター、最大のバーストの33個のワーカーすべて)は、同じ値を持っていました。

ipnext/avocado-5.16-v4

その文字列は観測されたものです。それが何を意味するかは不明です。内部モデルのビルド、ルーティングエイリアス、または他の何かである可能性があります。トレースはそれを語っておらず、推測するつもりもありません。トレースが提供する数少ないハード識別子の1つであるため、そのまま公開します。

ランタイムは、MetaのMuseファミリーからのMuse Spark 1.3としても自己記述していました。それはトレースではなく、ランタイム自身のコンテキストから来ており、自己申告であり、検証されていません。その説明をデータベースの証拠から分離して保持します。

独立したアーキテクチャコンテキスト

公開後、Rohan Adwankarによる現代のMuseインスタンスの独立した分解を見つけました。彼の環境では、PostgreSQLはローカルUnixソケット経由でユーザーごとのVM内で実行されており、ハーネスバイナリにはavocado-5.16-v4とipnext/...の両方のパスが含まれていました。これは私のいくつかの観測と一致し、それらに有用なアーキテクチャコンテキストを与えますが、証拠の境界を変更するものではありません。私のデータは、タイムアウトの原因となった特定のロック、テーブル、行、インデックス、クエリ、またはトランザクションをまだ特定していません。

私は依然としてipnext/avocado-5.16-v4を観測されたモデル識別子として扱います。AdwankarはipnextをMetaの内部トランスポート/ゲートウェイと解釈し、avocadoを内部モデルファミリーと解釈しています。avocadoをMuse Spark 1.3に直接マッピングすることは、私のトレースによって確立されたものではなく、依然として推論です。同様に、私のプローブはKVMの可視性を確立しましたが、Adwankarは彼のインスタンスでKVM上で実行されているCloud Hypervisorを特定しました。私は私のインスタンスで使用された特定のVMMを独立して確立しませんでした。

外部ソース:Rohan Adwankar, “What’s in a Muse?”

手法:重複するエージェントのカウント

実験は1つのワークロード、4つの構成、およびリトライなしを使用しました。そのうち3つ(PROBE-40、BURST-80、BURST-120)はルートエージェントから発行されたバーストスタイルの実行でした。構成内のすべての試行は単一のターンで実行されました。4番目のSTAGGERED-80は意図的に時間をかけて分散され、コーディネーターエージェントを使用してワーカーを生成しました。失敗した呼び出しは繰り返されませんでした。

ここでの同時実行性には、狭く意図的な定義があります。エージェントは、最初のツール呼び出しからターミナルレコードまでアクティブと見なされます。

active(t)  :=  first_tool_at <= t < finished_at

各記録されたタイムスタンプで、これらのアクティビティウィンドウがどれだけ重複したかをカウントしました。1つのエージェントが別のエージェントが開始したのと同じ秒に終了した場合、終了を先にカウントしました。タイムスタンプの解像度は1秒なので、秒内の実際の順序は不明です。

以下のすべての数値に3つの結果が適用されます。

  1. これは推論ではなく、エージェントのアクティビティを測定します。 33個の重複するアクティビティウィンドウは、33個の同時モデル呼び出しではありません。ここにあるものは何も推論バックエンドを測定しません。
  2. ピークは観測であり、限界ではありません。 テストは同時試行が120を超えることはなかったので、同時実行数の上限を確立したり、除外したりすることはできません。
  3. 欠落したレコードは証拠です。 失敗した生成呼び出しは、エージェントレジストリに何も残しません。その非対称性が、失敗をどのように検証する必要があったかに影響を与え、失敗数を把握するのが最も困難だった理由です。

最初のプローブ:40コール

最初の実験はキャリブレーション実行でした。UTC 06:10:36に40回の生成呼び出しが発行されました。

39個のエージェントが作成され、互いに2秒以内に受け入れられました。1回の呼び出しが失敗しました。その失敗は、チャットからではなく、保存されたツールトレースから回復されたため、詳しく調べる価値があります。呼び出しはUTC 06:10:44に発行され、エラーはUTC 06:10:56に返され、子エージェントは作成されませんでした。

観測されたピーク同時実行数は39でした。この数値はセッションのトレーステーブルからのアーカイブ再計算であり、ライブ測定ではありません。公開されている概要はそのように述べています。

セッション中に構築されたテーブルは、作成された39個のエージェントのうち11個が、要求されたDONE行の代わりにバックグラウンド処理ステータスメッセージで終了したとリストしています。この詳細は証拠としての信頼性が低いです。それは、手作業で構築されたテーブルにのみ残っています。それらのワークロードについては何も結論を出しませんが、ターミナルステータスと完了したタスクを区別する理由を示しています。

同時に80個、そして80個を分散

当初、BURST-80とSTAGGERED-80をA/B比較として扱っていました。振り返ってみると、それは寛大すぎました。STAGGERED-80は生成ケイデンスとトポロジーの両方を変更しました。

バーストスタイルの実行
設定試行作成失敗失敗率ピーク観測同時実行数
PROBE-40 (バースト)403912.5%39
BURST-80 (バースト)807556.25%72
BURST-120 (バースト)120338772.5%33
STAGGERED-80:別構成
設定試行作成失敗失敗率ピーク観測同時実行数
STAGGERED-80 (分散)808000%38

BURST-80はUTC 06:30:43に80回の生成呼び出しを一度に発行しました。75個のエージェントが作成され、すべてルートエージェントの直接の子でした。5回の呼び出しが失敗しました。5件すべてが、呼び出しから約58秒後に、同一のデータベースロックタイムアウトを返しました。ピーク観測同時実行数は72でした。これは、そのフェーズの分析入力から実行後に再計算されたものです。

STAGGERED-80はUTC 06:32:03に開始し、同じ数の呼び出しを分散して発行しました。失敗なしで80個のワーカーすべてを作成しました。呼び出しを100〜200ミリ秒間隔で配置するつもりでしたが、測定された平均アドミッションギャップは1.1266秒で、計画より約10倍広かったです。ルートは深さ1で1つのコーディネーターを生成し、それが深さ2で80個のワーカーを生成しました。

分散実行のピークは38個のアクティブワーカーでしたが、BURST-80では72個でした。

[画像: 0-80のアクティブエージェント軸と0-140秒軸を共有する2つの積み重ねられたステップラインパネル:BURST-80は開始から約55秒後にピーク72のアクティブエージェントに達し、STAGGERED-80は開始から約45秒後にピーク38に達します。]

観測されたアクティブエージェントの同時実行時間の推移。アクティビティはfirst_tool_at <= t < finished_atとして定義され、タイムスタンプのタイでは終了が開始より前に処理されます。タイムスタンプの解像度は1秒です。各構成は1回実行されました。STAGGERED-80はトポロジーも変更したため、これはケイデンスのみの比較ではありません。曲線はエージェントのアクティビティを示しており、推論の同時実行性ではありません。出典:完全なアーカイブトレースから再構築されたBURST-80の集計。STAGGERED-80は公開されたワーカー行から独立して再計算可能です。

[画像: アドミッション形状を比較するタイムライン:BURST-80は約20秒で75個のワーカーをアドミッションし、STAGGERED-80は約89秒で80個のワーカーをアドミッションし、BURST-120は1秒以内に33個のワーカーをアドミッションしました。]

3つのアドミッション形状、3つの観測された結果。出典:この記事とともに公開されたサニタイズされたアドミッションウィンドウとワーカーアクティビティ行。

80と120の間の崖

UTC 06:45:32にルートエージェントは1回のターンで120回の生成呼び出しを発行しました。実験試行台帳は、そのターンのすべての呼び出しをカバーしています。

  • 33件作成(27.5%)。すべてルートの直接の子であり、すべての受け入れは同じ秒(UTC 06:46:01、バースト発行から29秒後)で記録されました。
  • 87件失敗(72.5%)。すべて試行台帳でデータベースロックタイムアウトとして記録され、リトライされませんでした。

3つのバースト実行全体で、観測された失敗率はそれぞれ2.5%、6.25%、72.5%でした。増加の大部分は80から120試行の間で発生しました。これらの実行のみでは、その差をレート法則に変換することはできません。

[画像: 生成失敗率の棒グラフ:PROBE-40 2.5%、BURST-80 6.25%、BURST-120 72.5%、STAGGERED-80 0%(異なるトポロジー下)。]

設定ごとの失敗率。分散型は2つの変数を同時に変更したため、別個にプロットされています。出典:この記事とともに公開されたサニタイズされた実験概要。

この実行でのピーク観測同時実行数は33(UTC 06:46:24)でした。ランタイムは33個のワーカーを要求されたわけではありません。120個を要求されました。トレースが示すのは、アクティビティウィンドウを持つ33個のワーカーと、生成失敗として記録された87回の試行です。それらの呼び出しからエラーまでのレイテンシはキャプチャされなかったため、それらの失敗がいつ返されたかは示されていません。

両方のピークは公開行から再計算可能です。33個のBURST-120ワーカーのアクティビティウィンドウをカウントすると、UTC 06:46:24に33個になります。同じ手順で80個の分散ワーカーをカウントすると、UTC 06:32:48に38個になります。

[画像: 作成された33個のワーカーのアクティビティウィンドウをUTC 06:46:04から06:46:56の間に示す水平バー。アドミッションモーメントと33個のアクティブワーカーのピークがマークされています。]

存在した33個のワーカー、最初のツール呼び出しからターミナルレコードまで。1つのバーは破線です:C-85。出典:この記事とともに公開されたサニタイズされたワーカーごとのタイミング。

成功した呼び出しでさえ、ワーカーになるのが遅かったです。バーストが発行された瞬間から測定すると、中央値の作成されたワーカーは、約36.5秒後に最初のツール呼び出しに到達しました。アドミッションから測定すると、中央値は約7.5秒でした。トレースは、アドミッションがいつ記録され、各ワーカーがいつ最初にツールを呼び出したかを示しています。それらの2つのポイント間の間隔を分解するものではないため、ここにあるものは何も、その間にランタイムが何を行っていたかについての声明として読むべきではありません。

ツールトレースから回復された6件の失敗

失敗した生成は、保存されたツールトレースにその呼び出しとエラー出力を残しますが、子エージェント行やランタイム生成行は作成しません。セッションアーカイブは、それらの出力を確認する前にフリーズされました。後で、コンテキストアイテムから6回の失敗した呼び出しの生のペイロードを回復しました。実験試行台帳は、残りの87回の失敗を説明しています。それらの個々の生のペイロードは独立して回復されませんでした。

試行生成呼び出し (UTC)エラー結果 (UTC)呼び出し → エラー
PROBE-40 #1906:10:4406:10:5612 秒
BURST-80 A-6706:31:0006:31:58約58 秒
BURST-80 A-6906:31:0006:31:58約58 秒
BURST-80 A-7006:31:0006:31:58約58 秒
BURST-80 A-7306:31:0006:31:58約58 秒
BURST-80 A-7406:31:0006:31:58約58 秒

すべて6件は、文字通り同じペイロードを返しました。

{