Skip to main content

БЁК (принеси свой ключ)

BYOK позволяет использовать Copilot SDK с вашими собственными API-ключами от поставщиков моделей, обходя аутентификацию GitHub Copilot. Это полезно для корпоративных развертываний, хостинга кастомных моделей или когда вам нужен прямой биллинг с вашим поставщиком модели.

Поддерживаемые поставщики

ProviderЗначение типаNotes
OpenAI"openai"API OpenAI и совместимые с OpenAI конечные точки
Azure OpenAI / Azure AI Foundry"azure"Azure-hosted models
Anthropic"anthropic"Модели Claude
Ollama"openai"Локальные модели через совместимый с OpenAI API
Microsoft Foundry Local"openai"Запускайте модели ИИ локально на вашем устройстве через совместимый с OpenAI API
Другие совместимые с OpenAI"openai"vLLM, LiteLLM и так далее.

Быстрый старт: Azure AI Foundry

Azure AI Foundry (ранее Azure OpenAI) является распространённой целью развертывания BYOK для предприятий. Ниже приведен полный пример.

Python
import asyncio
import os
from copilot import CopilotClient
from copilot.session import PermissionHandler

FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/"
# Set FOUNDRY_API_KEY environment variable

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5.2-codex", provider={
        "type": "openai",
        "base_url": FOUNDRY_MODEL_URL,
        "wire_api": "responses",  # Use "completions" for older models
        "api_key": os.environ["FOUNDRY_API_KEY"],
    })

    done = asyncio.Event()

    def on_event(event):
        if event.type.value == "assistant.message":
            print(event.data.content)
        elif event.type.value == "session.idle":
            done.set()

    session.on(on_event)
    await session.send("What is 2+2?")
    await done.wait()

    await session.disconnect()
    await client.stop()

asyncio.run(main())
TypeScript
import { CopilotClient } from "@github/copilot-sdk";

const FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-5.2-codex",  // Your deployment name
    provider: {
        type: "openai",
        baseUrl: FOUNDRY_MODEL_URL,
        wireApi: "responses",  // Use "completions" for older models
        apiKey: process.env.FOUNDRY_API_KEY,
    },
});

session.on("assistant.message", (event) => {
    console.log(event.data.content);
});

await session.sendAndWait({ prompt: "What is 2+2?" });
await client.stop();
Go
package main

import (
    "context"
    "fmt"
    "os"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        panic(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model: "gpt-5.2-codex",  // Your deployment name
        Provider: &copilot.ProviderConfig{
            Type:    "openai",
            BaseURL: "https://your-resource.openai.azure.com/openai/v1/",
            WireAPI: "responses",  // Use "completions" for older models
            APIKey:  os.Getenv("FOUNDRY_API_KEY"),
        },
    })
    if err != nil {
        panic(err)
    }

    response, err := session.SendAndWait(ctx, copilot.MessageOptions{
        Prompt: "What is 2+2?",
    })
    if err != nil {
        panic(err)
    }

    if d, ok := response.Data.(*copilot.AssistantMessageData); ok {
        fmt.Println(d.Content)
    }
}
.NET
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5.2-codex",  // Your deployment name
    Provider = new ProviderConfig
    {
        Type = "openai",
        BaseUrl = "https://your-resource.openai.azure.com/openai/v1/",
        WireApi = "responses",  // Use "completions" for older models
        ApiKey = Environment.GetEnvironmentVariable("FOUNDRY_API_KEY"),
    },
});

var response = await session.SendAndWaitAsync(new MessageOptions
{
    Prompt = "What is 2+2?",
});
Console.WriteLine(response?.Data.Content);
Java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient();
client.start().get();

var session = client.createSession(new SessionConfig()
    .setModel("gpt-5.2-codex")  // Your deployment name
    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    .setProvider(new ProviderConfig()
        .setType("openai")
        .setBaseUrl("https://your-resource.openai.azure.com/openai/v1/")
        .setWireApi("responses")  // Use "completions" for older models
        .setApiKey(System.getenv("FOUNDRY_API_KEY")))
).get();

var response = session.sendAndWait(new MessageOptions()
    .setPrompt("What is 2+2?")).get();
System.out.println(response.getData().content());

client.stop().get();

Ссылка конфигурации провайдера

Поля ProviderConfig

ПолеТипDescription
type
"openai"
|
"azure"
|
"anthropic"
Тип провайдера (по умолчанию: "openai")
baseUrl / base_urlstring
Обязательно. URL конечной точки API
apiKey / api_keystringКлюч API (опционально для местных провайдеров, таких как Ollama)
bearerToken / bearer_tokenstringАутентификация токена носителя (имеет приоритет над apiKey)
wireApi / wire_api
"completions"
|
"responses"
Выберите "completions" для широкой совместимости моделей (API Chat Completions); выберите "responses" для многоходного управления состоянием, промежуточного расположения имён инструментов и поддержки рассуждения (API Responses). Anthropic всегда используют API Messages независимо от этой настройки.
azure.apiVersion / azure.api_versionstringAzure версия API (по умолчанию: "2024-10-21")

