Skip to Content
PerformanceACP extension watcher: 初回セッション計測

ACP extension watcher: 初回セッション計測

この変更は、ACP プロセス内の対話的拡張ファイル watcher をスキップします。デーモンはすでにリソース更新のライフサイクルを管理しています。対話型ターミナルセッションは引き続き watcher を構築します。これは初回セッション最適化の第一段階であり、500 ms 未満で新しいセッションを確立するものではありません。

変更と由来

ベースラインは main コミット 2985fef4e9b9393601141c16031b2ba039181158、計測対象の候補は watcher のみ変更したコミット 2aadc4b127ec24074e0e5ddfd402e978a0c43f5d です。本番への変更は 1 つ追加の ACP モードガードのみです。--acp と --experimental-acp の両方がカバーされ、対話モード用に watcher を構築するコントロールも含まれています。Core の初期化、リソース選択、プロンプト、認証、MCP ポリシー、またはプリヒート実装の変更は含まれていません。

両方のバンドルは CLI バージョン 0.27.2 を使用しています。呼び出し側の TypeScript パッケージは @qwen-code/sdk 0.1.32 です。パッケージバージョンと SDK エントリのハッシュは各実行の前後に記録されました。完全なベースライン、候補、およびコンパイル済み SDK ファイルツリーのダイジェストも凍結され、計測コホート周辺でチェックされました。候補は独立したワークツリーで、固定した pnpm 11.24.0 ロックファイルのインストール、フルビルド、型チェック、およびバンドルで構築されました。

ワークロードとタイミング境界

プライベートにインストールされたワークロードには 31 個のリソースが含まれています。14 の拡張スイートと 17 のスタンドアロンスキル、90 のカスタムスキル、3,944 ファイル、81,931,741 バイトです。各サンプルは、大文字小文字を区別するローカルファイルシステム上に全く同じリソースインベントリを展開します。リソース名、ソースファイル、ビジネスコンテンツ、マニフェスト、ローカルパス、識別子、および生ログは非公開です。集約カウントとタイミングのみがここで公開されています。

プロファイルはフックを保持し、MCP 許可リストを空のリストに設定します。プロンプト、モデルリクエスト、またはビジネツール呼び出しは送信されず、設定された外部 MCP サーバーにも接続しません。インストール済みのネイティブアクティベーション状態は、タイミング対象外のフィクスチャ準備中にシードされます。これはすでにインストールおよびアクティベート済みのリソースセットを表し、新しいプロセスと新しいセッション状態を使用します。リソース由来のすべてのキャッシュが空であるという主張ではありません。フィクスチャの作成、ファイルのコピー、ネイティブアクティベーションのシード、バンドルのビルド、および SDK モジュールのインポートは、どちらのクロックが開始するよりも前に完了します。

各サンプルには、新しい HOME、ランタイムディレクトリ、TMPDIR、永続化セッションルート、および最初は空の Node コンパイルキャッシュディレクトリがあります。デーモンは preheatBridge: false で実際の埋め込み HTTP ブリッジエントリーポイントを通じて起動されます。ドライバーは runtimeReady を待機し、最初の SDK 呼び出しの前にビジネセッションがゼロで、ライブ ACP チャネルがないことを検証します。その呼び出しの前に HTTP 準備状態やケイパビリティリクエストはありません。新しい UUID が新しいスレッドをリクエストし、結果は attached: false でそれをエコーする必要があります。さらに 2 つの新しい UUID 呼び出しで、後続セッションの動作を検証します。

ready リクエスト境界は SDK クライアント構築と呼び出し元 UUID 生成の前に観測されます。どちらもプライマリの create クロックの外部にあります。

プライマリクロックは await client.createOrAttachSession(...) の全体を囲みます。ケイパビリティ検出、セッション POST、レスポンス JSON パース、および SDK ID 検証です。最初の HTTP リクエストは GET /capabilities で、その単独の時間は新しいセッションの計測ではありません。リクエストレコードは 3 つの呼び出しすべての実際のシーケンスを保持します。後の呼び出しでケイパビリティチェックが省略されると想定してはなりません。

レポートはまた、セッション POST、デーモンプロセス.spawn からデーモン ready リクエスト境界まで、およびデーモン spawn から最初の完了した SDK 結果までの時間も公開します。デーモンの待機は ACP プロセスを作成しません。記録されたすべての ACP spawn は、SDK 呼び出しの開始と最初の HTTP リクエストの両方の後に発生する必要があります。デーモンステータスはプリヒート not_scheduled を報告する必要があります。CPU プロファイラー、明示的なコンパイルキャッシュフラッシュ、無効化された子コンパイルキャッシュ、人工的なスリープ、または起動プローブは公式サンプルには現れません。

