言語モデル 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
)はストリーミングベースであり、スムーズなユーザーエクスペリエンスを提供できます。たとえば、チャット 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 をインストールすることなく非言語モデル機能を使用できるようになります。この場合、言語モデルにアクセスする際には適切なエラー処理を行ってください。
- 拡張機能の公開で説明されているように、マーケットプレイスにアップロードします。