VS Codeのエージェントモードを拡張するには、を試してください!

チャット参加者API

チャット参加者は、ユーザーがドメイン固有の専門家でVS Code のチャットを拡張できるようにする、専門化されたアシスタントです。ユーザーは @-メンションでチャット参加者を呼び出し、参加者はユーザーの自然言語プロンプトの処理を担当します。

この拡張機能ガイドでは、チャット参加者APIを使用してチャット参加者を作成する方法を学びます。

VS Code には、@vscode@terminal@workspace など、いくつかの組み込みチャット参加者があります。これらはそれぞれのドメインに関する質問に答えるように最適化されています。

チャット参加者は、ユーザーのチャットプロンプトを解決するために必要なステップをオーケストレーションするLLMの一部として呼び出される言語モデルツールとは異なります。チャット参加者はユーザーのプロンプトを受け取り、必要なタスク自体をオーケストレーションします。

拡張機能にチャット参加者を実装する理由

拡張機能にチャット参加者を実装することにはいくつかの利点があります

  • 専門的なドメイン固有の知識と専門性でチャットを拡張します。例えば、組み込みの@vscode参加者は、VS Codeとその拡張APIに関する知識を持っています。
  • エンドツーエンドのユーザーチャットプロンプトと応答を管理することで、会話を所有します。
  • 幅広い拡張機能APIを使用することで、VS Codeと深く統合します。例えば、デバッグAPIを使用して現在のデバッグコンテキストを取得し、ツールの機能の一部として使用します。
  • Visual Studio Marketplace を介してチャット参加者を配布およびデプロイすることで、ユーザーに信頼性が高くシームレスな体験を提供します。ユーザーは個別のインストールや更新プロセスを必要としません。

自律的なエージェントコーディングセッションの一部として自動的に呼び出されるドメイン固有の機能を提供したい場合は、言語モデルツールまたはMCPサーバーの実装を検討できます。異なるオプションと、どのアプローチを使用するかを決定する方法については、AI拡張機能の概要を参照してください。

チャットユーザー体験の要素

以下のスクリーンショットは、サンプル拡張機能におけるVisual Studio Codeチャット体験の異なるチャットの概念を示しています。

Chat concepts explanation

  1. @構文を使用して@catチャット参加者を呼び出す
  2. /構文を使用して/teachコマンドを呼び出す
  3. ユーザー提供のクエリ(ユーザープロンプトとも呼ばれる)
  4. Copilotが@catチャット参加者を使用していることを示すアイコンと参加者のfullName
  5. @catが提供するMarkdown応答
  6. Markdown応答に含まれるコードフラグメント
  7. @cat応答に含まれるボタン。このボタンはVS Codeコマンドを呼び出します
  8. チャット参加者が提供する推奨されるフォローアップの質問
  9. チャット参加者のdescriptionプロパティによって提供されるプレースホルダーテキスト付きのチャット入力フィールド

チャット参加者を作成する

チャット参加者の実装は以下の要素で構成されます

  1. 拡張機能のpackage.jsonファイルでチャット参加者を定義します。
  2. ユーザーのチャットプロンプトを処理し、応答を返すためのリクエストハンドラーを実装します。
  3. (オプション) 共通のタスクに対するショートハンド表記をユーザーに提供するために、チャットスラッシュコマンドを実装します。
  4. (オプション) 推奨されるフォローアップの質問を定義します。
  5. (オプション) ユーザーからの明示的な言及なしに、VS Codeがチャットリクエストを適切なチャット参加者に自動的にルーティングする参加者検出を実装します。

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

Diagram showing how extension can contribute to chat

1. チャット参加者を登録する

チャット拡張機能を作成する最初のステップは、以下のプロパティを使用してpackage.jsonに登録することです

  • id: package.jsonファイルで定義されている、チャット参加者の一意の識別子。
  • name: チャット参加者の短い名前。チャットでの@-メンションに使用されます。
  • fullName: チャット参加者のフルネーム。応答のタイトル領域に表示されます。
  • description: チャット参加者の目的を簡潔に説明したもの。チャット入力フィールドのプレースホルダーテキストとして使用されます。
  • isSticky: 応答後にチャット参加者がチャット入力フィールドに永続的であるかどうかを示すブール値。
