LanguageModelTool API

言語モデル ツールを使用すると、大規模言語モデル (LLM) の機能を拡張できます。VS Code は、拡張機能によって提供されるツールを Copilot エージェント モードで表示します。VS Code 拡張機能でツールを提供することで、エージェント コーディングの能力と、拡張機能 API を介した VS Code の深い統合を組み合わせることができます。

この拡張機能ガイドでは、言語モデル ツールを作成する方法と、チャット拡張機能にツール呼び出しを実装する方法について学習します。

LLM におけるツール呼び出しとは?

言語モデル ツールとは、言語モデル リクエストの一部として呼び出すことができる関数です。たとえば、データベースから情報を取得したり、何らかの計算を実行したり、オンライン API を呼び出したりする関数があるかもしれません。VS Code 拡張機能でツールを提供すると、エージェント モードは会話のコンテキストに基づいてツールを呼び出すことができます。

LLM が実際にツール自体を実行することはありません。代わりに、LLM はツールを呼び出すために使用されるパラメーターを生成します。ツールが適切なコンテキストで呼び出されるように、ツールの目的、機能、および入力パラメーターを明確に記述することが重要です。

OpenAI ドキュメントの関数呼び出しの詳細をご覧ください。

拡張機能に言語モデル ツールを実装する理由?

拡張機能に言語モデル ツールを実装すると、次のことが可能になります。

  • ユーザー プロンプトへの応答の一部として自動的に呼び出される特殊なツールでエージェント モードを拡張します。たとえば、チャット会話の一部としてデータベースのスキャフォールディングとクエリを有効にします。
  • 幅広い拡張機能 API を使用して、VS Code と深く統合します。たとえば、デバッグ APIを使用して、ユーザーのデバッグ エクスペリエンスを向上させます。

言語モデル ツールの作成

データベースから情報を取得したり、ファイルを検索したり、計算を実行したりするなど、特定のタスクを実行するツールを作成できます。

言語モデル ツールの実装は、主に 2 つの部分で構成されています。

  1. 拡張機能の package.json ファイルにツールの構成を定義します。
  2. 拡張機能コードにツールを実装します。

package.json の静的構成

ツールの静的構成は、拡張機能の package.json ファイルで定義されます。これには、ツール名、説明、入力スキーマ、およびその他のメタデータが含まれます。

  1. 拡張機能の package.json ファイルの contributes.languageModelTools セクションにツールのエントリを追加します。

  2. ツールに一意の名前を付けます

    プロパティ 説明
    name ツールの一意の名前。拡張機能の実装コードでツールを参照するために使用されます。名前の形式は {動詞}_{名詞} にしてください。命名ガイドラインを参照してください。
    displayName ツールのユーザーフレンドリーな名前。UI での表示に使用されます。
  3. エージェント モードで使用したり、チャット プロンプトで参照したりできるツールの場合、次のプロパティを追加します。

    ユーザーは、モデル コンテキスト プロトコル (MCP) ツールと同様の方法で、チャット ビューでツールを有効または無効にできます。

    プロパティ 説明
    canBeReferencedInPrompt ツールをエージェント モードで使用したり、チャットで参照したりできる場合は true に設定します。
    toolReferenceName ユーザーが # を介してチャット プロンプトでツールを参照するための名前。
    icon UI でツールに表示するアイコン。
    userDescription ツールのユーザーフレンドリーな説明。UI での表示に使用されます。
  4. modelDescription に詳細な説明を追加します

    • ツールは正確に何をするのですか?
    • どのような種類の情報を返しますか?
    • いつ使用すべきで、いつ使用すべきでないですか?
    • ツールの重要な制限事項または制約事項について説明します。
  5. ツールが入力パラメーターを受け取る場合は、ツールの入力パラメーターを記述する inputSchema プロパティを追加します。

    この JSON スキーマは、ツールが入力として受け取るプロパティを持つオブジェクトと、それらが必須かどうかを記述します。ファイル パスは絶対パスである必要があります。

    各パラメーターが何をするのか、およびツールの機能とどのように関連しているかを説明します。

  6. when 句を使用して、ツールがいつ使用可能になるかを制御します。

    languageModelTools 貢献ポイントを使用すると、when 句を使用して、ツールがエージェント モードで使用可能になるか、プロンプトで参照できるかを制限できます。たとえば、デバッグ コール スタック情報を取得するツールは、ユーザーがデバッグしている場合にのみ使用可能にする必要があります。

    "contributes": {
        "languageModelTools": [
            {
                "name": "chat-tools-sample_tabCount",
                ...
                "when": "debugState == 'running'"
            }
        ]
    }
    

