VS CodeのGitHub Copilotを支えるコーディング・ハーネス

2026年5月15日 - Julia KasperMegan RoggeAaron Munger

新しいモデルがリリースされるたびに、同じ議論が再燃します。どのモデルが最もスマートか?どれが最も速いか?どれを使うべきか?これらは有益な問いですが、Visual Studio Codeのような製品にとって、モデルはエージェント型コーディング体験の一部にすぎません。開発者が実際に操作しているのは、コーディング・ハーネス(coding harness)です。これは、コンテキストを組み立て、ツールを公開し、エージェント・ループを実行し、ツール呼び出しを解釈し、モデルの出力をエディター内での有用なアクションに変換するレイヤーです。この記事では、このハーネスが何を行うのか、なぜ重要なのか、そしてモデルや開発者のワークフローが進化する中で、それをどのように評価しているのかを見ていきます。

Diagram showing that an agent is made up of a model plus a harness. The harness includes the agent loop, tools, context management, and system prompt.

コーディング・ハーネスとは何か?

言語モデルは、自身でファイルを編集したり、コマンドを実行したり、テストを走らせたりすることはできません。テキストを生成することしかできないのです。コーディング・ハーネスは、コード・エディターと言語モデルの架け橋として機能するシステムです。テキストをアクションに変換し、その結果をフィードバックすることで、モデルが次に何をすべきかを判断できるようにします。

VS Codeにおいて、コーディング・ハーネスには主に3つの役割があります。

  1. コンテキストの組み立て:リクエストがモデルに届く前に、ハーネスはプロンプトを構築します。このプロンプトには、動作指示を含むシステムメッセージ、ユーザーのクエリ、ワークスペースの構造(言語、フレームワーク、開いているエディター)、以前のターンからの会話履歴、ツールの実行結果、カスタム指示、そして過去のセッションのメモリが含まれます。ハーネスはモデルが何を目にするかを決定し、その決定が品質に直接影響を与えます。

  2. ツールの公開:ハーネスは、モデルが呼び出すことを許可されているツールを宣言します。これには、ファイルの読み取り(read_file)、コードの編集(replace_string_in_file または apply_patch)、ターミナルコマンドの実行(run_in_terminal)、コードベースの検索(semantic_search)など、多くのツールが含まれます。各ツールには、モデルが従うべきJSONスキーマと、いつそれを呼び出すべきかをモデルが判断するための説明が用意されています。利用可能なツールのセットはリクエストごとに変わることがあります。一部のツールは特定のモデルでのみ有効化され、実行前にユーザーの確認が必要なものもあります。また、ユーザーはツールピッカーでツールのオン/オフを切り替えることができ、MCPサーバーや拡張機能は同じループに組み込めるまったく新しいツールを提供できます。さらに、カスタムエージェント(.agent.md)は、使用するツールセットを特定のサブセットに制限することも可能です。

  3. ツールの実行:モデルがツールの実行を要求したとき(例えば、{"name": "run_in_terminal", "arguments": {"command": "npm test"}} のようなJSONを使用)、引数の検証、ツールの実行、エラー処理、結果のフォーマット、および次の反復(イテレーション)へのフィードバックを行うのはハーネスです。例えば、モデルがファイルの編集を求めた場合、ハーネスが差分(diff)を書き込みます。モデルがシェルコマンドの実行を求めた場合、ハーネスがプロセスを起動し、出力をキャプチャして伝達します。

これらのタスクはいずれも、言語モデルが直接実行することはできません。しかし、この入力こそがモデルの動作と結果を決定づけ、ひいてはあなたがコードエディターで体験するものを左右するのです。

これらのタスクをオーケストレーションし、イテレーションをいつ継続または停止するかを決定し、多数のラウンドにわたって会話の整合性を保つためのロジックが、エージェント・ループ(agent loop)です。

エージェント・ループ

根本的な部分として、VS Codeでエージェントを使用すると、ツールの呼び出しループが発生します。これは、「思考(think)→ 行動(act)→ 観察(observe)→ 再思考(think again)」というサイクルです。各イテレーションにおいて、エージェント・ハーネスはプロンプト(システム指示+コンテキスト+履歴+これまでのすべてのツール実行結果)を構築し、それをモデルに送信して、レスポンスを確認します。レスポンスにツールの呼び出しが含まれている場合、ハーネスはそれらのツールを実行し、結果をキャプチャしてループに戻ります。ツールの呼び出しがない場合、ループは終了し、アシスタントのテキストが最終的な回答となります。

Simplified diagram of the VS Code agent loop: the user sends a chat message, the tool-calling loop builds a prompt, sends it to the model, executes requested tools, records results, checks loop-control conditions, and either continues or finalizes the chat result.