"contributes": {
        "chatParticipants": [
            {
                "id": "chat-sample.my-participant",
                "name": "my-participant",
                "fullName": "My Participant",
                "description": "What can I teach you?",
                "isSticky": true
            }
        ]
}

既存のチャット参加者との整合性を保つため、nameには小文字を、fullNameにはタイトルケースを使用することをお勧めします。チャット参加者の命名規則の詳細についてはこちらをご覧ください。

一部の参加者名は予約されています。そのような予約された名前を使用した場合、VS Codeはチャット参加者の完全修飾名(拡張機能IDを含む)を表示します。

2. リクエストハンドラーを実装する

チャット参加者APIを使用してチャット参加者を実装します。これには以下のステップが含まれます

  1. 拡張機能のアクティベーション時に、vscode.chat.createChatParticipantを使用して参加者を作成します。

    package.jsonで定義したIDと、次のステップで実装するリクエストハンドラーへの参照を提供します。

    export function activate(context: vscode.ExtensionContext) {
      // Register the chat participant and its request handler
      const cat = vscode.chat.createChatParticipant('chat-sample.my-participant', handler);
    
      // Optionally, set some properties for @cat
      cat.iconPath = vscode.Uri.joinPath(context.extensionUri, 'cat.jpeg');
    
      // Add the chat request handler here
    }
    
  2. activate関数で、vscode.ChatRequestHandlerリクエストハンドラーを定義します。

    リクエストハンドラーは、VS Codeチャットビューでユーザーのチャットリクエストを処理する役割を担います。ユーザーがチャット入力フィールドにプロンプトを入力するたびに、チャットリクエストハンドラーが呼び出されます。

    const handler: vscode.ChatRequestHandler = async (
      request: vscode.ChatRequest,
      context: vscode.ChatContext,
      stream: vscode.ChatResponseStream,
      token: vscode.CancellationToken
    ): Promise<ICatChatResult> => {
      // Chat request handler implementation goes here
    };
    
  3. vscode.ChatRequestからユーザーの意図を判断します。

    ユーザーのリクエストの意図を判断するには、vscode.ChatRequestパラメーターを参照して、ユーザーのプロンプトテキスト、コマンド、およびチャットの場所へアクセスできます。

    オプションで、従来のロジックを使用する代わりに、言語モデルを利用してユーザーの意図を判断できます。requestオブジェクトの一部として、ユーザーがチャットモデルドロップダウンで選択した言語モデルインスタンスを取得できます。言語モデルAPIを拡張機能で使用する方法を学びましょう。

    以下のコードスニペットは、まずコマンドを使用し、次にユーザープロンプトを使用してユーザーの意図を判断する基本的な構造を示しています

    const handler: vscode.ChatRequestHandler = async (
      request: vscode.ChatRequest,
      context: vscode.ChatContext,
      stream: vscode.ChatResponseStream,
      token: vscode.CancellationToken
    ): Promise<ICatChatResult> => {
      // Test for the `teach` command
      if (request.command == 'teach') {
        // Add logic here to handle the teaching scenario
        doTeaching(request.prompt, request.variables);
      } else {
        // Determine the user's intent
        const intent = determineUserIntent(request.prompt, request.variables, request.model);
    
        // Add logic here to handle other scenarios
      }
    };
    
  4. ユーザーリクエストを処理するロジックを追加します。

    多くの場合、チャット拡張機能はrequest.model言語モデルインスタンスを使用してリクエストを処理します。この場合、ユーザーの意図に合わせて言語モデルのプロンプトを調整することがあります。

    あるいは、バックエンドサービスを呼び出すこと、従来のプログラミングロジックを使用すること、またはこれらのすべてのオプションの組み合わせを使用することで、拡張機能のロジックを実装できます。例えば、ウェブ検索を呼び出して追加情報を収集し、それを言語モデルへのコンテキストとして提供することができます。

    現在のリクエストを処理中に、以前のチャットメッセージを参照したい場合があります。例えば、以前の応答がC#のコードスニペットを返した場合、ユーザーの現在のリクエストは「Pythonでコードを提供してください」となるかもしれません。チャットメッセージ履歴を使用する方法を学びましょう。

    チャット入力の場所(チャットビュー、クイックチャット、インラインチャット)に基づいてリクエストを異なる方法で処理したい場合は、vscode.ChatRequestlocationプロパティを使用できます。例えば、ユーザーがターミナルのインラインチャットからリクエストを送信した場合、シェルコマンドを検索するかもしれません。一方、ユーザーがチャットビューを使用する場合、より詳細な応答を返すことができます。

  5. ユーザーにチャット応答を返します。

    リクエストを処理したら、チャットビューでユーザーに応答を返す必要があります。ストリーミングを使用してユーザーのクエリに応答できます。

    応答には、Markdown、画像、参照、進行状況、ボタン、ファイルツリーなど、さまざまなコンテンツタイプを含めることができます。

    Response from the cat extension that includes code, markdown and a button

    拡張機能は応答ストリームを次のように使用できます

    stream.progress('Picking the right topic to teach...');
    stream.markdown(`\`\`\`typescript
    const myStack = new Stack();
    myStack.push(1); // pushing a number on the stack (or let's say, adding a fish to the stack)
    myStack.push(2); // adding another fish (number 2)
    console.log(myStack.pop()); // eating the top fish, will output: 2
    \`\`\`
    So remember, Code Kitten, in a stack, the last fish in is the first fish out - which we tech cats call LIFO (Last In, First Out).`);
    
    stream.button({
      command: 'cat.meow',
      title: vscode.l10n.t('Meow!'),
      arguments: []
    });
    

    サポートされているチャット応答出力タイプの詳細についてはこちらをご覧ください。

    実際には、拡張機能は通常、言語モデルにリクエストを送信します。言語モデルから応答を受け取ると、さらに処理を行い、何かをユーザーにストリーミングするかどうかを決定します。VS CodeチャットAPIはストリーミングベースであり、ストリーミング言語モデルAPIと互換性があります。これにより、拡張機能は進行状況と結果を継続的に報告し、スムーズなユーザー体験を提供することを目的としています。言語モデルAPIの使用方法を学びましょう。