公式結果

最初の完全な SDK create は、中央値で 1096.1 ms から 772.9 ms に低下します。323.2 ms / 29.48% の改善です。候補はすべてのサンプルで 500 ms を超えています。

以下のすべての値はミリ秒で、中央値(最小値–最大値)として表示され、各条件で 8 回の独立した初回セッションがあります。両条件とも 8/8 の試行を完了し、24/24 の新しいセッションを作成します。公式サンプルから除外されたものはありません。

クロックベースラインWatcher のみ
最初の完全な SDK create(プライマリ)1096.1 (1078.3–1129.3)772.9 (758.4–824.1)
最初のセッション POST + JSON1075.7 (1058.8–1109.2)754.1 (739.3–798.5)
デーモン spawn → 観測されたリスナー336.7 (322.5–341.5)329.2 (323.1–358.5)
デーモン spawn → ready リクエスト境界630.6 (618.7–644.5)605.3 (591.8–621.0)
デーモン spawn → 最初の SDK 結果1731.0 (1709.6–1748.0)1384.5 (1355.5–1427.0)
最初のケイパビリティ GET + JSON18.7 (17.7–28.1)18.3 (18.1–25.1)
最初の HTTP → ACP spawn14.2 (13.9–22.3)14.2 (14.1–24.6)
2 番目の完全な SDK create71.1 (65.1–79.6)74.0 (65.2–80.0)
3 番目の完全な SDK create56.9 (53.7–63.7)54.4 (53.4–56.6)

ラウンドごとのペアによる初回 create サンプル:

ラウンドベースラインWatcher のみ
11098.5758.4
21078.3771.1
31129.3807.8
41110.2760.1
51082.6767.9
61089.2774.8
71093.7789.0
81110.5824.1

公開数値サマリーには、すべての公式サンプル、平均値、中央値、範囲、コンパイル/ビルドツリーのダイジェスト、および合格/不合格カウントが含まれています。これは明示的な許可リストから構築されており、非公開のリソースインベントリ、ソースコンテンツ、ローカルパス、UUID、トークン、または生ログは含まれていません。

以前の 6 回試行のコホートは、一時フィクスチャボリュームの空き容量が不足したために中止されました(5 つの完了サンプルと 1 つのセッション初期化失敗)。失敗ログにはランタイムディレクトリ作成時の ENOSPC が含まれています。6 つのプロセスはすべて正常に終了し、コホート全体(完了したタイミングを含む)は除外されています。より大きな独立した大文字小文字区別ボリュームと 16 の完全に新しいフィクスチャが、公式コホートを再開する前に準備されました。失敗したエビデンスはローカルに保持されており、結果にサイレントに再試行されていません。

8 ラウンドのペアが直列に実行され、A/B と B/A の順序が交互になりました。すべてのフィクスチャは排他的計測ウィンドウの前に準備されました。このタスクの下で、ビルド、フィクスチャのコピー、他のベンチマーク、またはテストが並行して実行されることはありませんでした。OS ファイルキャッシュは削除されていません。これらは 1 つのホストでの新しいプロセス、新しいセッションの計測であり、コールドディスクの計測ではありません。条件あたり 8 サンプルでは、本番のテイルレイテンシ保証を確立するには少なすぎます。

ホスト: macOS 26.6.2、arm64、Node.js v26.7.0。このローカルの隔離された再構築は非公開のプレプロダクションインストールインベントリを使用しており、本番またはライブプレプロダクションのレイテンシ計測ではありません。500 ms の目標は最初の完全な SDK create に適用され、この PR を超えたフォローアップ作業として残っています。

機能検証と制限

別の機能実行で、同じ完全なインストール済みインベントリで凍結されたベースラインと watcher のみのバンドルを比較します。これらは公式タイミングコホートのメンバーではありません。ヘルスとヘルパー呼び出しが一部の機能チェックに先行します。

  • 両条件とも 41/41 の外部変更アサーションと 18/18 のアクティベーション/ライフサイクルアサーションに合格します。

  • 8 つのヘルパースナップショット、ヘルパー後の 8 つの既存セッションメニュー、8 つの新規作成セッションメニュー、および 11 のライフサイクルスナップショットが、フィクスチャパスと UUID の対応後に一致します。

  • 通常の読み取りは観測された伝播の違いを保持します。完全なワークスペーススキルエンベロープは 29/32 サンプルで一致し、スキルコンテンツは 31/32、既存セッションコマンドリストは 31/32 で一致します。1 つの観測で候補の方がアトミックな置換が早く現れ、ベースラインではファイル再作成が一時的に早く現れます。後のサンプルまたは通常のヘルパーで収束します。拡張スキルの編集/復元は、3 秒の観測ウィンドウ中は両条件とも古いままとなり、ヘルパー後に修正されます。

  • 両側とも同じ type/phase シーケンスで 8 つの公開 SSE イベントを出力します。最初の 7 つの対応するペイロードは一致し、最後のリロードペイロードは異なる完了順序で同じ 9 つのセッションを更新します。等価性をチェックする際に元の配列順序が保持されます。

  • 新しいセッションのレスポンスは UUID、作成時間、およびクライアント ID で自然に異なります。他のレスポンスフィールドは一致し、実際の作成は UUID エコーと attached: false によって独立にアサーションされます。

