言語モデル API
言語モデル API を使用すると、言語モデルを使用し、AI 搭載機能と自然言語処理を Visual Studio Code 拡張機能に統合できます。
言語モデル API は、さまざまな種類の拡張機能で使用できます。この API の一般的な用途は、チャット拡張機能で、言語モデルを使用してユーザーのリクエストを解釈し、回答を提供するのに役立てる場合です。しかし、言語モデル API の使用は、このシナリオに限定されません。言語またはデバッガー拡張機能、あるいはカスタム拡張機能のコマンドまたはタスクの一部として言語モデルを使用することができます。例えば、Rust 拡張機能は、言語モデルを使用してデフォルト名を提供し、名前変更エクスペリエンスを向上させるかもしれません。
言語モデル API を使用するプロセスは、次のステップで構成されます。
- 言語モデルのプロンプトを作成する
- 言語モデルのリクエストを送信する
- 応答を解釈する
以下のセクションでは、これらのステップを拡張機能に実装する方法について詳しく説明します。
まず、チャット拡張機能のサンプルを調べてみてください。
言語モデルのプロンプトを作成する
言語モデルと対話するには、拡張機能はまずプロンプトを作成し、次に言語モデルにリクエストを送信する必要があります。プロンプトを使用して、モデルを使用している大まかなタスクについて言語モデルに指示を提供できます。プロンプトは、ユーザーメッセージが解釈されるコンテキストを定義することもできます。
言語モデル API は、言語モデルのプロンプトを作成する際に、2 種類のメッセージをサポートしています。
- User - 指示とユーザーのリクエストを提供するために使用されます
- Assistant - 以前の言語モデルの応答履歴をプロンプトのコンテキストとして追加するために使用されます
注: 現在、言語モデル 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) はストリーミングベースであり、スムーズなユーザーエクスペリエンスを提供できます。例えば、チャット 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 にアップロードしてください。