3. スラッシュコマンドを登録する

チャット参加者はスラッシュコマンドを提供できます。これは拡張機能が提供する特定の機能へのショートカットです。ユーザーは、例えば/explainのように、/構文を使用してチャットでスラッシュコマンドを参照できます。

質問に答える際のタスクの1つは、ユーザーの意図を判断することです。例えば、VS CodeはCreate a new workspace with Node.js Express Pug TypeScriptが新しいプロジェクトを望んでいることを推測できますが、@workspace /new Node.js Express Pug TypeScriptはより明示的で簡潔であり、入力時間を節約します。チャット入力フィールドに/を入力すると、VS Codeは登録されているコマンドとその説明のリストを提供します。

List of commands in chat for @workspace

チャット参加者は、package.jsonにスラッシュコマンドとその説明を追加することで提供できます

"contributes": {
    "chatParticipants": [
        {
            "id": "chat-sample.cat",
            "name": "cat",
            "fullName": "Cat",
            "description": "Meow! What can I teach you?",
            "isSticky": true,
            "commands": [
                {
                    "name": "teach",
                    "description": "Pick at random a computer science concept then explain it in purfect way of a cat"
                },
                {
                    "name": "play",
                    "description": "Do whatever you want, you are a cat after all"
                }
            ]
        }
    ]
}

スラッシュコマンドの命名規則の詳細についてはこちらをご覧ください。

4. フォローアップリクエストを登録する

各チャットリクエストの後、VS Codeはフォローアッププロバイダーを呼び出し、ユーザーに表示する推奨されるフォローアップの質問を取得します。ユーザーはその後、フォローアップの質問を選択し、すぐにチャット拡張機能に送信できます。フォローアップの質問は、ユーザーが会話をさらに進めたり、チャット拡張機能のより多くの機能を発見したりするためのインスピレーションを提供できます。

以下のコードスニペットは、チャット拡張機能でフォローアップリクエストを登録する方法を示しています

cat.followupProvider = {
    provideFollowups(result: ICatChatResult, context: vscode.ChatContext, token: vscode.CancellationToken) {
        if (result.metadata.command === 'teach') {
            return [{
                prompt: 'let us play',
                title: vscode.l10n.t('Play with the cat')
            } satisfies vscode.ChatFollowup];
        }
    }
};
ヒント

フォローアップは、簡潔なコマンドだけでなく、質問や指示として記述する必要があります。

5. 参加者検出を実装する

