現已釋出!閱讀關於 11 月新增功能和修復的內容。

語言模型 API

語言模型 API 使您能夠使用語言模型,並將 AI 驅動的功能和自然語言處理整合到您的 Visual Studio Code 擴充套件中。

您可以在不同型別的擴充套件中使用語言模型 API。此 API 的典型用途是聊天擴充套件,您可以在其中使用語言模型來解釋使用者請求並幫助提供答案。但是,語言模型 API 的使用不限於此場景。您可以在語言偵錯程式擴充套件中使用語言模型,或者作為自定義擴充套件中的命令任務的一部分。例如,Rust 擴充套件可能會使用語言模型提供預設名稱來改進其重新命名體驗。

使用語言模型 API 的過程包括以下步驟:

  1. 構建語言模型提示
  2. 傳送語言模型請求
  3. 解釋響應

以下部分將提供更多關於如何在擴充套件中實現這些步驟的詳細資訊。

要開始使用,您可以探索聊天擴充套件示例

構建語言模型提示

要與語言模型進行互動,擴充套件首先應構建其提示,然後向語言模型傳送請求。您可以使用提示向語言模型提供有關您正在使用該模型的廣泛任務的指令。提示還可以定義解釋使用者訊息的上下文。

語言模型 API 在構建語言模型提示時支援兩種型別的訊息:

  • 使用者 - 用於提供指令和使用者的請求
  • 助手 - 用於將先前語言模型響應的歷史記錄作為上下文新增到提示中

注意:目前,語言模型 API 不支援使用系統訊息。

您可以使用兩種方法來構建語言模型提示:

  • LanguageModelChatMessage - 透過提供一個或多個字串訊息來建立提示。如果您剛開始使用語言模型 API,可以使用此方法。
  • @vscode/prompt-tsx - 使用 TSX 語法宣告提示。

如果您希望更精確地控制語言模型提示的組成方式,可以使用 prompt-tsx 庫。例如,該庫可以幫助動態調整提示的長度以適應每個語言模型的上下文視窗大小。瞭解更多關於@vscode/prompt-tsx的資訊,或探索聊天擴充套件示例以開始使用。

要了解更多關於提示工程的概念,我們建議閱讀 OpenAI 出色的提示工程指南

提示:充分利用豐富的 VS Code 擴充套件 API,獲取最相關的上下文並將其包含在提示中。例如,包含編輯器中活動檔案的內容。

使用 LanguageModelChatMessage

語言模型 API 提供 LanguageModelChatMessage 類來表示和建立聊天訊息。您可以使用 LanguageModelChatMessage.UserLanguageModelChatMessage.Assistant 方法分別建立使用者或助手訊息。

在以下示例中,第一條訊息為提示提供了上下文:

  • 模型在其回覆中使用的角色(在此示例中為貓)
  • 模型在生成響應時應遵循的規則(在此示例中,以搞笑的方式解釋計算機科學概念,使用貓的隱喻)

第二條訊息然後提供來自使用者的特定請求或指令。它確定要完成的特定任務,給定第一條訊息提供的上下文。

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 方法將請求傳送到語言模型。

要選擇語言模型,您可以指定以下屬性:vendoridfamilyversion。使用這些屬性來廣泛匹配給定供應商或系列的所有模型,或透過其 ID 選擇一個特定模型。在API 參考中瞭解有關這些屬性的更多資訊。

注意:目前,語言模型系列支援 gpt-4ogpt-4o-minio1o1-miniclaude-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 個 token 的限制。selectChatModels 呼叫返回的模型物件有一個 maxInputTokens 屬性,顯示了 token 限制。隨著我們對擴充套件如何使用語言模型的瞭解增多,這些限制將得到擴充套件。

速率限制

擴充套件應負責任地使用語言模型,並注意速率限制。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。
© . This site is unofficial and not affiliated with Microsoft.