🚀 VS Code で で入手しましょう!

チャット拡張機能

Visual Studio Code の Copilot Chat アーキテクチャにより、拡張機能の作成者はGitHub Copilot Chat エクスペリエンスと統合できます。チャット拡張機能は、チャット参加者をコントリビューションすることにより、Chat 拡張機能 API を使用する VS Code 拡張機能です。

チャット参加者は、特定のドメイン内のユーザーのクエリに回答できるドメインエキスパートです。参加者は、ユーザーのクエリを処理するためにさまざまなアプローチを使用できます。

  • AI を使用してリクエストを解釈し、応答を生成します。たとえば、言語モデル API を使用するなど。
  • ユーザーリクエストをバックエンドサービスに転送します。
  • 手続き型ロジックとローカルリソースを使用します。

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

ユーザーがチャットプロンプトで @participant を明示的に言及すると、そのプロンプトは、その特定のチャット参加者をコントリビューションした拡張機能に転送されます。次に、参加者は ResponseStream を使用してリクエストに応答します。スムーズなユーザーエクスペリエンスを提供するために、Chat API はストリーミングベースです。チャット応答には、Markdown、ファイルツリー、コマンドボタンなど、豊富なコンテンツを含めることができます。サポートされている応答出力タイプの詳細をご覧ください。

ユーザーが会話をさらに進めるのを支援するために、参加者は各応答に対してフォローアップを提供できます。フォローアップの質問は、チャットユーザーインターフェイスに表示される提案であり、チャット拡張機能の機能についてユーザーにインスピレーションを与える可能性があります。

参加者はコマンドをコントリビューションすることもできます。これは、一般的なユーザーの意図に対する省略記法であり、/ 記号で示されます。拡張機能は、コマンドを使用して、言語モデルに適切にプロンプトを出すことができます。たとえば、/explain は、言語モデルがコードを説明する必要があるという意図に対応する @workspace 参加者のコマンドです。

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 ドキュメントをご覧ください。

チャットユーザーエクスペリエンスの構成要素

次のスクリーンショットは、サンプル拡張機能の 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 プロパティによって提供されるプレースホルダーテキストを含むチャット入力フィールド

チャット拡張機能の開発

チャット拡張機能は、チャットビューにチャット参加者をコントリビューションする拡張機能です。

チャット拡張機能を実装するために必要な最小限の機能は次のとおりです。

  • チャット参加者を登録して、ユーザーが VS Code チャットビューで @ 記号を使用して呼び出せるようにします。
  • ユーザーの質問を解釈し、チャットビューに応答を返すリクエストハンドラーを定義します。

オプション機能を使用して、チャット拡張機能の機能をさらに拡張できます。

  • チャットコマンドを登録して、一般的な質問に対する省略記法をユーザーに提供します。
  • ユーザーが会話を継続するのに役立つ、提案されたフォローアップの質問を定義します。

チャット拡張機能の開発の出発点として、チャット拡張機能のサンプルを参照できます。このサンプルは、コンピューターサイエンスのトピックを猫の比喩を使用して説明できる単純な猫の家庭教師を実装しています。

Diagram showing how extension can contribute to chat

チャット拡張機能を登録する

チャット拡張機能を作成する最初のステップは、一意の idname、および description を指定して、package.json に登録することです。

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

ユーザーは、@ 記号と指定した name を使用して、チャットビューでチャット参加者を参照できます。fullName は、参加者からの応答のタイトル領域に表示されます。description は、チャット入力フィールドのプレースホルダーテキストとして使用されます。

isSticky プロパティは、チャット参加者が永続的かどうかを制御します。つまり、ユーザーが参加者との対話を開始した後、チャット入力フィールドに自動的に参加者名が先頭に追加されます。

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

一部の参加者名は予約されており、予約された名前を使用した場合、VS Code は参加者の完全修飾名(拡張機能 ID を含む)を表示します。

VS Code が適切なタイミングで拡張機能をアクティブ化できるように、package.json での参加者とコマンドの事前登録が必要です。必要になる前にアクティブ化されることはありません。

登録後、拡張機能が行う必要があるのは、vscode.chat.createChatParticipant を使用して参加者を作成することだけです。参加者を作成するときは、package.json で定義した ID とリクエストハンドラーを指定する必要があります。

次のコードスニペットは、@cat チャット参加者を作成する方法を示しています(package.json に登録した後)。

export function activate(context: vscode.ExtensionContext) {
  // Register the chat participant and its request handler
  const cat = vscode.chat.createChatParticipant('chat-sample.cat', handler);

  // Optionally, set some properties for @cat
  cat.iconPath = vscode.Uri.joinPath(context.extensionUri, 'cat.jpeg');

  // Add the chat request handler here
}

チャット参加者を登録して作成したら、ユーザーのリクエストを処理するためのリクエストハンドラーを実装する必要があります。

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

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

  1. リクエストハンドラーを定義する
  2. ユーザーのリクエストの意図を特定する
  3. ユーザーの質問に答えるためのロジックを実行する
  4. ユーザーに応答を返す

リクエストハンドラーを定義する

拡張機能の activate 関数内でリクエストハンドラー (vscode.ChatRequestHandler) を定義します。

次のコードスニペットは、リクエストハンドラーを定義する方法を示しています。

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
};

リクエストの意図を特定する

ユーザーのリクエストの意図を特定するには、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
  }
};