チャット参加者を自然言語で使いやすくするために、参加者検出を実装できます。参加者検出とは、プロンプトで参加者を明示的に言及することなく、ユーザーの質問を適切な参加者に自動的にルーティングする方法です。例えば、ユーザーが「プロジェクトにログインページを追加するにはどうすればよいですか?」と尋ねた場合、その質問はユーザーのプロジェクトに関する質問に答えられるため、@workspace参加者に自動的にルーティングされます。

VS Codeはチャット参加者の説明と例を使用して、チャットプロンプトをどの参加者にルーティングするかを決定します。この情報は、拡張機能のpackage.jsonファイルのdisambiguationプロパティで指定できます。disambiguationプロパティには、それぞれ説明と例を持つ検出カテゴリのリストが含まれています。

プロパティ 説明
カテゴリ 検出カテゴリ。参加者が異なる目的で機能する場合、それぞれにカテゴリを持つことができます。
  • cat
  • workspace_questions
  • web_questions
説明 この参加者に適した質問の種類に関する詳細な説明。
  • ユーザーは特定のコンピュータサイエンスのトピックを非公式な方法で学びたいと考えています。
  • ユーザーはただリラックスして猫が遊ぶのを見たいだけです。
代表的な質問の例のリスト。
  • メタファーを使ってC++のポインターを教えてください
  • 連結リストとは何かを簡単に説明してください
  • レーザーポインターで遊ぶ猫を見せてくれますか?

全体的なチャット参加者、特定のコマンド、またはその両方の組み合わせに対して参加者検出を定義できます。

以下のコードスニペットは、参加者レベルで参加者検出を実装する方法を示しています。

"contributes": {
    "chatParticipants": [
        {
            "id": "chat-sample.cat",
            "fullName": "Cat",
            "name": "cat",
            "description": "Meow! What can I teach you?",

            "disambiguation": [
                {
                    "category": "cat",
                    "description": "The user wants to learn a specific computer science topic in an informal way.",
                    "examples": [
                        "Teach me C++ pointers using metaphors",
                        "Explain to me what is a linked list in a simple way",
                        "Can you explain to me what is a function in programming?"
                    ]
                }
            ]
        }
    ]
}

同様に、commandsプロパティ内の1つ以上の項目にdisambiguationプロパティを追加することで、コマンドレベルで参加者検出を構成することもできます。

拡張機能の参加者検出の精度を向上させるために、以下のガイドラインを適用してください

  • 具体的にする: 他の参加者との競合を避けるため、説明と例は可能な限り具体的にする必要があります。参加者情報とコマンド情報で一般的な用語を使用することは避けてください。
  • 例を使用する: 例は、参加者に適した質問の種類を代表するものである必要があります。同義語やバリエーションを使用して、幅広いユーザーのクエリをカバーしてください。
  • 自然言語を使用する: 説明と例は、ユーザーにその参加者を説明するかのように、自然言語で書く必要があります。
  • 検出をテストする: さまざまな質問例で参加者検出をテストし、組み込みのチャット参加者との競合がないことを確認してください。

参加者検出では、組み込みのチャット参加者が優先されます。例えば、ワークスペースファイル上で動作するチャット参加者は、組み込みの@workspace参加者と競合する可能性があります。

チャットメッセージ履歴を使用する

参加者は現在のチャットセッションのメッセージ履歴にアクセスできます。参加者は、自身が言及されたメッセージのみにアクセスできます。historyアイテムは、ChatRequestTurnまたはChatResponseTurnのいずれかです。例えば、以下のコードスニペットを使用して、現在のチャットセッションでユーザーが参加者に送信した以前のすべてのリクエストを取得します

const previousMessages = context.history.filter(h => h instanceof vscode.ChatRequestTurn);

履歴はプロンプトに自動的に含まれることはなく、言語モデルにメッセージを渡す際に履歴を追加のコンテキストとして追加するかどうかは参加者次第です。

サポートされているチャット応答出力タイプ

チャットリクエストに応答を返すには、ChatRequestHandlerChatResponseStreamパラメータを使用します。