ツールの定義例:

次の例は、タブ グループのアクティブなタブの数をカウントするツールを定義する方法を示しています。

"contributes": {
    "languageModelTools": [
        {
            "name": "chat-tools-sample_tabCount",
            "tags": [
                "editors",
                "chat-tools-sample"
            ],
            "toolReferenceName": "tabCount",
            "displayName": "Tab Count",
            "modelDescription": "The number of active tabs in a tab group in VS Code.",
            "userDescription": "Count the number of active tabs in a tab group.",
            "canBeReferencedInPrompt": true,
            "icon": "$(files)",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "tabGroup": {
                        "type": "number",
                        "description": "The index of the tab group to check. This is optional- if not specified, the active tab group will be checked.",
                        "default": 0
                    }
                }
            }
        }
    ]
}

ツールの実装

  1. 拡張機能のアクティブ化時に、vscode.lm.registerTool でツールを登録します。

    package.jsonname プロパティで指定したツールの名前を指定します。

    ツールを拡張機能に対してプライベートにしたい場合は、ツールの登録手順をスキップします。

    export function registerChatTools(context: vscode.ExtensionContext) {
      context.subscriptions.push(
        vscode.lm.registerTool('chat-tools-sample_tabCount', new TabCountTool())
      );
    }
    
  2. vscode.LanguageModelTool<> インターフェイスを実装するクラスを作成します。

  3. prepareInvocation メソッドにツールの確認メッセージを追加します。

    拡張機能からのツールには常に一般的な確認ダイアログが表示されますが、ツールは確認メッセージをカスタマイズできます。ツールが何をしているかをユーザーが理解できるように、十分なコンテキストを提供します。メッセージは、コード ブロックを含む MarkdownString にすることができます。

    次の例は、タブ数ツールに確認メッセージを提供する方法を示しています。

    async prepareInvocation(
        options: vscode.LanguageModelToolInvocationPrepareOptions<ITabCountParameters>,
        _token: vscode.CancellationToken
    ) {
        const confirmationMessages = {
            title: 'Count the number of open tabs',
            message: new vscode.MarkdownString(
                `Count the number of open tabs?` +
                (options.input.tabGroup !== undefined
                    ? ` in tab group ${options.input.tabGroup}`
                    : '')
            ),
        };
    
        return {
            invocationMessage: 'Counting the number of tabs',
            confirmationMessages,
        };
    }
    

    prepareInvocationundefined を返した場合、一般的な確認メッセージが表示されます。ユーザーは特定のツールを「常に許可」するように選択することもできます。

  4. ツールの入力パラメーターを記述するインターフェイスを定義します。

    インターフェイスは invoke メソッドで使用されます。入力パラメーターは、package.jsoninutSchema で定義された JSON スキーマに対して検証されます。

    次の例は、タブ数ツールのインターフェイスを示しています。

    export interface ITabCountParameters {
      tabGroup?: number;
    }
    
  5. ツールが呼び出されたときに呼び出される invoke メソッドを実装します。

    invoke メソッドは、options パラメーターでツールの入力パラメーターを受け取ります。パラメーターは、package.jsoninputSchema で定義された JSON スキーマに対して検証されます。

    エラーが発生した場合は、LLM に意味の通じるメッセージでエラーをスローします。オプションで、LLM が次に何をすべきか (異なるパラメーターで再試行したり、別の操作を実行したりするなど) に関する指示を提供します。

    次の例は、タブ数ツールの実装を示しています。ツールの結果は、vscode.LanguageModelToolResult 型のインスタンスです。

    async invoke(
        options: vscode.LanguageModelToolInvocationOptions<ITabCountParameters>,
        _token: vscode.CancellationToken
    ) {
        const params = options.input;
        if (typeof params.tabGroup === 'number') {
            const group = vscode.window.tabGroups.all[Math.max(params.tabGroup - 1, 0)];
            const nth =
                params.tabGroup === 1
                    ? '1st'
                    : params.tabGroup === 2
                        ? '2nd'
                        : params.tabGroup === 3
                            ? '3rd'
                            : `${params.tabGroup}th`;
            return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`There are ${group.tabs.length} tabs open in the ${nth} tab group.`)]);
        } else {
            const group = vscode.window.tabGroups.activeTabGroup;
            return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`There are ${group.tabs.length} tabs open.`)]);
        }
    }
    