Формат API провода

Настройка wireApi определяет, какой формат API OpenAI использовать:

  • "completions" (по умолчанию) — API завершения чата (/chat/completions) для широкой совместимости моделей.
  • "responses" - API Responses для многоходного управления состоянием, промежуточности имён инструментов и поддержки рассуждения.

Anthropic всегда используют API Anthropic Messages независимо от этой настройки.

Заметки, специфичные для типа

OpenAI (type: "openai")

  • Работает с API OpenAI и любыми конечными точками, совместимыми с OpenAI
  • baseUrl должно включать полный путь (например, https://api.openai.com/v1)

Azure (type: "azure")

  • Использование для нативных Azure OpenAI конечных точек
  • baseUrl Должен быть только хост (например, https://my-resource.openai.azure.com)
  • НЕ включайте /openai/v1 в URL — SDK занимается строительством пути

Антропический (type: "anthropic")

  • Для прямого доступа к Anthropic API
  • Использует специфичный для Claude формат API

Примеры конфигураций

OpenAI Direct

provider: {
    type: "openai",
    baseUrl: "https://api.openai.com/v1",
    apiKey: process.env.OPENAI_API_KEY,
}

Azure OpenAI (native Azure endpoint)

Использование type: "azure" для конечных точек по адресу *.openai.azure.com:

provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",  // Just the host
    apiKey: process.env.AZURE_OPENAI_KEY,
    azure: {
        apiVersion: "2024-10-21",
    },
}

Azure AI Foundry (OpenAI-совместимая конечная точка)

Для развертывания Azure AI Foundry с /openai/v1/ конечными точками используйте type: "openai":

provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
    apiKey: process.env.FOUNDRY_API_KEY,
    wireApi: "responses",  // For GPT-5 series models
}

Оллама (местный)

provider: {
    type: "openai",
    baseUrl: "http://localhost:11434/v1",
    // No apiKey needed for local Ollama
}

Microsoft Foundry Local

Microsoft Foundry Local позволяет запускать модели ИИ локально на вашем устройстве с API, совместимым с OpenAI. Установите его через Foundry Local CLI, затем направьте SDK на вашу локальную конечную точку:

provider: {
    type: "openai",
    baseUrl: "http://localhost:<PORT>/v1",
    // No apiKey needed for local Foundry Local
}

Примечание.

Foundry Local начинается с динамического порта — порт не фиксирован. Используйте foundry service status для подтверждения порта, на котором сервис сейчас слушает, затем используйте этот порт в вашем baseUrl.

Чтобы начать с Foundry Local:

# Windows: Install Foundry Local CLI (requires winget)
winget install Microsoft.FoundryLocal

# macOS / Linux: see https://foundrylocal.ai for installation instructions
# List available models
foundry model list

# Run a model (starts the local server automatically)
foundry model run phi-4-mini

# Check the port the service is running on
foundry service status

Anthropic

provider: {
    type: "anthropic",
    baseUrl: "https://api.anthropic.com",
    apiKey: process.env.ANTHROPIC_API_KEY,
}

Проверка подлинности маркера носителя

Некоторые провайдеры требуют аутентификацию с помощью токенов носителя вместо ключей API:

provider: {
    type: "openai",
    baseUrl: "https://my-custom-endpoint.example.com/v1",
    bearerToken: process.env.MY_BEARER_TOKEN,  // Sets Authorization header
}

Примечание.

Опция bearerToken принимает только статическую строку токенов . SDK не обновляет этот токен автоматически. Если ваш токен истекает, запросы будут неудачными, и вам придётся создать новую сессию с новым токеном.

Индивидуальный список моделей

При использовании BYOK CLI-сервер может не знать, какие модели поддерживает ваш провайдер. Вы можете предоставить индивидуальный onListModels обработчик на уровне клиента, чтобы client.listModels() модели вашего провайдера возвращались в стандартном ModelInfo формате. Это позволяет потребителям на последующей линии находить доступные модели без запроса в CLI.

TypeScript
import { CopilotClient } from "@github/copilot-sdk";
import type { ModelInfo } from "@github/copilot-sdk";

const client = new CopilotClient({
    onListModels: () => [
        {
            id: "my-custom-model",
            name: "My Custom Model",
            capabilities: {
                supports: { vision: false, reasoningEffort: false },
                limits: { max_context_window_tokens: 128000 },
            },
        },
    ],
});
Python
from copilot import CopilotClient
from copilot.client import ModelInfo, ModelCapabilities, ModelSupports, ModelLimits

client = CopilotClient(
    on_list_models=lambda: [
        ModelInfo(
            id="my-custom-model",
            name="My Custom Model",
            capabilities=ModelCapabilities(
                supports=ModelSupports(vision=False, reasoning_effort=False),
                limits=ModelLimits(max_context_window_tokens=128000),
            ),
        )
    ],
)
Go
package main