以下のリストは、チャットビューでのチャット応答の出力タイプを示しています。チャット応答は複数の異なる出力タイプを組み合わせることができます。

  • Markdown

    Markdownテキストの断片、単純なテキスト、または画像をレンダリングします。CommonMark仕様の一部である任意のMarkdown構文を使用できます。ChatResponseStream.markdownメソッドを使用してMarkdownテキストを提供します。

    コードスニペットの例

    // Render Markdown text
    stream.markdown('# This is a title \n');
    stream.markdown('This is stylized text that uses _italics_ and **bold**. ');
    stream.markdown('This is a [link](https://vscode.dokyumento.jp).\n\n');
    stream.markdown('![VS Code](https://vscode.dokyumento.jp/assets/favicon.ico)');
    
  • コードブロック

    IntelliSense、コード整形、およびアクティブなエディターにコードを適用するためのインタラクティブなコントロールをサポートするコードブロックをレンダリングします。コードブロックを表示するには、ChatResponseStream.markdownメソッドを使用し、コードブロックのMarkdown構文(バッククォートを使用)を適用します。

    コードスニペットの例

    // Render a code block that enables users to interact with
    stream.markdown('```bash\n');
    stream.markdown('```ls -l\n');
    stream.markdown('```');
    
  • コマンドリンク

    チャット応答にインラインでリンクをレンダリングし、ユーザーが選択してVS Codeコマンドを呼び出せるようにします。コマンドリンクを表示するには、ChatResponseStream.markdownメソッドを使用し、リンクのMarkdown構文[link text](command:commandId)を使用します。ここではURLにコマンドIDを指定します。例えば、以下のリンクはコマンドパレットを開きます: [Command Palette](command:workbench.action.showCommands)

    サービスからMarkdownテキストを読み込む際にコマンドインジェクションから保護するためには、isTrustedプロパティが信頼されたVS CodeコマンドIDのリストに設定されたvscode.MarkdownStringオブジェクトを使用する必要があります。このプロパティは、コマンドリンクが機能するために必要です。isTrustedプロパティが設定されていないか、コマンドがリストにない場合、コマンドリンクは機能しません。

    コードスニペットの例

    // Use command URIs to link to commands from Markdown
    let markdownCommandString: vscode.MarkdownString = new vscode.MarkdownString(
      `[Use cat names](command:${CAT_NAMES_COMMAND_ID})`
    );
    markdownCommandString.isTrusted = { enabledCommands: [CAT_NAMES_COMMAND_ID] };
    
    stream.markdown(markdownCommandString);
    

    コマンドが引数を取る場合、まず引数をJSONエンコードし、次にJSON文字列をURIコンポーネントとしてエンコードする必要があります。その後、エンコードされた引数をクエリ文字列としてコマンドリンクに追加します。

    // Encode the command arguments
    const encodedArgs = encodeURIComponent(JSON.stringify(args));
    
    // Use command URIs with arguments to link to commands from Markdown
    let markdownCommandString: vscode.MarkdownString = new vscode.MarkdownString(
      `[Use cat names](command:${CAT_NAMES_COMMAND_ID}?${encodedArgs})`
    );
    markdownCommandString.isTrusted = { enabledCommands: [CAT_NAMES_COMMAND_ID] };
    
    stream.markdown(markdownCommandString);
    
  • コマンドボタン

    VS Codeコマンドを呼び出すボタンをレンダリングします。このコマンドは、組み込みコマンドまたは拡張機能で定義したコマンドのいずれかです。ChatResponseStream.buttonメソッドを使用し、ボタンテキストとコマンドIDを提供します。

    コードスニペットの例

    // Render a button to trigger a VS Code command
    stream.button({
      command: 'my.command',
      title: vscode.l10n.t('Run my command')
    });
    
  • ファイルツリー

    ユーザーが個々のファイルをプレビューできるファイルツリーコントロールをレンダリングします。例えば、新しいワークスペースの作成を提案する際にワークスペースのプレビューを表示する場合などです。ChatResponseStream.filetreeメソッドを使用し、ファイルツリー要素の配列とファイルのベース場所(フォルダ)を提供します。

    コードスニペットの例

    // Create a file tree instance
    var tree: vscode.ChatResponseFileTree[] = [
      {
        name: 'myworkspace',
        children: [{ name: 'README' }, { name: 'app.js' }, { name: 'package.json' }]
      }
    ];
    
    // Render the file tree control at a base location
    stream.filetree(tree, baseLocation);
    
  • 進捗メッセージ

    長時間実行される操作中に進捗メッセージをレンダリングし、ユーザーに中間的なフィードバックを提供します。例えば、多段階操作の各ステップの完了を報告する場合などです。ChatResponseStream.progressメソッドを使用し、メッセージを提供します。

    コードスニペットの例

    // Render a progress message
    stream.progress('Connecting to the database.');
    
  • リファレンス

    外部URLまたはエディタの場所への参照をリスト参照に追加して、コンテキストとして使用する情報を示します。ChatResponseStream.referenceメソッドを使用し、参照場所を提供します。

    コードスニペットの例

    const fileUri: vscode.Uri = vscode.Uri.file('/path/to/workspace/app.js'); // On Windows, the path should be in the format of 'c:\\path\\to\\workspace\\app.js'
    const fileRange: vscode.Range = new vscode.Range(0, 0, 3, 0);
    const externalUri: vscode.Uri = vscode.Uri.parse('https://vscode.dokyumento.jp');
    
    // Add a reference to an entire file
    stream.reference(fileUri);
    
    // Add a reference to a specific selection within a file
    stream.reference(new vscode.Location(fileUri, fileRange));
    
    // Add a reference to an external URL
    stream.reference(externalUri);
    
  • インライン参照

    URIまたはエディタの場所へのインライン参照を追加します。ChatResponseStream.anchorメソッドを使用し、アンカーの場所とオプションのタイトルを提供します。記号(例えば、クラスや変数)を参照するには、エディタ内の場所を使用します。

    コードスニペットの例

    const symbolLocation: vscode.Uri = vscode.Uri.parse('location-to-a-symbol');
    
    // Render an inline anchor to a symbol in the workspace
    stream.anchor(symbolLocation, 'MySymbol');
    