ターン(turn)とは、ユーザーに見えるチャットのやり取りです。ユーザーがメッセージを送信し、最終的にエージェントが回答を生成します。その1ターンの間に、エージェント・ループは多数のラウンド(round)を実行することがあります。ラウンドとは、ループを1回通ることを指します(プロンプトを構築し、モデルを呼び出し、テキストやツールの呼び出しを受け取り、ツールを実行し、結果を記録し、継続するかどうかを決定する)。これらすべてのラウンドの完全な実行が、ループのラン(run)です。モデルがファイルを検索し、コードを読み、ファイルを編集し、テストを実行し、出力を読み取り、失敗に対してイテレーションを繰り返す中で、1回のユーザーターンが多数のラウンドをトリガーすることがあります。

ツール呼び出しループは、ループ制御チェックによって制限されています。ツール呼び出し回数の上限を設定し、ラウンド間でキャンセルが発生していないかを確認し、ストップフックを実行します。ストップフックは、エージェントの状態を検査し、終了させるか、あるいは処理を継続させるかを決定できる拡張ポイントです。ループ内では、イテレーションごとにプロンプトが再構築されます。これは、モデルが常にワークスペースの最新の状態を把握できることを意味します。例えば、3ラウンド前にファイルを編集した場合、現在のプロンプトはその編集を反映しています。また、ハーネスは会話の要約も管理します。蓄積された履歴が大きくなりすぎると、過去のラウンドを要約に圧縮し、コンテキストウィンドウの上限に達することなくモデルが作業を継続できるようにします。

注:ハーネスが実際に動作している様子を見てみたいですか?VS Codeのソースコードを探索することもできますし、チャットのツールUIを使用してリクエストに利用可能なツールを確認したり、チャットのデバッグビュー(Chat Debug View)を開いてプロンプト、ツール呼び出し、そしてその結果を検査したりできます。

ハーネスこそがプロダクトである

新しいモデルが提供されるとき、それは既存のハーネスに適合しなければなりません。システムプロンプト、ツール定義、ループのロジック、コンテキストの組み立て、そのすべてが、数ヶ月にわたる実際の使用を通じて構築され、調整されてきました。モデルは「空白を埋める」のが上手になりますが、その「空白」が何であるかを定義するのはハーネスです。

GitHub Copilotでは複数のモデルプロバイダーのモデルを使用できるため、このことはさらに重要になります。また、VS CodeのGitHub Copilotは、成長し続けるモデルのエコシステムをサポートしています。開発者はモデルを切り替えたり、自動選択を使用したり、独自のキー(APIキー)を持ち込んだり、拡張機能を介して追加のプロバイダーをインストールしたりできます。つまり、VS Codeは単一の安定したAPIではなく、広範で継続的に進化するエコシステムに対応しなければならないのです。

ハーネスがあるからこそ、VS Codeは開発者に毎回製品の使い方を再学習させることなく、このモデルの柔軟性を処理できます。モデルを切り替えたり、新しいプロバイダーを試したりしても、チャット、セッション、ツール、ターミナル出力、デバッグ、ソース管理といったコアな体験は、慣れ親しんだ状態のまま維持されます。

しかし、新しいモデルを統合することは、単にモデルピッカーに選択肢を追加するだけで済むことは滅多にありません。プロバイダーによって、ツールの呼び出し方法、構造化出力、推論制御、プロンプトのキャッシュ、コンテキストの制限、エラー時の挙動などは異なります。長期的な計画(プランニング)が得意なモデルもあれば、簡潔な編集が得意なモデルもあります。各モデルには異なる強みがあり、私たちはリリースごとにモデルプロバイダーと緊密に連携して、システムプロンプト、ツール説明、ループの動作をそれに応じて調整しています。多くの場合、プロバイダーはリリース前の次期モデルのスナップショットである「モデルチェックポイント」への早期アクセスを提供してくれるため、モデルが一般公開される前にハーネスの調整を開始できます。

Flow diagram showing VS Code and model providers iterating from an upcoming model release through Copilot API onboarding, harness optimization, evaluation, provider feedback, and launch.

モデルが異なれば、必要となるハーネスの動作も異なります。Claudeモデルは編集に replace_string_in_file を使用し、GPTモデルは apply_patch を使用します。Geminiは、記述(ナレーション)するのではなくツール呼び出しを実行するようリマインドする必要があり、履歴に孤立したツール呼び出しがあると動作を停止してしまいます。いくつかのモデルは拡張思考(extended thinking)をサポートしており、推論の取り組み(reasoning-effort)制御を必要とします。簡潔なシステムプロンプトで最適に機能するモデルもあれば、脱線しないように長文で構造化された指示を必要とするモデルもあります。ハーネスはモデルごとに異なるシステムプロンプトを選択します。例えば、Claude Sonnet 4には、Claude 4.5とは異なるプロンプトが適用され、Opusともまた異なるプロンプトが適用されます。