import (
    "context"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    client := copilot.NewClient(&copilot.ClientOptions{
        OnListModels: func(ctx context.Context) ([]copilot.ModelInfo, error) {
            return []copilot.ModelInfo{
                {
                    ID:   "my-custom-model",
                    Name: "My Custom Model",
                    Capabilities: copilot.ModelCapabilities{
                        Supports: copilot.ModelSupports{Vision: false, ReasoningEffort: false},
                        Limits:   copilot.ModelLimits{MaxContextWindowTokens: 128000},
                    },
                },
            }, nil
        },
    })
    _ = client
}
.NET
using GitHub.Copilot;

var client = new CopilotClient(new CopilotClientOptions
{
    OnListModels = (ct) => Task.FromResult<IList<ModelInfo>>(new List<ModelInfo>
    {
        new()
        {
            Id = "my-custom-model",
            Name = "My Custom Model",
            Capabilities = new ModelCapabilities
            {
                Supports = new ModelSupports { Vision = false, ReasoningEffort = false },
                Limits = new ModelLimits { MaxContextWindowTokens = 128000 }
            }
        }
    })
});
Java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;

var client = new CopilotClient(new CopilotClientOptions()
    .setOnListModels(() -> CompletableFuture.completedFuture(List.of(
        new ModelInfo()
            .setId("my-custom-model")
            .setName("My Custom Model")
            .setCapabilities(new ModelCapabilities()
                .setSupports(new ModelSupports().setVision(false).setReasoningEffort(false))
                .setLimits(new ModelLimits().setMaxContextWindowTokens(128000)))
    )))
);

Результаты кэшируются после первого вызова, как и по умолчанию. Обработчик полностью заменяет RPC CLI models.list — резервного перехода к серверу не происходит.

Ограничения

При использовании BYOK учитывайте следующие ограничения:

Ограничения идентичности

Аутентификация BYOK использует только статические учетные данные.

Вы должны использовать API или статический токен носителя, которым управляете сами.

Ограничения функций

Некоторые функции Copilot могут вести себя иначе с BYOK:

  • Доступность моделей — доступны только модели, поддерживаемые вашим провайдером
  • Rate limiting — Подчиняется тарифным лимитам вашего провайдера, а не Copilot
  • отслеживание использования - Использование отслеживается вашим провайдером, а не GitHub Copilot
  • Запросы на премии - Не учитываются в квотах Copilot премиум

Ограничения, специфичные для поставщика,

ProviderОграничения
Azure AI FoundryНет аутентификации Entra ID; необходимо использовать ключи API
OllamaНет ключа API; только местные; Поддержка моделей варьируется
Microsoft Foundry LocalТолько местные; Доступность модели зависит от аппаратного обеспечения устройства; API-ключ не требуется
OpenAIС учетом ограничений и квот OpenAI

Troubleshooting

Ошибка «Модель не указана»

При использовании BYOK требуется следующий model параметр:

// ❌ Error: Model required with custom provider
const session = await client.createSession({
    provider: { type: "openai", baseUrl: "..." },
});

// ✅ Correct: Model specified
const session = await client.createSession({
    model: "gpt-4",  // Required!
    provider: { type: "openai", baseUrl: "..." },
});

Azure endpoint type confusion

Для Azure конечных точек OpenAI (*.openai.azure.com) используйте правильный тип:

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-4.1",
    provider: {
        type: "azure",
        baseUrl: "https://my-resource.openai.azure.com",
    },
});
// ❌ Wrong: Using "openai" type with native Azure endpoint
provider: {
    type: "openai",  // This won't work correctly
    baseUrl: "https://my-resource.openai.azure.com",
}

// ✅ Correct: Using "azure" type
provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",
}

Однако если ваше развертывание Azure AI Foundry предоставляет совместимый с OpenAI путь конечных точек (например, /openai/v1/), используйте type: "openai":

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-4.1",
    provider: {
        type: "openai",
        baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
    },
});
// ✅ Correct: OpenAI-compatible Azure AI Foundry endpoint
provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
}

Соединение отказано (Оллама)

Убедитесь, что Ollama работает и доступна:

# Check Ollama is running
curl http://localhost:11434/v1/models

# Start Ollama if not running
ollama serve

Соединение отказано (Foundry Local)

Foundry Local использует динамический порт, который может меняться между перезапусками. Подтвердите активный порт:

# Check the service status and port
foundry service status

Обновите свой baseUrl порт, чтобы он совпадал с портом, показанным на выходе. Если сервис не запущен, запустите модель для его запуска:

foundry model run phi-4-mini

Сбой проверки подлинности

  1. Убедитесь, что ваш API ключ правильный и не просрочен
  2. Проверьте baseUrl формат соответствия ожидаемому провайдером
  3. Для токенов носителя убедитесь, что префикс полностью предоставлен (а не просто префикс).

Дальнейшие действия