重要: 画像とリンクは、信頼されたドメインリストに含まれるドメインから送信された場合にのみ利用可能です。VS Codeのリンク保護の詳細についてはこちらをご覧ください。

ツール呼び出しを実装する

ユーザーリクエストに応答するために、チャット拡張機能は言語モデルツールを呼び出すことができます。言語モデルツールツール呼び出しフローについて詳しく学びましょう。

ツール呼び出しは2つの方法で実装できます

  • チャット拡張機能でツールを呼び出すプロセスを簡素化するために、@vscode/chat-extension-utilsライブラリを使用する。
  • ツール呼び出しを自分で実装することで、ツール呼び出しプロセスをより細かく制御できます。例えば、追加の検証を実行したり、LLMに送信する前にツールの応答を特定の方法で処理したりできます。

チャット拡張機能ライブラリでツール呼び出しを実装する

チャット拡張機能でツールを呼び出すプロセスを簡素化するために、@vscode/chat-extension-utilsライブラリを使用できます。

チャット参加者vscode.ChatRequestHandler関数でツール呼び出しを実装します。

  1. 現在のチャットコンテキストに関連するツールを決定します。vscode.lm.toolsを使用して、利用可能なすべてのツールにアクセスできます。

    以下のコードスニペットは、特定のタグを持つツールのみにフィルターをかける方法を示しています。

    const tools =
      request.command === 'all'
        ? vscode.lm.tools
        : vscode.lm.tools.filter(tool => tool.tags.includes('chat-tools-sample'));
    
  2. sendChatParticipantRequestを使用して、リクエストとツール定義をLLMに送信します。

    const libResult = chatUtils.sendChatParticipantRequest(
      request,
      chatContext,
      {
        prompt: 'You are a cat! Answer as a cat.',
        responseStreamOptions: {
          stream,
          references: true,
          responseText: true
        },
        tools
      },
      token
    );
    

    ChatHandlerOptionsオブジェクトには以下のプロパティがあります

    • prompt: (オプション) チャット参加者プロンプトの指示。
    • model: (オプション) リクエストに使用するモデル。指定しない場合、チャットコンテキストからのモデルが使用されます。
    • tools: (オプション) リクエストで考慮するツールのリスト。
    • requestJustification: (オプション) リクエストが行われる理由を説明する文字列。
    • responseStreamOptions: (オプション) sendChatParticipantRequestが応答をVS Codeにストリーミングすることを有効にします。オプションで、参照や応答テキストも有効にできます。
  3. LLMからの結果を返します。これにはエラー詳細またはツール呼び出しメタデータが含まれる場合があります。

    return await libResult.result;
    

