言語モデル API
言語モデル API を使用すると、言語モデルを使用し、AI を活用した機能と自然言語処理を Visual Studio Code 拡張機能に統合できます。
言語モデル API は、さまざまな種類の拡張機能で使用できます。この API の一般的な用途は、チャット拡張機能で、言語モデルを使用してユーザーのリクエストを解釈し、回答を提供するのに役立ちます。ただし、言語モデル API の使用はこのシナリオに限定されません。言語モデルを言語またはデバッガー拡張機能、またはカスタム拡張機能のコマンドまたはタスクの一部として使用する場合があります。たとえば、Rust 拡張機能は、言語モデルを使用してデフォルト名を提供し、名前変更エクスペリエンスを向上させる可能性があります。
言語モデル API を使用するプロセスは、以下のステップで構成されます
- 言語モデルプロンプトの作成
- 言語モデルリクエストの送信
- 応答の解釈
以下のセクションでは、拡張機能でこれらのステップを実装する方法について詳しく説明します。
開始するには、チャット拡張機能のサンプルを探索できます。
言語モデルプロンプトの作成
言語モデルと対話するには、拡張機能はまずプロンプトを作成し、次に言語モデルにリクエストを送信する必要があります。プロンプトを使用して、モデルを使用している広範なタスクについて言語モデルに指示を与えることができます。プロンプトは、ユーザーメッセージが解釈されるコンテキストを定義することもできます。
言語モデル API は、言語モデルプロンプトを構築する際に 2 種類のメッセージをサポートしています
- ユーザー - 指示とユーザーのリクエストを提供するために使用されます
- アシスタント - 以前の言語モデル応答の履歴をプロンプトにコンテキストとして追加するために使用されます
注: 現在、言語モデル API はシステムメッセージの使用をサポートしていません。
言語モデルプロンプトを構築するには、2 つのアプローチを使用できます
- LanguageModelChatMessage- 1 つ以上のメッセージを文字列として提供してプロンプトを作成します。言語モデル API を始めたばかりの場合は、このアプローチを使用する場合があります。
- @vscode/prompt-tsx- TSX 構文を使用してプロンプトを宣言します。
言語モデルプロンプトの構成方法をより細かく制御したい場合は、prompt-tsx ライブラリを使用できます。たとえば、このライブラリは、プロンプトの長さを各言語モデルのコンテキストウィンドウサイズに動的に適合させるのに役立ちます。@vscode/prompt-tsx の詳細については、チャット拡張機能のサンプルを探索して開始してください。
プロンプトエンジニアリングの概念について詳しく知るには、OpenAI の優れたプロンプトエンジニアリングガイドラインを読むことをお勧めします。
ヒント: 豊富な VS Code 拡張機能 API を活用して、最も関連性の高いコンテキストを取得し、プロンプトに含めます。たとえば、エディターのアクティブなファイルの内容を含める場合などです。
LanguageModelChatMessage クラスを使用する
言語モデル API は、チャットメッセージを表現および作成するための LanguageModelChatMessage クラスを提供します。LanguageModelChatMessage.User または LanguageModelChatMessage.Assistant メソッドを使用して、それぞれユーザーメッセージまたはアシスタントメッセージを作成できます。
以下の例では、最初のメッセージがプロンプトのコンテキストを提供します
- モデルが返信で使用するペルソナ(この場合は猫)
- モデルが応答を生成する際に従うべきルール(この場合は、猫の比喩を使ってコンピューターサイエンスの概念を面白く説明する)
2 番目のメッセージは、ユーザーからの特定のリクエストまたは指示を提供します。最初のメッセージによって提供されたコンテキストを考慮して、達成すべき特定のタスクを決定します。
const craftedPrompt = [
  vscode.LanguageModelChatMessage.User(
    'You are a cat! Think carefully and step by step like a cat would. Your job is to explain computer science concepts in the funny manner of a cat, using cat metaphors. Always start your response by stating what concept you are explaining. Always include code samples.'
  ),
  vscode.LanguageModelChatMessage.User('I want to understand recursion')
];
言語モデルリクエストの送信
言語モデルのプロンプトを構築したら、まずselectChatModels メソッドを使用して使用する言語モデルを選択します。このメソッドは、指定された条件に一致する言語モデルの配列を返します。チャット参加者を実装している場合は、代わりにチャットリクエストハンドラーの request オブジェクトの一部として渡されるモデルを使用することをお勧めします。これにより、拡張機能がユーザーがチャットモデルドロップダウンで選択したモデルを尊重することが保証されます。次に、sendRequest メソッドを使用して言語モデルにリクエストを送信します。
言語モデルを選択するには、vendor、id、family、または version のプロパティを指定できます。これらのプロパティを使用して、特定のベンダーまたはファミリーのすべてのモデルに広く一致させるか、ID で特定のモデルを 1 つ選択します。これらのプロパティの詳細については、API リファレンスを参照してください。
注: 現在、言語モデルファミリーでは
gpt-4o、gpt-4o-mini、o1、o1-mini、claude-3.5-sonnetがサポートされています。どのモデルを使用すべきか不明な場合は、そのパフォーマンスと品質からgpt-4oをお勧めします。エディターでの直接的な対話には、そのパフォーマンスからgpt-4o-miniをお勧めします。
指定された条件に一致するモデルがない場合、selectChatModels メソッドは空の配列を返します。拡張機能はこのケースを適切に処理する必要があります。
次の例は、ファミリーやバージョンに関係なく、すべての Copilot モデルを選択する方法を示しています。
const models = await vscode.lm.selectChatModels({
  vendor: 'copilot'
});
// No models available
if (models.length === 0) {
  // TODO: handle the case when no models are available
}
重要: Copilot の言語モデルを使用する前に、拡張機能がユーザーからの同意を必要とします。同意は認証ダイアログとして実装されます。そのため、
selectChatModelsは、コマンドなどのユーザーによって開始されたアクションの一部として呼び出す必要があります。
モデルを選択したら、モデルインスタンスでsendRequest メソッドを呼び出して言語モデルにリクエストを送信できます。以前に作成したプロンプトを、追加のオプションとキャンセル トークンとともに渡します。
言語モデル API にリクエストを行うと、リクエストが失敗する場合があります。たとえば、モデルが存在しない、ユーザーが言語モデル API の使用に同意しなかった、またはクォータ制限を超過したなどです。LanguageModelError を使用して、さまざまな種類のエラーを区別します。
次のコードスニペットは、言語モデルリクエストを行う方法を示しています。
try {
  const [model] = await vscode.lm.selectChatModels({ vendor: 'copilot', family: 'gpt-4o' });
  const request = model.sendRequest(craftedPrompt, {}, token);
} catch (err) {
  // Making the chat request might fail because
  // - model does not exist
  // - user consent not given
  // - quota limits were exceeded
  if (err instanceof vscode.LanguageModelError) {
    console.log(err.message, err.code, err.cause);
    if (err.cause instanceof Error && err.cause.message.includes('off_topic')) {
      stream.markdown(
        vscode.l10n.t("I'm sorry, I can only explain computer science concepts.")
      );
    }
  } else {
    // add other error handling logic
    throw err;
  }
}
応答の解釈
リクエストを送信したら、言語モデル API からの応答を処理する必要があります。使用シナリオに応じて、応答を直接ユーザーに渡すか、応答を解釈して追加のロジックを実行できます。
言語モデル API からの応答(LanguageModelChatResponse)はストリーミングベースであり、スムーズなユーザーエクスペリエンスを提供できます。たとえば、Chat API と組み合わせて API を使用する場合に、結果と進行状況を継続的に報告することで実現できます。
ストリーミング応答の処理中に、ネットワーク接続の問題などのエラーが発生する可能性があります。これらのエラーを処理するために、コードに適切なエラー処理を追加してください。
次のコードスニペットは、拡張機能がコマンドを登録する方法を示しています。このコマンドは、言語モデルを使用して、アクティブなエディター内のすべての変数名を面白い猫の名前に変更します。拡張機能がスムーズなユーザーエクスペリエンスのためにコードをエディターにストリーミングすることに注目してください。
vscode.commands.registerTextEditorCommand(
  'cat.namesInEditor',
  async (textEditor: vscode.TextEditor) => {
    // Replace all variables in active editor with cat names and words
    const [model] = await vscode.lm.selectChatModels({
      vendor: 'copilot',
      family: 'gpt-4o'
    });
    let chatResponse: vscode.LanguageModelChatResponse | undefined;
    const text = textEditor.document.getText();
    const messages = [
      vscode.LanguageModelChatMessage
        .User(`You are a cat! Think carefully and step by step like a cat would.
        Your job is to replace all variable names in the following code with funny cat variable names. Be creative. IMPORTANT respond just with code. Do not use markdown!`),
      vscode.LanguageModelChatMessage.User(text)
    ];
    try {
      chatResponse = await model.sendRequest(
        messages,
        {},
        new vscode.CancellationTokenSource().token
      );
    } catch (err) {
      if (err instanceof vscode.LanguageModelError) {
        console.log(err.message, err.code, err.cause);
      } else {
        throw err;
      }
      return;
    }
    // Clear the editor content before inserting new content
    await textEditor.edit(edit => {
      const start = new vscode.Position(0, 0);
      const end = new vscode.Position(
        textEditor.document.lineCount - 1,
        textEditor.document.lineAt(textEditor.document.lineCount - 1).text.length
      );
      edit.delete(new vscode.Range(start, end));
    });
    try {
      // Stream the code into the editor as it is coming in from the Language Model
      for await (const fragment of chatResponse.text) {
        await textEditor.edit(edit => {
          const lastLine = textEditor.document.lineAt(textEditor.document.lineCount - 1);
          const position = new vscode.Position(lastLine.lineNumber, lastLine.text.length);
          edit.insert(position, fragment);
        });
      }
    } catch (err) {
      // async response stream may fail, e.g network interruption or server side error
      await textEditor.edit(edit => {
        const lastLine = textEditor.document.lineAt(textEditor.document.lineCount - 1);
        const position = new vscode.Position(lastLine.lineNumber, lastLine.text.length);
        edit.insert(position, (<Error>err).message);
      });
    }
  }
);
考慮事項
モデルの可用性
特定のモデルが永久にサポートされるとは限りません。拡張機能で言語モデルを参照するときは、その言語モデルにリクエストを送信する際に「防御的な」アプローチを取るようにしてください。これは、特定のモデルにアクセスできないケースを適切に処理する必要があることを意味します。
適切なモデルの選択
拡張機能の作成者は、自分の拡張機能に最も適切なモデルを選択できます。そのパフォーマンスと品質から gpt-4o を使用することをお勧めします。利用可能なモデルの完全なリストを取得するには、次のコードスニペットを使用できます。
const allModels = await vscode.lm.selectChatModels(MODEL_SELECTOR);
推奨される GPT-4o モデルには 64K トークンの制限があります。selectChatModels 呼び出しから返されるモデルオブジェクトには、トークン制限を示す maxInputTokens 属性があります。これらの制限は、拡張機能が言語モデルをどのように使用しているかについてより詳しくわかると、拡張されます。
レート制限
拡張機能は、言語モデルを責任を持って使用し、レート制限に注意する必要があります。VS Code は、拡張機能が言語モデルをどのように使用しているか、各拡張機能が送信しているリクエストの数、それがそれぞれのクォータにどのように影響するかについて、ユーザーに対して透過的です。
拡張機能は、レート制限のため、統合テストに言語モデル API を使用すべきではありません。内部的には、VS Code はシミュレーションテストに専用の非プロダクション言語モデルを使用しており、現在、拡張機能向けのスケーラブルな言語モデルテストソリューションを提供する方法を検討しています。
拡張機能のテスト
言語モデル API が提供する応答は非決定論的であり、これは同一のリクエストに対して異なる応答が得られる可能性があることを意味します。この動作は、拡張機能のテストを困難にする可能性があります。
プロンプトの構築と言語モデル応答の解釈に関する拡張機能の部分は決定論的であり、実際の言語モデルを使用せずに単体テストが可能です。ただし、言語モデル自体との対話や応答の取得は非決定論的であり、容易にテストすることはできません。テスト可能な特定の部分を単体テストできるように、拡張機能コードをモジュール式に設計することを検討してください。
拡張機能の公開
AI 拡張機能を作成したら、Visual Studio Marketplace に拡張機能を公開できます。
- VS Marketplace に公開する前に、Microsoft AI ツールとプラクティスガイドラインを読むことをお勧めします。これらのガイドラインは、AI テクノロジーの責任ある開発と使用に関するベストプラクティスを提供します。
- VS Marketplace に公開することで、拡張機能はGitHub Copilot 拡張機能の許容される開発および使用ポリシーに準拠していることになります。
- 拡張機能が言語モデル API の使用以外の機能を提供している場合、拡張機能マニフェストで GitHub Copilot への拡張機能の依存関係を導入しないことをお勧めします。これにより、GitHub Copilot を使用しない拡張機能ユーザーは、GitHub Copilot をインストールすることなく非言語モデル機能を使用できます。このケースでは、言語モデルにアクセスする際に適切なエラー処理を行うようにしてください。
- 拡張機能の公開で説明されているように、Marketplace にアップロードします。