語言模型聊天提供者 API

語言模型聊天提供者 (Language Model Chat Provider) API 讓您能夠將自己的語言模型貢獻給 Visual Studio Code 中的聊天功能。

注意

如果您是 Copilot Business 或 Enterprise 的使用者,您的管理員可以在 GitHub.com 的 Copilot 政策設定中,針對透過此 API 提供的模型停用「自備語言模型金鑰」(Bring Your Own Language Model Key) 政策。

總覽

LanguageModelChatProvider 介面遵循「一對多」的關係(一個提供者對應多個模型),讓提供者能夠發布多個模型。每個提供者負責:

  • 探索並準備可用的語言模型
  • 處理其模型的聊天請求
  • 提供 Token 計算功能

語言模型資訊

每個語言模型都必須透過 LanguageModelChatInformation 介面提供詮釋資料 (metadata)。provideLanguageModelChatInformation 方法會回傳這些物件的陣列,以通知 VS Code 有哪些可用模型。

interface LanguageModelChatInformation {
  readonly id: string; // Unique identifier for the model - unique within the provider
  readonly name: string; // Human-readable name of the language model - shown in the model picker
  readonly family: string; // Model family name
  readonly version: string; // Version string
  readonly maxInputTokens: number; // Maximum number of tokens the model can accept as input
  readonly maxOutputTokens: number; // Maximum number of tokens the model is capable of producing
  readonly tooltip?: string; // Optional tooltip text when hovering the model in the UI
  readonly detail?: string; // Human-readable text that is rendered alongside the model
  readonly capabilities: {
    readonly imageInput?: boolean; // Supports image inputs
    readonly toolCalling?: boolean | number; // Supports tool calling
  };
}

註冊提供者

  1. 第一步是在您的 package.json 中的 contributes.languageModelChatProviders 區段註冊提供者。請提供唯一的 vendor ID 和 displayName

    {
      "contributes": {
        "languageModelChatProviders": [
          {
            "vendor": "my-provider",
            "displayName": "My Provider"
          }
        ]
      }
    }
    
  2. 接下來,在您的擴充功能啟動函式中,使用 lm.registerLanguageModelChatProvider 方法註冊您的語言模型提供者。

    提供您在 package.json 中使用的提供者 ID 以及您的提供者類別實例

    import * as vscode from 'vscode';
    import { SampleChatModelProvider } from './provider';
    
    export function activate(_: vscode.ExtensionContext) {
      vscode.lm.registerLanguageModelChatProvider('my-provider', new SampleChatModelProvider());
    }
    
  3. 您可以選擇在 package.json 中提供 contributes.languageModelChatProviders.managementCommand,以允許使用者管理語言模型提供者。

    managementCommand 屬性的值必須是定義在 package.jsoncontributes.commands 區段的指令。在您的擴充功能中,註冊該指令 (vscode.commands.registerCommand) 並實作管理提供者的邏輯,例如設定 API 金鑰或其他設定。

    {
      "contributes": {
        "languageModelChatProviders": [
          {
            "vendor": "my-provider",
            "displayName": "My Provider",
            "managementCommand": "my-provider.manage"
          }
        ],
        "commands": [
          {
            "command": "my-provider.manage",
            "title": "Manage My Provider"
          }
        ]
      }
    }
    

實作提供者

語言提供者必須實作 LanguageModelChatProvider 介面,該介面具有三個主要方法:

  • provideLanguageModelChatInformation:回傳可用模型列表
  • provideLanguageModelChatResponse:處理聊天請求並串流回傳回應
  • provideTokenCount:實作 Token 計算功能

準備語言模型資訊

VS Code 會呼叫 provideLanguageModelChatInformation 方法來探索可用模型,並回傳 LanguageModelChatInformation 物件列表。

使用 options.silent 參數來控制是否提示使用者輸入憑證或額外設定

async provideLanguageModelChatInformation(
    options: { silent: boolean },
    token: CancellationToken
): Promise<LanguageModelChatInformation[]> {
    if (options.silent) {
        return []; // Don't prompt user in silent mode
    } else {
        await this.promptForApiKey(); // Prompt user for credentials
    }

    // Fetch available models from your service
    const models = await this.fetchAvailableModels();

    // Map your models to LanguageModelChatInformation format
    return models.map(model => ({
        id: model.id,
        name: model.displayName,
        family: model.family,
        version: '1.0.0',
        maxInputTokens: model.contextWindow - model.maxOutput,
        maxOutputTokens: model.maxOutput,
        capabilities: {
            imageInput: model.supportsImages,
            toolCalling: model.supportsTools
        }
    }));
}

處理聊天請求

provideLanguageModelChatResponse 方法會處理實際的聊天請求。提供者會以 LanguageModelChatRequestMessage 格式接收訊息陣列,您可以選擇將其轉換為語言模型 API 所需的格式(請參閱訊息格式與轉換)。

使用 progress 參數來串流回應片段。回應可包含文字部分、工具呼叫及工具結果(請參閱回應部分)。

async provideLanguageModelChatResponse(
    model: LanguageModelChatInformation,
    messages: readonly LanguageModelChatRequestMessage[],
    options: ProvideLanguageModelChatResponseOptions,
    progress: Progress<LanguageModelResponsePart>,
    token: CancellationToken
): Promise<void> {

    // TODO: Implement message conversion, processing, and response streaming

    // Optionally, differentiate behavior based on model ID
    if (model.id === "my-model-a") {
        progress.report(new LanguageModelTextPart("This is my A response."));
    } else {
        progress.report(new LanguageModelTextPart("Unknown model."));
    }
}

提供 Token 計算

provideTokenCount 方法負責估算給定文字輸入中的 Token 數量

async provideTokenCount(
    model: LanguageModelChatInformation,
    text: string | LanguageModelChatRequestMessage,
    token: CancellationToken
): Promise<number> {
    // TODO: Implement token counting for your models

    // Example estimation for strings
    return Math.ceil(text.toString().length / 4);
}

訊息格式與轉換

您的提供者會以 LanguageModelChatRequestMessage 格式接收訊息,通常您需要將其轉換為您服務的 API 格式。訊息內容可以包含文字部分、工具呼叫和工具結果的混合。

interface LanguageModelChatRequestMessage {
  readonly role: LanguageModelChatMessageRole;
  readonly content: ReadonlyArray<LanguageModelInputPart | unknown>;
  readonly name: string | undefined;
}

必要時,請針對您的語言模型 API 適當地轉換這些訊息

private convertMessages(messages: readonly LanguageModelChatRequestMessage[]) {
    return messages.map(msg => ({
        role: msg.role === vscode.LanguageModelChatMessageRole.User ? 'user' : 'assistant',
        content: msg.content
            .filter(part => part instanceof vscode.LanguageModelTextPart)
            .map(part => (part as vscode.LanguageModelTextPart).value)
            .join('')
    }));
}

回應部分

您的提供者可以透過進度回呼 (progress callback) 經由 LanguageModelResponsePart 類型報告不同類型的回應部分,其類型可以是:

  • LanguageModelTextPart - 文字內容
  • LanguageModelToolCallPart - 工具/函式呼叫
  • LanguageModelToolResultPart - 工具結果內容

入門指南

您可以從一個基礎範例專案開始著手。

© . This site is unofficial and not affiliated with Microsoft.