このツール呼び出しサンプルの完全なソースコードは、VS Code Extension Samplesリポジトリで入手できます。

自分でツール呼び出しを実装する

より高度なシナリオでは、自分でツール呼び出しを実装することもできます。オプションで、LLMプロンプトを作成するために@vscode/prompt-tsxライブラリを使用できます。自分でツール呼び出しを実装することで、ツール呼び出しプロセスをより細かく制御できます。例えば、追加の検証を実行したり、LLMに送信する前にツールの応答を特定の方法で処理したりできます。

VS Code Extension Samplesリポジトリで、prompt-tsxを使用したツール呼び出しの実装の完全なソースコードを表示します。

成功の測定

Unhelpfulユーザーフィードバックイベントおよび参加者が処理したリクエストの総数に対してテレメトリーロギングを追加することで、参加者の成功を測定することをお勧めします。初期の参加者成功メトリックは、unhelpful_feedback_count / total_requestsとして定義できます。

const logger = vscode.env.createTelemetryLogger({
  // telemetry logging implementation goes here
});

cat.onDidReceiveFeedback((feedback: vscode.ChatResultFeedback) => {
  // Log chat result feedback to be able to compute the success metric of the participant
  logger.logUsage('chatResultFeedback', {
    kind: feedback.kind
  });
});

チャット応答との他のユーザーインタラクションはすべて、肯定的なメトリックとして測定されるべきです(例えば、ユーザーがチャット応答で生成されたボタンを選択した場合)。AIは非決定論的な技術であるため、テレメトリーによる成功の測定は不可欠です。実験を行い、参加者を測定し、反復的に改善して、良好なユーザー体験を確保してください。

ガイドラインと規則

ガイドライン

チャット参加者は、純粋な質疑応答ボットであってはなりません。チャット参加者を構築する際は、創造性を発揮し、既存のVS Code APIを使用してVS Codeに豊富な統合を作成してください。ユーザーはまた、応答内のボタンや、チャットでユーザーを参加者に誘導するメニュー項目など、豊富で便利なインタラクションを好みます。AIがユーザーを助けることができる実生活のシナリオについて考えてみてください。

すべての拡張機能がチャット参加者を提供するのが理にかなっているわけではありません。チャットにあまりにも多くの参加者がいると、ユーザー体験が悪くなる可能性があります。チャット参加者は、言語モデルへの指示を含むプロンプト全体を制御したい場合に最適です。慎重に作成されたCopilotシステムメッセージを再利用し、他の参加者にコンテキストを提供できます。

例えば、言語拡張機能(C++拡張機能など)は、さまざまな方法で貢献できます

  • ユーザーのクエリに言語サービスのインテリジェンスをもたらすツールを提供します。例えば、C++拡張機能は#cppツールをワークスペースのC++状態に解決できます。これにより、Copilot言語モデルは適切なC++コンテキストを得て、C++に関するCopilotの回答の品質を向上させることができます。
  • 言語モデルを使用し、オプションで従来の言語サービス知識と組み合わせて、優れたユーザー体験を提供するスマートアクションを提供します。例えば、C++は、言語モデルを使用して新しいメソッドに適切なデフォルト名を生成する「メソッド抽出」スマートアクションを既に提供しているかもしれません。

チャット拡張機能は、コストのかかる操作を行おうとしている場合、または元に戻せないものを編集または削除しようとしている場合は、明示的にユーザーの同意を求めるべきです。優れたユーザー体験を提供するために、複数のチャット参加者を提供する拡張機能は推奨しません。拡張機能ごとに最大1つのチャット参加者は、UIでうまくスケールするシンプルなモデルです。

チャット参加者の命名規則

プロパティ 説明 命名ガイドライン
id チャット参加者のグローバルに一意な識別子
  • 文字列値
  • 拡張機能名をプレフィックスとして使用し、その後に拡張機能の一意のIDを続けます
  • 例: chat-sample.cat, code-visualizer.code-visualizer-participant