フィクスチャとバンドルのルート、それらのルートから派生したワークスペース識別子、および UUID の対応のみが正規化されます。個別に報告されるワークスペーススキルのビジネス比較では、観測タイムスタンプと経過時間は除外され、生のエンベロープはそのまま保持されます。キャッシュの鮮度、更新フラグ、アクティベーション状態、世代、すべてのスキル/コマンドフィールド、および元の配列順序は、等価性を製造するために消去されません。これらの観測は同一の伝播レイテンシまたはバイト単位の同一の通常の読み取りを証明するものではありません。

各機能グループは通常の close 応答を受け取り、コード 0、シグナルなし、強制フォールバックなしで終了します。最終的なスコープ付き OS 観測では、一致するベンチマークプロセスは見つかりません。公式タイミングサンプルは、独自の通常の close 応答、ゼロ終了ステータス、強制フォールバックなし、および記録されたすべての ACP 子 PID の消失を個別に強制します。

フォーカスされた CLI ユニットスイートは 129/129 に合格し、フルビルド、型チェック、バンドル、変更ファイルの ESLint、および Prettier チェックも合格します。対話的 watcher 構築はユニットコントロールで検証されます。対話型ターミナル UI のエンドツーエンド実行、Windows、Linux、モデル実行、プロンプトで実行されるフック、および外部 MCP の動作はこの検証の範囲外です。

公開合成リソースで再現する

公開ジェネレーターは非公開インストールを読み取ったりエクスポートしたりせずにジェネリックリソースを作成します。14 のスイート、17 のスタンドアロンスキル、および 90 のスキルマニフェストを使用しますが、バイト、ディレクトリ形状、スタンドアロンスキルの配置、フック定義、およびアクティベーション準備は異なります。そのタイミングは手順を再現し、スケーリングの動作を公開できます。上記の非公開ワークロードの数値を再現または置き換えることはできません。

それぞれのコミットから凍結されたベースラインと凍結された候補を、corepack pnpm install --frozen-lockfile、npm run build、および npm run bundle で構築します。公開再現は Node.js v26.7.0 でチェックされました。SDK ビルドを固定し、計測前にビルドとリソースのコピーを停止し、2 つのバンドルを直列に交互に実行します。このチェックアウトから、新しい出力ディレクトリごとに 1 サンプルを実行します:

node scripts/benchmarks/acp-first-session/fixture.mjs /tmp/acp-synthetic-a /absolute/frozen-baseline/dist node scripts/benchmarks/acp-first-session/fixture.mjs /tmp/acp-synthetic-b /absolute/frozen-candidate/dist node scripts/benchmarks/acp-first-session/run.mjs /tmp/acp-synthetic-a/fixture.json node scripts/benchmarks/acp-first-session/run.mjs /tmp/acp-synthetic-b/fixture.json

計測コホートの前にすべての新しいフィクスチャを準備します。新しい合成スモークは、3 つの create と、プリヒートなし、ID、クローズ、子終了、および記録済み入力ハッシュのチェックをすべて完了します。手順を検証し、非公開結果にサンプルを提供することはありません。各実行はパスフリーの数値/ブール値サマリーを出力し、詳細なローカルエビデンスをリクエストされた出力場所に保持します。合成リソースには SessionStart フックが含まれていません。プロンプトは送信されないため、作成された UserPromptSubmit フックは実行されません。少なくとも 8 つのインターリーブされたペアを使用し、失敗を保持し、すべてのプリヒート/セッション/spawn/クローズのアサーションを検査し、すべてのクロックを報告します。ローカルで生成されたフィクスチャツリーや生の結果をコミットしないでください。

シャットダウン後に記録された ACP PID がまだ存在する場合、公開ランナーは結果を失敗としてマークし、手動検査用のクリーンアップエラーを記録します。PID の再利用によりプロセス ID の証明ができないため、自動終了は独自のラッパープロセスハンドルに限定されます。

500 ms 未満にするための残りの作業は、同じプリヒートなし境界と機能チェックで、最初の SDK 呼び出しの後に実行される初期化を削減する必要があります。これはこの 1 行の watcher 変更から意図的に分離されています。

Last updated on