こうしたモデルごとの差異は、決して些細なものではありません。それらはモデルごとのシステムプロンプト、モデルごとのツールセット、およびモデルごとの会話管理へと変換されます。つまり、新しいモデルが提供される際、単にスイッチを切り替えるだけでなく、その動作を検証する必要があるのです。私たちはリリース前に、ツールのスキーマを検証し、デフォルト値を再調整し、完全なエージェントセッションを再実行します。モデルが正しく機能しているかどうかもさることながら、さらに難しい問題は、新しいモデルが実際に『より優れた結果』をもたらしているかどうかをどのように検証するか、ということです。

評価がハーネスの信頼性を担保する

新しい機能をリリースする前にテストする必要があるのと同様に、モデルもテストする必要があります。そこで登場するのが「モデル評価」です。VS Codeでモデルをリリースする前に、私たちはさまざまな角度から評価を行います。オフラインのベンチマークを実行し、社内でテストし、製品ですでに利用可能なモデルと比較します。モデルが本番環境に導入された後も、測定を続けます。A/Bテスト、集計された利用シグナル、週次のレポートなどを通じて、実際の開発者のワークフローにおいてモデルがどのように動作しているかを把握します。

Diagram showing an overview of the VS Code evaluation pipeline.

公開されているモデルベンチマークは複数存在し、これらは共通の参照点として役立ちます。私たちはこれらのベンチマークを利用して、より広範なモデルエコシステムとの比較を行い、明白なデグレード(先祖返り)を検出しています。しかし、最先端(フロンティア)のレベルになると、それらは品質指標として不十分になります。OpenAIは、最先端モデルが記憶から直接ゴールドパッチ(正解パッチ)を再現してしまうことがあり、データの混入(contamination)が無視できなくなったため、SWE-bench Verifiedの結果の報告を停止しました

カバレッジ(網羅性)もまた、もう一つの限界です。SWE-benchは価値がありますが、依然として公開されているバグ修正タスクに偏っています。Terminal-Benchはコマンドラインの能力を測定するのに便利ですが、そのタスクの多くは、開発者が実際にエディターで行うワークフローというよりも、孤立したターミナルのパズルのように見えます。現実世界のコーディングエージェントは、既知のバグにパッチを適用したり、シェルの課題を解決したりする以上のことを行う必要があります。プロジェクトの雛形作成(スキャフォールディング)を行い、コードベースを移行し、ファイルをまたいでリファクタリングし、指示に従い、ターミナルやブラウザを操作しなければならないのです。

私たちは現在もこれらのベンチマークを実行していますが、それらは出発点にすぎません。どのモデルをVS Codeでリリースする準備ができているかを判断するには、私たちが実際に構築している製品により近いものが必要でした。

VSC-Benchの構築

だからこそ私たちは、VS Codeのエージェントの動作を評価するためのオフライン評価スイート「VSC-Bench」を構築しました。VSC-Benchは、公開ベンチマークでは十分にカバーされていない、VS Code特有の開発者タスクに焦点を当てています。これには、カスタムエージェントモード、拡張機能のワークフロー、MCPおよびツールの使用、ターミナルやブラウザとのインタラクション、マルチターンの会話、TypeScript、Python、C++などを網羅したマルチ言語のコーディングタスクが含まれます。

私たちはVSC-Benchを使用して、解答の正確さ、エージェントの取り組み(エフォート)、トークン効率、およびレイテンシ(遅延)にわたるモデルの動作を測定しています。下の図は解決率とトークン使用量に焦点を当てていますが、モデルがVS Codeの体験に組み込まれる前に、私たちはこれらすべての側面を評価しています。モデルや推論設定をエディターのデフォルトにする前に、そのトレードオフを検討することが重要です。

さまざまなモデルおよび推論設定における、VSC-Benchモデルの解決率と中央値の総トークン数を比較する散布図。 このチャートは、8つの「モデル・エフォート」構成にわたる40回のVSC-Benchの実行結果をまとめたものです。各プロットは1つのモデル・エフォート構成を表しており、上にあるプロットほど多くのタスクを解決しており、右にあるプロットほど多くのトークンを使用しています。このVSC-Benchタスクのセットにおいて、xhigh(極高エフォート)はhigh(高エフォート)よりも多くのトークンを消費しているにもかかわらず、解決したタスクはわずかに少なくなっています。これは、追加の思考がもはや優れた結果につながらない、実用的なエフォートのスィートスポットを過ぎている可能性を示唆しています。