name チャット参加者の名前。ユーザーは@シンボルで参照します
  • 英数字、アンダースコア、ハイフンで構成される文字列値
  • 既存のチャット参加者との一貫性を確保するため、小文字のみを使用することをお勧めします
  • 参加者の目的が、会社名またはその機能を参照することで名前から明らかであることを確認してください
  • 一部の参加者名は予約されています。予約された名前を使用した場合、拡張機能IDを含む完全修飾名が表示されます
  • 例: vscode, terminal, code-visualizer
fullName (オプション) 参加者のフルネーム。参加者からの応答のラベルとして表示されます
  • 文字列値
  • タイトルケースを使用することをお勧めします
  • 参加者には、会社名、ブランド名、またはユーザーフレンドリーな名前を使用してください
  • 例: GitHub Copilot, VS Code, Math Tutor
説明 (オプション) チャット参加者の機能に関する短い説明。チャット入力フィールドまたは参加者リストのプレースホルダーテキストとして表示されます
  • 文字列値
  • 文頭大文字(Sentence case)を使用し、末尾に句読点を付けないことをお勧めします
  • 横スクロールを避けるため、説明は短くしてください
  • 例: VS Codeに関する質問をする, コードのUMLダイアグラムを生成する

プロパティ、チャット応答、チャットユーザーインターフェースなど、ユーザー向け要素でチャット参加者を参照する場合、participantという用語を使用しないことをお勧めします。これはAPIの名前であるためです。例えば、@cat拡張機能は「GitHub Copilot用Cat拡張機能」と呼ばれるかもしれません。

スラッシュコマンドの命名規則

プロパティ 説明 命名ガイドライン
name スラッシュコマンドの名前。ユーザーは/シンボルで参照します
  • 文字列値
  • 既存のスラッシュコマンドとの整合性を保つため、ローワーキャメルケースを使用することをお勧めします
  • コマンドの目的が名前から明らかであることを確認してください
  • 例: fix, explain, runCommand
説明 (オプション) スラッシュコマンドの機能に関する短い説明。チャット入力フィールドまたは参加者とコマンドのリストのプレースホルダーテキストとして表示されます
  • 文字列値
  • 文頭大文字(Sentence case)を使用し、末尾に句読点を付けないことをお勧めします
  • 横スクロールを避けるため、説明は短くしてください
  • 例: VS Codeでコマンドを検索して実行する, 選択されたコードの単体テストを生成する

拡張機能の公開

AI拡張機能を作成したら、Visual Studio Marketplaceに拡張機能を公開できます

  • VS Marketplaceに公開する前に、Microsoft AIツールとプラクティスガイドラインを読むことをお勧めします。これらのガイドラインは、AIテクノロジーの責任ある開発と使用に関するベストプラクティスを提供します。
  • VS Marketplaceに公開することにより、拡張機能はGitHub Copilot拡張機能の許容可能な開発および使用ポリシーに準拠します。
  • 拡張機能の公開で説明されているように、Marketplaceにアップロードしてください。
  • 拡張機能がすでにチャット以外の機能を提供している場合、拡張機能マニフェストでGitHub Copilotへの拡張機能の依存関係を導入しないことをお勧めします。これにより、GitHub Copilotを使用しない拡張機能ユーザーでも、GitHub Copilotをインストールすることなく非チャット機能を使用できます。

GitHub Apps を介した GitHub Copilot の拡張

別の方法として、チャットビューでチャット参加者を提供するGitHub Appを作成することにより、GitHub Copilotを拡張することも可能です。GitHub Appはサービスによって支えられており、github.com、Visual Studio、VS CodeなどのすべてのGitHub Copilotサーフェスで動作します。一方、GitHub AppはVS Code APIへの完全なアクセス権を持ちません。GitHub Appを介したGitHub Copilotの拡張について詳しくは、GitHubドキュメントを参照してください。

言語モデルを使用する

チャット参加者は、幅広い方法で言語モデルを使用できます。一部の参加者は、カスタムプロンプトへの回答を得るためだけに言語モデルを利用します。例えば、サンプルチャット参加者がそうです。他の参加者はより高度で、言語モデルの助けを借りて複数のツールを呼び出す自律エージェントのように振る舞います。そのような高度な参加者の例として、ワークスペースについて知識があり、それに関する質問に答えられる組み込みの@workspaceがあります。内部的には、@workspaceはGitHubの知識グラフと、セマンティック検索、ローカルコードインデックス、VS Codeの言語サービスを組み合わせた複数のツールによって動いています。