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

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

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

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

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

## Краткое руководство. Microsoft Foundry

Microsoft Foundry — это распространенный целевой объект развертывания BYOK для предприятий. Ниже приведен полный пример.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
import asyncio
import os
from copilot import CopilotClient
from copilot.session import PermissionHandler

FOUNDRY_MODEL_URL = "https://<resource-name>.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())
```

</div>

<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

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

const FOUNDRY_MODEL_URL = "https://<resource-name>.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();
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
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://<resource-name>.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)
    }
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
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://<resource-name>.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);
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```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://<resource-name>.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();
```

</div>

</div>

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

### Поля ProviderConfig

| Поле                                                                                                                                                                                                                                                                                                            | Тип            | Description                                                                                                                                        |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`                                                                                                                                                                                                                                                                                                          |                |                                                                                                                                                    |
| `"openai"`                                                                                                                                                                                                                                                                                                      |                |                                                                                                                                                    |
| \|                                                                                                                                                                                                                                                                                                              |                |                                                                                                                                                    |
| `"azure"`                                                                                                                                                                                                                                                                                                       |                |                                                                                                                                                    |
| \|                                                                                                                                                                                                                                                                                                              |                |                                                                                                                                                    |
| `"anthropic"`                                                                                                                                                                                                                                                                                                   |                |                                                                                                                                                    |
| Тип провайдера (по умолчанию: `"openai"`)                                                                                                                                                                                                                                                                       |                |                                                                                                                                                    |
| `baseUrl` / `base_url`                                                                                                                                                                                                                                                                                          | string         |                                                                                                                                                    |
| **Обязательно**. URL конечной точки API                                                                                                                                                                                                                                                                         |                |                                                                                                                                                    |
| `apiKey` / `api_key`                                                                                                                                                                                                                                                                                            | string         | Ключ API (опционально для местных провайдеров, таких как Ollama)                                                                                   |
| `bearerToken` / `bearer_token`                                                                                                                                                                                                                                                                                  | string         | Аутентификация токена носителя (имеет приоритет над apiKey)                                                                                        |
| `bearerTokenProvider` / `bearer_token_provider`                                                                                                                                                                                                                                                                 | обратный вызов | Возвращает маркер носителя по запросу (имеет приоритет над `apiKey` и `bearerToken`)                                                               |
| `wireApi` / `wire_api`                                                                                                                                                                                                                                                                                          |                |                                                                                                                                                    |
| `"completions"`                                                                                                                                                                                                                                                                                                 |                |                                                                                                                                                    |
| \|                                                                                                                                                                                                                                                                                                              |                |                                                                                                                                                    |
| `"responses"`                                                                                                                                                                                                                                                                                                   |                |                                                                                                                                                    |
| Выберите `"completions"` для широкой совместимости моделей (API Chat Completions); выберите `"responses"` для многоходного управления состоянием, промежуточного расположения имён инструментов и поддержки рассуждения (API Responses). Anthropic всегда используют API Messages независимо от этой настройки. |                |                                                                                                                                                    |
| `azure.apiVersion` / `azure.api_version`                                                                                                                                                                                                                                                                        | string         | Azure версии API. При установке среда выполнения использует маршрут развертывания с версией; При опущении используется маршрут без `v1` версии GA. |

### Формат 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

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

### Azure OpenAI (собственная конечная точка Azure)

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

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

### Microsoft Foundry (конечная точка, совместимая с OpenAI)

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

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

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

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

### Microsoft Foundry Local

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

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

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

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

```bash
# 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

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

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

Для некоторых поставщиков требуется проверка подлинности маркера носителя вместо ключей API. Укажите статический маркер или `bearerToken`предоставьте обратный `bearerTokenProvider` вызов, который среда выполнения пакета SDK GitHub Copilot вызывается перед запросами поставщика исходящих подключений. Обратная связь или библиотека удостоверений, которую она упаковывает, управляет кэшированием маркеров и обновлением.

Используйте, `bearerToken` когда у приложения уже есть маркер:

```typescript
provider: {
    type: "openai",
    baseUrl: "https://<resource-name>.openai.azure.com/openai/v1/",
    bearerToken: process.env.MY_BEARER_TOKEN,  // Sets Authorization header
}
```

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

Используется `bearerTokenProvider` для получения маркеров по запросу:

<!-- docs-validate: skip -->

```typescript
provider: {
    type: "openai",
    baseUrl: "https://my-custom-endpoint.example.com/v1",
    bearerTokenProvider: async () => {
        return await acquireBearerToken();
    },
}
```

Дополнительные сведения о получении и обновлении маркеров носителя Microsoft Entra см. в разделе [управляемое удостоверение Azure с помощью BYOK](/ru/copilot/how-tos/copilot-sdk/setup/azure-managed-identity).

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

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

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```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 },
            },
        },
    ],
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```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),
            ),
        )
    ],
)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
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: copilot.Int(128000)},
                    },
                },
            }, nil
        },
    })
    _ = client
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
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 }
            }
        }
    })
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```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)))
    )))
);
```

</div>

</div>

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

## Ограничения

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

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

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

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

| Provider                                           | Ограничения                                                                                             |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| [Microsoft Foundry Local](https://foundrylocal.ai) | Только местные; Доступность модели зависит от аппаратного обеспечения устройства; API-ключ не требуется |
| Ollama                                             | Нет ключа API; только местные; Поддержка моделей варьируется                                            |
| OpenAI                                             | С учетом ограничений и квот OpenAI                                                                      |

## Troubleshooting

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

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

```typescript
// ❌ 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

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

```typescript
// ❌ 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",
}
```

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

```typescript
// ✅ Correct: OpenAI-compatible Microsoft Foundry endpoint
provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
}
```

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

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

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

# Start Ollama if not running
ollama serve
```

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

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

```bash
# Check the service status and port
foundry service status
```

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

```bash
foundry model run phi-4-mini
```

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

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

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

* [АВТОТИТРЫ](/ru/copilot/how-tos/copilot-sdk/auth) — Изучите обо всех методах аутентификации
* [Создайте своё первое приложение на базе Copilot](/ru/copilot/how-tos/copilot-sdk/getting-started) — Создайте своё первое приложение на базе Copilot