各VSC-Benchタスクは、再現可能なコンテナ化されたワークスペースで実行されます。ハーネスはVS Codeを起動し、ワークスペースを開き、エージェントに1つ以上のユーザープロンプトを送信し、エージェントにテキストとツール呼び出しで応答させ、その後に何が起こったかを評価します。これにより、完全なエージェント・ループのより現実的なビューが得られます。最終的なコードが正しく見えるかだけでなく、エージェントがエディター、ターミナル、言語サービス、ブラウザ、およびツールを、VS Codeの体験に則した方法で使用したかどうかを検証できます。

公開ベンチマークとVSC-Benchを組み合わせることで、よりバランスの取れたシグナルが得られます。公開の評価はモデルが業界全体でどの位置にあるかを示し、製品固有の評価は、開発者がVS Codeに期待する体験を提供する準備ができているかを教えてくれます。

エージェントの変更をマージ前にどのようにベンチマーク評価するか

ベンチマークは、モデルをリリースするためだけのものではありません。それらは、ハーネスの変更を本番環境に適用する前に審査する方法でもあります。PR(プルリクエスト)がコアツールやシステムプロンプト、あるいはエージェントの動作を変化させ得る他の要素に触れる場合、マージ前にベンチマークの数値を確認したいと考えます。

そうしたPRに対して、VS Codeチームは自動化された評価アセスメントフローを使用します。PRに ~requires-eval-assessment ラベルを追加するとプロセスが開始されます。PRがビルドされ、評価用エージェントとして提供され、ベンチマークが実行され、その結果がPRに書き戻されます。

  1. PRをビルドする。 ウェブフックがラベルイベントを vscode-engineering のワークフローにルーティングし、PRのマージ参照に対してAzure DevOpsのビルドを開始します。失敗した場合は1回自動再試行されます。レビュアーが追跡できるように、PRには「queued 1 of 2(2つのうち1つをキューイング中)」というコメントが付きます。

  2. 評価用エージェントをパブリッシュする。 ビルドが成功すると、パブリッシュパイプラインがバージョン管理されたエージェント(0.0.0-dev.<sha>)を dev タグで vscode-evals のnpmフィードに配信します。PRのコメントは「queued 2 of 2」に切り替わります。

  3. evaldのIssueを作成する。 パブリッシュパイプラインが repository_dispatchvscode-engineering に送り返し、公開されたその正確なエージェントに固定(ピン留め)されたモデル評価Issueを github/evald 上にオープンします。

  4. 結果を報告する。 evaldがベンチマークを実行・監視し、分析コメントを生成します。Azure Logic Appが コメントのURL のみを(分析本文はevaldでプライベートに保たれます)別の repository_dispatch として転送し、元のVS Code PRにリンクを投稿します。

Screenshot of an eval assessment report showing eval evidence with terminal logs, a task comparison table, and the proposed fix.

モデルはエンジン。ハーネスは車。

私たちは、開発者が数ヶ月ごとに発する「どのモデルが最適か?」という問いから始めました。しかし、コーディングエージェントにおいて、その問いは「どのエンジンが最高か?」と尋ねるのに少し似ています。エンジンは重要ですが、それだけでは十分ではありません。モデルが見るコンテキスト、モデルがアクセスできるツール、それを動かし続けるループ、そしてそのすべてが正常に動作することを確認する評価。それこそがハーネスであり、私たちがエンジニアリング時間の大部分を費やしている対象なのです。

モデルがより長いコンテキスト、優れた計画力、ネイティブのツール使用といった新しい能力を獲得するにつれて、ハーネスもそれらを活用するために進化します。そして、開発者がエージェントモードを新しいワークフローへと押し進める中、私たちは学んだことをループ、ツール、および評価へとフィードバックしています。VS Codeのすべてのリリースには、モデルの更新とともにハーネスの改善が含まれています。

ハーネスがどのように動作するのか興味があるなら、今すぐ実際に体験してみることができます。VS Codeのソースコードを探索したり、チャットのツールUIを使用してリクエストにどのようなツールが利用可能かを確認したり、チャットのデバッグビュー(Chat Debug View)を開いてエージェントの実行の背後にあるプロンプト、ツール呼び出し、およびその結果を検査したりできます。モデルを切り替えたり、独自のツールを追加したりして、何が効果的だったかを教えてください。フィードバックはMicrosoftのGitHubリポジトリで共有できます。

ハッピーコーディング!💙

© . This site is unofficial and not affiliated with Microsoft.