Thanks to visit codestin.com
Credit goes to docs.github.com

Skip to main content

BYOK (Bring Your Own Key - traga sua própria chave)

O BYOK permite que você use o SDK do Copilot com suas próprias chaves de API de provedores de modelos, sem passar pela autenticação do GitHub Copilot. Isso é útil para implantações empresariais, hospedagem de modelo personalizado ou quando você deseja cobrança direta com seu provedor de modelo.

Provedores com suporte

FornecedorDigite um valorObservações
OpenAI"openai"API OpenAI e endpoints compatíveis com OpenAI
Azure OpenAI /Fábrica de IA do Azure"azure"modelos hospedados no Azure
Anthropic"anthropic"Modelos de Claude
Ollama"openai"Modelos locais por meio da API compatível com OpenAI
Microsoft Foundry Local"openai"Executar modelos de IA localmente em seu dispositivo por meio da API compatível com OpenAI
Outros compatíveis com OpenAI"openai"vLLM, LiteLLM, etc.

Início rápido: Fábrica de IA do Azure

O Fábrica de IA do Azure (antigo Azure OpenAI) é um destino de implantação BYOK comum para empresas. Aqui está um exemplo completo:

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

Referência de configuração do provedor

Campos ProviderConfig

CampoTipoDescription
type
"openai"
|
"azure"
|
"anthropic"
Tipo de provedor (padrão: "openai")
baseUrl / base_urlcadeia
Obrigatório. URL do endpoint da API
apiKey / api_keycadeiaChave de API (opcional para provedores locais como o Ollama)
bearerToken / bearer_tokencadeiaAutenticação de token de portador (tem precedência sobre a apiKey)
wireApi / wire_api
"completions"
|
"responses"
Selecione "completions" para ampla compatibilidade com modelos (a API Chat Completions); selecione "responses" para gerenciamento de estado em vários turnos, namespace de ferramentas e suporte a raciocínio (a API Responses). Anthropic modelos sempre usam a API de Mensagens independentemente dessa configuração.
azure.apiVersion / azure.api_versioncadeiaAzure versão da API (padrão: "2024-10-21")

Formato da API do Wire

A wireApi configuração determina qual formato de API OpenAI usar:

  • "completions" (padrão) – API de Conclusões de Chat (/chat/completions) para ampla compatibilidade de modelo.
  • "responses" - API Responses para gerenciamento de estado multiturno, uso de namespaces para ferramentas e suporte ao raciocínio.

Os modelos da Anthropic sempre usam a API Messages da Anthropic, independentemente dessa configuração.

Notas específicas do tipo

OpenAI (type: "openai")

  • Funciona com a API da OpenAI e qualquer endpoint compatível com a OpenAI
  • baseUrl deve incluir o caminho completo (por exemplo, https://api.openai.com/v1)

Azure (type: "azure")

  • Usar para endpoints nativos do Azure OpenAI
  • baseUrl deve ser apenas o host (por exemplo, https://my-resource.openai.azure.com)
  • NÃO inclua /openai/v1 na URL – o SDK manipula a construção do caminho

Anthropic (type: "anthropic")

  • Para acesso direto à API da Anthropic
  • Usa o formato de API específico de Claude

Configurações de exemplo

OpenAI direto

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

Azure OpenAI (ponto de extremidade nativo do Azure)

Utilize type: "azure" para os endpoints em *.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",
    },
}

Fábrica de IA do Azure (endpoint compatível com OpenAI)

Para implantações do Fábrica de IA do Azure com /openai/v1/ endpoints, use 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
}

Ollama (local)

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

Microsoft Foundry Local

Microsoft Foundry Local permite executar modelos de IA localmente em seu próprio dispositivo com uma API compatível com OpenAI. Instale através do Foundry Local CLI e direcione o SDK para o endpoint local.

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

Observação

Foundry Local inicia em uma porta dinâmica– a porta não é fixa. Use foundry service status para confirmar a porta em que o serviço está escutando no momento e use essa porta em sua baseUrl.

Para começar a usar o 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,
}

Autenticação com Bearer Token

Alguns provedores exigem autenticação de token de portador em vez de chaves de API:

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

Observação

A opção bearerToken aceita apenas uma string de token estático. O SDK não atualiza esse token automaticamente. Se o token expirar, as solicitações falharão e você precisará criar uma nova sessão com um novo token.

Listagem de modelo personalizado

Ao usar BYOK, o servidor da CLI pode não saber quais modelos seu provedor dá suporte. Você pode fornecer um manipulador personalizado onListModels no nível do cliente para que client.listModels() retorne os modelos do provedor no formato padrão ModelInfo . Isso permite que os consumidores downstream descubram modelos disponíveis sem consultar a 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)))
    )))
);

Os resultados são armazenados em cache após a primeira chamada, assim como o comportamento padrão. O manipulador substitui completamente o RPC da models.list CLI— não ocorre nenhum fallback para o servidor.

Limitações

Ao usar BYOK, lembre-se dessas limitações:

Limitações de identidade

A autenticação BYOK usa apenas credenciais estáticas.

Você deve usar uma chave de API ou um token de portador estático que você mesmo gerencie.

Limitações de funcionalidades

Alguns recursos de Copilot podem se comportar de forma diferente com BYOK:

  • Disponibilidade do modelo – somente os modelos compatíveis com seu provedor estão disponíveis
  • Limitação de taxa - Sujeito aos limites de taxa do seu provedor, não aos do Copilot
  • Usage tracking - O uso é acompanhado pelo seu provedor, não GitHub Copilot
  • Solicitações premium - Não são contabilizadas nas cotas de solicitações premium do Copilot

Limitações específicas do provedor

FornecedorLimitações
Fábrica de IA do AzureNenhuma autenticação de Entra ID; deve usar chaves de API
OllamaNenhuma chave de API; somente local; O suporte ao modelo varia
Microsoft Foundry LocalSomente local; A disponibilidade do modelo depende do hardware do dispositivo; nenhuma chave de API necessária
OpenAISujeito a limites de taxa e cotas do OpenAI

Troubleshooting

Erro "Modelo não especificado"

Ao usar BYOK, o model parâmetro é necessário:

// ❌ 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: "..." },
});

Confusão quanto ao tipo de ponto de extremidade no Azure

Para pontos de extremidade do Azure OpenAI (*.openai.azure.com), use o tipo correto:

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",
}

No entanto, se sua implantação do Fábrica de IA do Azure fornecer um caminho de endpoint compatível com OpenAI (por exemplo, /openai/v1/), use 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/",
}

Conexão recusada (Ollama)

Verifique se o Ollama está em execução e acessível:

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

# Start Ollama if not running
ollama serve

Conexão recusada (Foundry Local)

O Foundry Local usa uma porta dinâmica que pode mudar entre reinicializações. Confirme a porta ativa:

# Check the service status and port
foundry service status

Atualize-o baseUrl para corresponder à porta mostrada na saída. Se o serviço não estiver em execução, inicie um modelo para iniciá-lo:

foundry model run phi-4-mini

Falha na autenticação

  1. Verifique se a chave de API está correta e não expirou
  2. Verifique se o baseUrl corresponde ao formato esperado pelo seu provedor
  3. Para tokens de portador, verifique se o token completo é fornecido (não apenas um prefixo)

Próximas Etapas