に参加して、VS Code の AI 支援開発について学びましょう。

言語モデルツールAPI

言語モデルツールを使用すると、チャット内の大規模言語モデル(LLM)の機能を、ドメイン固有の機能で拡張できます。ユーザーのチャットプロンプトを処理するために、VS Codeのエージェントモードは、会話の一部としてこれらのツールを自動的に呼び出し、専門的なタスクを実行できます。VS Code拡張機能で言語モデルツールを提供することで、エージェント的なコーディングワークフローを拡張し、エディターとの深い統合も実現できます。

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

MCPサーバーを提供することで、特殊なツールでチャットエクスペリエンスを拡張することもできます。AI拡張機能の概要を参照して、さまざまなオプションと、どのアプローチを使用するかを決定する方法の詳細を確認してください。

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

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

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

次の図は、VS Codeのエージェントモードにおけるツール呼び出しフローを示しています。ツール呼び出しフローを参照して、関連する特定のステップの詳細を確認してください。

Diagram that shows the Copilot tool-calling flow

OpenAIドキュメントで関数呼び出しについて詳しく読む。

なぜ拡張機能で言語モデルツールを実装するのか?

拡張機能で言語モデルツールを実装することには、いくつかの利点があります。

  • ユーザープロンプトへの応答の一部として自動的に呼び出される、特殊なドメイン固有のツールでエージェントモードを拡張します。たとえば、データベースの足場とクエリを有効にして、LLMに動的に関連するコンテキストを提供します。
  • 幅広い拡張APIセットを使用して、VS Codeと深く統合します。たとえば、デバッグAPIを使用して、現在のデバッグコンテキストを取得し、それをツールの機能の一部として使用します。
  • Visual Studio Marketplaceを介してツールを配布および展開し、ユーザーに信頼性の高いシームレスなエクスペリエンスを提供します。ユーザーはツールの個別のインストールおよび更新プロセスを必要としません。

次のシナリオでは、MCPサーバーで言語モデルツールを実装することを検討するかもしれません。

  • すでにMCPサーバーの実装があり、VS Codeでもそれを使用したい場合。
  • 異なる開発環境およびプラットフォームで同じツールを再利用したい場合。
  • ツールがサービスとしてリモートでホストされている場合。
  • VS Code APIへのアクセスが必要ない場合。

言語モデルツールを作成する

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

  1. 拡張機能のpackage.jsonファイルでツールの構成を定義します。
  2. 言語モデルAPIリファレンスを使用して、拡張機能コードでツールを実装します。

基本的なサンプルプロジェクトから始めることができます。

1. package.jsonにおける静的構成

拡張機能で言語モデルツールを定義する最初のステップは、拡張機能のpackage.jsonファイルでそれを定義することです。この構成には、ツール名、説明、入力スキーマ、その他のメタデータが含まれます。

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

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

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

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

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

    • ツールは正確に何をするのですか?
    • どのような種類の情報を返しますか?
    • いつ使用すべきで、いつ使用すべきではありませんか?
    • ツールの重要な制限事項や制約を記述します。
  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
                    }
                }
            }
        }
    ]
}

2. ツールの実装

言語モデルAPIを使用して言語モデルツールを実装します。これは次のステップで構成されます。

  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. ツールの入力パラメーターを記述するインターフェースを定義します。

    このインターフェースは、vscode.LanguageModelToolクラスのinvokeメソッドで使用されます。入力パラメーターは、package.jsoninputSchemaで定義した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は、1つ以上のツールを呼び出すリクエストを含む応答を生成する場合があります。

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

    ツールの応答により、さらにツールの呼び出しリクエストが発生する場合があります。

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

  5. Copilotは、複数のツールからの応答を含む最終応答をユーザーに返します。

ガイドラインと規則

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

    • ツール名:一意で、その意図を明確に記述する必要があります。ツール名は{動詞}_{名詞}の形式で構造化します。例:get_weatherget_azure_deployment、またはget_terminal_output

    • パラメーター名:パラメーターの目的を記述する必要があります。パラメーター名は{名詞}の形式で構造化します。例:destination_locationticker、またはfile_name

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

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

  • エラー処理:エラーが発生した場合は、LLMにとって意味のあるメッセージでエラーをスローします。オプションで、異なるパラメーターで再試行したり、異なるアクションを実行したりするなど、LLMが次に行うべきことに関する指示を提供します。

OpenAIドキュメントおよびAnthropicドキュメントでツール作成に関するその他のベストプラクティスを入手してください。

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