言語モデル ツールを実装するための完全なソース コードを VS Code 拡張機能のサンプル リポジトリでご覧ください。

ツール呼び出しフロー

ユーザーがチャット プロンプトを送信すると、次の手順が発生します。

  1. Copilot は、ユーザーの構成に基づいて使用可能なツールのリストを決定します。

    ツールのリストは、組み込みツール、拡張機能によって登録されたツール、およびMCP サーバーからのツールで構成されています。拡張機能または MCP サーバー (図の緑色で表示) を介してエージェント モードに貢献できます。

  2. Copilot は、プロンプト、チャット コンテキスト、および検討するツール定義のリストを LLM に提供して、リクエストを LLM に送信します。

    LLM は応答を生成します。これには、1 つ以上のツールを呼び出すリクエストが含まれる場合があります。

  3. 必要に応じて、Copilot は LLM によって提供されたパラメーター値を使用して、提案されたツールを呼び出します。

    ツールの応答により、ツールの呼び出しに対する追加のリクエストが発生する可能性があります。

  4. エラーまたはフォローアップ ツールのリクエストの場合、Copilot はすべてのツール リクエストが解決されるまでツール呼び出しフローを反復処理します。

  5. Copilot はユーザーに最終的な応答を返します。これには、複数のツールからの応答が含まれる場合があります。

次の図は、Copilot ツール呼び出しフローを示しています。

Diagram that shows the Copilot tool-calling flow

はじめに

ガイドライン

  • 命名: ツールとパラメーターに明確でわかりやすい名前を付けます。

    • ツール名: 一意であり、意図を明確に記述する必要があります。ツール名の構造は {動詞}_{名詞} の形式にしてください。たとえば、get_weatherget_azure_deployment、または get_terminal_output などです。

    • パラメーター名: パラメーターの目的を記述する必要があります。パラメーター名の構造は {名詞} の形式にしてください。たとえば、destination_locationticker、または file_name などです。

  • 説明: ツールとパラメーターの詳細な説明を記述します。

    • ツールが何をするのか、いつ使用すべきで、いつ使用すべきでないかを説明します。たとえば、「このツールは、指定された場所の天候を取得します。」
    • 各パラメーターが何をするのか、およびツールの機能とどのように関連しているかを説明します。たとえば、「destination_location パラメーターは、天候を取得する場所を指定します。有効な場所名または座標である必要があります。」
    • ツールの重要な制限事項または制約事項について説明します。たとえば、「このツールは、米国内の場所の天気データのみを取得します。他の地域では機能しない場合があります。」
  • ユーザー確認: ツールの呼び出しの確認メッセージを提供します。拡張機能からのツールには常に一般的な確認ダイアログが表示されますが、ツールは確認メッセージをカスタマイズできます。ツールが何をしているかをユーザーが理解できるように、十分なコンテキストを提供します。

  • エラー処理: エラーが発生した場合は、LLM に意味の通じるメッセージでエラーをスローします。オプションで、LLM が次に何をすべきか (異なるパラメーターで再試行したり、別の操作を実行したりするなど) に関する指示を提供します。

OpenAI ドキュメントおよびAnthropic ドキュメントでツール作成のベスト プラクティスをご覧ください。