リクエストを処理する

次に、ユーザーリクエストを処理するための実際のロジックを実装する必要があります。多くの場合、チャット拡張機能は request.model 言語モデルインスタンスを使用してリクエストを処理します。この場合、ユーザーの意図に合わせて言語モデルプロンプトを調整する場合があります。または、バックエンドサービスを呼び出すか、従来の方法のプログラミングロジックを使用するか、またはこれらのすべてのオプションを組み合わせて拡張機能ロジックを実装できます。たとえば、Web 検索を呼び出して追加情報を収集し、それを言語モデルへのコンテキストとして提供できます。

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

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

チャット応答を返す

リクエストを処理したら、チャットビューでユーザーに応答を返す必要があります。チャット拡張機能は、ストリーミングを使用してユーザーのクエリに応答できます。応答には、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 Chat API はストリーミングベースであり、ストリーミング言語モデル API と互換性があります。これにより、拡張機能はスムーズなユーザーエクスペリエンスを実現するために、進捗状況と結果を継続的に報告できます。言語モデル API を使用する方法をご覧ください。

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

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

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

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

コマンドを登録する

チャット参加者は、拡張機能によって提供される特定の機能へのショートカットであるコマンドをコントリビューションできます。ユーザーは、/explain などの / 構文を使用してチャットでコマンドを参照できます。

質問に答えるときのタスクの 1 つは、ユーザーの意図を特定することです。たとえば、VS Code は 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"
                }
            ]
        }
    ]
}

スラッシュコマンドの命名規則の詳細をご覧ください。

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

各チャットリクエストの後、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];
        }
    }
};
ヒント

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

参加者の検出を実装する

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

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

プロパティ 説明
カテゴリ 検出カテゴリ。参加者がさまざまな目的を果たす場合、目的ごとにカテゴリを設定できます。
  • ワークスペースの質問
  • Web の質問
説明 この参加者に適した質問の種類に関する詳細な説明。
  • ユーザーは、特定のコンピューターサイエンスのトピックを非公式な方法で学習したいと考えています。
  • ユーザーはただリラックスして猫が遊ぶのを見たいだけです。
代表的な質問の例のリスト。
  • 比喩を使って 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 参加者と競合する可能性があります。

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

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

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

  • 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 構文 [リンクテキスト](command:commandId) を使用します。URL にコマンド ID を指定します。たとえば、次のリンクはコマンドパレットを開きます。[コマンドパレット](command:workbench.action.showCommands)

    サービスから Markdown テキストをロードするときのコマンドインジェクションから保護するには、vscode.MarkdownString オブジェクトを、isTrusted プロパティを信頼できる VS Code コマンド ID のリストに設定して使用する必要があります。このプロパティは、コマンドリンクを機能させるために必要です。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.md' }, { 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 拡張機能サンプルリポジトリで入手できます。

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

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

prompt-tsx を使用してツール呼び出しを実装するための完全なソースコードを、VS Code 拡張機能サンプルリポジトリでご覧ください。

成功の測定

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 が非決定論的なテクノロジーであるため、非常に重要です。実験を実行し、測定して、ユーザーエクスペリエンスを向上させるために参加者を反復的に改善します。

命名の制限と規則

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

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

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

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

プロパティ 説明 命名ガイドライン
name / 記号を介してユーザーが参照するスラッシュコマンドの名前
  • 文字列値
  • 既存のスラッシュコマンドと一致させるために、ローワーキャメルケースを使用することをお勧めします。
  • コマンドの目的が名前から明らかになるようにします。
  • 例: fixexplainrunCommand
説明 (オプション) スラッシュコマンドの簡単な説明。チャット入力フィールドまたは参加者とコマンドのリストにプレースホルダーテキストとして表示されます。
  • 文字列値
  • 文末に句読点を付けずに、文の先頭を大文字にすることをお勧めします。
  • 水平スクロールを避けるために、説明を短くしてください。
  • 例: VS Code でコマンドを検索して実行する選択したコードのユニットテストを生成する

ガイドライン

チャット参加者は、純粋に質問応答ボットであるべきではありません。チャット参加者を構築するときは、既存の VS Code API を創造的に使用して、VS Code で豊富な統合を作成してください。ユーザーは、応答のボタンや、ユーザーをチャットの参加者に誘導するメニュー項目など、豊富で便利なインタラクションも大好きです。AI がユーザーを支援できる現実のシナリオについて考えてみましょう。

すべての拡張機能がチャット参加者をコントリビューションすることは意味がありません。チャットに参加者が多すぎると、ユーザーエクスペリエンスが悪化する可能性があります。チャット参加者は、言語モデルへの指示を含む、プロンプト全体を制御したい場合に最適です。慎重に作成された Copilot システムメッセージを再利用し、他の参加者にコンテキストをコントリビューションできます。

たとえば、言語拡張機能(C++ 拡張機能など)は、他のさまざまな方法でコントリビューションできます。

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

チャット拡張機能は、コストのかかる操作を実行しようとしている場合、または元に戻せないものを編集または削除しようとしている場合は、ユーザーの同意を明示的に求める必要があります。優れたユーザーエクスペリエンスを実現するために、拡張機能が複数のチャット参加者をコントリビューションすることは推奨しません。拡張機能あたり最大 1 つのチャット参加者は、UI でうまくスケールするシンプルなモデルです。

拡張機能の公開

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

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